* Re: [PATCH 08/44] kernel: Move pm_power_off to common code
From: Vineet Gupta @ 2014-10-09 10:35 UTC (permalink / raw)
To: Guenter Roeck, linux-kernel@vger.kernel.org
Cc: linux-m32r-ja@ml.linux-m32r.org, linux-mips@linux-mips.org,
linux-efi@vger.kernel.org, linux-ia64@vger.kernel.org,
Steven Miao, linux-xtensa@linux-xtensa.org, Boris Ostrovsky,
Catalin Marinas, Will Deacon, Jeff Dike, David Howells,
Max Filippov, Paul Mackerras, Ralf Baechle, Pavel Machek,
H. Peter Anvin, Guan Xuetao, Thomas Gleixner, Lennox Wu,
Hans-Christian Egtvedt, devel@driverdev.osuosl.org,
linux-s390@vger.kernel.org, Jesper Nilsson,
lguest@lists.ozlabs.org, Russell King,
linux-c6x-dev@linux-c6x.org, Len Brown, David S. Miller,
linux-hexagon@vger.kernel.org, Hirokazu Takata,
linux-sh@vger.kernel.org, James E.J. Bottomley,
linux-acpi@vger.kernel.org, Ingo Molnar, Geert Uytterhoeven,
Mark Salter, xen-devel@lists.xenproject.org, Matt Turner,
Chen Liqin, Jonas Bonn, Haavard Skinnemoen,
devicetree@vger.kernel.org, James Hogan,
user-mode-linux-devel@lists.sourceforge.net,
linux-pm@vger.kernel.org, Aurelien Jacquiot, Heiko Carstens,
Vineet Gupta, adi-buildroot-devel@lists.sourceforge.net,
Chris Metcalf, Konrad Rzeszutek Wilk, Mikael Starvik,
Richard Weinberger, linux-m68k@lists.linux-m68k.org,
linux-am33-list@redhat.com, Ivan Kokshaysky,
linux-tegra@vger.kernel.org,
openipmi-developer@lists.sourceforge.net,
linux-metag@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Richard Henderson, Chris Zankel, Michal Simek, Tony Luck,
linux-parisc@vger.kernel.org, linux-cris-kernel@axis.com,
Rafael J. Wysocki, Fenghua Yu, Richard Kuo, David Vrabel,
linux-alpha@vger.kernel.org, Martin Schwidefsky, Koichi Yasutake,
linuxppc-dev@lists.ozlabs.org, Helge Deller
In-Reply-To: <1412659726-29957-9-git-send-email-linux@roeck-us.net>
On Tuesday 07 October 2014 11:01 AM, Guenter Roeck wrote:
diff --git a/arch/arc/kernel/reset.c b/arch/arc/kernel/reset.c
index 2768fa1..8a4fc47 100644
--- a/arch/arc/kernel/reset.c
+++ b/arch/arc/kernel/reset.c
@@ -26,9 +26,6 @@ void machine_restart(char *__unused)
void machine_power_off(void)
{
- /* FIXME :: power off ??? */
+ do_kernel_poweroff();
machine_halt();
}
-
-void (*pm_power_off) (void) =3D NULL;
-EXPORT_SYMBOL(pm_power_off);
Acked-by: Vineet Gupta <vgupta@synopsys.com><mailto:vgupta@synopsys.com>
Thx,
-Vineet
^ permalink raw reply related
* Re: [PATCH 03/44] hibernate: Call have_kernel_poweroff instead of checking pm_power_off
From: Pavel Machek @ 2014-10-09 10:32 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-m32r-ja, linux-mips, linux-efi, linux-ia64, Len Brown,
linux-xtensa, devel, linux-s390, lguest, linux-c6x-dev,
linux-hexagon, linux-sh, linux-acpi, xen-devel, devicetree,
user-mode-linux-devel, linux-pm, adi-buildroot-devel, linux-m68k,
linux-am33-list, linux-tegra, openipmi-developer, linux-metag,
linux-arm-kernel, linux-parisc, linux-cris-kernel,
Rafael J. Wysocki, linux-kernel, linux-alpha, linuxppc-dev
In-Reply-To: <1412659726-29957-4-git-send-email-linux@roeck-us.net>
On Mon 2014-10-06 22:28:05, Guenter Roeck wrote:
> Poweroff handlers may now be installed with register_poweroff_handler.
> Use the new API function have_kernel_poweroff to determine if a poweroff
> handler has been installed.
>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Cc: Pavel Machek <pavel@ucw.cz>
> Cc: Len Brown <len.brown@intel.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
> kernel/power/hibernate.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
> index a9dfa79..20353c5 100644
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -602,7 +602,7 @@ static void power_down(void)
> case HIBERNATION_PLATFORM:
> hibernation_platform_enter();
> case HIBERNATION_SHUTDOWN:
> - if (pm_power_off)
> + if (have_kernel_poweroff())
> kernel_power_off();
> break;
poweroff -> power_off.
But if you are playing with this, anyway... does it make sense to
introduce kernel_power_off() that just works, no need to check
have_..?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* Re: [PATCH 01/44] kernel: Add support for poweroff handler call chain
From: Pavel Machek @ 2014-10-09 10:31 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-m32r-ja, linux-mips, linux-efi, linux-ia64, Heiko Stuebner,
Len Brown, linux-xtensa, devel, linux-s390, lguest, linux-c6x-dev,
linux-hexagon, linux-sh, Alexander Graf, linux-acpi,
Geert Uytterhoeven, xen-devel, devicetree, user-mode-linux-devel,
linux-pm, adi-buildroot-devel, linux-m68k, linux-am33-list,
linux-tegra, openipmi-developer, linux-metag, linux-arm-kernel,
linux-parisc, linux-cris-kernel, Rafael J. Wysocki, linux-kernel,
linux-alpha, Andrew Morton, Romain Perier, linuxppc-dev
In-Reply-To: <1412659726-29957-2-git-send-email-linux@roeck-us.net>
Hi!
> +/**
> + * register_poweroff_handler_simple - Register function to be called to power off
> + * the system
> + * @handler: Function to be called to power off the system
> + * @priority: Handler priority. For priority guidelines see
> + * register_poweroff_handler.
> + *
> + * This is a simplified version of register_poweroff_handler. It does not
> + * take a notifier as argument, but a function pointer. The function
> + * registers a poweroff handler with specified priority. Poweroff
> + * handlers registered with this function can not be unregistered,
> + * and only a single poweroff handler can be installed using it.
> + *
> + * This function must not be called from modules and is therefore
> + * not exported.
> + *
> + * Returns -EBUSY if a poweroff handler has already been registered
> + * using register_poweroff_handler_simple. Otherwise returns zero,
> + * since atomic_notifier_chain_register() currently always returns zero.
> + */
> +int register_poweroff_handler_simple(void (*handler)(void), int priority)
> +{
> + char symname[KSYM_NAME_LEN];
> +
> + if (poweroff_handler_data.handler) {
> + lookup_symbol_name((unsigned long)poweroff_handler_data.handler,
> + symname);
> + pr_warn("Poweroff function already registered (%s)", symname);
> + lookup_symbol_name((unsigned long)handler, symname);
> + pr_cont(", cannot register %s\n", symname);
> + return -EBUSY;
> + }
Dunno, are you maybe overdoing the debugging infrastructure a bit?
This is not going to happen in production, and if it does happen,
developer can look the symbol name himself.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* Re: [PATCH 08/44] kernel: Move pm_power_off to common code
From: Catalin Marinas @ 2014-10-09 10:28 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-m32r-ja@ml.linux-m32r.org, linux-mips@linux-mips.org,
linux-m68k@vger.kernel.org, linux-efi@vger.kernel.org,
linux-ia64@vger.kernel.org, Steven Miao,
linux-xtensa@linux-xtensa.org, Boris Ostrovsky, Will Deacon,
David Howells, Max Filippov, Paul Mackerras, Ralf Baechle,
Pavel Machek, H. Peter Anvin, Guan Xuetao, Thomas Gleixner,
Lennox Wu, Hans-Christian Egtvedt, devel@driverdev.osuosl.org,
linux-s390@vger.kernel.org, Jesper Nilsson,
lguest@lists.ozlabs.org, Russell King,
linux-c6x-dev@linux-c6x.org, Len Brown, David S. Miller,
linux-hexagon@vger.kernel.org, Hirokazu Takata,
linux-sh@vger.kernel.org, James E.J. Bottomley,
linux-acpi@vger.kernel.org, Ingo Molnar, Geert Uytterhoeven,
msalter@redhat.com, xen-devel@lists.xenproject.org, Matt Turner,
Chen Liqin, Jonas Bonn, Haavard Skinnemoen,
devicetree@vger.kernel.org, James Hogan,
user-mode-linux-devel@lists.sourceforge.net,
linux-pm@vger.kernel.org, Aurelien Jacquiot, Heiko Carstens,
Jeff Dike, adi-buildroot-devel@lists.sourceforge.net,
Chris Metcalf, Konrad Rzeszutek Wilk, Mikael Starvik,
Richard Weinberger, linux-am33-list@redhat.com, Ivan Kokshaysky,
linux-tegra@vger.kernel.org,
openipmi-developer@lists.sourceforge.net,
linux-metag@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Richard Henderson, Chris Zankel, Michal Simek, Tony Luck,
linux-parisc@vger.kernel.org, linux-cris-kernel@axis.com,
Vineet Gupta, Rafael J. Wysocki, linux-kernel@vger.kernel.org,
Fenghua Yu, Richard Kuo, David Vrabel,
linux-alpha@vger.kernel.org, Martin Schwidefsky,
yasutake.koichi@jp.panasonic.com, linuxppc-dev@lists.ozlabs.org,
Helge Deller
In-Reply-To: <1412659726-29957-9-git-send-email-linux@roeck-us.net>
On Tue, Oct 07, 2014 at 06:28:10AM +0100, Guenter Roeck wrote:
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index e0ef8ba..db396bb 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -94,8 +94,6 @@ void soft_restart(unsigned long addr)
> /*
> * Function pointers to optional machine specific functions
> */
> -void (*pm_power_off)(void);
> -EXPORT_SYMBOL_GPL(pm_power_off);
>
> void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
>
> @@ -155,8 +153,7 @@ void machine_power_off(void)
> {
> local_irq_disable();
> smp_send_stop();
> - if (pm_power_off)
> - pm_power_off();
> + do_kernel_poweroff();
> }
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* Re: [PATCH v2 2/3] powerpc/kvm/book3s_hv: Enable CPUs to run guest after waking up from fast-sleep
From: Preeti U Murthy @ 2014-10-09 10:03 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Shreyas B. Prabhu
Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <1412658682.30859.137.camel@pasglop>
On 10/07/2014 10:41 AM, Benjamin Herrenschmidt wrote:
> On Wed, 2014-10-01 at 13:15 +0530, Shreyas B. Prabhu wrote:
>>
>> diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
>> index 050f79a..c64f3cc0 100644
>> --- a/arch/powerpc/kernel/exceptions-64s.S
>> +++ b/arch/powerpc/kernel/exceptions-64s.S
>> @@ -100,25 +100,8 @@ system_reset_pSeries:
>> SET_SCRATCH0(r13)
>> #ifdef CONFIG_PPC_P7_NAP
>> BEGIN_FTR_SECTION
>> - /* Running native on arch 2.06 or later, check if we are
>> - * waking up from nap. We only handle no state loss and
>> - * supervisor state loss. We do -not- handle hypervisor
>> - * state loss at this time.
>> - */
>> - mfspr r13,SPRN_SRR1
>> - rlwinm. r13,r13,47-31,30,31
>> - beq 9f
>>
>> - /* waking up from powersave (nap) state */
>> - cmpwi cr1,r13,2
>> - /* Total loss of HV state is fatal, we could try to use the
>> - * PIR to locate a PACA, then use an emergency stack etc...
>> - * OPAL v3 based powernv platforms have new idle states
>> - * which fall in this catagory.
>> - */
>> - bgt cr1,8f
>> GET_PACA(r13)
>> -
>> #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
>> li r0,KVM_HWTHREAD_IN_KERNEL
>> stb r0,HSTATE_HWTHREAD_STATE(r13)
>> @@ -131,13 +114,27 @@ BEGIN_FTR_SECTION
>> 1:
>> #endif
>
> So you moved the state loss check to after the KVM check ? Was this
> reviewed by Paul ? Is that ok ? (Does this match what we have in
> PowerKVM ?). Is it possible that we end up calling kvm_start_guest
> after a HV state loss or do we know for sure that this won't happen
> for a reason or another ? If that's the case, then that reason needs
> to be clearly documented here in a comment.
This wont happen because the first thread in the core which comes out of
an idle state which has a state loss will not enter into KVM since the
HSTATE_HWTHREAD_STATE is not yet set. It continues on to restore the
lost state.
This thread sets the HSTATE_HWTHREAD_STATE and wakes up the remaining
threads in the core. These sibling threads enter kvm directly not
requiring to restore lost state since the first thread has restored it
anyway. So we are safe. We will certainly add a comment there.
Thanks
Regards
Preeti U Murthy
^ permalink raw reply
* Re: [PATCH 0/2] net: fs_enet: Remove non NAPI RX and add NAPI for TX
From: leroy christophe @ 2014-10-09 5:23 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linuxppc-dev, linux-kernel, vbordug
In-Reply-To: <20141008.160301.394010995208640934.davem@davemloft.net>
Le 08/10/2014 22:03, David Miller a écrit :
> From: Christophe Leroy <christophe.leroy@c-s.fr>
> Date: Tue, 7 Oct 2014 15:04:53 +0200 (CEST)
>
>> When using a MPC8xx as a router, 'perf' shows a significant time spent in
>> fs_enet_interrupt() and fs_enet_start_xmit().
>> 'perf annotate' shows that the time spent in fs_enet_start_xmit is indeed spent
>> between spin_unlock_irqrestore() and the following instruction, hence in
>> interrupt handling. This is due to the TX complete interrupt that fires after
>> each transmitted packet.
>> This patchset first remove all non NAPI handling as NAPI has become the only
>> mode for RX, then adds NAPI for handling TX complete.
>> This improves NAT TCP throughput by 21% on MPC885 with FEC.
>>
>> Tested on MPC885 with FEC.
>>
>> [PATCH 1/2] net: fs_enet: Remove non NAPI RX
>> [PATCH 2/2] net: fs_enet: Add NAPI TX
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> Series applied, thanks.
>
> Any particular reason you didn't just put the TX reclaim calls into
> the existing NAPI handler?
Not really. I used the gianfar.c driver as a model.
>
> That's what other drivers do, because TX reclaim can make SKBs
> available for RX packet receive on the local cpu. So generally you
> have one NAPI context that first does any pending TX reclaim, then
> polls the RX ring for new packets.
>
Is that a better approach ?
^ permalink raw reply
* Re: [PATCH V3 2/3] powerpc, ptrace: Enable support for transactional memory register sets
From: Anshuman Khandual @ 2014-10-09 5:04 UTC (permalink / raw)
To: Sukadev Bhattiprolu
Cc: mikey, james.hogan, avagin, Paul.Clothier, davem, peterz, palves,
linux-kernel, oleg, dhowells, linuxppc-dev, davej, akpm, tglx
In-Reply-To: <20140827213514.GA11489@us.ibm.com>
On 08/28/2014 03:05 AM, Sukadev Bhattiprolu wrote:
> Anshuman Khandual [khandual@linux.vnet.ibm.com] wrote:
> | This patch enables get and set of transactional memory related register
> | sets through PTRACE_GETREGSET/PTRACE_SETREGSET interface by implementing
> | four new powerpc specific register sets i.e REGSET_TM_SPR, REGSET_TM_CGPR,
> | REGSET_TM_CFPR, REGSET_CVMX support corresponding to these following new
> | ELF core note types added previously in this regard.
> |
> | (1) NT_PPC_TM_SPR
> | (2) NT_PPC_TM_CGPR
> | (3) NT_PPC_TM_CFPR
> | (4) NT_PPC_TM_CVMX
> |
> | Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
> | ---
> | arch/powerpc/include/asm/switch_to.h | 8 +
> | arch/powerpc/kernel/process.c | 24 ++
> | arch/powerpc/kernel/ptrace.c | 792 +++++++++++++++++++++++++++++++++--
> | 3 files changed, 795 insertions(+), 29 deletions(-)
> |
> | diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h
> | index 0e83e7d..2737f46 100644
> | --- a/arch/powerpc/include/asm/switch_to.h
> | +++ b/arch/powerpc/include/asm/switch_to.h
> | @@ -80,6 +80,14 @@ static inline void flush_spe_to_thread(struct task_struct *t)
> | }
> | #endif
> |
> | +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> | +extern void flush_tmregs_to_thread(struct task_struct *);
> | +#else
> | +static inline void flush_tmregs_to_thread(struct task_struct *t)
> | +{
> | +}
> | +#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
> | +
> | static inline void clear_task_ebb(struct task_struct *t)
> | {
> | #ifdef CONFIG_PPC_BOOK3S_64
> | diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> | index 31d0215..e247898 100644
> | --- a/arch/powerpc/kernel/process.c
> | +++ b/arch/powerpc/kernel/process.c
> | @@ -695,6 +695,30 @@ static inline void __switch_to_tm(struct task_struct *prev)
> | }
> | }
> |
> | +void flush_tmregs_to_thread(struct task_struct *tsk)
> | +{
> | + /*
> | + * If task is not current, it should have been flushed
> | + * already to it's thread_struct during __switch_to().
> | + */
> | + if (tsk != current)
> | + return;
> | +
> | + preempt_disable();
> | + if (tsk->thread.regs) {
> | + /*
> | + * If we are still current, the TM state need to
> | + * be flushed to thread_struct as it will be still
> | + * present in the current cpu.
> | + */
> | + if (MSR_TM_ACTIVE(tsk->thread.regs->msr)) {
> | + __switch_to_tm(tsk);
> | + tm_recheckpoint_new_task(tsk);
> | + }
> | + }
> | + preempt_enable();
> | +}
> | +
> | /*
> | * This is called if we are on the way out to userspace and the
> | * TIF_RESTORE_TM flag is set. It checks if we need to reload
> | diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
> | index 2e3d2bf..17642ef 100644
> | --- a/arch/powerpc/kernel/ptrace.c
> | +++ b/arch/powerpc/kernel/ptrace.c
> | @@ -357,6 +357,17 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
> | return ret;
> | }
> |
> | +/*
> | + * When any transaction is active, "thread_struct->transact_fp" holds
> | + * the current running value of all FPR registers and "thread_struct->
> | + * fp_state" holds the last checkpointed FPR registers state for the
> | + * current transaction.
> | + *
> | + * struct data {
> | + * u64 fpr[32];
> | + * u64 fpscr;
> | + * };
> | + */
>
> Maybe a reference to 'struct thread_fp_state' in the comments will help ?
Okay, will try to add.
>
>
> | static int fpr_get(struct task_struct *target, const struct user_regset *regset,
> | unsigned int pos, unsigned int count,
> | void *kbuf, void __user *ubuf)
> | @@ -365,21 +376,41 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
> | u64 buf[33];
> | int i;
> | #endif
> | - flush_fp_to_thread(target);
> | + if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
> | + flush_fp_to_thread(target);
> | + flush_altivec_to_thread(target);
> | + flush_tmregs_to_thread(target);
> | + } else {
> | + flush_fp_to_thread(target);
> | + }
>
> flush_fp_to_thread(target) is uncondtional - so could be outside
> the if and else blocks ?
yes
>
> |
> | #ifdef CONFIG_VSX
> | /* copy to local buffer then write that out */
> | - for (i = 0; i < 32 ; i++)
> | - buf[i] = target->thread.TS_FPR(i);
> | - buf[32] = target->thread.fp_state.fpscr;
> | + if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
> | + for (i = 0; i < 32 ; i++)
> | + buf[i] = target->thread.TS_TRANS_FPR(i);
> | + buf[32] = target->thread.transact_fp.fpscr;
> | + } else {
> | + for (i = 0; i < 32 ; i++)
> | + buf[i] = target->thread.TS_FPR(i);
> | + buf[32] = target->thread.fp_state.fpscr;
> | + }
> | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
> |
> | #else
> | - BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
> | - offsetof(struct thread_fp_state, fpr[32][0]));
> | + if (MSR_TM_ACTIVE(tsk->thread.regs->msr)) {
> | + BUILD_BUG_ON(offsetof(struct transact_fp, fpscr) !=
> | + offsetof(struct transact_fp, fpr[32][0]));
>
> Is MSR_TM_ACTIVE() a run time check or compile time ?
Its a run time check.
> ie is there a reason to move the compile time check into the if block ?
Have cleaned up all of these.
>
> |
> | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.transact_fp, 0, -1);
> | + } esle {
> | + BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
> | + offsetof(struct thread_fp_state, fpr[32][0]));
> | +
> | + return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | &target->thread.fp_state, 0, -1);
> | + }
> | #endif
> | }
> |
> | @@ -391,23 +422,44 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
> | u64 buf[33];
> | int i;
> | #endif
> | - flush_fp_to_thread(target);
> | + if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
> | + flush_fp_to_thread(target);
> | + flush_altivec_to_thread(target);
> | + flush_tmregs_to_thread(target);
> | + } else {
> | + flush_fp_to_thread(target);
> | + }
> |
>
> As mentioned above, flush_fp_to_thread() could be outside the if block.
sure
> | #ifdef CONFIG_VSX
> | /* copy to local buffer then write that out */
> | i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
> | if (i)
> | return i;
> | - for (i = 0; i < 32 ; i++)
> | - target->thread.TS_FPR(i) = buf[i];
> | - target->thread.fp_state.fpscr = buf[32];
> | + for (i = 0; i < 32 ; i++) {
> | + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> | + target->thread.TS_TRANS_FPR(i) = buf[i];
> | + else
> | + target->thread.TS_FPR(i) = buf[i];
> | + }
> | + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> | + target->thread.transact_fp.fpscr = buf[32];
> | + else
> | + target->thread.fp_state.fpscr = buf[32];
>
> I think this code is easier to read than the similar code above
> in fpr_get() where you have the 'for' loop in both if and else blocks.
Have done some modifications here.
>
> | return 0;
> | #else
> | - BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
> | - offsetof(struct thread_fp_state, fpr[32][0]));
> | + if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
> | + BUILD_BUG_ON(offsetof(struct transact_fp, fpscr) !=
> | + offsetof(struct transact_fp, fpr[32][0]));
> |
> | - return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | - &target->thread.fp_state, 0, -1);
> | + return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.transact_fp, 0, -1);
> | + } else {
> | + BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
> | + offsetof(struct thread_fp_state, fpr[32][0]));
> | +
> | + return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.fp_state, 0, -1);
> | + }
> | #endif
> | }
> |
> | @@ -432,20 +484,44 @@ static int vr_active(struct task_struct *target,
> | return target->thread.used_vr ? regset->n : 0;
> | }
> |
> | +/*
> | + * When any transaction is active, "thread_struct->transact_vr" holds
> | + * the current running value of all VMX registers and "thread_struct->
> | + * vr_state" holds the last checkpointed value of VMX registers for the
> | + * current transaction.
> | + *
> | + * struct data {
> | + * vector128 vr[32];
> | + * vector128 vscr;
> | + * vector128 vrsave;
> | + * };
> | + */
> | static int vr_get(struct task_struct *target, const struct user_regset *regset,
> | unsigned int pos, unsigned int count,
> | void *kbuf, void __user *ubuf)
> | {
> | int ret;
> | + struct thread_vr_state *addr;
> |
> | - flush_altivec_to_thread(target);
> | + if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
> | + flush_fp_to_thread(target);
> | + flush_altivec_to_thread(target);
>
> Is order of flush_fp_to_thread() and flush_altivec_to_thread()
> significant or can we call flush_altivec_to_thread() unconditionally
> outside the if block ?
We can move it outside the if block.
> | + flush_tmregs_to_thread(target);
> | + } else {
> | + flush_altivec_to_thread(target);
> | + }
> |
> | BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
> | offsetof(struct thread_vr_state, vr[32]));
> |
> | + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> | + addr = &target->thread.transact_vr;
> | + else
> | + addr = &target->thread.vr_state;
> | +
> | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | - &target->thread.vr_state, 0,
> | - 33 * sizeof(vector128));
> | + addr, 0, 33 * sizeof(vector128));
> | +
> | if (!ret) {
> | /*
> | * Copy out only the low-order word of vrsave.
> | @@ -455,11 +531,14 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
> | u32 word;
> | } vrsave;
> | memset(&vrsave, 0, sizeof(vrsave));
> | - vrsave.word = target->thread.vrsave;
> | + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> | + vrsave.word = target->thread.transact_vrsave;
> | + else
> | + vrsave.word = target->thread.vrsave;
> | +
> | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
> | 33 * sizeof(vector128), -1);
> | }
> | -
> | return ret;
> | }
> |
> | @@ -467,16 +546,27 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
> | unsigned int pos, unsigned int count,
> | const void *kbuf, const void __user *ubuf)
> | {
> | + struct thread_vr_state *addr;
> | int ret;
> |
> | - flush_altivec_to_thread(target);
> | + if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
> | + flush_fp_to_thread(target);
> | + flush_altivec_to_thread(target);
> | + flush_tmregs_to_thread(target);
> | + } else {
> | + flush_altivec_to_thread(target);
> | + }
> |
> | BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
> | offsetof(struct thread_vr_state, vr[32]));
> |
> | + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> | + addr = &target->thread.transact_vr;
> | + else
> | + addr = &target->thread.vr_state;
> | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | - &target->thread.vr_state, 0,
> | - 33 * sizeof(vector128));
> | + addr, 0, 33 * sizeof(vector128));
> | +
> | if (!ret && count > 0) {
> | /*
> | * We use only the first word of vrsave.
> | @@ -486,13 +576,21 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
> | u32 word;
> | } vrsave;
> | memset(&vrsave, 0, sizeof(vrsave));
> | - vrsave.word = target->thread.vrsave;
> | +
> | + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> | + vrsave.word = target->thread.transact_vrsave;
> | + else
> | + vrsave.word = target->thread.vrsave;
> | +
> | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
> | 33 * sizeof(vector128), -1);
> | - if (!ret)
> | - target->thread.vrsave = vrsave.word;
> | + if (!ret) {
> | + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> | + target->thread.transact_vrsave = vrsave.word;
> | + else
> | + target->thread.vrsave = vrsave.word;
> | + }
> | }
> | -
> | return ret;
> | }
> | #endif /* CONFIG_ALTIVEC */
> | @@ -613,6 +711,442 @@ static int evr_set(struct task_struct *target, const struct user_regset *regset,
> | }
> | #endif /* CONFIG_SPE */
> |
> | +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> | +
> | +static int tm_spr_active(struct task_struct *target,
> | + const struct user_regset *regset)
> | +{
> | + if (!cpu_has_feature(CPU_FTR_TM))
> | + return -ENODEV;
> | +
> | + if(!MSR_TM_ACTIVE(target->thread.regs->msr))
> | + return 0;
> | +
> | + return regset->n;
> | +}
> | +/*
> | + * Transactional memory SPR
> | + *
> | + * struct {
> | + * u64 tm_tfhar;
> | + * u64 tm_texasr;
> | + * u64 tm_tfiar;
> | + * unsigned long tm_orig_msr;
> | + * unsigned long tm_tar;
> | + * unsigned long tm_ppr;
> | + * unsigned long tm_dscr;
> | + * };
> | + */
> | +static int tm_spr_get(struct task_struct *target, const struct user_regset *regset,
> | + unsigned int pos, unsigned int count,
> | + void *kbuf, void __user *ubuf)
> | +{
> | + int ret;
> | +
> | + if (!cpu_has_feature(CPU_FTR_TM))
> | + return -ENODEV;
> | +
> | + if(!MSR_TM_ACTIVE(target->thread.regs->msr))
> | + return -ENODATA;
> | +
> | + flush_fp_to_thread(target);
> | + flush_altivec_to_thread(target);
> | + flush_tmregs_to_thread(target);
> | +
>
> Can we copy all the values ot a local buf and then do a single
> copyout to user space ?
In the present code, it can copy out registers to user space
till one attempt fails. Just one copy out to user space will
not give this opportunity. Either all of them go or none of
them goes.
>
> | + /* TFHAR register */
> | + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_tfhar, 0, sizeof(u64));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfhar) +
> | + sizeof(u64) != offsetof(struct thread_struct, tm_texasr));
> | +
> | + /* TEXASR register */
> | + if (!ret)
> | + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_texasr, sizeof(u64), 2 * sizeof(u64));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, tm_texasr) +
> | + sizeof(u64) != offsetof(struct thread_struct, tm_tfiar));
> | +
> | + /* TFIAR register */
> | + if (!ret)
> | + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_tfiar, 2 * sizeof(u64), 3 * sizeof(u64));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfiar) +
> | + sizeof(u64) != offsetof(struct thread_struct, tm_orig_msr));
> | +
> | + /* TM checkpointed original MSR */
> | + if (!ret)
> | + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_orig_msr, 3 * sizeof(u64),
> | + 3 * sizeof(u64) + sizeof(unsigned long));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, tm_orig_msr) +
> | + sizeof(unsigned long) + sizeof(struct pt_regs)
> | + != offsetof(struct thread_struct, tm_tar));
> | +
> | + /* TM checkpointed TAR register */
> | + if (!ret)
> | + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_tar, 3 * sizeof(u64) +
> | + sizeof(unsigned long) , 3 * sizeof(u64) +
> | + 2 * sizeof(unsigned long));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, tm_tar)
> | + + sizeof(unsigned long) !=
> | + offsetof(struct thread_struct, tm_ppr));
> | +
> | + /* TM checkpointed PPR register */
> | + if (!ret)
> | + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_ppr, 3 * sizeof(u64) +
> | + 2 * sizeof(unsigned long), 3 * sizeof(u64) +
> | + 3 * sizeof(unsigned long));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, tm_ppr) +
> | + sizeof(unsigned long) !=
> | + offsetof(struct thread_struct, tm_dscr));
> | +
> | + /* TM checkpointed DSCR register */
> | + if (!ret)
> | + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_dscr, 3 * sizeof(u64)
> | + + 3 * sizeof(unsigned long), 3 * sizeof(u64)
> | + + 4 * sizeof(unsigned long));
> | + return ret;
> | +}
> | +
> | +static int tm_spr_set(struct task_struct *target, const struct user_regset *regset,
> | + unsigned int pos, unsigned int count,
> | + const void *kbuf, const void __user *ubuf)
> | +{
> | + int ret;
> | +
> | + if (!cpu_has_feature(CPU_FTR_TM))
> | + return -ENODEV;
> | +
> | + if(!MSR_TM_ACTIVE(target->thread.regs->msr))
> | + return -ENODATA;
> | +
> | + flush_fp_to_thread(target);
> | + flush_altivec_to_thread(target);
> | + flush_tmregs_to_thread(target);
> | +
> | + /* TFHAR register */
> | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_tfhar, 0, sizeof(u64));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfhar)
> | + + sizeof(u64) != offsetof(struct thread_struct, tm_texasr));
>
> A single copyin into a local buffer followed by a local assignment would
> be easier to read ?
I guess the same logic applies here as well.
>
> It could be easier to read if all BUILD_BUG_ON() calls are in one place
> maybe near the beginning of the function or in the header file.
Will move them to the beginning of the function.
>
> | +
> | + /* TEXASR register */
> | + if (!ret)
> | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_texasr, sizeof(u64), 2 * sizeof(u64));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, tm_texasr)
> | + + sizeof(u64) != offsetof(struct thread_struct, tm_tfiar));
> | +
> | + /* TFIAR register */
> | + if (!ret)
> | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_tfiar, 2 * sizeof(u64), 3 * sizeof(u64));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfiar)
> | + + sizeof(u64) != offsetof(struct thread_struct, tm_orig_msr));
> | +
> | + /* TM checkpointed orig MSR */
> | + if (!ret)
> | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_orig_msr, 3 * sizeof(u64),
> | + 3 * sizeof(u64) + sizeof(unsigned long));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, tm_orig_msr)
> | + + sizeof(unsigned long) + sizeof(struct pt_regs) !=
> | + offsetof(struct thread_struct, tm_tar));
> | +
> | + /* TM checkpointed TAR register */
> | + if (!ret)
> | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_tar, 3 * sizeof(u64) +
> | + sizeof(unsigned long), 3 * sizeof(u64) +
> | + 2 * sizeof(unsigned long));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, tm_tar)
> | + + sizeof(unsigned long) != offsetof(struct thread_struct, tm_ppr));
> | +
> | + /* TM checkpointed PPR register */
> | + if (!ret)
> | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_ppr, 3 * sizeof(u64)
> | + + 2 * sizeof(unsigned long), 3 * sizeof(u64)
> | + + 3 * sizeof(unsigned long));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, tm_ppr) +
> | + sizeof(unsigned long) !=
> | + offsetof(struct thread_struct, tm_dscr));
> | +
> | + /* TM checkpointed DSCR register */
> | + if (!ret)
> | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tm_dscr,
> | + 3 * sizeof(u64) + 3 * sizeof(unsigned long),
> | + 3 * sizeof(u64) + 4 * sizeof(unsigned long));
> | +
> | + return ret;
> | +}
> | +
> | +static int tm_cgpr_active(struct task_struct *target,
> | + const struct user_regset *regset)
> | +{
> | + if (!cpu_has_feature(CPU_FTR_TM))
> | + return -ENODEV;
> | +
> | + if(!MSR_TM_ACTIVE(target->thread.regs->msr))
> | + return 0;
> | +
> | + return regset->n;
> | +}
> | +
> | +/*
> | + * TM Checkpointed GPR
> | + *
> | + * struct data {
> | + * struct pt_regs ckpt_regs;
> | + * };
> | + */
> | +static int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset,
> | + unsigned int pos, unsigned int count,
> | + void *kbuf, void __user *ubuf)
> | +{
> | + int ret;
> | +
> | + if (!cpu_has_feature(CPU_FTR_TM))
> | + return -ENODEV;
> | +
> | + if(!MSR_TM_ACTIVE(target->thread.regs->msr))
> | + return -ENODATA;
> | +
> | + flush_fp_to_thread(target);
> | + flush_altivec_to_thread(target);
> | + flush_tmregs_to_thread(target);
> | + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.ckpt_regs, 0,
> | + sizeof(struct pt_regs));
> | + return ret;
> | +}
> | +
> | +static int tm_cgpr_set(struct task_struct *target, const struct user_regset *regset,
> | + unsigned int pos, unsigned int count,
> | + const void *kbuf, const void __user *ubuf)
> | +{
> | + int ret;
> | +
> | + if (!cpu_has_feature(CPU_FTR_TM))
> | + return -ENODEV;
> | +
> | + if(!MSR_TM_ACTIVE(target->thread.regs->msr))
> | + return -ENODATA;
> | +
> | + flush_fp_to_thread(target);
> | + flush_altivec_to_thread(target);
> | + flush_tmregs_to_thread(target);
> | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.ckpt_regs, 0,
> | + sizeof(struct pt_regs));
> | + return ret;
> | +}
> | +
> | +static int tm_cfpr_active(struct task_struct *target,
> | + const struct user_regset *regset)
> | +{
> | + if (!cpu_has_feature(CPU_FTR_TM))
> | + return -ENODEV;
> | +
> | + if(!MSR_TM_ACTIVE(target->thread.regs->msr))
> | + return 0;
> | +
> | + return regset->n;
> | +}
> | +
> | +/*
> | + * TM Checkpointed FPR
> | + *
> | + * struct data {
> | + * u64 fpr[32];
> | + * u64 fpscr;
> | + * };
> | + */
> | +static int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset,
> | + unsigned int pos, unsigned int count,
> | + void *kbuf, void __user *ubuf)
> | +{
> | +#ifdef CONFIG_VSX
> | + u64 buf[33];
> | + int i;
> | +#endif
> | + if (!cpu_has_feature(CPU_FTR_TM))
> | + return -ENODEV;
> | +
> | + if(!MSR_TM_ACTIVE(target->thread.regs->msr))
> | + return -ENODATA;
> | +
> | + flush_fp_to_thread(target);
> | + flush_altivec_to_thread(target);
> | + flush_tmregs_to_thread(target);
> | +
> | +#ifdef CONFIG_VSX
> | + /* copy to local buffer then write that out */
> | + for (i = 0; i < 32 ; i++)
> | + buf[i] = target->thread.TS_FPR(i);
> | + buf[32] = target->thread.fp_state.fpscr;
> | + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
> | +
> | +#else
> | + BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
> | + offsetof(struct thread_fp_state, fpr[32][0]));
> | +
> | + return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.thread_fp_state, 0, -1);
> | +#endif
> | +}
> | +
> | +static int tm_cfpr_set(struct task_struct *target, const struct user_regset *regset,
> | + unsigned int pos, unsigned int count,
> | + const void *kbuf, const void __user *ubuf)
> | +{
> | +#ifdef CONFIG_VSX
> | + u64 buf[33];
> | + int i;
> | +#endif
> | + if (!cpu_has_feature(CPU_FTR_TM))
> | + return -ENODEV;
> | +
> | + if(!MSR_TM_ACTIVE(target->thread.regs->msr))
> | + return -ENODATA;
> | +
> | + flush_fp_to_thread(target);
> | + flush_altivec_to_thread(target);
> | + flush_tmregs_to_thread(target);
> | +
> | +#ifdef CONFIG_VSX
> | + /* copy to local buffer then write that out */
> | + i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
> | + if (i)
> | + return i;
> | + for (i = 0; i < 32 ; i++)
> | + target->thread.TS_FPR(i) = buf[i];
> | + target->thread.fp_state.fpscr = buf[32];
> | + return 0;
> | +#else
> | + BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
> | + offsetof(struct thread_fp_state, fpr[32][0]));
> | +
> | + return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.fp_state, 0, -1);
> | +#endif
> | +}
> | +
> | +static int tm_cvmx_active(struct task_struct *target,
> | + const struct user_regset *regset)
> | +{
> | + if (!cpu_has_feature(CPU_FTR_TM))
> | + return -ENODEV;
> | +
> | + if(!MSR_TM_ACTIVE(target->thread.regs->msr))
> | + return 0;
> | +
> | + return regset->n;
> | +}
>
> All these tm_*_active() functions do the same checks - maybe they could all
> call a common function ?
Will look into it.
>
> | +
> | +/*
> | + * TM Checkpointed VMX
> | + *
> | + * struct data {
> | + * vector128 vr[32];
> | + * vector128 vscr;
> | + * vector128 vrsave;
> | + *};
> | + */
> | +static int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset,
> | + unsigned int pos, unsigned int count,
> | + void *kbuf, void __user *ubuf)
> | +{
> | + int ret;
> | +
> | + if (!cpu_has_feature(CPU_FTR_TM))
> | + return -ENODEV;
> | +
> | + if(!MSR_TM_ACTIVE(target->thread.regs->msr))
> | + return -ENODATA;
> | +
> | + flush_fp_to_thread(target);
> | + flush_altivec_to_thread(target);
> | + flush_tmregs_to_thread(target);
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
> | + offsetof(struct thread_vr_state, vr[32]));
> | +
> | + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.vr_state, 0,
> | + 33 * sizeof(vector128));
> | + if (!ret) {
> | + /*
> | + * Copy out only the low-order word of vrsave.
> | + */
> | + union {
> | + elf_vrreg_t reg;
> | + u32 word;
> | + } vrsave;
> | + memset(&vrsave, 0, sizeof(vrsave));
> | + vrsave.word = target->thread.vrsave;
> | + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
> | + 33 * sizeof(vector128), -1);
> | + }
> | + return ret;
> | +}
> | +
> | +static int tm_cvmx_set(struct task_struct *target, const struct user_regset *regset,
> | + unsigned int pos, unsigned int count,
> | + const void *kbuf, const void __user *ubuf)
> | +{
> | + int ret;
> | +
> | + if (!cpu_has_feature(CPU_FTR_TM))
> | + return -ENODEV;
> | +
> | + if(!MSR_TM_ACTIVE(target->thread.regs->msr))
> | + return -ENODATA;
> | +
> | + flush_fp_to_thread(target);
> | + flush_altivec_to_thread(target);
> | + flush_tmregs_to_thread(target);
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
> | + offsetof(struct thread_vr_state, vr[32]));
> | +
> | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.vr_state, 0,
> | + 33 * sizeof(vector128));
> | + if (!ret && count > 0) {
> | + /*
> | + * We use only the first word of vrsave.
> | + */
> | + union {
> | + elf_vrreg_t reg;
> | + u32 word;
> | + } vrsave;
> | + memset(&vrsave, 0, sizeof(vrsave));
> | + vrsave.word = target->thread.vrsave;
> | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
> | + 33 * sizeof(vector128), -1);
> | + if (!ret)
> | + target->thread.vrsave = vrsave.word;
> | + }
> | + return ret;
> | +}
> | +#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
> |
> | /*
> | * These are our native regset flavors.
> | @@ -629,6 +1163,12 @@ enum powerpc_regset {
> | #ifdef CONFIG_SPE
> | REGSET_SPE,
> | #endif
> | +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> | + REGSET_TM_SPR, /* TM specific SPR */
> | + REGSET_TM_CGPR, /* TM checkpointed GPR */
> | + REGSET_TM_CFPR, /* TM checkpointed FPR */
> | + REGSET_TM_CVMX, /* TM checkpointed VMX */
> | +#endif
> | };
> |
> | static const struct user_regset native_regsets[] = {
> | @@ -663,6 +1203,28 @@ static const struct user_regset native_regsets[] = {
> | .active = evr_active, .get = evr_get, .set = evr_set
> | },
> | #endif
> | +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> | + [REGSET_TM_SPR] = {
> | + .core_note_type = NT_PPC_TM_SPR, .n = 7,
>
> How about adding a macro ELF_NSPRREG for the 7 special registers ?
Will do that.
>
> | + .size = sizeof(u64), .align = sizeof(u64),
> | + .active = tm_spr_active, .get = tm_spr_get, .set = tm_spr_set
> | + },
> | + [REGSET_TM_CGPR] = {
> | + .core_note_type = NT_PPC_TM_CGPR, .n = ELF_NGREG,
> | + .size = sizeof(long), .align = sizeof(long),
> | + .active = tm_cgpr_active, .get = tm_cgpr_get, .set = tm_cgpr_set
> | + },
> | + [REGSET_TM_CFPR] = {
> | + .core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG,
> | + .size = sizeof(double), .align = sizeof(double),
> | + .active = tm_cfpr_active, .get = tm_cfpr_get, .set = tm_cfpr_set
> | + },
> | + [REGSET_TM_CVMX] = {
> | + .core_note_type = NT_PPC_TM_CVMX, .n = 34,
>
> Similarly for the .n = 34
Sure.
^ permalink raw reply
* RE: [PATCH] powerpc/fsl: Add support for pci(e) machine check exception on E500MC / E5500
From: Hongtao Jia @ 2014-10-09 2:18 UTC (permalink / raw)
To: Scott Wood
Cc: linux-kernel@vger.kernel.org, Guenter Roeck, Paul Mackerras,
linuxppc-dev@lists.ozlabs.org, Guenter Roeck, Jojy G Varghese
In-Reply-To: <1412812099.13320.547.camel@snotra.buserror.net>
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogV29vZCBTY290dC1CMDc0
MjENCj4gU2VudDogVGh1cnNkYXksIE9jdG9iZXIgMDksIDIwMTQgNzo0OCBBTQ0KPiBUbzogSmlh
IEhvbmd0YW8tQjM4OTUxDQo+IENjOiBHdWVudGVyIFJvZWNrOyBCZW5qYW1pbiBIZXJyZW5zY2ht
aWR0OyBQYXVsIE1hY2tlcnJhczsgTWljaGFlbA0KPiBFbGxlcm1hbjsgbGludXhwcGMtZGV2QGxp
c3RzLm96bGFicy5vcmc7IGxpbnV4LWtlcm5lbEB2Z2VyLmtlcm5lbC5vcmc7DQo+IEpvankgRyBW
YXJnaGVzZTsgR3VlbnRlciBSb2Vjaw0KPiBTdWJqZWN0OiBSZTogW1BBVENIXSBwb3dlcnBjL2Zz
bDogQWRkIHN1cHBvcnQgZm9yIHBjaShlKSBtYWNoaW5lIGNoZWNrDQo+IGV4Y2VwdGlvbiBvbiBF
NTAwTUMgLyBFNTUwMA0KPiANCj4gT24gVHVlLCAyMDE0LTEwLTA3IGF0IDIyOjA4IC0wNTAwLCBK
aWEgSG9uZ3Rhby1CMzg5NTEgd3JvdGU6DQo+ID4NCj4gPiA+IC0tLS0tT3JpZ2luYWwgTWVzc2Fn
ZS0tLS0tDQo+ID4gPiBGcm9tOiBXb29kIFNjb3R0LUIwNzQyMQ0KPiA+ID4gU2VudDogVHVlc2Rh
eSwgU2VwdGVtYmVyIDMwLCAyMDE0IDI6MzYgQU0NCj4gPiA+IFRvOiBHdWVudGVyIFJvZWNrDQo+
ID4gPiBDYzogQmVuamFtaW4gSGVycmVuc2NobWlkdDsgUGF1bCBNYWNrZXJyYXM7IE1pY2hhZWwg
RWxsZXJtYW47DQo+ID4gPiBsaW51eHBwYy0gZGV2QGxpc3RzLm96bGFicy5vcmc7IGxpbnV4LWtl
cm5lbEB2Z2VyLmtlcm5lbC5vcmc7IEpvankgRw0KPiA+ID4gVmFyZ2hlc2U7IEd1ZW50ZXIgUm9l
Y2s7IEppYSBIb25ndGFvLUIzODk1MQ0KPiA+ID4gU3ViamVjdDogUmU6IFtQQVRDSF0gcG93ZXJw
Yy9mc2w6IEFkZCBzdXBwb3J0IGZvciBwY2koZSkgbWFjaGluZQ0KPiA+ID4gY2hlY2sgZXhjZXB0
aW9uIG9uIEU1MDBNQyAvIEU1NTAwDQo+ID4gPg0KPiA+ID4gT24gTW9uLCAyMDE0LTA5LTI5IGF0
IDA5OjQ4IC0wNzAwLCBHdWVudGVyIFJvZWNrIHdyb3RlOg0KPiA+ID4gPiBGcm9tOiBKb2p5IEcg
VmFyZ2hlc2UgPGpvanl2QGp1bmlwZXIubmV0Pg0KPiA+ID4gPg0KPiA+ID4gPiBGb3IgRTUwME1D
IGFuZCBFNTUwMCwgYSBtYWNoaW5lIGNoZWNrIGV4Y2VwdGlvbiBpbiBwY2koZSkgbWVtb3J5DQo+
ID4gPiA+IHNwYWNlIGNyYXNoZXMgdGhlIGtlcm5lbC4NCj4gPiA+ID4NCj4gPiA+ID4gVGVzdGlu
ZyBzaG93cyB0aGF0IHRoZSBNQ0FSKFUpIHJlZ2lzdGVyIGlzIHplcm8gb24gYSBNQyBleGNlcHRp
b24NCj4gPiA+ID4gZm9yIHRoZQ0KPiA+ID4gPiBFNTUwMCBjb3JlLiBBdCB0aGUgc2FtZSB0aW1l
LCBERUFSIHJlZ2lzdGVyIGhhcyBiZWVuIGZvdW5kIHRvIGhhdmUNCj4gPiA+ID4gdGhlIGFkZHJl
c3Mgb2YgdGhlIGZhdWx0eSBsb2FkIGFkZHJlc3MgZHVyaW5nIGFuIE1DIGV4Y2VwdGlvbiBmb3IN
Cj4gdGhpcyBjb3JlLg0KPiA+ID4gPg0KPiA+ID4gPiBUaGlzIGZpeCBjaGFuZ2VzIHRoZSBjdXJy
ZW50IGJlaGF2aW9yIHRvIGZpeHVwIHRoZSByZXN1bHQgcmVnaXN0ZXINCj4gPiA+ID4gYW5kIGlu
c3RydWN0aW9uIHBvaW50ZXJzIGluIHRoZSBjYXNlIG9mIGEgbG9hZCBvcGVyYXRpb24gb24gYQ0K
PiA+ID4gPiBmYXVsdHkgUENJIGFkZHJlc3MuDQo+ID4gPiA+DQo+ID4gPiA+IFRoZSBjaGFuZ2Vz
IGFyZToNCj4gPiA+ID4gLSBBZGRlZCB0aGUgaG9vayB0byBwY2kgbWFjaGluZSBjaGVjayBoYW5k
aW5nIHRvIHRoZSBlNTAwbWMNCj4gPiA+ID4gbWFjaGluZQ0KPiA+ID4gY2hlY2sNCj4gPiA+ID4g
ICBleGNlcHRpb24gaGFuZGxlci4NCj4gPiA+ID4gLSBGb3IgdGhlIEU1NTAwIGNvcmUsIGxvYWQg
ZmF1bHRpbmcgYWRkcmVzcyBmcm9tIFNQUk5fREVBUiByZWdpc3Rlci4NCj4gPiA+ID4gICBBcyBt
ZW50aW9uZWQgYWJvdmUsIHRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdGhlIEU1NTAwIGNvcmUg
ZG9lcw0KPiBub3QNCj4gPiA+ID4gICByZXBvcnQgdGhlIGZhdWx0IGFkZHJlc3MgaW4gdGhlIE1D
QVIgcmVnaXN0ZXIuDQo+ID4gPiA+DQo+ID4gPiA+IENjOiBTY290dCBXb29kIDxzY290dHdvb2RA
ZnJlZXNjYWxlLmNvbT4NCj4gPiA+ID4gU2lnbmVkLW9mZi1ieTogSm9qeSBHIFZhcmdoZXNlIDxq
b2p5dkBqdW5pcGVyLm5ldD4gW0d1ZW50ZXIgUm9lY2s6DQo+ID4gPiA+IHVwZGF0ZWQgZGVzY3Jp
cHRpb25dDQo+ID4gPiA+IFNpZ25lZC1vZmYtYnk6IEd1ZW50ZXIgUm9lY2sgPGdyb2Vja0BqdW5p
cGVyLm5ldD4NCj4gPiA+ID4gU2lnbmVkLW9mZi1ieTogR3VlbnRlciBSb2VjayA8bGludXhAcm9l
Y2stdXMubmV0Pg0KPiA+ID4gPiAtLS0NCj4gPiA+ID4gIGFyY2gvcG93ZXJwYy9rZXJuZWwvdHJh
cHMuYyAgIHwgMyArKy0NCj4gPiA+ID4gIGFyY2gvcG93ZXJwYy9zeXNkZXYvZnNsX3BjaS5jIHwg
NSArKysrKw0KPiA+ID4gPiAgMiBmaWxlcyBjaGFuZ2VkLCA3IGluc2VydGlvbnMoKyksIDEgZGVs
ZXRpb24oLSkNCj4gPiA+ID4NCj4gPiA+ID4gZGlmZiAtLWdpdCBhL2FyY2gvcG93ZXJwYy9rZXJu
ZWwvdHJhcHMuYw0KPiA+ID4gPiBiL2FyY2gvcG93ZXJwYy9rZXJuZWwvdHJhcHMuYyBpbmRleCAw
ZGM0M2Y5Li5lY2I3MDliIDEwMDY0NA0KPiA+ID4gPiAtLS0gYS9hcmNoL3Bvd2VycGMva2VybmVs
L3RyYXBzLmMNCj4gPiA+ID4gKysrIGIvYXJjaC9wb3dlcnBjL2tlcm5lbC90cmFwcy5jDQo+ID4g
PiA+IEBAIC00OTQsNyArNDk0LDggQEAgaW50IG1hY2hpbmVfY2hlY2tfZTUwMG1jKHN0cnVjdCBw
dF9yZWdzICpyZWdzKQ0KPiA+ID4gPiAgCWludCByZWNvdmVyYWJsZSA9IDE7DQo+ID4gPiA+DQo+
ID4gPiA+ICAJaWYgKHJlYXNvbiAmIE1DU1JfTEQpIHsNCj4gPiA+ID4gLQkJcmVjb3ZlcmFibGUg
PSBmc2xfcmlvX21jaGVja19leGNlcHRpb24ocmVncyk7DQo+ID4gPiA+ICsJCXJlY292ZXJhYmxl
ID0gZnNsX3Jpb19tY2hlY2tfZXhjZXB0aW9uKHJlZ3MpIHx8DQo+ID4gPiA+ICsJCQlmc2xfcGNp
X21jaGVja19leGNlcHRpb24ocmVncyk7DQo+ID4gPiA+ICAJCWlmIChyZWNvdmVyYWJsZSA9PSAx
KQ0KPiA+ID4gPiAgCQkJZ290byBzaWxlbnRfb3V0Ow0KPiA+ID4gPiAgCX0NCj4gPiA+ID4gZGlm
ZiAtLWdpdCBhL2FyY2gvcG93ZXJwYy9zeXNkZXYvZnNsX3BjaS5jDQo+ID4gPiA+IGIvYXJjaC9w
b3dlcnBjL3N5c2Rldi9mc2xfcGNpLmMgaW5kZXggYzUwNzc2Ny4uYmRiOTU2YiAxMDA2NDQNCj4g
PiA+ID4gLS0tIGEvYXJjaC9wb3dlcnBjL3N5c2Rldi9mc2xfcGNpLmMNCj4gPiA+ID4gKysrIGIv
YXJjaC9wb3dlcnBjL3N5c2Rldi9mc2xfcGNpLmMNCj4gPiA+ID4gQEAgLTEwMjEsNiArMTAyMSwx
MSBAQCBpbnQgZnNsX3BjaV9tY2hlY2tfZXhjZXB0aW9uKHN0cnVjdCBwdF9yZWdzDQo+ID4gPiA+
ICpyZWdzKSAgI2VuZGlmDQo+ID4gPiA+ICAJYWRkciArPSBtZnNwcihTUFJOX01DQVIpOw0KPiA+
ID4gPg0KPiA+ID4gPiArI2lmZGVmIENPTkZJR19FNTUwMF9DUFUNCj4gPiA+ID4gKwlpZiAobWZz
cHIoU1BSTl9FUENSKSAmIFNQUk5fRVBDUl9JQ00pDQo+ID4gPiA+ICsJCWFkZHIgPSBQRk5fUEhZ
Uyh2bWFsbG9jX3RvX3Bmbigodm9pZA0KPiAqKW1mc3ByKFNQUk5fREVBUikpKTsNCj4gPiA+ICNl
bmRpZg0KPiA+ID4NCj4gPiA+IEtjb25maWcgdGVsbHMgeW91IHdoYXQgaGFyZHdhcmUgaXMgc3Vw
cG9ydGVkLCBub3Qgd2hhdCBoYXJkd2FyZQ0KPiA+ID4geW91J3JlIGFjdHVhbGx5IHJ1bm5pbmcg
b24uDQo+ID4gPg0KPiA+ID4gSmlhIEhvbmd0YW8sIGRvIHlvdSBrbm93IGFueXRoaW5nIGFib3V0
IHRoaXMgaXNzdWU/ICBJcyB0aGVyZSBhbg0KPiBlcnJhdHVtPw0KPiA+DQo+ID4gU29ycnkgZm9y
IHRoZSBsYXRlIHJlc3BvbnNlLCBJIGp1c3QgcmV0dXJuIGZyb20gbXkgdmFjYXRpb24uDQo+ID4g
SSBkb24ndCBrbm93IHRoaXMgaXNzdWUuDQo+ID4NCj4gPiA+IFdoYXQgY2hpcHMgYXJlIGFmZmVj
dGVkIGJ5IHRoZSB0aGUgZXJyYXR1bSBjb3ZlcmVkIGJ5DQo+ID4gPiA8aHR0cDovL3BhdGNod29y
ay5vemxhYnMub3JnL3BhdGNoLzI0MDIzOS8+Pw0KPiA+DQo+ID4gTVBDODU0NCwgTVBDODU0OCwg
TVBDODU3MiBhcmUgYWZmZWN0ZWQgYnkgdGhpcyBlcnJhdHVtLg0KPiANCj4gV2hhdCBpcyB0aGUg
ZXJyYXR1bSBudW1iZXI/DQoNClRoZSBudW1iZXIgb2YgdGhpcyBlcnJhdHVtIGZvciBlYWNoIGNo
aXAgaXMgbm90IGNvbnNpc3RlbnQuDQpNUEM4NTQ0OiBQQ0llIDQNCk1QQzg1NDg6IFBDSS1FeCAz
OQ0KTVBDODU3MjogUENJLUV4IDMNCg0KPiANCj4gPiBJIGNoZWNrZWQgUDQwODAgd2hpY2ggdXNp
bmcgZTUwMG1jIGFuZCBubyBzdWNoIGVycmF0dW0gaXMgZm91bmQuDQo+IA0KPiBXaGF0IGlzIHRo
ZSBlcnJhdHVtIGJlaGF2aW9yLCBhbmQgaG93IGRvZXMgaXQgZGlmZmVyIGZyb20gdGhlIHByb2Js
ZW0NCj4gdGhhdCBKb2p5IGFuZCBHdWVudGVyIGFyZSB0cnlpbmcgdG8gc29sdmU/DQoNCkhlcmUg
aXMgdGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBlcnJhdHVtOg0KDQoiV2hlbiBpdHMgbGluayBnb2Vz
IGRvd24sIHRoZSBQQ0kgRXhwcmVzcyBjb250cm9sbGVyIGNsZWFycyBhbGwgb3V0c3RhbmRpbmcg
dHJhbnNhY3Rpb25zIHdpdGggYW4NCmVycm9yIGluZGljYXRvciBhbmQgc2VuZHMgYSBsaW5rIGRv
d24gZXhjZXB0aW9uIHRvIHRoZSBpbnRlcnJ1cHQgY29udHJvbGxlciBpZg0KUEVYX1BNRV9NRVNf
RElTUltMREREXSA9IDAuIElmLCBob3dldmVyLCBhbnkgdHJhbnNhY3Rpb25zIGFyZSBzZW50IHRv
IHRoZSBjb250cm9sbGVyDQphZnRlciB0aGUgbGluayBkb3duIGV2ZW50LCB0aGV5IHdpbGwgYmUg
YWNjZXB0ZWQgYnkgdGhlIGNvbnRyb2xsZXIgYW5kIHdhaXQgZm9yIHRoZSBsaW5rIHRvIGNvbWUN
CmJhY2sgdXAgYmVmb3JlIHN0YXJ0aW5nIGFueSB0aW1lb3V0IGNvdW50ZXJzIChlLmcuIGNvbXBs
ZXRpb24gdGltZW91dCkuIFRoZXJlIGlzIG5vIG1lY2hhbmlzbQ0KdG8gY2FuY2VsIHRoZSBuZXcg
dHJhbnNhY3Rpb25zIHNob3J0IG9mIGEgZGV2aWNlIEhSRVNFVC4iDQoNCkZvciBlNTAwbWMgYXMg
Sm9qeSBhbmQgR3VlbnRlciBkZXNjcmliZWQgaXQncyBsaWtlIHRoZSBzYW1lIGVycmF0dW0gb24g
ZTUwMCwgbm90IDEwMCUgc3VyZS4NCg0KRm9yIGU1NTAwIEkgZG9uJ3QgcXVpdGUgdW5kZXJzdGFu
ZCB5ZXQuDQoNCj4gDQo+IC1TY290dA0KPiANCg0K
^ permalink raw reply
* [PATCH] CXL: Fix afu_read() not doing finish_wait() on signal or non-blocking
From: Ian Munsie @ 2014-10-09 0:17 UTC (permalink / raw)
To: mpe
Cc: cbe-oss-dev, mikey, arnd, Aneesh Kumar K.V, greg, linux-kernel,
linuxppc-dev, anton, imunsie, jk
In-Reply-To: <1412764803-sup-6790@delenn.ozlabs.ibm.com>
From: Ian Munsie <imunsie@au1.ibm.com>
If afu_read() returned due to a signal or the AFU file descriptor being
opened non-blocking it would not call finish_wait() before returning,
which could lead to a crash later when something else wakes up the wait
queue.
This patch restructures the wait logic to ensure that the cleanup is
done correctly.
Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
---
Resending with correct whitespace as my mailer decided to replace tabs with
spaces on the last try.
drivers/misc/cxl/file.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index 847b7e6..378b099 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -273,6 +273,7 @@ static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
struct cxl_context *ctx = file->private_data;
struct cxl_event event;
unsigned long flags;
+ int rc;
DEFINE_WAIT(wait);
if (count < CXL_READ_MIN_SIZE)
@@ -285,13 +286,17 @@ static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
if (ctx_event_pending(ctx))
break;
- spin_unlock_irqrestore(&ctx->lock, flags);
- if (file->f_flags & O_NONBLOCK)
- return -EAGAIN;
+ if (file->f_flags & O_NONBLOCK) {
+ rc = -EAGAIN;
+ goto out;
+ }
- if (signal_pending(current))
- return -ERESTARTSYS;
+ if (signal_pending(current)) {
+ rc = -ERESTARTSYS;
+ goto out;
+ }
+ spin_unlock_irqrestore(&ctx->lock, flags);
pr_devel("afu_read going to sleep...\n");
schedule();
pr_devel("afu_read woken up\n");
@@ -336,6 +341,11 @@ static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
if (copy_to_user(buf, &event, event.header.size))
return -EFAULT;
return event.header.size;
+
+out:
+ finish_wait(&ctx->wq, &wait);
+ spin_unlock_irqrestore(&ctx->lock, flags);
+ return rc;
}
static const struct file_operations afu_fops = {
--
2.1.0
^ permalink raw reply related
* Re: [PATCH] powerpc/fsl: Add support for pci(e) machine check exception on E500MC / E5500
From: Scott Wood @ 2014-10-08 23:48 UTC (permalink / raw)
To: Jia Hongtao-B38951
Cc: linux-kernel@vger.kernel.org, Guenter Roeck, Paul Mackerras,
linuxppc-dev@lists.ozlabs.org, Guenter Roeck, Jojy G Varghese
In-Reply-To: <cfa12996b9a54b3baaa75f517f78c7ea@BLUPR03MB149.namprd03.prod.outlook.com>
On Tue, 2014-10-07 at 22:08 -0500, Jia Hongtao-B38951 wrote:
>
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Tuesday, September 30, 2014 2:36 AM
> > To: Guenter Roeck
> > Cc: Benjamin Herrenschmidt; Paul Mackerras; Michael Ellerman; linuxppc-
> > dev@lists.ozlabs.org; linux-kernel@vger.kernel.org; Jojy G Varghese;
> > Guenter Roeck; Jia Hongtao-B38951
> > Subject: Re: [PATCH] powerpc/fsl: Add support for pci(e) machine check
> > exception on E500MC / E5500
> >
> > On Mon, 2014-09-29 at 09:48 -0700, Guenter Roeck wrote:
> > > From: Jojy G Varghese <jojyv@juniper.net>
> > >
> > > For E500MC and E5500, a machine check exception in pci(e) memory space
> > > crashes the kernel.
> > >
> > > Testing shows that the MCAR(U) register is zero on a MC exception for
> > > the
> > > E5500 core. At the same time, DEAR register has been found to have the
> > > address of the faulty load address during an MC exception for this core.
> > >
> > > This fix changes the current behavior to fixup the result register and
> > > instruction pointers in the case of a load operation on a faulty PCI
> > > address.
> > >
> > > The changes are:
> > > - Added the hook to pci machine check handing to the e500mc machine
> > check
> > > exception handler.
> > > - For the E5500 core, load faulting address from SPRN_DEAR register.
> > > As mentioned above, this is necessary because the E5500 core does not
> > > report the fault address in the MCAR register.
> > >
> > > Cc: Scott Wood <scottwood@freescale.com>
> > > Signed-off-by: Jojy G Varghese <jojyv@juniper.net> [Guenter Roeck:
> > > updated description]
> > > Signed-off-by: Guenter Roeck <groeck@juniper.net>
> > > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> > > ---
> > > arch/powerpc/kernel/traps.c | 3 ++-
> > > arch/powerpc/sysdev/fsl_pci.c | 5 +++++
> > > 2 files changed, 7 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
> > > index 0dc43f9..ecb709b 100644
> > > --- a/arch/powerpc/kernel/traps.c
> > > +++ b/arch/powerpc/kernel/traps.c
> > > @@ -494,7 +494,8 @@ int machine_check_e500mc(struct pt_regs *regs)
> > > int recoverable = 1;
> > >
> > > if (reason & MCSR_LD) {
> > > - recoverable = fsl_rio_mcheck_exception(regs);
> > > + recoverable = fsl_rio_mcheck_exception(regs) ||
> > > + fsl_pci_mcheck_exception(regs);
> > > if (recoverable == 1)
> > > goto silent_out;
> > > }
> > > diff --git a/arch/powerpc/sysdev/fsl_pci.c
> > > b/arch/powerpc/sysdev/fsl_pci.c index c507767..bdb956b 100644
> > > --- a/arch/powerpc/sysdev/fsl_pci.c
> > > +++ b/arch/powerpc/sysdev/fsl_pci.c
> > > @@ -1021,6 +1021,11 @@ int fsl_pci_mcheck_exception(struct pt_regs
> > > *regs) #endif
> > > addr += mfspr(SPRN_MCAR);
> > >
> > > +#ifdef CONFIG_E5500_CPU
> > > + if (mfspr(SPRN_EPCR) & SPRN_EPCR_ICM)
> > > + addr = PFN_PHYS(vmalloc_to_pfn((void *)mfspr(SPRN_DEAR)));
> > #endif
> >
> > Kconfig tells you what hardware is supported, not what hardware you're
> > actually running on.
> >
> > Jia Hongtao, do you know anything about this issue? Is there an erratum?
>
> Sorry for the late response, I just return from my vacation.
> I don't know this issue.
>
> > What chips are affected by the the erratum covered by
> > <http://patchwork.ozlabs.org/patch/240239/>?
>
> MPC8544, MPC8548, MPC8572 are affected by this erratum.
What is the erratum number?
> I checked P4080 which using e500mc and no such erratum is found.
What is the erratum behavior, and how does it differ from the problem
that Jojy and Guenter are trying to solve?
-Scott
^ permalink raw reply
* Re: [PATCH 0/2] net: fs_enet: Remove non NAPI RX and add NAPI for TX
From: David Miller @ 2014-10-08 20:03 UTC (permalink / raw)
To: christophe.leroy; +Cc: netdev, linuxppc-dev, linux-kernel, vbordug
In-Reply-To: <20141007130454.13EF21AB266@localhost.localdomain>
From: Christophe Leroy <christophe.leroy@c-s.fr>
Date: Tue, 7 Oct 2014 15:04:53 +0200 (CEST)
> When using a MPC8xx as a router, 'perf' shows a significant time spent in
> fs_enet_interrupt() and fs_enet_start_xmit().
> 'perf annotate' shows that the time spent in fs_enet_start_xmit is indeed spent
> between spin_unlock_irqrestore() and the following instruction, hence in
> interrupt handling. This is due to the TX complete interrupt that fires after
> each transmitted packet.
> This patchset first remove all non NAPI handling as NAPI has become the only
> mode for RX, then adds NAPI for handling TX complete.
> This improves NAT TCP throughput by 21% on MPC885 with FEC.
>
> Tested on MPC885 with FEC.
>
> [PATCH 1/2] net: fs_enet: Remove non NAPI RX
> [PATCH 2/2] net: fs_enet: Add NAPI TX
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Series applied, thanks.
Any particular reason you didn't just put the TX reclaim calls into
the existing NAPI handler?
That's what other drivers do, because TX reclaim can make SKBs
available for RX packet receive on the local cpu. So generally you
have one NAPI context that first does any pending TX reclaim, then
polls the RX ring for new packets.
^ permalink raw reply
* Re: [PATCH 2/2] spi: fsl-spi: Allow dynamic allocation of CPM1 parameter RAM
From: Scott Wood @ 2014-10-08 18:45 UTC (permalink / raw)
To: leroy christophe
Cc: Marcelo Tosatti, linux-kernel, linux-spi, Mark Brown,
Paul Mackerras, linuxppc-dev
In-Reply-To: <54356A53.3010700@c-s.fr>
On Wed, 2014-10-08 at 18:46 +0200, leroy christophe wrote:
> Le 07/10/2014 02:19, Scott Wood a écrit :
> > On Sat, 2014-10-04 at 12:15 +0200, christophe leroy wrote:
> >> Le 03/10/2014 22:24, Scott Wood a écrit :
> >>> On Fri, 2014-10-03 at 22:15 +0200, christophe leroy wrote:
> >>>> Le 03/10/2014 16:44, Mark Brown a écrit :
> >>>>> On Fri, Oct 03, 2014 at 02:56:09PM +0200, Christophe Leroy wrote:
> >>>>>
> >>>>>> +config CPM1_RELOCSPI
> >>>>>> + bool "Dynamic SPI relocation"
> >>>>>> + default n
> >>>>>> + help
> >>>>>> + On recent MPC8xx (at least MPC866 and MPC885) SPI can be relocated
> >>>>>> + without micropatch. This activates relocation to a dynamically
> >>>>>> + allocated area in the CPM Dual port RAM.
> >>>>>> + When combined with SPI relocation patch (for older MPC8xx) it avoids
> >>>>>> + the "loss" of additional Dual port RAM space just above the patch,
> >>>>>> + which might be needed for example when using the CPM QMC.
> >>>>> Something like this shouldn't be a compile time option. Either it
> >>>>> should be unconditional or it should be triggered in some system
> >>>>> specific manner (from DT, from knowing about other users or similar).
> >>>> Can't be unconditional as older versions of mpc8xx (eg MPC860) don't
> >>>> support relocation without a micropatch.
> >>>> I have therefore submitted a v2 based on a DTS compatible property.
> >>> So the device tree change is about whether relocation is supported, not
> >>> whether it is required?
> >> Indeed no, my intension is to say that relocation is requested. Do you
> >> mean that it should then not use a compatible ?
> > The device tree describes hardware. It doesn't tell software how to use
> > that hardware.
> >
> > Based on one of your other e-mails, I think what you want to say here is
> > that the old binding didn't describe the registers needed for
> > relocation, so the new compatible describes the new binding, rather than
> > requesting that software do a relocation. Software that sees the new
> > binding could choose to relocate, or just choose to read the current
> > offset from the register.
> Not exactly.
> The old binding does describe the entire default param RAM (0x3d80 size
> 0x30). The relocation index is within this param RAM at 0x3dac.
> So the old binding is enough to allow relocation.
Oh, so the relocation register is part of the region? If you relocate
the region, does the relocation register move, or stay at 0x3dac? I
checked the manual and it wasn't clear. I had assumed it worked the
same as cpm2, where the relocation register does not move.
> The issue today with the driver (hence my first patch) is that the
> driver reads the relocation index but takes a wrong decision if the
> index is 0: it assumes that an nul index means that a param RAM shall be
> allocated, which is wrong. A nul index means that the component doesn't
> support relocation, so the default param RAM shall be used. The function
> used for that is supposed to return the index. So when the index is
> null, I need to calculate it.
>
> Now, it can't be the SPI driver by itself that decide if he has to
> relocate or not. Because it depends whether I need to relocate or not.
> There is no point in waisting another area of the dualport RAM if I
> don't need to use SCC2 in a mode that overlaps the SPI parameter RAM.
Is the DPRAM currently fully utilized?
If it's really important to not waste 48 bytes of DPRAM, Could you make
the policy decision in platform code, or check at runtime what mode SCC2
is in?
> Today on the old MPC8xx, a microcode patch is needed in order to be able
> to relocate, and relocated address is directly fixed by the code
> handling the patch (sysdev/micropatch.c). The patch loading function is
> call very early in the boot process by cpm_reset() which is call by the
> xxx_setup_arch().
> I have two issues with the way it is done today:
> 1/ the address which in hard coded is the micropatch loading function()
> is within the area for descripters for the QMC, so I would need to use
> another address.
> 2/ for new MPC8xx which don't need microcode patch, I have no way today
> to relocate.
>
> I have the same issue with the relocation of SMC1. Today when we
> activate SMC1 relocation microcode patch, the loading function has a
> hard coded relocation area for SMC1 which is the area dedicated to the
> MPC8xx DSP. It means that I need to change it as I want to use the DSP.
>
> Would it be acceptable to define a fixed relocation address in the
> Kconfig in which we select microcode patch (arch/powerpc/platforms/8xx),
> instead of having it hardcoded in micropatch.c ?
No, that would prevent the ability to build support for all 8xx in one
kernel.
> Or maybe it would be possible to select which microcode patch we
> want/need via the device tree and which address shall be used for
> relocation ? What would you suggest to describe it ?
Yes, use the existing information in the device tree, or use PVR, to
determine which chip you're on and thus whic microcode to use.
> >
> >>> How about checking for the existing specific-SoC compatibles?
> >> What do you mean ?
> > Look for "fsl,mpc885-cpm-i2c" etc. Or, if you didn't follow that
> > pattern (remember, I can't see your device tree!), look for
> > "fsl,mpc885-cpm" or "fsl,mpc866-cpm" in the parent node. It's moot
> > though, if the device tree also needs to be modified to describe the
> > register used to relocate.
> >
> > -Scott
> >
> I'm not sure I understood your question.
> My full device tree below
[snip]
> cpm@9c0 {
> #address-cells = <1>;
> #size-cells = <1>;
> compatible = "fsl,mpc885-cpm", "fsl,cpm1";
[snip]
> spi: spi@a80 {
> #address-cells = <1>;
> #size-cells = <0>;
> cell-index = <0>;
> compatible = "fsl,spi", "fsl,cpm1-spi";
"fsl,cpm1-spi" should come first.
You didn't follow the pattern most CPM devices use, of
"fsl,mpc885-<device>", but you could look in the cpm node above to
determine that it's an mpc885.
-Scott
^ permalink raw reply
* Re: [PATCH] tools/perf/powerpc: Fix build break
From: Sukadev Bhattiprolu @ 2014-10-08 18:01 UTC (permalink / raw)
To: Aneesh Kumar K.V
Cc: Arnaldo Carvalho de Melo, paulus, linux-kernel, linuxppc-dev,
mingo
In-Reply-To: <87oatm3m26.fsf@linux.vnet.ibm.com>
Aneesh Kumar K.V [aneesh.kumar@linux.vnet.ibm.com] wrote:
| "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> writes:
|=20
| > CC arch/powerpc/util/skip-callchain-idx.o
| > arch/powerpc/util/skip-callchain-idx.c: In function =E2=80=98check_retu=
rn_reg=E2=80=99:
| > arch/powerpc/util/skip-callchain-idx.c:55:3: error: implicit declaratio=
n of function =E2=80=98pr_debug=E2=80=99 [-Werror=3Dimplicit-function-decla=
ration]
| > pr_debug("dwarf_frame_register() %s\n", dwarf_errmsg(-1));
| >
| > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
| > ---
| > tools/perf/arch/powerpc/util/skip-callchain-idx.c | 1 +
| > 1 file changed, 1 insertion(+)
| >
| > diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/=
perf/arch/powerpc/util/skip-callchain-idx.c
| > index a7c23a4b3778..d73ef8bb08c7 100644
| > --- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c
| > +++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
| > @@ -15,6 +15,7 @@
| >
| > #include "util/thread.h"
| > #include "util/callchain.h"
| > +#include "util/debug.h"
| >
| > /*
| > * When saving the callchain on Power, the kernel conservatively saves
|=20
| We still have this broken upstream.
The fix is in Ingo's tree, commit ad7e767.
Ingo, can you push this fix to Linus - it fixes a build failure in
Powerpc.
Sukadev
|=20
| -aneesh
|=20
| _______________________________________________
| Linuxppc-dev mailing list
| Linuxppc-dev@lists.ozlabs.org
| https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* Re: [PATCH V3 3/3] powerpc, ptrace: Enable support for miscellaneous registers
From: Sukadev Bhattiprolu @ 2014-10-08 17:16 UTC (permalink / raw)
To: Anshuman Khandual
Cc: mikey, james.hogan, avagin, Paul.Clothier, davem, peterz, palves,
linux-kernel, oleg, dhowells, linuxppc-dev, davej, akpm, tglx
In-Reply-To: <54356444.1080702@linux.vnet.ibm.com>
Anshuman Khandual [khandual@linux.vnet.ibm.com] wrote:
| On 08/28/2014 03:05 AM, Sukadev Bhattiprolu wrote:
| >=20
| > I see these in arch/powerpc/include/asm/processor.h
| >=20
| > #ifdef CONFIG_PPC64
| > unsigned long dscr;
| > int dscr_inherit;
| > unsigned long ppr; /* used to save/restore SMT priority */
| > #endif
| >=20
| > where there is an 'int' between ppr and dscr. So, should one of
| > the above sizeof(unsigned long) be changed to sizeof(int) ?
|=20
| Right, I understand that but strangely I get this compile time error
| when it is changed to sizeof(int).
|=20
| error: call to =E2=80=98__compiletime_assert_1350=E2=80=99 declared with=
attribute error:
| BUILD_BUG_ON failed: TSO(dscr) + sizeof(unsigned long) + sizeof(int) !=
=3D TSO(ppr)
| BUILD_BUG_ON(TSO(dscr) + sizeof(unsigned long) + sizeof(int) !=3D TSO(p=
pr));
|=20
| may be I am missing something here.
I guess there is a 4-byte padding after dscr_inherit. We could make that
explicit by adding a field or just go with the sizeof(unsigned long).
Thanks,
Sukadev
^ permalink raw reply
* Re: [PATCH 2/2] spi: fsl-spi: Allow dynamic allocation of CPM1 parameter RAM
From: leroy christophe @ 2014-10-08 16:46 UTC (permalink / raw)
To: Scott Wood
Cc: Marcelo Tosatti, linux-kernel, linux-spi, Mark Brown,
Paul Mackerras, linuxppc-dev
In-Reply-To: <1412641184.13320.506.camel@snotra.buserror.net>
Le 07/10/2014 02:19, Scott Wood a écrit :
> On Sat, 2014-10-04 at 12:15 +0200, christophe leroy wrote:
>> Le 03/10/2014 22:24, Scott Wood a écrit :
>>> On Fri, 2014-10-03 at 22:15 +0200, christophe leroy wrote:
>>>> Le 03/10/2014 16:44, Mark Brown a écrit :
>>>>> On Fri, Oct 03, 2014 at 02:56:09PM +0200, Christophe Leroy wrote:
>>>>>
>>>>>> +config CPM1_RELOCSPI
>>>>>> + bool "Dynamic SPI relocation"
>>>>>> + default n
>>>>>> + help
>>>>>> + On recent MPC8xx (at least MPC866 and MPC885) SPI can be relocated
>>>>>> + without micropatch. This activates relocation to a dynamically
>>>>>> + allocated area in the CPM Dual port RAM.
>>>>>> + When combined with SPI relocation patch (for older MPC8xx) it avoids
>>>>>> + the "loss" of additional Dual port RAM space just above the patch,
>>>>>> + which might be needed for example when using the CPM QMC.
>>>>> Something like this shouldn't be a compile time option. Either it
>>>>> should be unconditional or it should be triggered in some system
>>>>> specific manner (from DT, from knowing about other users or similar).
>>>> Can't be unconditional as older versions of mpc8xx (eg MPC860) don't
>>>> support relocation without a micropatch.
>>>> I have therefore submitted a v2 based on a DTS compatible property.
>>> So the device tree change is about whether relocation is supported, not
>>> whether it is required?
>> Indeed no, my intension is to say that relocation is requested. Do you
>> mean that it should then not use a compatible ?
> The device tree describes hardware. It doesn't tell software how to use
> that hardware.
>
> Based on one of your other e-mails, I think what you want to say here is
> that the old binding didn't describe the registers needed for
> relocation, so the new compatible describes the new binding, rather than
> requesting that software do a relocation. Software that sees the new
> binding could choose to relocate, or just choose to read the current
> offset from the register.
Not exactly.
The old binding does describe the entire default param RAM (0x3d80 size
0x30). The relocation index is within this param RAM at 0x3dac.
So the old binding is enough to allow relocation.
The issue today with the driver (hence my first patch) is that the
driver reads the relocation index but takes a wrong decision if the
index is 0: it assumes that an nul index means that a param RAM shall be
allocated, which is wrong. A nul index means that the component doesn't
support relocation, so the default param RAM shall be used. The function
used for that is supposed to return the index. So when the index is
null, I need to calculate it.
Now, it can't be the SPI driver by itself that decide if he has to
relocate or not. Because it depends whether I need to relocate or not.
There is no point in waisting another area of the dualport RAM if I
don't need to use SCC2 in a mode that overlaps the SPI parameter RAM.
Today on the old MPC8xx, a microcode patch is needed in order to be able
to relocate, and relocated address is directly fixed by the code
handling the patch (sysdev/micropatch.c). The patch loading function is
call very early in the boot process by cpm_reset() which is call by the
xxx_setup_arch().
I have two issues with the way it is done today:
1/ the address which in hard coded is the micropatch loading function()
is within the area for descripters for the QMC, so I would need to use
another address.
2/ for new MPC8xx which don't need microcode patch, I have no way today
to relocate.
I have the same issue with the relocation of SMC1. Today when we
activate SMC1 relocation microcode patch, the loading function has a
hard coded relocation area for SMC1 which is the area dedicated to the
MPC8xx DSP. It means that I need to change it as I want to use the DSP.
Would it be acceptable to define a fixed relocation address in the
Kconfig in which we select microcode patch (arch/powerpc/platforms/8xx),
instead of having it hardcoded in micropatch.c ?
Or maybe it would be possible to select which microcode patch we
want/need via the device tree and which address shall be used for
relocation ? What would you suggest to describe it ?
>
>>> How about checking for the existing specific-SoC compatibles?
>> What do you mean ?
> Look for "fsl,mpc885-cpm-i2c" etc. Or, if you didn't follow that
> pattern (remember, I can't see your device tree!), look for
> "fsl,mpc885-cpm" or "fsl,mpc866-cpm" in the parent node. It's moot
> though, if the device tree also needs to be modified to describe the
> register used to relocate.
>
> -Scott
>
I'm not sure I understood your question.
My full device tree below
Christophe
/*
* MIA ethernet Device Tree Source
*
* Copyright 2011 CSSI, Inc
*/
/dts-v1/;
/ {
model = "MIAE";
compatible = "fsl,cmpc885", "fsl,mod885";
#address-cells = <1>;
#size-cells = <1>;
aliases {
ethernet0 = ð0;
ethernet1 = ð1;
mdio = &phy;
serial0 = &smc1;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
PowerPC,885@0 {
device_type = "cpu";
reg = <0x0>;
d-cache-line-size = <16>; // 16 bytes
i-cache-line-size = <16>; // 16 bytes
d-cache-size = <8192>;
i-cache-size = <8192>;
timebase-frequency = <0>;
bus-frequency = <0>;
clock-frequency = <0>;
interrupts = <15 2>; // decrementer interrupt
interrupt-parent = <&PIC>;
};
};
memory {
device_type = "memory";
reg = <0x0 0x0>; // defined by U-BOOT
};
localbus@ff000100 {
compatible = "fsl,cmpc885-localbus", "fsl,pq1-localbus";
#address-cells = <2>;
#size-cells = <1>;
reg = <0xff000100 0x40>; // ORx and BRx register
ranges = <0 0x0 0x40000000 0x00400000 // Boot Flash
1 0x0 0x00000000 0x08000000 // SDRAM
2 0x0 0xc0000000 0x00008000 // Nand Flash
3 0x0 0xe0000000 0x00010000 // DPRAM
4 0x0 0xd0000000 0x10000000 // Periphs
5 0x0 0xc8000000 0x00008000 // CPLD
6 0x0 0x80000000 0x00008000 // mezzanine
7 0x0 0xf0000000 0x00008000>; // DSP
flash@0,0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "cfi-flash";
reg = <0x0 0x00000000 0x400000>;
bank-width = <2>;
device-width = <2>;
partition@0 {
label = "boot";
reg = <0x0 0x50000>;
};
partition@50000 {
label = "env";
reg = <0x50000 0x10000>;
};
partition@60000 {
label = "blob";
reg = <0x60000 0x30000>;
};
partition@90000 {
label = "kernel";
reg = <0x90000 0x370000>;
};
};
nand@2,0 {
compatible = "s3k,cmpc885-nand";
reg = <2 0x0 0x01>;
#address-cells = <1>;
#size-cells = <1>;
gpios = <&CPM1_PIO_D 12 1 // CLE
&CPM1_PIO_D 13 1 // ALE
&CPM1_PIO_D 15 1>; // NCE
};
cpld-cmpc@5,0000000 { // Driver KNL
#address-cells = <1>;
#size-cells = <1>;
compatible = "s3k,mcr3000-cpld-cmpc";
reg = <5 0x0 0x10>;
};
cpld-mpc@5,0000000 { // Driver LDB (deviendra obsolete)
#address-cells = <1>;
#size-cells = <1>;
compatible = "s3k,mcr3000-cpld-mpc";
reg = <5 0x0 0x10>;
};
fpga-m@4,0000000 { // Driver LDB (deviendra peut etre obsolete)
#address-cells = <1>;
#size-cells = <1>;
compatible = "s3k,mcr3000-fpga-m";
reg = <4 0x0000000 0x60>;
ranges = <0 4 0x0000000 0x60>;
ident: gpio-controller@00 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x00 2>;
gpio-controller;
};
ver: gpio-controller@02 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x02 2>;
gpio-controller;
};
tst: gpio-controller@04 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x04 2>;
gpio-controller;
};
rst: gpio-controller@10 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x10 2>;
gpio-controller;
};
mask1: gpio-controller@20 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x20 2>;
gpio-controller;
};
mask2: gpio-controller@22 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x22 2>;
gpio-controller;
};
pend1: gpio-controller@24 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x24 2>;
gpio-controller;
};
pend2: gpio-controller@26 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x26 2>;
gpio-controller;
};
acq1: gpio-controller@28 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x28 2>;
gpio-controller;
};
acq2: gpio-controller@2A {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x2A 2>;
gpio-controller;
};
ctrl: gpio-controller@2C {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x2C 2>;
gpio-controller;
};
torin: gpio-controller@30 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x30 2>;
interrupts = <255 255 255 255 255 5 6 7 8 9 10 11 12 13
14 15>;
interrupt-parent = <&FPGAM_PIC>;
gpio-controller;
};
torout: gpio-controller@32 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x32 2>;
gpio-controller;
};
liens: gpio-controller@34 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-direct-gpio";
reg = <0x34 2>;
gpio-controller;
};
gen: gpio-controller@40 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x40 2>;
gpio-controller;
};
far: gpio-controller@42 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x42 2>;
interrupts = <255 255 255 255 255 255 255 255 255 255
255 0 28 30 29 31>;
interrupt-parent = <&FPGAM_PIC>;
gpio-controller;
};
fav: gpio-controller@44 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x44 2>;
interrupts = <255 255 255 255 255 255 255 255 17 25 19
27 16 24 18 26>;
interrupt-parent = <&FPGAM_PIC>;
gpio-controller;
};
statpll: gpio-controller@50 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x50 2>;
gpio-controller;
};
srcpll: gpio-controller@52 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x52 2>;
gpio-controller;
};
etatref: gpio-controller@54 {
#gpio-cells = <2>;
compatible = "s3k,mcr3000-fpga-m-gpio";
reg = <0x54 2>;
gpio-controller;
};
FPGAM_PIC: pic@22 {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
interrupts = <6 1>;
interrupt-parent = <&PIC>;
reg = <0x00 0x60>; /* Mappage registres FPGAM */
compatible = "s3k,miae-pic";
};
};
PRES_EQUT {
compatible = "ident-gpio-pres-equt";
interrupts = <17 19 16 18>; /* Equipt 1 et 2 */
interrupt-parent = <&FPGAM_PIC>;
reg = <4 0x44 2>;
gpios = <&fav 8 1 /* Presence µCasque1 */
&fav 10 1 /* Presence µMain1 */
&fav 12 1 /* Presence µCasque2 */
&fav 14 1>; /* Presence µMain2 */
};
led_pwr {
compatible = "s3k,miae-led-pwr";
gpios = <&fav 6 2 /* led multi verte */
&fav 7 0>; /* led multi rouge */
};
e1@4,2000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "s3k,mcr3000-e1";
reg = <4 0x2000000 0xFF>;
interrupts = <8 1>;
interrupt-parent = <&PIC>;
};
e1-wan@4,2000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "lantiq,pef2256";
reg = <4 0x2000000 0xFF>;
interrupts = <8 1>;
interrupt-parent = <&PIC>;
};
GPIO {
/* 0 = sortie initialisee active */
/* 1 = entree */
/* 2 = sortie initialisee inactive */
compatible = "s3k,gpios-appli";
reg = <4 0x42 4>;
gpios = <&torin 15 1 // TOR in 1
&torin 14 1 // TOR in 2
&torin 13 1 // TOR in 3
&torin 12 1 // TOR in 4
&torin 11 1 // TOR in 5
&torin 10 1 // TOR in 6
&torin 9 1 // TOR in 7
&torin 8 1 // TOR in 8
&torin 7 1 // TOR in 9
&torin 6 1 // TOR in 10
&torin 5 1 // TOR in 11
&torout 15 2 // TOR out 1
&torout 14 2 // TOR out 2
&torout 13 2 // TOR out 3
&torout 12 2 // TOR out 4
&torout 11 2 // TOR out 5
&torout 10 2 // TOR out 6
&torout 9 2 // TOR out 7
&torout 8 2 // TOR out 8
&far 15 1 // BP Alt
&far 13 1 // Alternat 1
&far 14 1 // Alternat 2
&far 12 1 // Alternat Combine
&far 11 1 // Presence Combine
&fav 11 1 // Alternat µMain1
&fav 15 1 // Alternat µMain2
&fav 9 1 // Alternat µCasque1
&fav 13 1>; // Alternat µCasque2
};
GPIO_CA_CLA {
compatible = "s3k,gpios-def-ca", "cs,mia-far";
far-id = <0 7>;
names = "tor_in_1",
"tor_in_2",
"tor_in_3",
"tor_in_4",
"tor_in_5",
"tor_in_6",
"tor_in_7",
"tor_in_8",
"tor_in_9",
"tor_in_10",
"tor_in_11",
"tor_out_1",
"tor_out_2",
"tor_out_3",
"tor_out_4",
"tor_out_5",
"tor_out_6",
"tor_out_7",
"tor_out_8",
"alt_bp",
"tor_in_13", // Alternat 1
"tor_in_14", // Alternat 2
"alt_ucomb",
"pres_ucomb";
codec = "Rec. In 1",
"Interco In 1",
"Rec. In 2",
"Interco In 2",
"Micro ITH",
"Audio OPT 1",
"Audio OPT 2",
"Micro Combine",
"Rec. Out 1",
"Interco Out 1",
"Rec. Out 2",
"Interco Out 2",
"HP ITH",
"HP 1",
"HP 2",
"Ecoute Combine";
};
GPIO_FAV_CLA {
compatible = "s3k,gpios-def-fav", "cs,mia-fav";
fav-id = <7>;
names = "alt_umain_a",
"alt_umain_b",
"alt_ucasque_a",
"alt_ucasque_b";
pres = "pres_ucasque_a",
"pres_umain_a",
"pres_ucasque_b",
"pres_umain_b";
codec = "Micro Casque_a",
"Micro Main_a",
"Micro Casque_b",
"Micro Main_b",
"Ec. droite Casque_a",
"Ec. gauche Casque_a",
"Ec. droite Casque_b",
"Ec. gauche Casque_b";
};
GPIO_CA_NVCS {
compatible = "s3k,gpios-def-ca", "cs,mia-far";
far-id = <1>;
names = "tor_in_audio_1",
"tor_in_audio_2",
"tor_in_audio_3",
"tor_in_audio_4",
"tor_in_5",
"alt_pedale_1",
"alt_pedale_2",
"dec_ucomb",
"tor_in_9",
"tor_in_10",
"alt_aith",
"tor_out_audio_1",
"tor_out_audio_2",
"tor_out_audio_3",
"tor_out_audio_4",
"tor_out_5",
"tor_out_6",
"none",
"none",
"alt_bp",
"tor_in_13", // Alternat 1
"tor_in_14", // Alternat 2
"alt_ucomb",
"pres_ucomb";
codec = "Audio In 1",
"Audio In 2",
"Audio In 3",
"Audio In 4",
"Micro ITH",
"Audio OPT 1",
"Audio OPT 2",
"Micro Combine",
"Audio Out 1",
"Audio Out 2",
"Audio Out 3",
"Audio Out 4",
"Audio Out 5",
"HP 1",
"HP 2",
"Ecoute Combine";
};
GPIO_FAV_NVCS {
compatible = "s3k,gpios-def-fav", "cs,mia-fav";
fav-id = <3 5 6>;
names = "alt_umain_a",
"alt_umain_b",
"alt_ucasque_a",
"alt_ucasque_b";
pres = "pres_ucasque_a",
"pres_umain_a",
"pres_ucasque_b",
"pres_umain_b";
codec = "Micro Casque_a",
"Micro Main_a",
"Micro Casque_b",
"Micro Main_b",
"Ec. droite Casque_a",
"Ec. gauche Casque_a",
"Ec. droite Casque_b",
"Ec. gauche Casque_b";
};
GPIO_CA_GW {
compatible = "s3k,gpios-def-ca", "cs,mia-far";
far-id = <4>;
names = "tor_in_1",
"tor_in_2",
"tor_in_3",
"tor_in_4",
"tor_in_5",
"tor_in_6",
"tor_in_7",
"none",
"none",
"dptt",
"pt_ct",
"tor_out_1",
"tor_out_2",
"tor_out_3",
"tor_out_4",
"tor_out_5",
"tor_out_6",
"tor_out_7",
"cgc",
"none",
"none",
"none",
"none",
"none";
codec = "Audio In 1",
"Audio In 2",
"Audio In 3",
"Audio In 4",
"Audio In 5",
"Audio In 6",
"Audio In 7",
"Audio In 8",
"Audio Out 1",
"Audio Out 2",
"Audio Out 3",
"Audio Out 4",
"not used",
"not used",
"not used",
"not used";
};
GPIO_FAV_GW {
compatible = "s3k,gpios-def-fav", "cs,mia-fav";
fav-id = <4>;
names = "none",
"none",
"none",
"none";
pres = "none",
"none",
"none",
"none";
codec = "Micro Casque_a",
"not used",
"not used",
"not used",
"Ec. droite Casque_a",
"not used",
"not used",
"not used";
};
IDENT_EQUIPT_NVCS {
compatible = "ident-equipt-fav", "cs,mia-fav";
fav-id = <3 5 6>;
infos = "22", /* nombre d'équipements possibles */
/* bornes min et max, niveaux in et out en dB,
croissement TS, type casque */
"0", "340", "-27", "-10", "no", "yes",
/* equipement 1 */
"341", "420", "-27", "-10", "no", "yes",
/* equipement 2 */
"421", "502", "-27", "-10", "no", "yes",
/* equipement 3 */
"503", "578", "-27", "-10", "no", "yes",
/* equipement 4 */
"579", "682", "-27", "-10", "no", "yes",
/* equipement 5 */
"683", "804", "-27", "-10", "no", "yes",
/* equipement 6 */
"805", "908", "-7", "-17", "yes", "yes",
/* equipement 7 */
"909", "1016", "-27", "-10", "no",
"yes", /* equipement 8 */
"1017", "1120", "-27", "-10", "no",
"yes", /* equipement 9 */
"1121", "1232", "-27", "-10", "no",
"yes", /* equipement 10 */
"1233", "1392", "-27", "-10", "no",
"yes", /* equipement 11 */
"1393", "1523", "-23", "-1", "no",
"yes", /* equipement 12 */
"1524", "1664", "-27", "-10", "no",
"yes", /* equipement 13 */
"1665", "1786", "-27", "-10", "no",
"yes", /* equipement 14 */
"1787", "1954", "-27", "-10", "no",
"yes", /* equipement 15 */
"1955", "2194", "-27", "-10", "no",
"yes", /* equipement 16 */
"2195", "2396", "-27", "-10", "no",
"yes", /* equipement 17 */
"2397", "2556", "-27", "-10", "no",
"yes", /* equipement 18 */
"2557", "2738", "-27", "-10", "no",
"yes", /* equipement 19 */
"2739", "2966", "-27", "-10", "no",
"yes", /* equipement 20 */
"2967", "3156", "-11", "-10", "no",
"no", /* equipement 21 */
"3157", "4095", "-27", "-10", "no",
"yes"; /* sans equipement */
};
FAV_CS_SPI: gpio-controller@dummy0 {
#gpio-cells = <2>;
compatible = "cs-fav-poste";
gpio-controller;
reg = <4 0x44 2>; /* necessaire mais non utilise */
gpios = <&fav 5 1 /* CS FAV */
&fav 4 1 /* CS Ident equipement */
&fav 3 1>; /* CS FPGA */
};
POT_A_NVCS {
compatible = "pot-miae", "cs,mia-fav";
fav-id = <5 6>;
user-name = "pot_a";
dev-name = "ad7923";
io-channels = <&iio 0>;
io-channel-names = "channel_0";
dev-channel = "channel_0";
};
POT_B_NVCS {
compatible = "pot-miae", "cs,mia-fav";
fav-id = <5 6>;
user-name = "pot_b";
dev-name = "ad7923";
io-channels = <&iio 1>;
io-channel-names = "channel_1";
dev-channel = "channel_1";
};
POT_A_PO {
compatible = "pot-miae", "cs,mia-fav";
fav-id = <3>;
user-name = "pot_a";
dev-name = "none";
dev-channel = "channel_0";
};
POT_B_PO {
compatible = "pot-miae", "cs,mia-fav";
fav-id = <3>;
user-name = "pot_b";
dev-name = "none";
dev-channel = "channel_1";
};
POT_C_PO {
compatible = "pot-miae", "cs,mia-fav";
fav-id = <3>;
user-name = "pot_c";
dev-name = "none";
dev-channel = "channel_2";
};
POT_D_PO {
compatible = "pot-miae", "cs,mia-fav";
fav-id = <3>;
user-name = "pot_d";
dev-name = "none";
dev-channel = "channel_3";
};
};
soc@ff000000 {
compatible = "fsl,mpc885", "fsl,pq1-soc";
#address-cells = <1>;
#size-cells = <1>;
device_type = "soc";
ranges = <0x0 0xff000000 0x28000>;
bus-frequency = <0>;
clock-frequency = <0>;
WDT: watchdon@0 {
compatible = "fsl,mpc823-wdt";
reg = <0x0 0x10>;
};
phy: mdio@e00 {
compatible = "fsl,mpc885-fec-mdio", "fsl,pq1-fec-mdio";
reg = <0xe00 0x188>;
#address-cells = <1>;
#size-cells = <0>;
PHY1: ethernet-phy@1 {
interrupts = <2 1>;
interrupt-parent = <&PIC>;
reg = <0x1>;
device_type = "ethernet-phy";
};
PHY2: ethernet-phy@2 {
interrupts = <2 1>;
interrupt-parent = <&PIC>;
reg = <0x3>;
device_type = "ethernet-phy";
};
PHY3: ethernet-phy@3 {
interrupts = <2 1>;
interrupt-parent = <&PIC>;
reg = <0x2>;
device_type = "ethernet-phy";
};
};
eth0: ethernet@e00 {
device_type = "network";
compatible = "fsl,mpc885-fec-enet", "fsl,pq1-fec-enet";
reg = <0xe00 0x188>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <5 1>;
interrupt-parent = <&PIC>;
phy-handle = <&PHY1>;
linux,network-index = <0>;
};
eth1: ethernet@1e00 {
device_type = "network";
compatible = "fsl,mpc885-fec-enet", "fsl,pq1-fec-enet";
reg = <0x1e00 0x188>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <7 1>;
interrupt-parent = <&PIC>;
phy-handle = <&PHY2 &PHY3>;
linux,network-index = <1>;
gpios = <&CPM1_PIO_E 18 1>;
PHY-disable = "isolate";
};
PIC: pic@0 {
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x0 0x24>;
compatible = "fsl,mpc885-pic", "fsl,pq1-pic";
};
SIT: sit@200 {
compatible = "fsl,mpc866-sit", "fsl,pq1-sit";
reg = <0x200 0x80>;
interrupts = <11 1>;
interrupt-parent = <&PIC>;
};
cpm@9c0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc885-cpm", "fsl,cpm1";
ranges;
reg = <0x9c0 0x40>;
brg-frequency = <0>;
interrupts = <0>; // cpm error interrupt
interrupt-parent = <&CPM_PIC>;
muram@2000 {
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x2000 0x2000>;
data@0 {
compatible = "fsl,cpm-muram-data";
reg = <0x0 0x1c00>;
};
};
brg@9f0 {
compatible = "fsl,mpc885-brg", "fsl,cpm1-brg",
"fsl,cpm-brg";
reg = <0x9f0 0x10>;
clock-frequency = <0>;
};
CPM_PIC: pic@930 {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
interrupts = <3 2 0 2>;
interrupt-parent = <&PIC>;
reg = <0x930 0x20>;
compatible = "fsl,mpc885-cpm-pic", "fsl,cpm1-pic";
};
CPM1_PIO_A: gpio-controller@950 {
#gpio-cells = <2>;
compatible = "fsl,cpm1-pario-bank-a";
reg = <0x950 0x10>;
gpio-controller;
};
CPM1_PIO_B: gpio-controller@ab8 {
#gpio-cells = <2>;
compatible = "fsl,cpm1-pario-bank-b";
reg = <0xab8 0x10>;
gpio-controller;
};
CPM1_PIO_C: gpio-controller@960 {
#gpio-cells = <2>;
compatible = "fsl,cpm1-pario-bank-c";
reg = <0x960 0x10>;
interrupts = <0 0 0 0 1 2 6 9 10 11 14 15 23 24 26 31>;
interrupt-parent = <&CPM_PIC>;
gpio-controller;
};
CPM1_PIO_D: gpio-controller@970 {
#gpio-cells = <2>;
compatible = "fsl,cpm1-pario-bank-d";
reg = <0x970 0x10>;
gpio-controller;
};
CPM1_PIO_E: gpio-controller@ac8 {
#gpio-cells = <2>;
compatible = "fsl,cpm1-pario-bank-e";
reg = <0xac8 0x18>;
gpio-controller;
};
dsp1: dsp1@900 {
device_type = "dsp";
compatible = "fsl,cpm1-dsp";
reg = <0x900 0x30 0x3ec0 0x40>;
interrupts = <22>;
interrupt-parent = <&CPM_PIC>;
fsl,cpm-dsp = <1>;
fsl,cpm-command = <0x90>;
};
dsp2: dsp2@900 {
device_type = "dsp";
compatible = "fsl,cpm1-dsp";
reg = <0x900 0x30 0x3fc0 0x40>;
interrupts = <22>;
interrupt-parent = <&CPM_PIC>;
fsl,cpm-dsp = <2>;
fsl,cpm-command = <0xd0>;
};
tsa: tsa@9c0 {
compatible = "fsl,mpc885-tsa", "fsl,cpm1-tsa";
reg = <0x9c0 0x440 0x930 0x20>;
/* parametres possible : none, SCC3, SCC4 (ou SMC2 si
defini) */
scc_tdm = "SCC4";
/* vitesse bus numerique 4 ou 8 MHz */
data_rate = <4>;
};
smc1: serial@a80 {
device_type = "serial";
compatible = "fsl,mpc885-smc-uart", "fsl,cpm1-smc-uart";
reg = <0xa80 0x10 0x3e80 0x40>;
interrupts = <4>;
interrupt-parent = <&CPM_PIC>;
fsl,cpm-brg = <4>;
fsl,cpm-command = <0x90>;
};
scc2: serial@a20 {
device_type = "serial";
compatible = "fsl,mpc885-scc-uart", "fsl,cpm1-scc-uart";
reg = <0xa20 0x20 0x3d00 0x80>;
interrupts = <29>;
interrupt-parent = <&CPM_PIC>;
fsl,cpm-brg = <1>;
fsl,cpm-command = <0x40>;
gpios = <&CPM1_PIO_C 9 1 /* CTS2 */
&CPM1_PIO_B 18 1>; /* RTS2 */
};
smc2: serial@a90 {
device_type = "serial";
compatible = "fsl,mpc885-smc-uart",
"fsl,cpm1-smc-uart", "cs,mia-far";
reg = <0xa90 0x10 0x3f80 0x40>;
interrupts = <3>;
interrupt-parent = <&CPM_PIC>;
fsl,cpm-brg = <3>;
fsl,cpm-command = <0xd0>;
gpios = <&liens 3 1 /* CTS */
&liens 4 1>; /* RTS */
far-id = <4>;
};
scc3: serial@a40 {
device_type = "serial";
compatible = "fsl,mpc885-scc-uart",
"fsl,cpm1-scc-uart", "cs,mia-far";
reg = <0xa40 0x20 0x3e00 0x80>;
interrupts = <28>;
interrupt-parent = <&CPM_PIC>;
fsl,cpm-brg = <2>;
fsl,cpm-command = <0x80>;
gpios = <&CPM1_PIO_C 5 1 /* CTS3 */
&CPM1_PIO_D 7 1>; /* RTS3 */
far-id = <4>;
};
scc3wb: wb@a40 {
device_type = "wb_scc";
wb_name = "scc3";
compatible = "cs,wb-scc", "cs,mia-far";
reg = <0xa40 0x20 0x3e00 0x80>;
interrupts = <28 2>; /* scc, cts */
interrupt-parent = <&CPM_PIC>;
fsl,cpm-brg = <2>;
fsl,cpm-command = <0x80>;
gpios = <&CPM1_PIO_C 5 1 /* CTS3 */
&CPM1_PIO_D 7 1>; /* RTS3 */
far-id = <4>;
};
scc4t: tdm@a60 {
device_type = "tdm";
tdm_name = "scc4";
compatible = "fsl,mpc885-scc-tdm", "fsl,cpm1-scc-tdm";
reg = <0xa60 0x20 0x3f00 0x80>;
interrupts = <27>;
interrupt-parent = <&CPM_PIC>;
fsl,cpm-command = <0xc0>;
};
smc2_9b: smc@a90 {
device_type = "smc_9bits";
compatible = "cs,smc-9bits", "cs,mia-far";
reg = <0xa90 0x10 0x3f80 0x40 0x9c0 0x440>;
interrupts = <3>;
interrupt-parent = <&CPM_PIC>;
fsl,cpm-brg = <3>;
fsl,cpm-command = <0xd0>;
gpios = <&liens 12 1 /* CTS */
&liens 11 1>; /* RTS */
far-id = <4>;
};
spi: spi@a80 {
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
compatible = "fsl,spi", "fsl,cpm1-spi";
reg = <0xa80 0x30 0x3d80 0x30>;
interrupts = <5>;
interrupt-parent = <&CPM_PIC>;
mode = "cpu";
gpios = <&CPM1_PIO_C 4 1 /* SICOFI 1 */
&CPM1_PIO_B 23 1 /* TEMP MCR */
&CPM1_PIO_C 8 1 /* SICOFI 2 */
&CPM1_PIO_C 12 1 /* EEPROM MIAE */
&CPM1_PIO_D 6 1 /* SICOFI 3 */
&CPM1_PIO_B 14 1 /* TEMP MPC885 */
&CPM1_PIO_B 21 1 /* EEPROM CMPC885 */
&FAV_CS_SPI 1 1 /* FAV SPI */
&FAV_CS_SPI 2 1>; /* FAV POSTE FPGA */
sicofi@0 {
compatible = "infineon,miae-sicofi", "cs,mia-far";
far-id = <0 2 3 4 5 6 7>;
spi-max-frequency = <1000000>;
reg = <0>;
spi-cs-high;
spi-cpha;
spi-troll;
name_codec = "codec_1";
analog_in = "-2dB -2dB -2dB -2dB";
analog_out = "6dB 6dB 6dB 6dB";
niveau_in = "-10dB -10dB -10dB -10dB";
niveau_out = "-10dB -10dB -10dB -10dB";
};
sicofi_nvcs@0 {
compatible = "infineon,miae-sicofi", "cs,mia-far";
far-id = <1>;
spi-max-frequency = <1000000>;
reg = <0>;
spi-cs-high;
spi-cpha;
spi-troll;
name_codec = "codec_1";
analog_in = "-2dB -2dB -2dB -2dB";
analog_out = "0dB 0dB 0dB 0dB";
niveau_in = "-10dB -10dB -10dB -10dB";
niveau_out = "-10dB -10dB -10dB -10dB";
};
lm74@1 {
compatible = "ns,lm74";
spi-max-frequency = <1000000>;
reg = <1>;
spi-cs-high;
};
sicofi@2 {
compatible = "infineon,miae-sicofi", "cs,mia-far";
far-id = <0 2 3 5 6 7>;
spi-max-frequency = <1000000>;
reg = <2>;
spi-cs-high;
spi-cpha;
spi-troll;
name_codec = "codec_2";
analog_in = "-2dB 0dB 0dB 12dB";
analog_out = "3dB 3dB 3dB 4,5dB";
niveau_in = "-10dB -10dB -10dB -31dB";
niveau_out = "-10dB -10dB -10dB -10dB";
};
sicofi_nvcs@2 {
compatible = "infineon,miae-sicofi", "cs,mia-far";
far-id = <1>;
spi-max-frequency = <1000000>;
reg = <2>;
spi-cs-high;
spi-cpha;
spi-troll;
name_codec = "codec_2";
analog_in = "-2dB 0dB 0dB 18dB";
analog_out = "6dB 3dB 3dB 4,5dB";
niveau_in = "-10dB -10dB -10dB -37dB";
niveau_out = "-10dB -10dB -10dB -10dB";
};
sicofi_gw@2 {
compatible = "infineon,miae-sicofi", "cs,mia-far";
far-id = <4>;
spi-max-frequency = <1000000>;
reg = <2>;
spi-cs-high;
spi-cpha;
spi-troll;
name_codec = "codec_2";
analog_in = "-3dB -3dB -3dB -3dB";
analog_out = "3dB 3dB 3dB 3dB";
niveau_in = "-10dB -10dB -10dB -10dB";
niveau_out = "-10dB -10dB -10dB -10dB";
};
eeprom@3 {
compatible = "atmel,at25", "cs,eeprom";
spi-max-frequency = <1000000>;
reg = <3>;
spi-cs-high;
at25,byte-len = <1024>;
at25,addr-mode = <2>;
at25,page-size = <32>;
};
sicofi@4 {
compatible = "infineon,miae-sicofi", "cs,mia-fav";
fav-id = <0 1 2 4 7>;
spi-max-frequency = <1000000>;
reg = <4>;
spi-cs-high;
spi-cpha;
spi-troll;
name_codec = "codec_3";
analog_in = "12dB -7dB 12dB -7dB";
analog_out = "6dB 6dB 6dB 6dB";
niveau_in = "-27dB -8dB -27dB -8dB";
niveau_out = "-10dB -10dB -10dB -10dB";
};
sicofi_nvcs@4 {
compatible = "infineon,miae-sicofi", "cs,mia-fav";
fav-id = <5 6>;
spi-max-frequency = <1000000>;
reg = <4>;
spi-cs-high;
spi-cpha;
spi-troll;
name_codec = "codec_3";
analog_in = "12dB -7dB 12dB -7dB";
analog_out = "6dB 6dB 6dB 6dB";
niveau_in = "-27dB -8dB -27dB -8dB";
niveau_out = "-10dB -10dB -10dB -10dB";
io-channels = <&iio 2>, <&iio 3>;
iio-name = "ad7923";
io-channel-names = "channel_2", "channel_3";
iio-channel = "channel_2", "channel_3";
};
sicofi_postes@4 {
compatible = "infineon,miae-sicofi", "cs,mia-fav";
fav-id = <3>;
spi-max-frequency = <1000000>;
reg = <4>;
spi-cs-high;
spi-cpha;
spi-troll;
name_codec = "codec_3";
analog_in = "12dB -7dB 12dB -7dB";
analog_out = "6dB 6dB 6dB 6dB";
niveau_in = "-27dB -8dB -27dB -8dB";
niveau_out = "-10dB -10dB -10dB -10dB";
io-channels = <&iio 0>, <&iio 1>;
iio-name = "ad7923";
io-channel-names = "channel_0", "channel_1";
iio-channel = "channel_0", "channel_1";
};
lm74@5 {
compatible = "ns,lm74";
spi-max-frequency = <1000000>;
reg = <5>;
spi-cs-high;
};
eeprom@6 {
compatible = "atmel,at25", "cs,eeprom";
spi-max-frequency = <1000000>;
reg = <6>;
spi-cs-high;
at25,byte-len = <1024>;
at25,addr-mode = <2>;
at25,page-size = <32>;
};
iio: csfav@7 {
compatible = "iio,ad7923", "cs,mia-fav";
spi-max-frequency = <2000000>;
reg = <7>;
spi-cs-high;
spi-cpol;
fav-id = <3 5 6>;
#io-channel-cells = <1>;
};
gpiofav: csfavgw@7 {
compatible = "gpio,max7301", "cs,mia-fav";
spi-max-frequency = <2000000>;
reg = <7>;
spi-cs-high;
#gpio-cells = <2>;
gpio-controller;
fav-id = <4>;
};
csfavfpga@8 {
compatible = "cs,fpga-poste", "cs,mia-fav";
spi-max-frequency = <2000000>;
reg = <8>;
spi-cs-high;
fav-id = <3>;
};
};
dummy_pio {
compatible = "s3k,dummy_pio";
reg = <0xa980 0x40>;
};
dummy: gpio-controller@dummygpio {
#gpio-cells = <2>;
compatible = "s3k,dummy-gpio";
reg = <0x2 0x1>; /* necessaire mais non utilise */
gpio-controller;
};
gpio-leds {
compatible = "gpio-leds", "cs,mia-fav";
fav-id = <4>;
port_31 {
label = "favgw:red:1";
gpios = <&gpiofav 27 1>;
};
port_30 {
label = "favgw:red:2";
gpios = <&gpiofav 26 1>;
};
port_29 {
label = "favgw:red:3";
gpios = <&gpiofav 25 1>;
};
port_28 {
label = "favgw:red:4";
gpios = <&gpiofav 24 1>;
};
port_27 {
label = "favgw:red:5";
gpios = <&gpiofav 23 1>;
};
port_26 {
label = "favgw:red:6";
gpios = <&gpiofav 22 1>;
};
port_25 {
label = "favgw:red:7";
gpios = <&gpiofav 21 1>;
};
port_24 {
label = "favgw:red:8";
gpios = <&gpiofav 20 1>;
};
port_23 {
label = "favgw:green:1";
gpios = <&gpiofav 19 1>;
};
port_22 {
label = "favgw:green:2";
gpios = <&gpiofav 18 1>;
};
port_21 {
label = "favgw:green:3";
gpios = <&gpiofav 17 1>;
};
port_20 {
label = "favgw:green:4";
gpios = <&gpiofav 16 1>;
};
port_19 {
label = "favgw:green:5";
gpios = <&gpiofav 15 1>;
};
port_18 {
label = "favgw:green:6";
gpios = <&gpiofav 14 1>;
};
port_17 {
label = "favgw:green:7";
gpios = <&gpiofav 13 1>;
};
port_16 {
label = "favgw:green:8";
gpios = <&gpiofav 12 1>;
};
port_15 {
label = "favgw:yellow:9";
gpios = <&gpiofav 11 1>;
};
port_14 {
label = "favgw:yellow:10";
gpios = <&gpiofav 10 1>;
};
port_13 {
label = "favgw:yellow:11";
gpios = <&gpiofav 9 1>;
};
port_12 {
label = "favgw:yellow:12";
gpios = <&gpiofav 8 1>;
};
port_11 {
label = "favgw:yellow:13";
gpios = <&gpiofav 7 1>;
};
port_10 {
label = "favgw:yellow:14";
gpios = <&gpiofav 6 1>;
};
port_9 {
label = "favgw:yellow:15";
gpios = <&gpiofav 5 1>;
};
port_8 {
label = "favgw:yellow:16";
gpios = <&gpiofav 4 1>;
};
};
};
/* crypto@20000 {
compatible = "fsl,sec1.2", "fsl,sec1.0";
reg = <0x20000 0x8000>;
interrupts = <1 1>;
interrupt-parent = <&PIC>;
fsl,num-channels = <1>;
fsl,channel-fifo-len = <24>;
fsl,exec-units-mask = <0x4c>;
fsl,descriptor-types-mask = <0x05000155>;
};
*/ };
chosen {
linux,stdout-path = &smc1;
};
};
^ permalink raw reply
* Re: [PATCH v2 1/2] spi: fsl-spi: Fix parameter ram offset setup for CPM1
From: Scott Wood @ 2014-10-08 16:30 UTC (permalink / raw)
To: leroy christophe; +Cc: Mark Brown, linuxppc-dev, linux-kernel, linux-spi
In-Reply-To: <5435649F.5070908@c-s.fr>
On Wed, 2014-10-08 at 18:21 +0200, leroy christophe wrote:
> Le 07/10/2014 02:15, Scott Wood a écrit :
> > On Sat, 2014-10-04 at 14:02 +0200, christophe leroy wrote:
> >> What should it look like if that offset had to be in the device tree ?
> > If the offset is not relocatable or discoverable, it should stay in the
> > device tree. If you have an old chip you wouldn't have
> > fsl,cpm1-spi-reloc and thus you'd still have "0x3d80 0x30" in reg.
> This index is from the start of the dual port RAM. It is 0x2000 above
> the start of the CPM area.
> In the DTS, we have:
>
> soc@ff000000 {
> compatible = "fsl,mpc885", "fsl,pq1-soc";
> #address-cells = <1>;
> #size-cells = <1>;
> device_type = "soc";
> ranges = <0x0 0xff000000 0x28000>;
> bus-frequency = <0>;
> clock-frequency = <0>;
>
> cpm@9c0 {
> #address-cells = <1>;
> #size-cells = <1>;
> compatible = "fsl,mpc885-cpm", "fsl,cpm1";
> ranges;
> reg = <0x9c0 0x40>;
> brg-frequency = <0>;
> interrupts = <0>; // cpm error interrupt
> interrupt-parent = <&CPM_PIC>;
>
> muram@2000 {
> #address-cells = <1>;
> #size-cells = <1>;
> ranges = <0x0 0x2000 0x2000>;
>
> data@0 {
> compatible = "fsl,cpm-muram-data";
> reg = <0x0 0x1c00>;
> };
> };
>
> spi: spi@a80 {
> #address-cells = <1>;
> #size-cells = <0>;
> cell-index = <0>;
> compatible = "fsl,spi", "fsl,cpm1-spi";
> reg = <0xa80 0x30 0x3d80 0x30>;
> interrupts = <5>;
> interrupt-parent = <&CPM_PIC>;
> mode = "cpu";
>
>
> The binding allows me to do an of_iomap() on the parameter RAM, hence to
> get access to the relocation index which is inside it.
> But if the relocation index is 0, I have to calculate it by myself
> because the calling function expects it in return.
> The binding is also supposed to tell that the muram is at 0xff002000.
> But I don't know how I can get this info and use it to calculate the
> index of my param RAM ? I need to calculate the index which is 1d80
> (0x3d80 - 0x2000)
What binding are you talking about? There is no published binding for
this yet.
As for what the driver should do, it should do an of_iomap(), but what
it does with the resulting memory depends on the compatible. For
fsl,cpm1-spi, the result would be the parameter RAM for the device. For
fsl,cpm1-spi-reloc and fsl,cpm2-spi, it would be the relocation
register. The driver would either read the contents of the register, or
write a different offset.
My understanding is that the relocation register would only be zero on
the chips where we'd use fsl,cpm1-spi, not fsl,cpm1-spi-reloc.
-Scott
^ permalink raw reply
* Re: [PATCH v2 1/2] spi: fsl-spi: Fix parameter ram offset setup for CPM1
From: leroy christophe @ 2014-10-08 16:21 UTC (permalink / raw)
To: Scott Wood; +Cc: Mark Brown, linuxppc-dev, linux-kernel, linux-spi
In-Reply-To: <1412640953.13320.502.camel@snotra.buserror.net>
Le 07/10/2014 02:15, Scott Wood a écrit :
> On Sat, 2014-10-04 at 14:02 +0200, christophe leroy wrote:
>> Le 03/10/2014 22:29, Scott Wood a écrit :
>>> On Fri, 2014-10-03 at 18:49 +0200, Christophe Leroy wrote:
>>>> On CPM1, the SPI parameter RAM has a default location. In fsl_spi_cpm_get_pram()
>>>> there was a confusion between the SPI_BASE register and the base of the SPI
>>>> parameter RAM. Fortunatly, it was working properly with MPC866 and MPC885
>>>> because they do set SPI_BASE, but on MPC860 and other old MPC8xx that doesn't
>>>> set SPI_BASE, pram_ofs was not properly set. This patch fixes this confusion.
>>>>
>>>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>>>>
>>>> ---
>>>> Changes from v1 to v2: none
>>>>
>>>> drivers/spi/spi-fsl-cpm.c | 9 ++++-----
>>>> 1 file changed, 4 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c
>>>> index 54b0637..0f3a912 100644
>>>> --- a/drivers/spi/spi-fsl-cpm.c
>>>> +++ b/drivers/spi/spi-fsl-cpm.c
>>>> @@ -262,15 +262,14 @@ static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi)
>>>> pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
>>>> out_be16(spi_base, pram_ofs);
>>>> } else {
>>>> - struct spi_pram __iomem *pram = spi_base;
>>>> - u16 rpbase = in_be16(&pram->rpbase);
>>>> + u16 rpbase = in_be16(spi_base);
>>>>
>>>> - /* Microcode relocation patch applied? */
>>>> + /* Microcode relocation patch applied | rpbase set by default */
>>>> if (rpbase) {
>>>> pram_ofs = rpbase;
>>>> } else {
>>>> - pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
>>>> - out_be16(spi_base, pram_ofs);
>>>> + pram_ofs = offsetof(cpm8xx_t, cp_dparam[PROFF_SPI]) -
>>>> + offsetof(cpm8xx_t, cp_dpmem[0]);
>>>> }
>>>> }
>>> Why is PROFF_SPI not coming from the device tree?
>> That's where it starts to become tricky.
>>
>> PROFF_SPI is defined in cpm1.h which is included by the driver already.
> Yes, but those values shouldn't be used. It's a leftover from the old
> way of hardcoding things and describing the hardware with kconfig rather
> than the device tree.
>
>> It provides the default offset from the start of the parameter RAM.
>> Previously I had the following in my device tree, and the last part of
>> the source above (the one for rpbase == 0) could not work.
>>
>> spi: spi@a80 {
>> cell-index = <0>;
>> compatible = "fsl,spi", "fsl,cpm1-spi";
>> reg = <0xa80 0x30 0x3d80 0x30>;
>>
>> First reg area was the area for SPI registers. Second area was the
>> parameter RAM zone, which was just mapped to get access to the SPI_BASE
>> pointer (rpbase)
>>
>> Now I have
>>
>> compatible = "fsl,spi", "fsl,cpm1-spi-reloc";
>> reg = <0xa80 0x30 0x3dac 0x2>;
>>
>> First reg area is the area for SPI registers. Second area is the
>> SPI_BASE, as for the CPM2.
>>
>> On recent 8xx (885 and 866 at least) it contains the offset (=0x1D80) of
>> the parameter RAM. But on old ones (860, ...) it contains 0. Therefore
>> we have to get the default index in another way.
>> What I wanted was to keep something similar to what's done with CPM2.
>>
>> What should it look like if that offset had to be in the device tree ?
> If the offset is not relocatable or discoverable, it should stay in the
> device tree. If you have an old chip you wouldn't have
> fsl,cpm1-spi-reloc and thus you'd still have "0x3d80 0x30" in reg.
This index is from the start of the dual port RAM. It is 0x2000 above
the start of the CPM area.
In the DTS, we have:
soc@ff000000 {
compatible = "fsl,mpc885", "fsl,pq1-soc";
#address-cells = <1>;
#size-cells = <1>;
device_type = "soc";
ranges = <0x0 0xff000000 0x28000>;
bus-frequency = <0>;
clock-frequency = <0>;
cpm@9c0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc885-cpm", "fsl,cpm1";
ranges;
reg = <0x9c0 0x40>;
brg-frequency = <0>;
interrupts = <0>; // cpm error interrupt
interrupt-parent = <&CPM_PIC>;
muram@2000 {
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x2000 0x2000>;
data@0 {
compatible = "fsl,cpm-muram-data";
reg = <0x0 0x1c00>;
};
};
spi: spi@a80 {
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
compatible = "fsl,spi", "fsl,cpm1-spi";
reg = <0xa80 0x30 0x3d80 0x30>;
interrupts = <5>;
interrupt-parent = <&CPM_PIC>;
mode = "cpu";
The binding allows me to do an of_iomap() on the parameter RAM, hence to
get access to the relocation index which is inside it.
But if the relocation index is 0, I have to calculate it by myself
because the calling function expects it in return.
The binding is also supposed to tell that the muram is at 0xff002000.
But I don't know how I can get this info and use it to calculate the
index of my param RAM ? I need to calculate the index which is 1d80
(0x3d80 - 0x2000)
Christophe
^ permalink raw reply
* Re: [PATCH V3 3/3] powerpc, ptrace: Enable support for miscellaneous registers
From: Anshuman Khandual @ 2014-10-08 16:20 UTC (permalink / raw)
To: Sukadev Bhattiprolu
Cc: mikey, james.hogan, avagin, Paul.Clothier, davem, peterz, palves,
linux-kernel, oleg, dhowells, linuxppc-dev, davej, akpm, tglx
In-Reply-To: <20140827213559.GB11489@us.ibm.com>
On 08/28/2014 03:05 AM, Sukadev Bhattiprolu wrote:
>
> Anshuman Khandual [khandual@linux.vnet.ibm.com] wrote:
> | This patch enables get and set of miscellaneous registers through ptrace
> | PTRACE_GETREGSET/PTRACE_SETREGSET interface by implementing new powerpc
> | specific register set REGSET_MISC support corresponding to the new ELF
> | core note NT_PPC_MISC added previously in this regard.
> |
> | Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
> | ---
> | arch/powerpc/kernel/ptrace.c | 81 ++++++++++++++++++++++++++++++++++++++++++++
> | 1 file changed, 81 insertions(+)
> |
> | diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
> | index 17642ef..63b883a 100644
> | --- a/arch/powerpc/kernel/ptrace.c
> | +++ b/arch/powerpc/kernel/ptrace.c
> | @@ -1149,6 +1149,76 @@ static int tm_cvmx_set(struct task_struct *target, const struct user_regset *reg
> | #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
> |
> | /*
> | + * Miscellaneous Registers
> | + *
> | + * struct {
> | + * unsigned long dscr;
> | + * unsigned long ppr;
> | + * unsigned long tar;
> | + * };
> | + */
> | +static int misc_get(struct task_struct *target, const struct user_regset *regset,
> | + unsigned int pos, unsigned int count,
> | + void *kbuf, void __user *ubuf)
> | +{
> | + int ret;
> | +
> | + /* DSCR register */
> | + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.dscr, 0,
> | + sizeof(unsigned long));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, dscr) + sizeof(unsigned long) +
> | + sizeof(unsigned long) != offsetof(struct thread_struct, ppr));
>
>
> I see these in arch/powerpc/include/asm/processor.h
>
> #ifdef CONFIG_PPC64
> unsigned long dscr;
> int dscr_inherit;
> unsigned long ppr; /* used to save/restore SMT priority */
> #endif
>
> where there is an 'int' between ppr and dscr. So, should one of
> the above sizeof(unsigned long) be changed to sizeof(int) ?
Right, I understand that but strangely I get this compile time error
when it is changed to sizeof(int).
error: call to ‘__compiletime_assert_1350’ declared with attribute error:
BUILD_BUG_ON failed: TSO(dscr) + sizeof(unsigned long) + sizeof(int) != TSO(ppr)
BUILD_BUG_ON(TSO(dscr) + sizeof(unsigned long) + sizeof(int) != TSO(ppr));
may be I am missing something here.
>
> Also, since we use offsetof(struct thread_struct, field) heavily, a
> macro local to the file, may simplify the code.
Right, will do that.
> #define TSO(f) (offsetof(struct thread_struct, f))
>
> | +
> | + /* PPR register */
> | + if (!ret)
> | + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.ppr, sizeof(unsigned long),
> | + 2 * sizeof(unsigned long));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, ppr) + sizeof(unsigned long)
> | + != offsetof(struct thread_struct, tar));
> | + /* TAR register */
> | + if (!ret)
> | + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tar, 2 * sizeof(unsigned long),
> | + 3 * sizeof(unsigned long));
> | + return ret;
> | +}
> | +
> | +static int misc_set(struct task_struct *target, const struct user_regset *regset,
> | + unsigned int pos, unsigned int count,
> | + const void *kbuf, const void __user *ubuf)
> | +{
> | + int ret;
> | +
> | + /* DSCR register */
> | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.dscr, 0,
> | + sizeof(unsigned long));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, dscr) + sizeof(unsigned long) +
> | + sizeof(unsigned long) != offsetof(struct thread_struct, ppr));
> | +
> | + /* PPR register */
> | + if (!ret)
> | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.ppr, sizeof(unsigned long),
> | + 2 * sizeof(unsigned long));
> | +
> | + BUILD_BUG_ON(offsetof(struct thread_struct, ppr) + sizeof(unsigned long)
> | + != offsetof(struct thread_struct, tar));
> | +
> | + /* TAR register */
> | + if (!ret)
> | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> | + &target->thread.tar, 2 * sizeof(unsigned long),
> | + 3 * sizeof(unsigned long));
> | + return ret;
> | +}
> | +
> | +/*
> | * These are our native regset flavors.
> | */
> | enum powerpc_regset {
> | @@ -1169,6 +1239,7 @@ enum powerpc_regset {
> | REGSET_TM_CFPR, /* TM checkpointed FPR */
> | REGSET_TM_CVMX, /* TM checkpointed VMX */
> | #endif
> | + REGSET_MISC /* Miscellaneous */
> | };
> |
> | static const struct user_regset native_regsets[] = {
> | @@ -1225,6 +1296,11 @@ static const struct user_regset native_regsets[] = {
> | .active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set
> | },
> | #endif
> | + [REGSET_MISC] = {
> | + .core_note_type = NT_PPC_MISC, .n = 3,
> | + .size = sizeof(u64), .align = sizeof(u64),
> | + .get = misc_get, .set = misc_set
> | + },
> | };
> |
> | static const struct user_regset_view user_ppc_native_view = {
> | @@ -1566,6 +1642,11 @@ static const struct user_regset compat_regsets[] = {
> | .active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set
> | },
> | #endif
> | + [REGSET_MISC] = {
> | + .core_note_type = NT_PPC_MISC, .n = 3,
> | + .size = sizeof(u64), .align = sizeof(u64),
> | + .get = misc_get, .set = misc_set
> | + },
>
> Since the .n = 3 is used more than once, how about a macro for the
> number of misc registers ?
Will add it as well. Thanks !
^ permalink raw reply
* Re: [PATCH] powerpc: mitigate impact of decrementer reset
From: Paul Clarke @ 2014-10-08 12:27 UTC (permalink / raw)
To: Heinz Wrobel, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <cf20308cc3b44935a604f409958b610d@BLUPR03MB167.namprd03.prod.outlook.com>
On 10/08/2014 12:37 AM, Heinz Wrobel wrote:
> what if your tb wraps during the test?
Per the Power ISA, Time Base is 64 bits, monotonically increasing, and
is writable only in hypervisor state. To my understanding, it is set to
zero at boot (although this is not prescribed).
Also, as noted by others, the logic is roughly duplicated (with some
differences) from the analogous code in __timer_interrupt just above it.
I don't see wrapping as a concern.
PC
^ permalink raw reply
* 回复: [PATCH 08/44] kernel: Move pm_power_off to common code
From: Xuetao Guan @ 2014-10-08 11:06 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-m32r-ja, linux-mips, linux-m68k, linux-efi, linux-ia64,
Steven Miao, linux-xtensa, Boris Ostrovsky, Catalin Marinas,
Will Deacon, David Howells, Max Filippov, Paul Mackerras,
Ralf Baechle, Pavel Machek, H. Peter Anvin, Guan Xuetao,
Thomas Gleixner, Lennox Wu, Hans-Christian Egtvedt, devel,
linux-s390, Jesper Nilsson, lguest, Russell King, linux-c6x-dev,
Len Brown, David S. Miller, linux-hexagon, Hirokazu Takata,
linux-sh, James E.J. Bottomley, linux-acpi, Ingo Molnar,
Geert Uytterhoeven, Mark Salter, xen-devel, Matt Turner,
Chen Liqin, Jonas Bonn, Haavard Skinnemoen, devicetree,
James Hogan, user-mode-linux-devel, linux-pm, Aurelien Jacquiot,
Heiko Carstens, Jeff Dike, adi-buildroot-devel, Chris Metcalf,
Konrad Rzeszutek Wilk, Mikael Starvik, Richard Weinberger,
linux-am33-list, Ivan Kokshaysky, linux-tegra, openipmi-developer,
linux-metag, linux-arm-kernel, Richard Henderson, Chris Zankel,
Michal Simek, Tony Luck, linux-parisc, linux-cris-kernel,
Vineet Gupta, Rafael J. Wysocki, linux-kernel, Fenghua Yu,
Richard Kuo, David Vrabel, linux-alpha, Martin Schwidefsky,
Koichi Yasutake, linuxppc-dev, Helge Deller
In-Reply-To: <1412659726-29957-9-git-send-email-linux@roeck-us.net>
----- Guenter Roeck <linux@roeck-us.net> =E5=86=99=E9=81=93=EF=BC=9A
> pm_power_off is defined for all architectures. Move it to common code.
>=20
> Have all architectures call do_kernel_poweroff instead of pm_power_off.
> Some architectures point pm_power_off to machine_power_off. For those,
> call do_kernel_poweroff from machine_power_off instead.
>=20
For UniCore32 part,
Acked-by: Xuetao Guan <gxt@mprc.pku.edu.cn>
Thanks
Xuetao
^ permalink raw reply
* [PATCH] CXL: Fix afu_read() not doing finish_wait() on signal or non-blocking
From: Ian Munsie @ 2014-10-08 10:41 UTC (permalink / raw)
To: greg, arnd, mpe, benh
Cc: cbe-oss-dev, mikey, Aneesh Kumar K.V, linux-kernel, linuxppc-dev,
jk, imunsie, anton
In-Reply-To: <1412763264-sup-2737@delenn.ozlabs.ibm.com>
If afu_read() returned due to a signal or the AFU file descriptor being
opened non-blocking it would not call finish_wait() before returning,
which could lead to a crash later when something else wakes up the wait
queue.
This patch restructures the wait logic to ensure that the cleanup is
done correctly.
Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/file.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index 847b7e6..378b099 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -273,6 +273,7 @@ static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
struct cxl_context *ctx = file->private_data;
struct cxl_event event;
unsigned long flags;
+ int rc;
DEFINE_WAIT(wait);
if (count < CXL_READ_MIN_SIZE)
@@ -285,13 +286,17 @@ static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
if (ctx_event_pending(ctx))
break;
- spin_unlock_irqrestore(&ctx->lock, flags);
- if (file->f_flags & O_NONBLOCK)
- return -EAGAIN;
+ if (file->f_flags & O_NONBLOCK) {
+ rc = -EAGAIN;
+ goto out;
+ }
- if (signal_pending(current))
- return -ERESTARTSYS;
+ if (signal_pending(current)) {
+ rc = -ERESTARTSYS;
+ goto out;
+ }
+ spin_unlock_irqrestore(&ctx->lock, flags);
pr_devel("afu_read going to sleep...\n");
schedule();
pr_devel("afu_read woken up\n");
@@ -336,6 +341,11 @@ static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
if (copy_to_user(buf, &event, event.header.size))
return -EFAULT;
return event.header.size;
+
+out:
+ finish_wait(&ctx->wq, &wait);
+ spin_unlock_irqrestore(&ctx->lock, flags);
+ return rc;
}
static const struct file_operations afu_fops = {
--
2.1.0
^ permalink raw reply related
* Re: [PATCH v4 13/16] cxl: Driver code for powernv PCIe based cards for userspace access
From: Ian Munsie @ 2014-10-08 10:28 UTC (permalink / raw)
To: Michael Neuling
Cc: cbe-oss-dev, arnd, Aneesh Kumar K.V, greg, linux-kernel,
linuxppc-dev, anton, jk
In-Reply-To: <1412758505-23495-14-git-send-email-mikey@neuling.org>
Excerpts from Michael Neuling's message of 2014-10-08 19:55:02 +1100:
> +static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
> + loff_t *off)
...
> + for (;;) {
> + prepare_to_wait(&ctx->wq, &wait, TASK_INTERRUPTIBLE);
> + if (ctx_event_pending(ctx))
> + break;
> +
> + spin_unlock_irqrestore(&ctx->lock, flags);
> + if (file->f_flags & O_NONBLOCK)
> + return -EAGAIN;
> +
> + if (signal_pending(current))
> + return -ERESTARTSYS;
Looks like I mucked this up while refactoring - these two cases no
longer call finish_wait() which can lead to a crash if something later
wakes up the ctx->wq... I'll post a fix in a separate patch shortly.
-Ian
^ permalink raw reply
* Re: powerpc: mitigate impact of decrementer reset
From: Preeti U Murthy @ 2014-10-08 10:27 UTC (permalink / raw)
To: Michael Ellerman, Paul Clarke, linuxppc-dev
In-Reply-To: <20141008025210.AF949140144@ozlabs.org>
On 10/08/2014 08:22 AM, Michael Ellerman wrote:
> On Tue, 2014-07-10 at 19:13:24 UTC, Paul Clarke wrote:
>> The POWER ISA defines an always-running decrementer which can be used
>> to schedule interrupts after a certain time interval has elapsed.
>> The decrementer counts down at the same frequency as the Time Base,
>> which is 512 MHz. The maximum value of the decrementer is 0x7fffffff.
>> This works out to a maximum interval of about 4.19 seconds.
>>
>> If a larger interval is desired, the kernel will set the decrementer
>> to its maximum value and reset it after it expires (underflows)
>> a sufficient number of times until the desired interval has elapsed.
>>
>> The negative effect of this is that an unwanted latency spike will
>> impact normal processing at most every 4.19 seconds. On an IBM
>> POWER8-based system, this spike was measured at about 25-30
>> microseconds, much of which was basic, opportunistic housekeeping
>> tasks that could otherwise have waited.
>>
>> This patch short-circuits the reset of the decrementer, exiting after
>> the decrementer reset, but before the housekeeping tasks if the only
>> need for the interrupt is simply to reset it. After this patch,
>> the latency spike was measured at about 150 nanoseconds.
>
> Hi Paul,
>
> Thanks for the excellent changelog. But this patch makes me a bit nervous :)
>
> Do you know where the latency is coming from? Is it primarily the irq work?
>
> If so I'd prefer if we could move the short circuit into __timer_interrupt()
> itself. That way we'd still have the trace points usable, and it would
> hopefully result in less duplicated logic.
I agree, this is perhaps the better approach.
Regards
Preeti U Murthy
>
> cheers
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
^ permalink raw reply
* Re: [PATCH] tools/perf/powerpc: Fix build break
From: Aneesh Kumar K.V @ 2014-10-08 10:14 UTC (permalink / raw)
To: benh, paulus, mpe, linux-kernel; +Cc: linuxppc-dev
In-Reply-To: <1408004299-18986-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com>
"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> writes:
> CC arch/powerpc/util/skip-callchain-idx.o
> arch/powerpc/util/skip-callchain-idx.c: In function =E2=80=98check_return=
_reg=E2=80=99:
> arch/powerpc/util/skip-callchain-idx.c:55:3: error: implicit declaration =
of function =E2=80=98pr_debug=E2=80=99 [-Werror=3Dimplicit-function-declara=
tion]
> pr_debug("dwarf_frame_register() %s\n", dwarf_errmsg(-1));
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
> tools/perf/arch/powerpc/util/skip-callchain-idx.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/pe=
rf/arch/powerpc/util/skip-callchain-idx.c
> index a7c23a4b3778..d73ef8bb08c7 100644
> --- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c
> +++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
> @@ -15,6 +15,7 @@
>
> #include "util/thread.h"
> #include "util/callchain.h"
> +#include "util/debug.h"
>
> /*
> * When saving the callchain on Power, the kernel conservatively saves
We still have this broken upstream.
-aneesh
^ permalink raw reply
* [PATCH v4 16/16] cxl: Add documentation for userspace APIs
From: Michael Neuling @ 2014-10-08 8:55 UTC (permalink / raw)
To: greg, arnd, mpe, benh
Cc: cbe-oss-dev, mikey, Aneesh Kumar K.V, imunsie, linux-kernel,
linuxppc-dev, jk, anton
In-Reply-To: <1412758505-23495-1-git-send-email-mikey@neuling.org>
From: Ian Munsie <imunsie@au1.ibm.com>
This documentation gives an overview of the hardware architecture, userspace
APIs via /dev/cxl/afuM.N and the syfs files. It also adds a MAINTAINERS file
entry for cxl.
Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
Documentation/ABI/testing/sysfs-class-cxl | 130 ++++++++++
Documentation/ioctl/ioctl-number.txt | 1 +
Documentation/powerpc/00-INDEX | 2 +
Documentation/powerpc/cxl.txt | 379 ++++++++++++++++++++++++++++++
MAINTAINERS | 12 +
include/uapi/misc/cxl.h | 7 +-
6 files changed, 528 insertions(+), 3 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-class-cxl
create mode 100644 Documentation/powerpc/cxl.txt
diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl
new file mode 100644
index 0000000..0a5508c
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-cxl
@@ -0,0 +1,130 @@
+Slave contexts (eg. /sys/class/cxl/afu0.0s):
+
+What: /sys/class/cxl/<afu>/irqs_max
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read/write
+ Decimal value of maximum number of interrupts that can be
+ requested by userspace. The default on probe is the maximum
+ that hardware can support (eg. 2037). Write values will limit
+ userspace applications to that many userspace interrupts. Must
+ be >= irqs_min.
+
+What: /sys/class/cxl/<afu>/irqs_min
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read only
+ Decimal value of the minimum number of interrupts that
+ userspace must request on a CXL_START_WORK ioctl. Userspace may
+ omit the num_interrupts field in the START_WORK IOCTL to get
+ this minimum automatically.
+
+What: /sys/class/cxl/<afu>/mmio_size
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read only
+ Decimal value of the size of the MMIO space that may be mmaped
+ by userspace.
+
+What: /sys/class/cxl/<afu>/modes_supported
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read only
+ List of the modes this AFU supports. One per line.
+ Valid entries are: "dedicated_process" and "afu_directed"
+
+What: /sys/class/cxl/<afu>/mode
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read/write
+ The current mode the AFU is using. Will be one of the modes
+ given in modes_supported. Writing will change the mode
+ provided that no user contexts are attached.
+
+
+What: /sys/class/cxl/<afu>/prefault_mode
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read/write
+ Set the mode for prefaulting in segments into the segment table
+ when performing the START_WORK ioctl. Possible values:
+ none: No prefaulting (default)
+ work_element_descriptor: Treat the work element
+ descriptor as an effective address and
+ prefault what it points to.
+ all: all segments process calling START_WORK maps.
+
+What: /sys/class/cxl/<afu>/reset
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: write only
+ Writing 1 here will reset the AFU provided there are not
+ contexts active on the AFU.
+
+What: /sys/class/cxl/<afu>/api_version
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read only
+ Decimal value of the current version of the kernel/user API.
+
+What: /sys/class/cxl/<afu>/api_version_com
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read only
+ Decimal value of the the lowest version of the userspace API
+ this this kernel supports.
+
+
+
+Master contexts (eg. /sys/class/cxl/afu0.0m)
+
+What: /sys/class/cxl/<afu>m/mmio_size
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read only
+ Decimal value of the size of the MMIO space that may be mmaped
+ by userspace. This includes all slave contexts space also.
+
+What: /sys/class/cxl/<afu>m/pp_mmio_len
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read only
+ Decimal value of the Per Process MMIO space length.
+
+What: /sys/class/cxl/<afu>m/pp_mmio_off
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read only
+ Decimal value of the Per Process MMIO space offset.
+
+
+Card info (eg. /sys/class/cxl/card0)
+
+What: /sys/class/cxl/<card>/caia_version
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read only
+ Identifies the CAIA Version the card implements.
+
+What: /sys/class/cxl/<card>/psl_version
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read only
+ Identifies the revision level of the PSL.
+
+What: /sys/class/cxl/<card>/base_image
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read only
+ Identifies the revision level of the base image for devices
+ that support loadable PSLs. For FPGAs this field identifies
+ the image contained in the on-adapter flash which is loaded
+ during the initial program load.
+
+What: /sys/class/cxl/<card>/image_loaded
+Date: September 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read only
+ Will return "user" or "factory" depending on the image loaded
+ onto the card.
+
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 7e240a7..8136e1f 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -313,6 +313,7 @@ Code Seq#(hex) Include File Comments
0xB1 00-1F PPPoX <mailto:mostrows@styx.uwaterloo.ca>
0xB3 00 linux/mmc/ioctl.h
0xC0 00-0F linux/usb/iowarrior.h
+0xCA 00-0F uapi/misc/cxl.h
0xCB 00-1F CBM serial IEC bus in development:
<mailto:michael.klein@puffin.lb.shuttle.de>
0xCD 01 linux/reiserfs_fs.h
diff --git a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX
index a68784d..6fd0e8b 100644
--- a/Documentation/powerpc/00-INDEX
+++ b/Documentation/powerpc/00-INDEX
@@ -11,6 +11,8 @@ bootwrapper.txt
cpu_features.txt
- info on how we support a variety of CPUs with minimal compile-time
options.
+cxl.txt
+ - Overview of the CXL driver.
eeh-pci-error-recovery.txt
- info on PCI Bus EEH Error Recovery
firmware-assisted-dump.txt
diff --git a/Documentation/powerpc/cxl.txt b/Documentation/powerpc/cxl.txt
new file mode 100644
index 0000000..2c71ecc
--- /dev/null
+++ b/Documentation/powerpc/cxl.txt
@@ -0,0 +1,379 @@
+Coherent Accelerator Interface (CXL)
+====================================
+
+Introduction
+============
+
+ The coherent accelerator interface is designed to allow the
+ coherent connection of accelerators (FPGAs and other devices) to a
+ POWER system. These devices need to adhere to the Coherent
+ Accelerator Interface Architecture (CAIA).
+
+ IBM refers to this as the Coherent Accelerator Processor Interface
+ or CAPI. In the kernel it's referred to by the name CXL to avoid
+ confusion with the ISDN CAPI subsystem.
+
+ Coherent in this context means that the accelerator and CPUs can
+ both access system memory directly and with the same effective
+ addresses.
+
+
+Hardware overview
+=================
+
+ POWER8 FPGA
+ +----------+ +---------+
+ | | | |
+ | CPU | | AFU |
+ | | | |
+ | | | |
+ | | | |
+ +----------+ +---------+
+ | PHB | | |
+ | +------+ | PSL |
+ | | CAPP |<------>| |
+ +---+------+ PCIE +---------+
+
+ The POWER8 chip has a Coherently Attached Processor Proxy (CAPP)
+ unit which is part of the PCIe Host Bridge (PHB). This is managed
+ by Linux by calls into OPAL. Linux doesn't directly program the
+ CAPP.
+
+ The FPGA (or coherently attached device) consists of two parts.
+ The POWER Service Layer (PSL) and the Accelerator Function Unit
+ (AFU). The AFU is used to implement specific functionality behind
+ the PSL. The PSL, among other things, provides memory address
+ translation services to allow each AFU direct access to userspace
+ memory.
+
+ The AFU is the core part of the accelerator (eg. the compression,
+ crypto etc function). The kernel has no knowledge of the function
+ of the AFU. Only userspace interacts directly with the AFU.
+
+ The PSL provides the translation and interrupt services that the
+ AFU needs. This is what the kernel interacts with. For example, if
+ the AFU needs to read a particular effective address, it sends
+ that address to the PSL, the PSL then translates it, fetches the
+ data from memory and returns it to the AFU. If the PSL has a
+ translation miss, it interrupts the kernel and the kernel services
+ the fault. The context to which this fault is serviced is based on
+ who owns that acceleration function.
+
+
+AFU Modes
+=========
+
+ There are two programming modes supported by the AFU. Dedicated
+ and AFU directed. AFU may support one or both modes.
+
+ When using dedicated mode only one MMU context is supported. In
+ this mode, only one userspace process can use the accelerator at
+ time.
+
+ When using AFU directed mode, up to 16K simultaneous contexts can
+ be supported. This means up to 16K simultaneous userspace
+ applications may use the accelerator (although specific AFUs may
+ support fewer). In this mode, the AFU sends a 16 bit context ID
+ with each of its requests. This tells the PSL which context is
+ associated with each operation. If the PSL can't translate an
+ operation, the ID can also be accessed by the kernel so it can
+ determine the userspace context associated with an operation.
+
+
+MMIO space
+==========
+
+ A portion of the accelerator MMIO space can be directly mapped
+ from the AFU to userspace. Either the whole space can be mapped or
+ just a per context portion. The hardware is self describing, hence
+ the kernel can determine the offset and size of the per context
+ portion.
+
+
+Interrupts
+==========
+
+ AFUs may generate interrupts that are destined for userspace. These
+ are received by the kernel as hardware interrupts and passed onto
+ userspace by a read syscall documented below.
+
+ Data storage faults and error interrupts are handled by the kernel
+ driver.
+
+
+Work Element Descriptor (WED)
+=============================
+
+ The WED is a 64-bit parameter passed to the AFU when a context is
+ started. Its format is up to the AFU hence the kernel has no
+ knowledge of what it represents. Typically it will be the
+ effective address of a work queue or status block where the AFU
+ and userspace can share control and status information.
+
+
+
+
+User API
+========
+
+ For AFUs operating in AFU directed mode, two character device
+ files will be created. /dev/cxl/afu0.0m will correspond to a
+ master context and /dev/cxl/afu0.0s will correspond to a slave
+ context. Master contexts have access to the full MMIO space an
+ AFU provides. Slave contexts have access to only the per process
+ MMIO space an AFU provides.
+
+ For AFUs operating in dedicated process mode, the driver will
+ only create a single character device per AFU called
+ /dev/cxl/afu0.0d. This will have access to the entire MMIO space
+ that the AFU provides (like master contexts in AFU directed).
+
+ The types described below are defined in include/uapi/misc/cxl.h
+
+ The following file operations are supported on both slave and
+ master devices.
+
+
+open
+----
+
+ Opens the device and allocates a file descriptor to be used with
+ the rest of the API.
+
+ A dedicated mode AFU only has one context and only allows the
+ device to be opened once.
+
+ An AFU directed mode AFU can have many contexts, the device can be
+ opened once for each context that is available.
+
+ When all available contexts are allocated the open call will fail
+ and return -ENOSPC.
+
+ Note: IRQs need to be allocated for each context, which may limit
+ the number of contexts that can be created, and therefore
+ how many times the device can be opened. The POWER8 CAPP
+ supports 2040 IRQs and 3 are used by the kernel, so 2037 are
+ left. If 1 IRQ is needed per context, then only 2037
+ contexts can be allocated. If 4 IRQs are needed per context,
+ then only 2037/4 = 509 contexts can be allocated.
+
+
+ioctl
+-----
+
+ CXL_IOCTL_START_WORK:
+ Starts the AFU context and associates it with the current
+ process. Once this ioctl is successfully executed, all memory
+ mapped into this process is accessible to this AFU context
+ using the same effective addresses. No additional calls are
+ required to map/unmap memory. The AFU memory context will be
+ updated as userspace allocates and frees memory. This ioctl
+ returns once the AFU context is started.
+
+ Takes a pointer to a struct cxl_ioctl_start_work:
+
+ struct cxl_ioctl_start_work {
+ __u64 flags;
+ __u64 work_element_descriptor;
+ __u64 amr;
+ __s16 num_interrupts;
+ __s16 reserved1;
+ __s32 reserved2;
+ __u64 reserved3;
+ __u64 reserved4;
+ __u64 reserved5;
+ __u64 reserved6;
+ };
+
+ flags:
+ Indicates which optional fields in the structure are
+ valid.
+
+ work_element_descriptor:
+ The Work Element Descriptor (WED) is a 64-bit argument
+ defined by the AFU. Typically this is an effective
+ address pointing to an AFU specific structure
+ describing what work to perform.
+
+ amr:
+ Authority Mask Register (AMR), same as the powerpc
+ AMR. This field is only used by the kernel when the
+ corresponding CXL_START_WORK_AMR value is specified in
+ flags. If not specified the kernel will use a default
+ value of 0.
+
+ num_interrupts:
+ Number of userspace interrupts to request. This field
+ is only used by the kernel when the corresponding
+ CXL_START_WORK_NUM_IRQS value is specified in flags.
+ If not specified the minimum number required by the
+ AFU will be allocated. The min and max number can be
+ obtained from sysfs.
+
+ reserved fields:
+ For ABI padding and future extensions
+
+ CXL_IOCTL_GET_PROCESS_ELEMENT:
+ Get the current context id, also known as the process element.
+ The value is returned from the kernel as a __u32.
+
+
+mmap
+----
+
+ An AFU may have an MMIO space to facilitate communication with the
+ AFU. If it does, the MMIO space can be accessed via mmap. The size
+ and contents of this area are specific to the particular AFU. The
+ size can be discovered via sysfs.
+
+ In AFU directed mode, master contexts are allowed to map all of
+ the MMIO space and slave contexts are allowed to only map the per
+ process MMIO space associated with the context. In dedicated
+ process mode the entire MMIO space can always be mapped.
+
+ This mmap call must be done after the START_WORK ioctl.
+
+ Care should be taken when accessing MMIO space. Only 32 and 64-bit
+ accesses are supported by POWER8. Also, the AFU will be designed
+ with a specific endianness, so all MMIO accesses should consider
+ endianness (recommend endian(3) variants like: le64toh(),
+ be64toh() etc). These endian issues equally apply to shared memory
+ queues the WED may describe.
+
+
+read
+----
+
+ Reads events from the AFU. Blocks if no events are pending
+ (unless O_NONBLOCK is supplied). Returns -EIO in the case of an
+ unrecoverable error or if the card is removed.
+
+ read() will always return an integral number of events.
+
+ The buffer passed to read() must be at least 4K bytes.
+
+ The result of the read will be a buffer of one or more events,
+ each event is of type struct cxl_event, of varying size.
+
+ struct cxl_event {
+ struct cxl_event_header header;
+ union {
+ struct cxl_event_afu_interrupt irq;
+ struct cxl_event_data_storage fault;
+ struct cxl_event_afu_error afu_error;
+ };
+ };
+
+ The struct cxl_event_header is defined as:
+
+ struct cxl_event_header {
+ __u16 type;
+ __u16 size;
+ __u16 process_element;
+ __u16 reserved1;
+ };
+
+ type:
+ This defines the type of event. The type determines how
+ the rest of the event is structured. These types are
+ described below and defined by enum cxl_event_type.
+
+ size:
+ This is the size of the event in bytes including the
+ struct cxl_event_header. The start of the next event can
+ be found at this offset from the start of the current
+ event.
+
+ process_element:
+ Context ID of the event.
+
+ reserved field:
+ For future extensions and padding.
+
+ If the event type is CXL_EVENT_AFU_INTERRUPT then the event
+ structure is defined as:
+
+ struct cxl_event_afu_interrupt {
+ __u16 flags;
+ __u16 irq; /* Raised AFU interrupt number */
+ __u32 reserved1;
+ };
+
+ flags:
+ These flags indicate which optional fields are present
+ in this struct. Currently all fields are mandatory.
+
+ irq:
+ The IRQ number sent by the AFU.
+
+ reserved field:
+ For future extensions and padding.
+
+ If the event type is CXL_EVENT_DATA_STORAGE then the event
+ structure is defined as:
+
+ struct cxl_event_data_storage {
+ __u16 flags;
+ __u16 reserved1;
+ __u32 reserved2;
+ __u64 addr;
+ __u64 dsisr;
+ __u64 reserved3;
+ };
+
+ flags:
+ These flags indicate which optional fields are present in
+ this struct. Currently all fields are mandatory.
+
+ address:
+ The address that the AFU unsuccessfully attempted to
+ access. Valid accesses will be handled transparently by the
+ kernel but invalid accesses will generate this event.
+
+ dsisr:
+ This field gives information on the type of fault. It is a
+ copy of the DSISR from the PSL hardware when the address
+ fault occurred. The form of the DSISR is as defined in the
+ CAIA.
+
+ reserved fields:
+ For future extensions
+
+ If the event type is CXL_EVENT_AFU_ERROR then the event structure
+ is defined as:
+
+ struct cxl_event_afu_error {
+ __u16 flags;
+ __u16 reserved1;
+ __u32 reserved2;
+ __u64 error;
+ };
+
+ flags:
+ These flags indicate which optional fields are present in
+ this struct. Currently all fields are Mandatory.
+
+ error:
+ Error status from the AFU. Defined by the AFU.
+
+ reserved fields:
+ For future extensions and padding
+
+Sysfs Class
+===========
+
+ A cxl sysfs class is added under /sys/class/cxl to facilitate
+ enumeration and tuning of the accelerators. Its layout is
+ described in Documentation/ABI/testing/sysfs-class-cxl
+
+Udev rules
+==========
+
+ The following udev rules could be used to create a symlink to the
+ most logical chardev to use in any programming mode (afuX.Yd for
+ dedicated, afuX.Ys for afu directed), since the API is virtually
+ identical for each:
+
+ SUBSYSTEM=="cxl", ATTRS{mode}=="dedicated_process", SYMLINK="cxl/%b"
+ SUBSYSTEM=="cxl", ATTRS{mode}=="afu_directed", \
+ KERNEL=="afu[0-9]*.[0-9]*s", SYMLINK="cxl/%b"
diff --git a/MAINTAINERS b/MAINTAINERS
index 809ecd6..facc219 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2711,6 +2711,18 @@ W: http://www.chelsio.com
S: Supported
F: drivers/net/ethernet/chelsio/cxgb4vf/
+CXL (IBM Coherent Accelerator Processor Interface CAPI) DRIVER
+M: Ian Munsie <imunsie@au1.ibm.com>
+M: Michael Neuling <mikey@neuling.org>
+L: linuxppc-dev@lists.ozlabs.org
+S: Supported
+F: drivers/misc/cxl/
+F: include/misc/cxl.h
+F: include/uapi/misc/cxl.h
+F: Documentation/powerpc/cxl.txt
+F: Documentation/powerpc/cxl.txt
+F: Documentation/ABI/testing/sysfs-class-cxl
+
STMMAC ETHERNET DRIVER
M: Giuseppe Cavallaro <peppe.cavallaro@st.com>
L: netdev@vger.kernel.org
diff --git a/include/uapi/misc/cxl.h b/include/uapi/misc/cxl.h
index c232be6..cd6d789 100644
--- a/include/uapi/misc/cxl.h
+++ b/include/uapi/misc/cxl.h
@@ -13,7 +13,7 @@
#include <linux/types.h>
#include <linux/ioctl.h>
-/* Structs for IOCTLS for userspace to talk to the kernel */
+
struct cxl_ioctl_start_work {
__u64 flags;
__u64 work_element_descriptor;
@@ -26,19 +26,20 @@ struct cxl_ioctl_start_work {
__u64 reserved5;
__u64 reserved6;
};
+
#define CXL_START_WORK_AMR 0x0000000000000001ULL
#define CXL_START_WORK_NUM_IRQS 0x0000000000000002ULL
#define CXL_START_WORK_ALL (CXL_START_WORK_AMR |\
CXL_START_WORK_NUM_IRQS)
-/* IOCTL numbers */
+/* ioctl numbers */
#define CXL_MAGIC 0xCA
#define CXL_IOCTL_START_WORK _IOW(CXL_MAGIC, 0x00, struct cxl_ioctl_start_work)
#define CXL_IOCTL_GET_PROCESS_ELEMENT _IOR(CXL_MAGIC, 0x01, __u32)
-/* Events from read() */
#define CXL_READ_MIN_SIZE 0x1000 /* 4K */
+/* Events from read() */
enum cxl_event_type {
CXL_EVENT_RESERVED = 0,
CXL_EVENT_AFU_INTERRUPT = 1,
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox