LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [Patch 2/5] PPC64-HWBKPT: Implement hw-breakpoints for PowerPC BookIII S
From: K.Prasad @ 2010-06-09 10:25 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org, Paul Mackerras
  Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
	Frederic Weisbecker, David Gibson, Alan Stern, K.Prasad,
	Roland McGrath
In-Reply-To: <20100609101417.644628763@linux.vnet.ibm.com>

Implement perf-events based hw-breakpoint interfaces for PowerPC Book III S
processors. These interfaces help arbitrate requests from various users and
schedules them as appropriate.

Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
---
 arch/powerpc/Kconfig                     |    1 
 arch/powerpc/include/asm/cputable.h      |    4 
 arch/powerpc/include/asm/hw_breakpoint.h |   73 +++++++
 arch/powerpc/include/asm/processor.h     |    8 
 arch/powerpc/kernel/Makefile             |    1 
 arch/powerpc/kernel/hw_breakpoint.c      |  320 +++++++++++++++++++++++++++++++
 arch/powerpc/kernel/machine_kexec_64.c   |    3 
 arch/powerpc/kernel/process.c            |   14 +
 arch/powerpc/kernel/ptrace.c             |   64 ++++++
 arch/powerpc/lib/Makefile                |    1 
 10 files changed, 489 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===================================================================
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -0,0 +1,73 @@
+/*
+ * PowerPC BookIII S hardware breakpoint definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2010, IBM Corporation.
+ * Author: K.Prasad <prasad@linux.vnet.ibm.com>
+ *
+ */
+
+#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
+#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
+
+#ifdef	__KERNEL__
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+struct arch_hw_breakpoint {
+	u8		len; /* length of the target data symbol */
+	int		type;
+	unsigned long	address;
+};
+
+#include <linux/kdebug.h>
+#include <asm/reg.h>
+#include <asm/system.h>
+
+static inline int hw_breakpoint_slots(int type)
+{
+	return HBP_NUM;
+}
+struct perf_event;
+struct pmu;
+struct perf_sample_data;
+
+#define HW_BREAKPOINT_ALIGN 0x7
+/* Maximum permissible length of any HW Breakpoint */
+#define HW_BREAKPOINT_LEN 0x8
+
+extern int arch_bp_generic_fields(int type, int *gen_bp_type);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+						unsigned long val, void *data);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+extern struct pmu perf_ops_bp;
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+			struct perf_sample_data *data, struct pt_regs *regs);
+static inline void hw_breakpoint_disable(void)
+{
+	set_dabr(0);
+}
+
+#else	/* CONFIG_HAVE_HW_BREAKPOINT */
+static inline void hw_breakpoint_disable(void) { }
+#endif	/* CONFIG_HAVE_HW_BREAKPOINT */
+#endif	/* __KERNEL__ */
+#endif	/* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===================================================================
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -0,0 +1,320 @@
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers. Derived from
+ * "arch/x86/kernel/hw_breakpoint.c"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2010 IBM Corporation
+ * Author: K.Prasad <prasad@linux.vnet.ibm.com>
+ *
+ */
+
+#include <linux/hw_breakpoint.h>
+#include <linux/notifier.h>
+#include <linux/kprobes.h>
+#include <linux/percpu.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/hw_breakpoint.h>
+#include <asm/processor.h>
+#include <asm/sstep.h>
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for every cpu
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg);
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free debug address register and use it for this
+ * breakpoint.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+	struct perf_event **slot = &__get_cpu_var(bp_per_reg);
+
+	*slot = bp;
+
+	/*
+	 * Do not install DABR values if the instruction must be single-stepped.
+	 * If so, DABR will be populated in single_step_dabr_instruction().
+	 */
+	if (current->thread.last_hit_ubp != bp)
+		set_dabr(info->address | info->type | DABR_TRANSLATION);
+
+	return 0;
+}
+
+/*
+ * Uninstall the breakpoint contained in the given counter.
+ *
+ * First we search the debug address register it uses and then we disable
+ * it.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+void arch_uninstall_hw_breakpoint(struct perf_event *bp)
+{
+	struct perf_event **slot = &__get_cpu_var(bp_per_reg);
+
+	if (*slot != bp) {
+		WARN_ONCE(1, "Can't find the breakpoint");
+		return;
+	}
+
+	*slot = NULL;
+	set_dabr(0);
+}
+
+/*
+ * Perform cleanup of arch-specific counters during unregistration
+ * of the perf-event
+ */
+void arch_unregister_hw_breakpoint(struct perf_event *bp)
+{
+	/*
+	 * If the breakpoint is unregistered between a hw_breakpoint_handler()
+	 * and the single_step_dabr_instruction(), then cleanup the breakpoint
+	 * restoration variables to prevent dangling pointers.
+	 */
+	if (bp->ctx->task)
+		bp->ctx->task->thread.last_hit_ubp = NULL;
+}
+
+/*
+ * Check for virtual address in kernel space.
+ */
+int arch_check_bp_in_kernelspace(struct perf_event *bp)
+{
+	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+	return is_kernel_addr(info->address);
+}
+
+int arch_bp_generic_fields(int type, int *gen_bp_type)
+{
+	switch (type) {
+	case DABR_DATA_READ:
+		*gen_bp_type = HW_BREAKPOINT_R;
+		break;
+	case DABR_DATA_WRITE:
+		*gen_bp_type = HW_BREAKPOINT_W;
+		break;
+	case (DABR_DATA_WRITE | DABR_DATA_READ):
+		*gen_bp_type = (HW_BREAKPOINT_W | HW_BREAKPOINT_R);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/*
+ * Validate the arch-specific HW Breakpoint register settings
+ */
+int arch_validate_hwbkpt_settings(struct perf_event *bp)
+{
+	int ret = -EINVAL;
+	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+	if (!bp)
+		return ret;
+
+	switch (bp->attr.bp_type) {
+	case HW_BREAKPOINT_R:
+		info->type = DABR_DATA_READ;
+		break;
+	case HW_BREAKPOINT_W:
+		info->type = DABR_DATA_WRITE;
+		break;
+	case HW_BREAKPOINT_R | HW_BREAKPOINT_W:
+		info->type = (DABR_DATA_READ | DABR_DATA_WRITE);
+		break;
+	default:
+		return ret;
+	}
+
+	info->address = bp->attr.bp_addr;
+	info->len = bp->attr.bp_len;
+
+	/*
+	 * Since breakpoint length can be a maximum of HW_BREAKPOINT_LEN(8)
+	 * and breakpoint addresses are aligned to nearest double-word
+	 * HW_BREAKPOINT_ALIGN by rounding off to the lower address, the
+	 * 'symbolsize' should satisfy the check below.
+	 */
+	if (info->len >
+	    (HW_BREAKPOINT_LEN - (info->address & HW_BREAKPOINT_ALIGN)))
+		return -EINVAL;
+	return 0;
+}
+
+/*
+ * Handle debug exception notifications.
+ */
+int __kprobes hw_breakpoint_handler(struct die_args *args)
+{
+	bool is_ptrace_bp = false;
+	int rc = NOTIFY_STOP;
+	struct perf_event *bp;
+	struct pt_regs *regs = args->regs;
+	int stepped = 1;
+	struct arch_hw_breakpoint *info;
+
+	/* Disable breakpoints during exception handling */
+	set_dabr(0);
+	/*
+	 * The counter may be concurrently released but that can only
+	 * occur from a call_rcu() path. We can then safely fetch
+	 * the breakpoint, use its callback, touch its counter
+	 * while we are in an rcu_read_lock() path.
+	 */
+	rcu_read_lock();
+
+	bp = __get_cpu_var(bp_per_reg);
+	if (!bp)
+		goto out;
+	info = counter_arch_bp(bp);
+	is_ptrace_bp = (bp->overflow_handler == ptrace_triggered) ?
+			true : false;
+
+	/*
+	 * Return early after invoking user-callback function without restoring
+	 * DABR if the breakpoint is from ptrace which always operates in
+	 * one-shot mode. The ptrace-ed process will receive the SIGTRAP signal
+	 * generated in do_dabr().
+	 */
+	if (is_ptrace_bp) {
+		perf_bp_event(bp, regs);
+		rc = NOTIFY_DONE;
+		goto out;
+	}
+
+	/* Do not emulate user-space instructions, instead single-step them */
+	if (user_mode(regs)) {
+		bp->ctx->task->thread.last_hit_ubp = bp;
+		regs->msr |= MSR_SE;
+		goto out;
+	}
+
+	stepped = emulate_step(regs, regs->nip);
+	/*
+	 * emulate_step() could not execute it. We've failed in reliably
+	 * handling the hw-breakpoint. Unregister it and throw a warning
+	 * message to let the user know about it.
+	 */
+	if (!stepped) {
+		WARN(1, "Unable to handle hardware breakpoint. Breakpoint at "
+			"0x%lx will be uninstalled.", info->address);
+		unregister_hw_breakpoint(bp);
+		goto out;
+	}
+	/*
+	 * As a policy, the callback is invoked in a 'trigger-after-execute'
+	 * fashion
+	 */
+	perf_bp_event(bp, regs);
+
+	set_dabr(info->address | info->type | DABR_TRANSLATION);
+out:
+	rcu_read_unlock();
+	return rc;
+}
+
+/*
+ * Handle single-step exceptions following a DABR hit.
+ */
+int __kprobes single_step_dabr_instruction(struct die_args *args)
+{
+	struct pt_regs *regs = args->regs;
+	struct perf_event *bp = NULL;
+	struct arch_hw_breakpoint *bp_info;
+
+	bp = current->thread.last_hit_ubp;
+	/*
+	 * Check if we are single-stepping as a result of a
+	 * previous HW Breakpoint exception
+	 */
+	if (!bp)
+		return NOTIFY_DONE;
+
+	bp_info = counter_arch_bp(bp);
+
+	/*
+	 * We shall invoke the user-defined callback function in the single
+	 * stepping handler to confirm to 'trigger-after-execute' semantics
+	 */
+	perf_bp_event(bp, regs);
+
+	/*
+	 * Do not disable MSR_SE if the process was already in
+	 * single-stepping mode.
+	 */
+	if (!test_thread_flag(TIF_SINGLESTEP))
+		regs->msr &= ~MSR_SE;
+
+	set_dabr(bp_info->address | bp_info->type | DABR_TRANSLATION);
+	current->thread.last_hit_ubp = NULL;
+	return NOTIFY_STOP;
+}
+
+/*
+ * Handle debug exception notifications.
+ */
+int __kprobes hw_breakpoint_exceptions_notify(
+		struct notifier_block *unused, unsigned long val, void *data)
+{
+	int ret = NOTIFY_DONE;
+
+	switch (val) {
+	case DIE_DABR_MATCH:
+		ret = hw_breakpoint_handler(data);
+		break;
+	case DIE_SSTEP:
+		ret = single_step_dabr_instruction(data);
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * Release the user breakpoints used by ptrace
+ */
+void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
+{
+	struct thread_struct *t = &tsk->thread;
+
+	unregister_hw_breakpoint(t->ptrace_bps[0]);
+	t->ptrace_bps[0] = NULL;
+}
+
+void hw_breakpoint_pmu_read(struct perf_event *bp)
+{
+	/* TODO */
+}
+
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/Makefile
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/Makefile
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/Makefile
@@ -34,6 +34,7 @@ obj-y				+= vdso32/
 obj-$(CONFIG_PPC64)		+= setup_64.o sys_ppc32.o \
 				   signal_64.o ptrace32.o \
 				   paca.o nvram_64.o firmware.o
+obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_ppc970.o cpu_setup_pa6t.o
 obj64-$(CONFIG_RELOCATABLE)	+= reloc_64.o
 obj-$(CONFIG_PPC_BOOK3E_64)	+= exceptions-64e.o
Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/processor.h
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/processor.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/processor.h
@@ -209,6 +209,14 @@ struct thread_struct {
 #ifdef CONFIG_PPC64
 	unsigned long	start_tb;	/* Start purr when proc switched in */
 	unsigned long	accum_tb;	/* Total accumilated purr for process */
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+	struct perf_event *ptrace_bps[HBP_NUM];
+	/*
+	 * Helps identify source of single-step exception and subsequent
+	 * hw-breakpoint enablement
+	 */
+	struct perf_event *last_hit_ubp;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif
 	unsigned long	dabr;		/* Data address breakpoint register */
 #ifdef CONFIG_ALTIVEC
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/ptrace.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/ptrace.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/ptrace.c
@@ -32,6 +32,8 @@
 #ifdef CONFIG_PPC32
 #include <linux/module.h>
 #endif
+#include <linux/hw_breakpoint.h>
+#include <linux/perf_event.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -866,9 +868,34 @@ void user_disable_single_step(struct tas
 	clear_tsk_thread_flag(task, TIF_SINGLESTEP);
 }
 
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+void ptrace_triggered(struct perf_event *bp, int nmi,
+		      struct perf_sample_data *data, struct pt_regs *regs)
+{
+	struct perf_event_attr attr;
+
+	/*
+	 * Disable the breakpoint request here since ptrace has defined a
+	 * one-shot behaviour for breakpoint exceptions in PPC64.
+	 * The SIGTRAP signal is generated automatically for us in do_dabr().
+	 * We don't have to do anything about that here
+	 */
+	attr = bp->attr;
+	attr.disabled = true;
+	modify_user_hw_breakpoint(bp, &attr);
+}
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
 int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
 			       unsigned long data)
 {
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+	int ret;
+	struct thread_struct *thread = &(task->thread);
+	struct perf_event *bp;
+	struct perf_event_attr attr;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
 	/* For ppc64 we support one DABR and no IABR's at the moment (ppc64).
 	 *  For embedded processors we support one DAC and no IAC's at the
 	 *  moment.
@@ -896,6 +923,43 @@ int ptrace_set_debugreg(struct task_stru
 	/* Ensure breakpoint translation bit is set */
 	if (data && !(data & DABR_TRANSLATION))
 		return -EIO;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+	bp = thread->ptrace_bps[0];
+	if ((!data) || !(data & (DABR_DATA_WRITE | DABR_DATA_READ))) {
+		if (bp) {
+			unregister_hw_breakpoint(bp);
+			thread->ptrace_bps[0] = NULL;
+		}
+		return 0;
+	}
+	if (bp) {
+		attr = bp->attr;
+		attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN;
+		arch_bp_generic_fields(data &
+					(DABR_DATA_WRITE | DABR_DATA_READ),
+							&attr.bp_type);
+		ret =  modify_user_hw_breakpoint(bp, &attr);
+		if (ret)
+			return ret;
+		thread->ptrace_bps[0] = bp;
+		thread->dabr = data;
+		return 0;
+	}
+
+	/* Create a new breakpoint request if one doesn't exist already */
+	hw_breakpoint_init(&attr);
+	attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN;
+	arch_bp_generic_fields(data & (DABR_DATA_WRITE | DABR_DATA_READ),
+								&attr.bp_type);
+
+	thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
+							ptrace_triggered, task);
+	if (IS_ERR(bp)) {
+		thread->ptrace_bps[0] = NULL;
+		return PTR_ERR(bp);
+	}
+
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
 	/* Move contents to the DABR register */
 	task->thread.dabr = data;
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/process.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/process.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/process.c
@@ -37,6 +37,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/personality.h>
 #include <linux/random.h>
+#include <linux/hw_breakpoint.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -462,8 +463,14 @@ struct task_struct *__switch_to(struct t
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
 	switch_booke_debug_regs(&new->thread);
 #else
+/*
+ * For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would
+ * schedule DABR
+ */
+#ifndef CONFIG_HAVE_HW_BREAKPOINT
 	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
 		set_dabr(new->thread.dabr);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif
 
 
@@ -642,7 +649,11 @@ void flush_thread(void)
 {
 	discard_lazy_cpu_state();
 
+#ifdef CONFIG_HAVE_HW_BREAKPOINTS
+	flush_ptrace_hw_breakpoint(current);
+#else /* CONFIG_HAVE_HW_BREAKPOINTS */
 	set_debug_reg_defaults(&current->thread);
+#endif /* CONFIG_HAVE_HW_BREAKPOINTS */
 }
 
 void
@@ -660,6 +671,9 @@ void prepare_to_copy(struct task_struct 
 	flush_altivec_to_thread(current);
 	flush_vsx_to_thread(current);
 	flush_spe_to_thread(current);
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+	flush_ptrace_hw_breakpoint(tsk);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 }
 
 /*
Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/cputable.h
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/cputable.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/cputable.h
@@ -516,6 +516,10 @@ static inline int cpu_has_feature(unsign
 		& feature);
 }
 
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+#define HBP_NUM 1
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/machine_kexec_64.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/machine_kexec_64.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/machine_kexec_64.c
@@ -25,6 +25,7 @@
 #include <asm/sections.h>	/* _end */
 #include <asm/prom.h>
 #include <asm/smp.h>
+#include <asm/hw_breakpoint.h>
 
 int default_machine_kexec_prepare(struct kimage *image)
 {
@@ -165,6 +166,7 @@ static void kexec_smp_down(void *arg)
 	while(kexec_all_irq_disabled == 0)
 		cpu_relax();
 	mb(); /* make sure all irqs are disabled before this */
+	hw_breakpoint_disable();
 	/*
 	 * Now every CPU has IRQs off, we can clear out any pending
 	 * IPIs and be sure that no more will come in after this.
@@ -180,6 +182,7 @@ static void kexec_prepare_cpus_wait(int 
 {
 	int my_cpu, i, notified=-1;
 
+	hw_breakpoint_disable();
 	my_cpu = get_cpu();
 	/* Make sure each CPU has atleast made it to the state we need */
 	for (i=0; i < NR_CPUS; i++) {
Index: linux-2.6.ppc64_test/arch/powerpc/lib/Makefile
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/lib/Makefile
+++ linux-2.6.ppc64_test/arch/powerpc/lib/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_PPC64)	+= copypage_64.o cop
 			   memcpy_64.o usercopy_64.o mem_64.o string.o
 obj-$(CONFIG_XMON)	+= sstep.o
 obj-$(CONFIG_KPROBES)	+= sstep.o
+obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= sstep.o
 
 ifeq ($(CONFIG_PPC64),y)
 obj-$(CONFIG_SMP)	+= locks.o
Index: linux-2.6.ppc64_test/arch/powerpc/Kconfig
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/Kconfig
+++ linux-2.6.ppc64_test/arch/powerpc/Kconfig
@@ -141,6 +141,7 @@ config PPC
 	select GENERIC_ATOMIC64 if PPC32
 	select HAVE_PERF_EVENTS
 	select HAVE_REGS_AND_STACK_ACCESS_API
+	select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64
 
 config EARLY_PRINTK
 	bool

^ permalink raw reply

* [Patch 3/5] PPC64-HWBKPT: Handle concurrent alignment interrupts
From: K.Prasad @ 2010-06-09 10:25 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org, Paul Mackerras
  Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
	Frederic Weisbecker, David Gibson, Alan Stern, K.Prasad,
	Roland McGrath
In-Reply-To: <20100609101417.644628763@linux.vnet.ibm.com>

An alignment interrupt may intervene between a DSI/hw-breakpoint exception
and the single-step exception. Enable the alignment interrupt (through
modifications to emulate_single_step()) to notify the single-step exception
handler for proper restoration of hw-breakpoints.

Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/traps.c |    8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/traps.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
@@ -602,7 +602,7 @@ void RunModeException(struct pt_regs *re
 
 void __kprobes single_step_exception(struct pt_regs *regs)
 {
-	regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
+	clear_single_step(regs);
 
 	if (notify_die(DIE_SSTEP, "single_step", regs, 5,
 					5, SIGTRAP) == NOTIFY_STOP)
@@ -621,10 +621,8 @@ void __kprobes single_step_exception(str
  */
 static void emulate_single_step(struct pt_regs *regs)
 {
-	if (single_stepping(regs)) {
-		clear_single_step(regs);
-		_exception(SIGTRAP, regs, TRAP_TRACE, 0);
-	}
+	if (single_stepping(regs))
+		single_step_exception(regs);
 }
 
 static inline int __parse_fpscr(unsigned long fpscr)

^ permalink raw reply

* [Patch 4/5] PPC64-HWBKPT: Enable hw-breakpoints while handling intervening signals
From: K.Prasad @ 2010-06-09 10:25 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org, Paul Mackerras
  Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
	Frederic Weisbecker, David Gibson, Alan Stern, K.Prasad,
	Roland McGrath
In-Reply-To: <20100609101417.644628763@linux.vnet.ibm.com>

A signal delivered between a hw_breakpoint_handler() and the
single_step_dabr_instruction() will not have the breakpoint active during
signal handling (since breakpoint will not be restored through single-stepping
due to absence of MSR_SE bit on the signal frame). Enable breakpoints before
signal delivery.

Restore hw-breakpoints if the user-context is altered in the signal handler.

Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/hw_breakpoint.h |    3 +++
 arch/powerpc/kernel/hw_breakpoint.c      |   18 ++++++++++++++++++
 arch/powerpc/kernel/signal.c             |    3 +++
 3 files changed, 24 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/hw_breakpoint.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -65,9 +65,12 @@ static inline void hw_breakpoint_disable
 {
 	set_dabr(0);
 }
+extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
 
 #else	/* CONFIG_HAVE_HW_BREAKPOINT */
 static inline void hw_breakpoint_disable(void) { }
+static inline void thread_change_pc(struct task_struct *tsk,
+					struct pt_regs *regs) { }
 #endif	/* CONFIG_HAVE_HW_BREAKPOINT */
 #endif	/* __KERNEL__ */
 #endif	/* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -174,6 +174,24 @@ int arch_validate_hwbkpt_settings(struct
 }
 
 /*
+ * Restores the breakpoint on the debug registers.
+ * Invoke this function if it is known that the execution context is about to
+ * change to cause loss of MSR_SE settings.
+ */
+void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
+{
+	struct arch_hw_breakpoint *info;
+
+	if (likely(!tsk->thread.last_hit_ubp))
+		return;
+
+	info = counter_arch_bp(tsk->thread.last_hit_ubp);
+	regs->msr &= ~MSR_SE;
+	set_dabr(info->address | info->type | DABR_TRANSLATION);
+	tsk->thread.last_hit_ubp = NULL;
+}
+
+/*
  * Handle debug exception notifications.
  */
 int __kprobes hw_breakpoint_handler(struct die_args *args)
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
 
 #include <linux/tracehook.h>
 #include <linux/signal.h>
+#include <asm/hw_breakpoint.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 
@@ -149,6 +150,8 @@ static int do_signal_pending(sigset_t *o
 	if (current->thread.dabr)
 		set_dabr(current->thread.dabr);
 #endif
+	/* Re-enable the breakpoints for the signal stack */
+	thread_change_pc(current, regs);
 
 	if (is32) {
         	if (ka.sa.sa_flags & SA_SIGINFO)

^ permalink raw reply

* [Patch 5/5] PPC64-HWBKPT: Discard extraneous interrupt due to accesses outside symbol length
From: K.Prasad @ 2010-06-09 10:25 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org, Paul Mackerras
  Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
	Frederic Weisbecker, David Gibson, Alan Stern, K.Prasad,
	Roland McGrath
In-Reply-To: <20100609101417.644628763@linux.vnet.ibm.com>

Many a times, the requested breakpoint length can be less than the fixed
breakpoint length i.e. 8 bytes supported by PowerPC BookIII S. This could lead
to extraneous interrupts resulting in false breakpoint notifications. The patch
below detects and discards such interrupts for non-ptrace requests (we don't
want to change ptrace behaviour for fear of breaking compatability).

Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 arch/powerpc/include/asm/hw_breakpoint.h |    1 +
 arch/powerpc/kernel/hw_breakpoint.c      |   19 ++++++++++++++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -202,6 +202,7 @@ int __kprobes hw_breakpoint_handler(stru
 	struct pt_regs *regs = args->regs;
 	int stepped = 1;
 	struct arch_hw_breakpoint *info;
+	unsigned long dar = regs->dar;
 
 	/* Disable breakpoints during exception handling */
 	set_dabr(0);
@@ -232,6 +233,21 @@ int __kprobes hw_breakpoint_handler(stru
 		goto out;
 	}
 
+	/*
+	 * Verify if dar lies within the address range occupied by the symbol
+	 * being watched to filter extraneous exceptions.
+	 */
+	if (!((bp->attr.bp_addr <= dar) &&
+	     (dar <= (bp->attr.bp_addr + bp->attr.bp_len)))) {
+		/*
+		 * This exception is triggered not because of a memory access
+		 * on the monitored variable but in the double-word address
+		 * range in which it is contained. We will consume this
+		 * exception, considering it as 'noise'.
+		 */
+		info->extraneous_interrupt = true;
+	}
+
 	/* Do not emulate user-space instructions, instead single-step them */
 	if (user_mode(regs)) {
 		bp->ctx->task->thread.last_hit_ubp = bp;
@@ -286,7 +302,8 @@ int __kprobes single_step_dabr_instructi
 	 * We shall invoke the user-defined callback function in the single
 	 * stepping handler to confirm to 'trigger-after-execute' semantics
 	 */
-	perf_bp_event(bp, regs);
+	if (!bp_info->extraneous_interrupt)
+		perf_bp_event(bp, regs);
 
 	/*
 	 * Do not disable MSR_SE if the process was already in
Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/hw_breakpoint.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -27,6 +27,7 @@
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 
 struct arch_hw_breakpoint {
+	bool		extraneous_interrupt;
 	u8		len; /* length of the target data symbol */
 	int		type;
 	unsigned long	address;

^ permalink raw reply

* Re: [PATCH 4/5] Removing dead CONFIG_SERIAL_TEXT_DEBUG
From: Josh Boyer @ 2010-06-09 10:28 UTC (permalink / raw)
  To: Christoph Egger; +Cc: vamos, Paul Mackerras, linux-kernel, linuxppc-dev
In-Reply-To: <ddcbd960ff300073939bb0c6f20a38118c0875d4.1275925219.git.siccegge@cs.fau.de>

On Wed, Jun 09, 2010 at 12:00:46PM +0200, Christoph Egger wrote:
>CONFIG_SERIAL_TEXT_DEBUG doesn't exist in Kconfig, therefore removing all
>references for it from the source code.
>
>Signed-off-by: Christoph Egger <siccegge@cs.fau.de>

It would be better to conver this to work with CONFIG_PPC_EARLY_DEBUG and
CONFIG_PPC_EARLY_DEBUG_40x.  I'd rather just leave this for now until we can
get it switched over.

josh

>---
> arch/powerpc/kernel/head_40x.S |   19 -------------------
> 1 files changed, 0 insertions(+), 19 deletions(-)
>
>diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
>index a90625f..1a10e4d 100644
>--- a/arch/powerpc/kernel/head_40x.S
>+++ b/arch/powerpc/kernel/head_40x.S
>@@ -939,25 +939,6 @@ initial_mmu:
> 	tlbwe	r4,r0,TLB_DATA		/* Load the data portion of the entry */
> 	tlbwe	r3,r0,TLB_TAG		/* Load the tag portion of the entry */
>
>-#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(SERIAL_DEBUG_IO_BASE)
>-
>-	/* Load a TLB entry for the UART, so that ppc4xx_progress() can use
>-	 * the UARTs nice and early.  We use a 4k real==virtual mapping. */
>-
>-	lis	r3,SERIAL_DEBUG_IO_BASE@h
>-	ori	r3,r3,SERIAL_DEBUG_IO_BASE@l
>-	mr	r4,r3
>-	clrrwi	r4,r4,12
>-	ori	r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G)
>-
>-	clrrwi	r3,r3,12
>-	ori	r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K))
>-
>-	li	r0,0			/* TLB slot 0 */
>-	tlbwe	r4,r0,TLB_DATA
>-	tlbwe	r3,r0,TLB_TAG
>-#endif /* CONFIG_SERIAL_DEBUG_TEXT && SERIAL_DEBUG_IO_BASE */
>-
> 	isync
>
> 	/* Establish the exception vector base
>-- 
>1.6.3.3
>
>_______________________________________________
>Linuxppc-dev mailing list
>Linuxppc-dev@lists.ozlabs.org
>https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [Patch 0/5] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XXII
From: K.Prasad @ 2010-06-09 10:32 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev@ozlabs.org, Benjamin Herrenschmidt
In-Reply-To: <20100607112559.GA2419@brick.ozlabs.ibm.com>

On Mon, Jun 07, 2010 at 09:25:59PM +1000, Paul Mackerras wrote:
> On Mon, Jun 07, 2010 at 12:33:51PM +0530, K.Prasad wrote:
> 
> > Given that 'ptrace_bps' is used only for ptrace originated breakpoints
> > and that we return early i.e. before detecting extraneous interrupts
> > in hw_breakpoint_handler() (as shown above) they shouldn't overlap each
> > other. The following comment in hw_breakpoint_handler() explains the
> > same.
> > 		/*
> > 		 * To prevent invocation of perf_event_bp(), we shall overload
> > 		 * thread.ptrace_bps[] pointer (unused for non-ptrace
> > 		 * exceptions) to flag an extraneous interrupt which must be
> > 		 * skipped.
> > 		 */
> 
> My point is that while we are using ptrace_bps[0] to mark a non-ptrace
> breakpoint that we're single-stepping, some other process could be
> ptracing this process and could get into ptrace_set_debugreg() and
> would think that the process already has a ptrace breakpoint and call
> modify_user_hw_breakpoint() when it should be calling
> register_user_hw_breakpoint().  Or this process could die and so we
> call flush_ptrace_hw_breakpoint() and it incorrectly thinks we have a
> ptrace breakpoint.
> 
> If there is a reason why we can be quite sure that while we are using
> current->thread.ptrace_bps[0] in this way, ptrace_set_debugreg() can
> never get called with this task as the ptracee, and nor can
> flush_ptrace_hw_breakpoint() get called on this task, then maybe it's
> safe.  But it's not at all obviously safe.  So I'd very much rather we
> just use an extra flag somewhere, that isn't used elsewhere for
> anything else, so we can convince ourselves that it is all correct
> without having to look at lots of different pieces of code.
> 
> There are 3 bytes of padding in struct arch_hw_breakpoint; couldn't we
> use one of them as a "not really hit" flag?
> 
> Paul.
> _______________________________________________

I get your reasoning now; ptrace_bps[] re-use will cause failures under
these circumstances. I've sent a new version of the patchset which adds
a new flag in 'struct arch_hw_breakpoint' (I was always thinking of
'struct thread_struct' before and was scared to introduce another new
member in it, thereby leading me to incorrectly optimise using ptrace_bps)
to flag extraneous_interrupt (Given that it's your idea I've added your
signed-off too).

Kindly let me know your comments, if any.

Thanks,
K.Prasad

^ permalink raw reply

* Re: [PATCH 2/2] sound/soc: mpc5200_psc_ac97: Use gpio pins for cold reset.
From: Mark Brown @ 2010-06-09 10:25 UTC (permalink / raw)
  To: Eric Millbrandt; +Cc: linuxppc-dev
In-Reply-To: <1276015562-28928-3-git-send-email-emillbrandt@dekaresearch.com>

On Tue, Jun 08, 2010 at 12:46:02PM -0400, Eric Millbrandt wrote:

> +       switch (psc_dma->id) {
> +       case 0:
> +               gpio_mux = MPC52xx_GPIO_PSC1_MASK; break;
> +       case 1:
> +               gpio_mux = MPC52xx_GPIO_PSC2_MASK; break;

Please don't place the break on the same line as the statement, it's
not good for legibility.

> +       dev_err(psc_dma->dev, "cold reset\n");

You shouldn't be logging this as an error, doing a cold reset is
perfectly normal.

^ permalink raw reply

* Re: [PATCH 0/2] mpc5200 ac97 gpio reset
From: Mark Brown @ 2010-06-09 10:30 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: linuxppc-dev, Eric Millbrandt
In-Reply-To: <20100609061330.620AC14E867@gemini.denx.de>

On Wed, Jun 09, 2010 at 08:13:30AM +0200, Wolfgang Denk wrote:
> In message <AANLkTimIs90kR5uqhdBQ02oSd94dn08sOITm51Ylrl4-@mail.gmail.com> you wrote:

> > Would making a change in uboot be a better solution? Eric, can you
> > verify if changing uboot also fixes the problem?

> To me it seems better if the driver itself does what needs to be done
> instead of relying on specific settings that may or may not be done in
> U-Boot. Keep in mind that drivers may be loaded as modules, and that
> we even see cases where the same port serves multiple purposes by
> loading different driver modules (yes, this is not exactly a clever
> idea, but hardware designers come up with such solutions).

I do tend to agree that having the driver be able to cope with things is
a bit more robust - it's not terribly discoverable for users and people
are often justifiably nervous about updating their bootloader.

It might, however, be sensible to make the GPIO based reset be optional
based on having the OF data for the GPIOs.  That way existing DTs will
work without changes and systems that can use the reset implementation
in the controller will be able to do so.

^ permalink raw reply

* [PATCH 5b/5] Removing dead CONFIG_PPC47x
From: Christoph Egger @ 2010-06-09 11:02 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Stephen Rothwell,
	Torez Smith, Dave Kleikamp, Josh Boyer, linuxppc-dev,
	linux-kernel
  Cc: vamos
In-Reply-To: <cover.1275925219.git.siccegge@cs.fau.de>

CONFIG_PPC47x should actually be spelled CONFIG_PPC_47x as reported by
Andreas Schwab.

Signed-off-by: Christoph Egger <siccegge@cs.fau.de>
---
 arch/powerpc/mm/44x_mmu.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
index d8c6efb..f70da7e 100644
--- a/arch/powerpc/mm/44x_mmu.c
+++ b/arch/powerpc/mm/44x_mmu.c
@@ -76,11 +76,11 @@ static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys)
 		"tlbwe	%1,%3,%5\n"
 		"tlbwe	%0,%3,%6\n"
 	:
-#ifdef CONFIG_PPC47x
+#ifdef CONFIG_PPC_47x
 	: "r" (PPC47x_TLB2_S_RWX),
 #else
 	: "r" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
 #endif
 	  "r" (phys),
 	  "r" (virt | PPC44x_TLB_VALID | PPC44x_TLB_256M),
 	  "r" (entry),
-- 
1.6.3.3

^ permalink raw reply related

* Re: [PATCH] powerpc: Fix integer constant warning
From: Steve Best @ 2010-06-09 11:50 UTC (permalink / raw)
  To: David Howells; +Cc: linuxppc-dev
In-Reply-To: <9000.1276002746@redhat.com>


On Tue, 2010-06-08 at 14:12 +0100, David Howells wrote:
> Steve Best <sfbest@us.ibm.com> wrote:
> 
> > -#define KERNELBASE (0xc000000000000000)
> > +#define KERNELBASE (0xc000000000000000ULL)
> 
> Is this the right fix?  The code producing the warning is subtracting
> 0xc000000000000000 from a 32-bit number:

agree this fix needs more work, and can be dropped. Paul has another
patch that removes this file, since it is no longer used. I assume we'll
go with that patch.
> 
> 	naca = ntohl(*((u_int32_t*) &inbuf[0x0C])) - KERNELBASE;
> 
> which seems distinctly odd.
> 
> David

-Steve

^ permalink raw reply

* Re: [PATCH 5b/5] Removing dead CONFIG_PPC47x
From: Josh Boyer @ 2010-06-09 12:05 UTC (permalink / raw)
  To: Christoph Egger
  Cc: Stephen Rothwell, Dave Kleikamp, vamos, linux-kernel,
	linuxppc-dev, Paul Mackerras, Torez Smith
In-Reply-To: <20100609110239.GA28290@faui48a.informatik.uni-erlangen.de>

On Wed, Jun 09, 2010 at 01:02:39PM +0200, Christoph Egger wrote:
>CONFIG_PPC47x should actually be spelled CONFIG_PPC_47x as reported by
>Andreas Schwab.
>
>Signed-off-by: Christoph Egger <siccegge@cs.fau.de>

Thanks, I'll pull this one in and get it merged.

josh

>---
> arch/powerpc/mm/44x_mmu.c |    4 ----
> 1 files changed, 0 insertions(+), 4 deletions(-)
>
>diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
>index d8c6efb..f70da7e 100644
>--- a/arch/powerpc/mm/44x_mmu.c
>+++ b/arch/powerpc/mm/44x_mmu.c
>@@ -76,11 +76,11 @@ static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys)
> 		"tlbwe	%1,%3,%5\n"
> 		"tlbwe	%0,%3,%6\n"
> 	:
>-#ifdef CONFIG_PPC47x
>+#ifdef CONFIG_PPC_47x
> 	: "r" (PPC47x_TLB2_S_RWX),
> #else
> 	: "r" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
> #endif
> 	  "r" (phys),
> 	  "r" (virt | PPC44x_TLB_VALID | PPC44x_TLB_256M),
> 	  "r" (entry),
>-- 
>1.6.3.3
>

^ permalink raw reply

* Please pull 'merge' branch of 4xx tree
From: Josh Boyer @ 2010-06-09 12:09 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev

Hi Ben,

Two small fixes that should go into 2.6.35.  Please pull them and shuffle along
to Linus.  I know Linus is leaving for a while at the end of this week, so if
you want me to ask him to pull directly just let me know.

josh

The following changes since commit c2cdf6aba0dfcfb54be646ab630c1bccd180e890:
  Benjamin Herrenschmidt (1):
        powerpc/macio: Fix probing of macio devices by using the right of match table

are available in the git repository at:

  ssh://master.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git merge

Christoph Egger (1):
      powerpc/47x: Correct typo in ifdef guard for 47x

Stefan Roese (1):
      powerpc/44x: Fix UART2/3 interrupt assignment in PPC460EX/GT dts files

 arch/powerpc/boot/dts/canyonlands.dts |    4 ++--
 arch/powerpc/boot/dts/glacier.dts     |    4 ++--
 arch/powerpc/mm/44x_mmu.c             |    2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

^ permalink raw reply

* Re: [PATCH 0/2] mpc5200 ac97 gpio reset
From: Jon Smirl @ 2010-06-09 12:21 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: Mark Brown, linuxppc-dev, Eric Millbrandt
In-Reply-To: <20100609061330.620AC14E867@gemini.denx.de>

On Wed, Jun 9, 2010 at 2:13 AM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Jon Smirl,
>
> In message <AANLkTimIs90kR5uqhdBQ02oSd94dn08sOITm51Ylrl4-@mail.gmail.com>=
 you wrote:
>>
>> Would making a change in uboot be a better solution? Eric, can you
>> verify if changing uboot also fixes the problem?
>
> To me it seems better if the driver itself does what needs to be done
> instead of relying on specific settings that may or may not be done in
> U-Boot. Keep in mind that drivers may be loaded as modules, and that
> we even see cases where the same port serves multiple purposes by
> loading different driver modules (yes, this is not exactly a clever
> idea, but hardware designers come up with such solutions).


Someone with a scope can verify this, but my understanding of what
happens is that uboot by default puts the pins into GPIO mode. Linux
boots and reprograms the pins into AC97 mode. When the pins are
reprogrammed it generates glitches on the reset line. About half of
the time these glitches put the attached codec into test mode. Once
the chip is in test mode it won't respond to normal commands.

Does the opposite happen? What if uboot has the pins in AC97 mode and
Linux reprograms them into GPIO mode. Will it also put the chip into
test mode? The piece of information I've been missing is an
understanding of what is making the glitches that trigger test mode.

Another strategy would be to leave reset as is. If the chip is
unresponsive send it the commands to get it out of test mode. That
could be made part of the reset logic in the Linux driver.


>
>
> Best regards,
>
> Wolfgang Denk
>
> --
> DENX Software Engineering GmbH, =A0 =A0 MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
> The typical page layout program is nothing more =A0than =A0an =A0electron=
ic
> light table for cutting and pasting documents.
>



--=20
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* Re: [PATCH 3/5] Removing dead CONFIG_SMP_750
From: Josh Boyer @ 2010-06-09 12:35 UTC (permalink / raw)
  To: Christoph Egger; +Cc: vamos, Paul Mackerras, linux-kernel, linuxppc-dev
In-Reply-To: <8bf8cfaf47590e1a85f9510bb546ca35e3458bf8.1275925219.git.siccegge@cs.fau.de>

On Wed, Jun 09, 2010 at 12:00:21PM +0200, Christoph Egger wrote:
>CONFIG_SMP_750 doesn't exist in Kconfig, therefore removing all
>references for it from the source code.

Yeah, we don't support SMP on 750 at the moment.  This code was carried over
from the arch/ppc days, and that code was present pre-git.  I think we can
drop it, but I'll leave that up to Ben.  Maybe he has crazy plans for a 750 SMP
board.

josh

>
>Signed-off-by: Christoph Egger <siccegge@cs.fau.de>
>---
> arch/powerpc/mm/tlb_hash32.c |    4 ----
> 1 files changed, 0 insertions(+), 4 deletions(-)
>
>diff --git a/arch/powerpc/mm/tlb_hash32.c b/arch/powerpc/mm/tlb_hash32.c
>index 8aaa8b7..925fecb 100644
>--- a/arch/powerpc/mm/tlb_hash32.c
>+++ b/arch/powerpc/mm/tlb_hash32.c
>@@ -94,11 +94,7 @@ void tlb_flush(struct mmu_gather *tlb)
>  * the cache operations on the bus.  Hence we need to use an IPI
>  * to get the other CPU(s) to invalidate their TLBs.
>  */
>-#ifdef CONFIG_SMP_750
>-#define FINISH_FLUSH	smp_send_tlb_invalidate(0)
>-#else
> #define FINISH_FLUSH	do { } while (0)
>-#endif
>
> static void flush_range(struct mm_struct *mm, unsigned long start,
> 			unsigned long end)
>-- 
>1.6.3.3
>
>_______________________________________________
>Linuxppc-dev mailing list
>Linuxppc-dev@lists.ozlabs.org
>https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* RE: [PATCH 0/2] mpc5200 ac97 gpio reset
From: Eric Millbrandt @ 2010-06-09 14:21 UTC (permalink / raw)
  To: 'Jon Smirl', Wolfgang Denk
  Cc: Mark Brown, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <AANLkTikDE14Y_r7nMpj5lNMy5anAyU3cuLjk_uxStHvo@mail.gmail.com>

> -----Original Message-----
> From: Jon Smirl [mailto:jonsmirl@gmail.com]
> Sent: Wednesday, June 09, 2010 08:22
> To: Wolfgang Denk
> Cc: Eric Millbrandt; Mark Brown; linuxppc-dev@lists.ozlabs.org
> Subject: Re: [PATCH 0/2] mpc5200 ac97 gpio reset
>
> On Wed, Jun 9, 2010 at 2:13 AM, Wolfgang Denk <wd@denx.de> wrote:
> > Dear Jon Smirl,
> >
> > In message <AANLkTimIs90kR5uqhdBQ02oSd94dn08sOITm51Ylrl4-
> @mail.gmail.com> you wrote:
> >>
> >> Would making a change in uboot be a better solution? Eric, can you
> >> verify if changing uboot also fixes the problem?
> >
> > To me it seems better if the driver itself does what needs to be done
> > instead of relying on specific settings that may or may not be done in
> > U-Boot. Keep in mind that drivers may be loaded as modules, and that
> > we even see cases where the same port serves multiple purposes by
> > loading different driver modules (yes, this is not exactly a clever
> > idea, but hardware designers come up with such solutions).
>
>
> Someone with a scope can verify this, but my understanding of what
> happens is that uboot by default puts the pins into GPIO mode. Linux
> boots and reprograms the pins into AC97 mode. When the pins are
> reprogrammed it generates glitches on the reset line. About half of
> the time these glitches put the attached codec into test mode. Once
> the chip is in test mode it won't respond to normal commands.
>

Most of the pins on the 5200 default to gpio when the chip comes out of res=
et.  U-Boot then sets the pin muxing by writing to the port configuration r=
egister.  This value is defined as CONFIG_SYS_GPS_PORT_CONFIG in the U-Boot=
 board header file.

The implementation of ac97 gives the codec control of the bus clock.  This =
means that the codec is usually be clocking BITCLK when the 5200 pulls the =
reset line low, which is the cause of the problem.  Freescale should have h=
andled this on the silicon by having the ac97 cold reset function pull the =
SYNC and SDATAOUT lines low during cold reset, but instead they just docume=
nted the problem.

>From the MPC5200B user manual:
"Some AC97 devices goes to a test mode, if the Sync line is high during the=
 Res line is low (reset phase). To avoid this behavior the Sync line must b=
e also forced to zero during the reset phase. To do that, the pin muxing sh=
ould switch to GPIO mode and the GPIO control register should be used to co=
ntrol the output lines."

> Another strategy would be to leave reset as is. If the chip is
> unresponsive send it the commands to get it out of test mode. That
> could be made part of the reset logic in the Linux driver.

This is what we used to do when we were using the out-of-tree ac97 driver f=
rom Sylvain Munaut.  We would generate a cold reset/warm reset sequence in =
U-Boot.  We modified the Linux ac97 driver so that the cold reset functions=
 was a no-op.  It did avoid the problem, but it caused other problems.  Som=
etimes it is necessary to cold reset the codec in Linux to resync the ac97 =
bus.

>
>
> >
> >
> > Best regards,
> >
> > Wolfgang Denk
> >
> > --
> > DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
> > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> > Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
> > The typical page layout program is nothing more  than  an  electronic
> > light table for cutting and pasting documents.
> >
>
>
>
> --
> Jon Smirl
> jonsmirl@gmail.com

Eric Millbrandt

-DISCLAIMER: an automatically appended disclaimer may follow. By posting-
-to a public e-mail mailing list I hereby grant permission to distribute-
-and copy this message.-


This e-mail and the information, including any attachments, it contains are=
 intended to be a confidential communication only to the person or entity t=
o whom it is addressed and may contain information that is privileged. If t=
he reader of this message is not the intended recipient, you are hereby not=
ified that any dissemination, distribution or copying of this communication=
 is strictly prohibited. If you have received this communication in error, =
please immediately notify the sender and destroy the original message.

Thank you.

Please consider the environment before printing this email.

^ permalink raw reply

* RE: [PATCH 0/2] mpc5200 ac97 gpio reset
From: Eric Millbrandt @ 2010-06-09 14:24 UTC (permalink / raw)
  To: 'Mark Brown', Wolfgang Denk; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20100609103046.GC5618@opensource.wolfsonmicro.com>

> -----Original Message-----
> From: Mark Brown [mailto:broonie@opensource.wolfsonmicro.com]
> Sent: Wednesday, June 09, 2010 06:31
> To: Wolfgang Denk
> Cc: Jon Smirl; Eric Millbrandt; linuxppc-dev@lists.ozlabs.org
> Subject: Re: [PATCH 0/2] mpc5200 ac97 gpio reset
--snip--
> It might, however, be sensible to make the GPIO based reset be optional
> based on having the OF data for the GPIOs.  That way existing DTs will
> work without changes and systems that can use the reset implementation
> in the controller will be able to do so.

This is a reasonable request.  I will respin the patch to do this.

Eric Millbrandt

This e-mail and the information, including any attachments, it contains are=
 intended to be a confidential communication only to the person or entity t=
o whom it is addressed and may contain information that is privileged. If t=
he reader of this message is not the intended recipient, you are hereby not=
ified that any dissemination, distribution or copying of this communication=
 is strictly prohibited. If you have received this communication in error, =
please immediately notify the sender and destroy the original message.

Thank you.

Please consider the environment before printing this email.

^ permalink raw reply

* Re: [PATCH 0/2] mpc5200 ac97 gpio reset
From: Mark Brown @ 2010-06-09 14:32 UTC (permalink / raw)
  To: Eric Millbrandt; +Cc: linuxppc-dev@lists.ozlabs.org, Wolfgang Denk
In-Reply-To: <0A40042D85E7C84DB443060EC44B3FD3253ECB8C84@dekaexchange07.deka.local>

On Wed, Jun 09, 2010 at 10:21:40AM -0400, Eric Millbrandt wrote:

[Please fix your MUA to word wrap paragraphs to within 80 characters,
I've reflowed the text below.]

> From the MPC5200B user manual:
> "Some AC97 devices goes to a test mode, if the Sync line is high
> during the Res line is low (reset phase). To avoid this behavior the
> Sync line must be also forced to zero during the reset phase. To do
> that, the pin muxing should switch to GPIO mode and the GPIO control
> register should be used to control the output lines."

Please include this quote in the changelog for the patch, if this a
documented workaround from the vendor that's a very different thing to
something that you've found happens to work on your systems (which is
more what your changelog sounded like).

^ permalink raw reply

* CPM UART on MPC8270
From: Martyn Welch @ 2010-06-09 14:37 UTC (permalink / raw)
  To: linuxppc-dev list

Hi All,

I'm attempting to get an SCC port on an MPC8270 working with Linux. I'm
not overly familiar with the CPM and am having a bit of trouble.

Linux is booting natively on the 8270. I have access to the 8270 via a
set of PCI windows from a second core (includes one setup over the main
memory and one over the IMMR) and SMC1 is up and working with a console.

The SCCs seem to be detected correctly at boot:

f011a80.serial: ttyCPM0 at MMIO 0xc3014a80 (irq = 16) is a CPM UART
f011a00.serial: ttyCPM1 at MMIO 0xc3018a00 (irq = 40) is a CPM UART
f011a20.serial: ttyCPM2 at MMIO 0xc3020a20 (irq = 41) is a CPM UART
f011a40.serial: ttyCPM3 at MMIO 0xc3028a40 (irq = 42) is a CPM UART

With the DTS reading:

                        smc1: serial@11a80 {
                                device_type = "serial";
                                compatible = "fsl,mpc8270-smc-uart",
                                             "fsl,cpm2-smc-uart";
                                reg = <0x11a80 0x20 0x87fc 2>;
                                interrupts = <4 8>;
                                interrupt-parent = <&PIC>;
                                fsl,cpm-brg = <7>;
                                fsl,cpm-command = <0x1d000000>;
                        };

                        scc1: serial@11a00 {
                                device_type = "serial";
                                compatible = "fsl,mpc8270-scc-uart",
                                             "fsl,cpm2-scc-uart";
                                reg = <0x11a00 0x20 0x8000 0x100>;
                                interrupts = <40 8>;
                                interrupt-parent = <&PIC>;
                                fsl,cpm-brg = <3>;
                                fsl,cpm-command = <0x800000>;
                        };

                        scc2: serial@11a20 {
                                device_type = "serial";
                                compatible = "fsl,mpc8270-scc-uart",
                                             "fsl,cpm2-scc-uart";
                                reg = <0x11a20 0x20 0x8100 0x100>;
                                interrupts = <41 8>;
                                interrupt-parent = <&PIC>;
                                fsl,cpm-brg = <6>;
                                fsl,cpm-command = <0x4a00000>;
                        };

                        scc3: serial@11a40 {
                                device_type = "serial";
                                compatible = "fsl,mpc8270-scc-uart",
                                             "fsl,cpm2-scc-uart";
                                reg = <0x11a40 0x20 0x8200 0x100>;
                                interrupts = <42 8>;
                                interrupt-parent = <&PIC>;
                                fsl,cpm-brg = <1>;
                                fsl,cpm-command = <0x8c00000>;
                        };

I believe that I have the pins setup correctly and the BRGs connected
correctly in the setup_arch function.

At the moment I have SCC3 wired out. If I attempt to echo data out of
the SCC (echo "Hello" > /dev/ttyCPM3) I get the prompt sits waiting.
Rebooting and turning on the debug yields the following output on the
console (but nothing out of the SCC port):

CPM uart[3]:startup
Interrupt attached
CPM uart[3]:set_termios
CPM uart[3]:start tx
CPM uart[3]:stop tx
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:stop rx
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:shutdown
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
CPM uart[3]:tx_empty: 0
...


It seemed to be waiting for ready bit of the Transmit Buffer Descriptor
to be cleared (which it never seems to be), prodding this bit through
the pci window did cause the process to continue, no data out but I did
get back to the prompt on the console.

I'm sure I'm just missing something really basic - can anyone enlighten me?

Martyn

-- 
Martyn Welch (Principal Software Engineer)   |   Registered in England and
GE Intelligent Platforms                     |   Wales (3828642) at 100
T +44(0)127322748                            |   Barbirolli Square, Manchester,
E martyn.welch@ge.com                        |   M2 3AB  VAT:GB 927559189

^ permalink raw reply

* can you give me some advice to test "dTSEC"
From: lei yang @ 2010-06-09 14:40 UTC (permalink / raw)
  To: linuxppc-dev

Hi experts

can you give me some advice to test "dTSEC"

Lei

^ permalink raw reply

* Re: [PATCH 0/2] mpc5200 ac97 gpio reset
From: Jon Smirl @ 2010-06-09 14:41 UTC (permalink / raw)
  To: Mark Brown; +Cc: linuxppc-dev@lists.ozlabs.org, Eric Millbrandt, Wolfgang Denk
In-Reply-To: <20100609143246.GA17945@opensource.wolfsonmicro.com>

On Wed, Jun 9, 2010 at 10:32 AM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
> On Wed, Jun 09, 2010 at 10:21:40AM -0400, Eric Millbrandt wrote:
>
> [Please fix your MUA to word wrap paragraphs to within 80 characters,
> I've reflowed the text below.]
>
>> From the MPC5200B user manual:
>> "Some AC97 devices goes to a test mode, if the Sync line is high
>> during the Res line is low (reset phase). To avoid this behavior the
>> Sync line must be also forced to zero during the reset phase. To do
>> that, the pin muxing should switch to GPIO mode and the GPIO control
>> register should be used to control the output lines."
>
> Please include this quote in the changelog for the patch, if this a
> documented workaround from the vendor that's a very different thing to
> something that you've found happens to work on your systems (which is
> more what your changelog sounded like).
>

Mark, is there a way to ask the chip if it is in test mode? We need to
be sure that's whats happening and it isn't some other glitch.


-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* [tip:irq/urgent] genirq: Deal with desc->set_type() changing desc->chip
From: tip-bot for Thomas Gleixner @ 2010-06-09 15:06 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: eha, linuxppc-dev, mingo, hpa, tglx

Commit-ID:  4673247562e39a17e09440fa1400819522ccd446
Gitweb:     http://git.kernel.org/tip/4673247562e39a17e09440fa1400819522ccd446
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Mon, 7 Jun 2010 17:53:51 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 9 Jun 2010 17:05:08 +0200

genirq: Deal with desc->set_type() changing desc->chip

The set_type() function can change the chip implementation when the
trigger mode changes. That might result in using an non-initialized
irq chip when called from __setup_irq() or when called via
set_irq_type() on an already enabled irq. 

The set_irq_type() function should not be called on an enabled irq,
but because we forgot to put a check into it, we have a bunch of users
which grew the habit of doing that and it never blew up as the
function is serialized via desc->lock against all users of desc->chip
and they never hit the non-initialized irq chip issue.

The easy fix for the __setup_irq() issue would be to move the
irq_chip_set_defaults(desc->chip) call after the trigger setting to
make sure that a chip change is covered.

But as we have already users, which do the type setting after
request_irq(), the safe fix for now is to call irq_chip_set_defaults()
from __irq_set_trigger() when desc->set_type() changed the irq chip.

It needs a deeper analysis whether we should refuse to change the chip
on an already enabled irq, but that'd be a large scale change to fix
all the existing users. So that's neither stable nor 2.6.35 material.

Reported-by: Esben Haabendal <eha@doredevelopment.dk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: linuxppc-dev <linuxppc-dev@ozlabs.org>
Cc: stable@kernel.org
---
 kernel/irq/manage.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 3164ba7..e149748 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -456,6 +456,9 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
 		/* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */
 		desc->status &= ~(IRQ_LEVEL | IRQ_TYPE_SENSE_MASK);
 		desc->status |= flags;
+
+		if (chip != desc->chip)
+			irq_chip_set_defaults(desc->chip);
 	}
 
 	return ret;

^ permalink raw reply related

* Re: [PATCH 0/2] mpc5200 ac97 gpio reset
From: Mark Brown @ 2010-06-09 15:11 UTC (permalink / raw)
  To: Jon Smirl; +Cc: linuxppc-dev@lists.ozlabs.org, Eric Millbrandt, Wolfgang Denk
In-Reply-To: <AANLkTinxoQ7PL2OssJc5dZi2WnhkXMaTTGR7OVWxqL2g@mail.gmail.com>

On Wed, Jun 09, 2010 at 10:41:23AM -0400, Jon Smirl wrote:
> On Wed, Jun 9, 2010 at 10:32 AM, Mark Brown

> > Please include this quote in the changelog for the patch, if this a
> > documented workaround from the vendor that's a very different thing to
> > something that you've found happens to work on your systems (which is
> > more what your changelog sounded like).

> Mark, is there a way to ask the chip if it is in test mode? We need to
> be sure that's whats happening and it isn't some other glitch.

I'd need to work with the hardware teams to obtain this information, but
I can confirm that having SYNC high while doing a reset is not supported
and so fixing the driver to not do that is a good idea independantly of
what it actually does to the chip.

^ permalink raw reply

* [PATCH 2/2 v2] sound/soc: mpc5200_psc_ac97: Use gpio pins for cold reset.
From: Eric Millbrandt @ 2010-06-09 15:54 UTC (permalink / raw)
  To: Grant Likely; +Cc: Mark Brown, linuxppc-dev, Eric Millbrandt

The implementation of the ac97 "cold" reset is flawed.  If the sync and
output lines are high when reset is asserted the attached ac97 device
may go into test mode.  Avoid this by reconfiguring the psc to gpio mode
and generating the reset manually.

>From MPC5200B User's Manual:
"Some AC97 devices goes to a test mode, if the Sync line is high
during the Res line is low (reset phase). To avoid this behavior the
Sync line must be also forced to zero during the reset phase. To do
that, the pin muxing should switch to GPIO mode and the GPIO control
register should be used to control the output lines."

Signed-off-by: Eric Millbrandt <emillbrandt@dekaresearch.com>
---

changes since v1
- Amended with comments from Mark Brown
- Fall back to the original reset implementation if no gpio pins are define=
d
  in the device tree

 arch/powerpc/boot/dts/lite5200.dts  |    3 +
 arch/powerpc/boot/dts/lite5200b.dts |    3 +
 arch/powerpc/boot/dts/pcm030.dts    |    3 +
 arch/powerpc/boot/dts/pcm032.dts    |    3 +
 sound/soc/fsl/mpc5200_dma.h         |    5 ++
 sound/soc/fsl/mpc5200_psc_ac97.c    |   98 +++++++++++++++++++++++++++++++=
++--
 6 files changed, 111 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lit=
e5200.dts
index 82ff2b1..cb4e49b 100644
--- a/arch/powerpc/boot/dts/lite5200.dts
+++ b/arch/powerpc/boot/dts/lite5200.dts
@@ -180,6 +180,9 @@
                //      compatible =3D "fsl,mpc5200-psc-ac97";
                //      cell-index =3D <1>;
                //      reg =3D <0x2200 0x100>;
+               //      gpios =3D <&gpio 7 0              /* AC97_1_RES */
+               //               &gpio_simple 29 0      /* AC97_1_SYNC */
+               //               &gpio_simple 31 0>;    /* AC97_1_SDATA_OUT=
 */
                //      interrupts =3D <2 2 0>;
                //};

diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/li=
te5200b.dts
index e45a63b..1fb0ac7 100644
--- a/arch/powerpc/boot/dts/lite5200b.dts
+++ b/arch/powerpc/boot/dts/lite5200b.dts
@@ -184,6 +184,9 @@
                //      compatible =3D "fsl,mpc5200b-psc-ac97","fsl,mpc5200=
-psc-ac97";
                //      cell-index =3D <1>;
                //      reg =3D <0x2200 0x100>;
+               //      gpios =3D <&gpio 7 0              /* AC97_1_RES */
+               //               &gpio_simple 29 0      /* AC97_1_SYNC */
+               //               &gpio_simple 31 0>;    /* AC97_1_SDATA_OUT=
 */
                //      interrupts =3D <2 2 0>;
                //};

diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm03=
0.dts
index 8a4ec30..0085e0f 100644
--- a/arch/powerpc/boot/dts/pcm030.dts
+++ b/arch/powerpc/boot/dts/pcm030.dts
@@ -189,6 +189,9 @@
                        compatible =3D "mpc5200b-psc-ac97","fsl,mpc5200b-ps=
c-ac97";
                        cell-index =3D <0>;
                        reg =3D <0x2000 0x100>;
+                       gpios =3D <&gpio 7 0              /* AC97_1_RES */
+                                &gpio_simple 29 0      /* AC97_1_SYNC */
+                                &gpio_simple 31 0>;    /* AC97_1_SDATA_OUT=
 */
                        interrupts =3D <2 1 0>;
                };

diff --git a/arch/powerpc/boot/dts/pcm032.dts b/arch/powerpc/boot/dts/pcm03=
2.dts
index 85d857a..76f86d3 100644
--- a/arch/powerpc/boot/dts/pcm032.dts
+++ b/arch/powerpc/boot/dts/pcm032.dts
@@ -189,6 +189,9 @@
                        compatible =3D "fsl,mpc5200b-psc-ac97","fsl,mpc5200=
-psc-ac97";
                        cell-index =3D <0>;
                        reg =3D <0x2000 0x100>;
+                       gpios =3D <&gpio 7 0              /* AC97_1_RES */
+                                &gpio_simple 29 0      /* AC97_1_SYNC */
+                                &gpio_simple 31 0>;    /* AC97_1_SDATA_OUT=
 */
                        interrupts =3D <2 1 0>;
                };

diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h
index 22208b3..9fb0248 100644
--- a/sound/soc/fsl/mpc5200_dma.h
+++ b/sound/soc/fsl/mpc5200_dma.h
@@ -61,6 +61,11 @@ struct psc_dma {
        int id;
        unsigned int slots;

+       /* gpio pins locations for cold reset */
+       int reset_gpio;
+       int sync_gpio;
+       int out_gpio;
+
        /* per-stream data */
        struct psc_dma_stream playback;
        struct psc_dma_stream capture;
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_a=
c97.c
index e2ee220..08cd51f 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -9,8 +9,10 @@
  * published by the Free Software Foundation.
  */

+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <linux/of_platform.h>
 #include <linux/delay.h>

@@ -20,12 +22,17 @@

 #include <asm/time.h>
 #include <asm/delay.h>
+#include <asm/mpc52xx.h>
 #include <asm/mpc52xx_psc.h>

 #include "mpc5200_dma.h"
 #include "mpc5200_psc_ac97.h"

 #define DRV_NAME "mpc5200-psc-ac97"
+#define MPC52xx_GPIO_PSC1_MASK 0x7
+#define MPC52xx_GPIO_PSC2_MASK (0x7<<4)
+#define MPC52xx_AC97_PSC1 0x2
+#define MPC52xx_AC97_PSC2 (0x2<<4)

 /* ALSA only supports a single AC97 device so static is recommend here */
 static struct psc_dma *psc_dma;
@@ -100,19 +107,84 @@ static void psc_ac97_warm_reset(struct snd_ac97 *ac97=
)
 {
        struct mpc52xx_psc __iomem *regs =3D psc_dma->psc_regs;

+       mutex_lock(&psc_dma->mutex);
+
        out_be32(&regs->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_AWR);
        udelay(3);
        out_be32(&regs->sicr, psc_dma->sicr);
+
+       mutex_unlock(&psc_dma->mutex);
 }

 static void psc_ac97_cold_reset(struct snd_ac97 *ac97)
 {
        struct mpc52xx_psc __iomem *regs =3D psc_dma->psc_regs;
+       u32 gpio_mux;
+
+       mutex_lock(&psc_dma->mutex);
+
+       if ((psc_dma->reset_gpio < 0) ||
+           (psc_dma->sync_gpio < 0) ||
+           (psc_dma->out_gpio < 0)) {
+               /* Use the psc function to do a cold reset */
+               out_8(&regs->op1, MPC52xx_PSC_OP_RES);
+               udelay(10);
+               out_8(&regs->op0, MPC52xx_PSC_OP_RES);
+               goto warm;
+       }
+
+       /* Reconfigure pin-muxing to gpio */
+       switch (psc_dma->id) {
+       case 0:
+               gpio_mux =3D MPC52xx_GPIO_PSC1_MASK;
+               break;
+       case 1:
+               gpio_mux =3D MPC52xx_GPIO_PSC2_MASK;
+               break;
+       default:
+               dev_err(psc_dma->dev,
+                       "Unable to determine PSC, no cold-reset will be "
+                       "performed\n");
+               goto warm;
+       }
+
+       dev_info(psc_dma->dev, "cold reset\n");
+       mpc52xx_write_port_config(~gpio_mux, 1);
+
+       /* Assert cold reset */
+       gpio_direction_output(psc_dma->sync_gpio, 0);
+       gpio_direction_output(psc_dma->out_gpio, 0);
+       gpio_direction_output(psc_dma->reset_gpio, 0);
+
+       /* Notify the PSC that a cold reset is occurring */
+       out_be32(&regs->sicr, 0);
+       udelay(2);
+
+       /* Deassert reset */
+       gpio_direction_output(psc_dma->reset_gpio, 1);
+       msleep(1);
+
+       /* Restore pin-muxing */
+       switch (psc_dma->id) {
+       case 0:
+               gpio_mux =3D MPC52xx_AC97_PSC1;
+               break;
+       case 1:
+               gpio_mux =3D MPC52xx_AC97_PSC2;
+               break;
+       default:
+               goto warm;
+       }
+
+       mpc52xx_write_port_config(gpio_mux, 0);
+
+       /* Restore the serial interface mode to AC97 */
+       out_be32(&regs->sicr, psc_dma->sicr);
+       out_8(&regs->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE=
);
+
+warm:
+       mutex_unlock(&psc_dma->mutex);

-       /* Do a cold reset */
-       out_8(&regs->op1, MPC52xx_PSC_OP_RES);
-       udelay(10);
-       out_8(&regs->op0, MPC52xx_PSC_OP_RES);
        msleep(1);
        psc_ac97_warm_reset(ac97);
 }
@@ -287,6 +359,24 @@ static int __devinit psc_ac97_of_probe(struct of_devic=
e *op,
        regs =3D psc_dma->psc_regs;
        ac97.private_data =3D psc_dma;

+       psc_dma->reset_gpio =3D of_get_gpio_flags(op->dev.of_node, 0, NULL)=
;
+       psc_dma->sync_gpio =3D of_get_gpio_flags(op->dev.of_node, 1, NULL);
+       psc_dma->out_gpio =3D of_get_gpio_flags(op->dev.of_node, 2, NULL);
+       if ((psc_dma->reset_gpio < 0) ||
+           (psc_dma->sync_gpio < 0) ||
+           (psc_dma->out_gpio < 0)) {
+               dev_err(&op->dev, "error: cannot get GPIO pins; "
+                       "reset=3D%i sync=3D%i out=3D%i, defaulting to norma=
l ac97 "
+                       "reset\n",
+                       psc_dma->reset_gpio,
+                       psc_dma->sync_gpio,
+                       psc_dma->out_gpio);
+       } else {
+               gpio_request(psc_dma->reset_gpio, "psc_dma-reset");
+               gpio_request(psc_dma->sync_gpio, "psc_dma-sync");
+               gpio_request(psc_dma->out_gpio, "psc_dma-out");
+       }
+
        for (i =3D 0; i < ARRAY_SIZE(psc_ac97_dai); i++)
                psc_ac97_dai[i].private_data =3D psc_dma;

--
1.6.3.1


This e-mail and the information, including any attachments, it contains are=
 intended to be a confidential communication only to the person or entity t=
o whom it is addressed and may contain information that is privileged. If t=
he reader of this message is not the intended recipient, you are hereby not=
ified that any dissemination, distribution or copying of this communication=
 is strictly prohibited. If you have received this communication in error, =
please immediately notify the sender and destroy the original message.

Thank you.

Please consider the environment before printing this email.

^ permalink raw reply related

* Re: CPM UART on MPC8270
From: James Black @ 2010-06-09 16:19 UTC (permalink / raw)
  To: Martyn Welch; +Cc: linuxppc-dev list
In-Reply-To: <4C0FA73B.4070905@ge.com>

SSBjb3VsZG4ndCBnZXQgdGhlIGVjaG8gPiAvZGV2L3h4eCB0byB3b3JrLiBJIGhhZCB0byB3cml0
ZSBhIHNtYWxsIGFwcAp0aGF0IG9wZW5lZCB0aGUgZGV2aWNlIGFuZCB3cml0ZSBhbmQgcmVhZCBj
aGFyYWN0ZXJzIGZvciB0ZXN0aW5nLgoKU3RhcnQgdGhlcmUgYW5kIHlvdSBtYXkgZmluZCBpdCBp
cyBhY3R1YWxseSB3b3JraW5nLgoKSkIKCk9uIFdlZCwgSnVuIDksIDIwMTAgYXQgODozNyBBTSwg
TWFydHluIFdlbGNoIDxtYXJ0eW4ud2VsY2hAZ2UuY29tPiB3cm90ZToKPiBIaSBBbGwsCj4KPiBJ
J20gYXR0ZW1wdGluZyB0byBnZXQgYW4gU0NDIHBvcnQgb24gYW4gTVBDODI3MCB3b3JraW5nIHdp
dGggTGludXguIEknbQo+IG5vdCBvdmVybHkgZmFtaWxpYXIgd2l0aCB0aGUgQ1BNIGFuZCBhbSBo
YXZpbmcgYSBiaXQgb2YgdHJvdWJsZS4KPgo+IExpbnV4IGlzIGJvb3RpbmcgbmF0aXZlbHkgb24g
dGhlIDgyNzAuIEkgaGF2ZSBhY2Nlc3MgdG8gdGhlIDgyNzAgdmlhIGEKPiBzZXQgb2YgUENJIHdp
bmRvd3MgZnJvbSBhIHNlY29uZCBjb3JlIChpbmNsdWRlcyBvbmUgc2V0dXAgb3ZlciB0aGUgbWFp
bgo+IG1lbW9yeSBhbmQgb25lIG92ZXIgdGhlIElNTVIpIGFuZCBTTUMxIGlzIHVwIGFuZCB3b3Jr
aW5nIHdpdGggYSBjb25zb2xlLgo+Cj4gVGhlIFNDQ3Mgc2VlbSB0byBiZSBkZXRlY3RlZCBjb3Jy
ZWN0bHkgYXQgYm9vdDoKPgo+IGYwMTFhODAuc2VyaWFsOiB0dHlDUE0wIGF0IE1NSU8gMHhjMzAx
NGE4MCAoaXJxID0gMTYpIGlzIGEgQ1BNIFVBUlQKPiBmMDExYTAwLnNlcmlhbDogdHR5Q1BNMSBh
dCBNTUlPIDB4YzMwMThhMDAgKGlycSA9IDQwKSBpcyBhIENQTSBVQVJUCj4gZjAxMWEyMC5zZXJp
YWw6IHR0eUNQTTIgYXQgTU1JTyAweGMzMDIwYTIwIChpcnEgPSA0MSkgaXMgYSBDUE0gVUFSVAo+
IGYwMTFhNDAuc2VyaWFsOiB0dHlDUE0zIGF0IE1NSU8gMHhjMzAyOGE0MCAoaXJxID0gNDIpIGlz
IGEgQ1BNIFVBUlQKPgo+IFdpdGggdGhlIERUUyByZWFkaW5nOgo+Cj4gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqBzbWMxOiBzZXJpYWxAMTFhODAgewo+IMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZGV2aWNlX3R5cGUgPSAic2VyaWFsIjsK
PiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGNvbXBhdGli
bGUgPSAiZnNsLG1wYzgyNzAtc21jLXVhcnQiLAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICJmc2wsY3BtMi1zbWMtdWFy
dCI7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZWcg
PSA8MHgxMWE4MCAweDIwIDB4ODdmYyAyPjsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoGludGVycnVwdHMgPSA8NCA4PjsKPiDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGludGVycnVwdC1wYXJlbnQgPSA8JlBJQz47
Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBmc2wsY3Bt
LWJyZyA9IDw3PjsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoGZzbCxjcG0tY29tbWFuZCA9IDwweDFkMDAwMDAwPjsKPiDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoH07Cj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oHNjYzE6IHNlcmlhbEAxMWEwMCB7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqBkZXZpY2VfdHlwZSA9ICJzZXJpYWwiOwo+IMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY29tcGF0aWJsZSA9ICJmc2wsbXBjODI3MC1z
Y2MtdWFydCIsCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgImZzbCxjcG0yLXNjYy11YXJ0IjsKPiDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJlZyA9IDwweDExYTAwIDB4MjAgMHg4
MDAwIDB4MTAwPjsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoGludGVycnVwdHMgPSA8NDAgOD47Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqBpbnRlcnJ1cHQtcGFyZW50ID0gPCZQSUM+Owo+IMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZnNsLGNwbS1icmcgPSA8Mz47Cj4g
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBmc2wsY3BtLWNv
bW1hbmQgPSA8MHg4MDAwMDA+Owo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
fTsKPgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc2NjMjogc2VyaWFsQDEx
YTIwIHsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGRl
dmljZV90eXBlID0gInNlcmlhbCI7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqBjb21wYXRpYmxlID0gImZzbCxtcGM4MjcwLXNjYy11YXJ0IiwKPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCAiZnNsLGNwbTItc2NjLXVhcnQiOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgcmVnID0gPDB4MTFhMjAgMHgyMCAweDgxMDAgMHgxMDA+Owo+IMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaW50ZXJydXB0cyA9
IDw0MSA4PjsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oGludGVycnVwdC1wYXJlbnQgPSA8JlBJQz47Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqBmc2wsY3BtLWJyZyA9IDw2PjsKPiDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGZzbCxjcG0tY29tbWFuZCA9IDwweDRhMDAw
MDA+Owo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfTsKPgo+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc2NjMzogc2VyaWFsQDExYTQwIHsKPiDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGRldmljZV90eXBlID0gInNl
cmlhbCI7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBj
b21wYXRpYmxlID0gImZzbCxtcGM4MjcwLXNjYy11YXJ0IiwKPiDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAiZnNsLGNwbTIt
c2NjLXVhcnQiOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgcmVnID0gPDB4MTFhNDAgMHgyMCAweDgyMDAgMHgxMDA+Owo+IMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaW50ZXJydXB0cyA9IDw0MiA4PjsKPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGludGVycnVwdC1wYXJl
bnQgPSA8JlBJQz47Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqBmc2wsY3BtLWJyZyA9IDwxPjsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoGZzbCxjcG0tY29tbWFuZCA9IDwweDhjMDAwMDA+Owo+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfTsKPgo+IEkgYmVsaWV2ZSB0aGF0IEkgaGF2ZSB0
aGUgcGlucyBzZXR1cCBjb3JyZWN0bHkgYW5kIHRoZSBCUkdzIGNvbm5lY3RlZAo+IGNvcnJlY3Rs
eSBpbiB0aGUgc2V0dXBfYXJjaCBmdW5jdGlvbi4KPgo+IEF0IHRoZSBtb21lbnQgSSBoYXZlIFND
QzMgd2lyZWQgb3V0LiBJZiBJIGF0dGVtcHQgdG8gZWNobyBkYXRhIG91dCBvZgo+IHRoZSBTQ0Mg
KGVjaG8gIkhlbGxvIiA+IC9kZXYvdHR5Q1BNMykgSSBnZXQgdGhlIHByb21wdCBzaXRzIHdhaXRp
bmcuCj4gUmVib290aW5nIGFuZCB0dXJuaW5nIG9uIHRoZSBkZWJ1ZyB5aWVsZHMgdGhlIGZvbGxv
d2luZyBvdXRwdXQgb24gdGhlCj4gY29uc29sZSAoYnV0IG5vdGhpbmcgb3V0IG9mIHRoZSBTQ0Mg
cG9ydCk6Cj4KPiBDUE0gdWFydFszXTpzdGFydHVwCj4gSW50ZXJydXB0IGF0dGFjaGVkCj4gQ1BN
IHVhcnRbM106c2V0X3Rlcm1pb3MKPiBDUE0gdWFydFszXTpzdGFydCB0eAo+IENQTSB1YXJ0WzNd
OnN0b3AgdHgKPiBDUE0gdWFydFszXTp0eF9lbXB0eTogMAo+IENQTSB1YXJ0WzNdOnR4X2VtcHR5
OiAwCj4gQ1BNIHVhcnRbM106dHhfZW1wdHk6IDAKPiBDUE0gdWFydFszXTp0eF9lbXB0eTogMAo+
IENQTSB1YXJ0WzNdOnR4X2VtcHR5OiAwCj4gQ1BNIHVhcnRbM106dHhfZW1wdHk6IDAKPiBDUE0g
dWFydFszXTp0eF9lbXB0eTogMAo+IENQTSB1YXJ0WzNdOnR4X2VtcHR5OiAwCj4gQ1BNIHVhcnRb
M106dHhfZW1wdHk6IDAKPiBDUE0gdWFydFszXTp0eF9lbXB0eTogMAo+IENQTSB1YXJ0WzNdOnR4
X2VtcHR5OiAwCj4gQ1BNIHVhcnRbM106c3RvcCByeAo+IENQTSB1YXJ0WzNdOnR4X2VtcHR5OiAw
Cj4gQ1BNIHVhcnRbM106dHhfZW1wdHk6IDAKPiBDUE0gdWFydFszXTp0eF9lbXB0eTogMAo+IENQ
TSB1YXJ0WzNdOnR4X2VtcHR5OiAwCj4gQ1BNIHVhcnRbM106dHhfZW1wdHk6IDAKPiBDUE0gdWFy
dFszXTp0eF9lbXB0eTogMAo+IENQTSB1YXJ0WzNdOnNodXRkb3duCj4gQ1BNIHVhcnRbM106dHhf
ZW1wdHk6IDAKPiBDUE0gdWFydFszXTp0eF9lbXB0eTogMAo+IENQTSB1YXJ0WzNdOnR4X2VtcHR5
OiAwCj4gQ1BNIHVhcnRbM106dHhfZW1wdHk6IDAKPiBDUE0gdWFydFszXTp0eF9lbXB0eTogMAo+
IENQTSB1YXJ0WzNdOnR4X2VtcHR5OiAwCj4gQ1BNIHVhcnRbM106dHhfZW1wdHk6IDAKPiAuLi4K
Pgo+Cj4gSXQgc2VlbWVkIHRvIGJlIHdhaXRpbmcgZm9yIHJlYWR5IGJpdCBvZiB0aGUgVHJhbnNt
aXQgQnVmZmVyIERlc2NyaXB0b3IKPiB0byBiZSBjbGVhcmVkICh3aGljaCBpdCBuZXZlciBzZWVt
cyB0byBiZSksIHByb2RkaW5nIHRoaXMgYml0IHRocm91Z2gKPiB0aGUgcGNpIHdpbmRvdyBkaWQg
Y2F1c2UgdGhlIHByb2Nlc3MgdG8gY29udGludWUsIG5vIGRhdGEgb3V0IGJ1dCBJIGRpZAo+IGdl
dCBiYWNrIHRvIHRoZSBwcm9tcHQgb24gdGhlIGNvbnNvbGUuCj4KPiBJJ20gc3VyZSBJJ20ganVz
dCBtaXNzaW5nIHNvbWV0aGluZyByZWFsbHkgYmFzaWMgLSBjYW4gYW55b25lIGVubGlnaHRlbiBt
ZT8KPgo+IE1hcnR5bgo+Cj4gLS0KPiBNYXJ0eW4gV2VsY2ggKFByaW5jaXBhbCBTb2Z0d2FyZSBF
bmdpbmVlcikgwqAgfCDCoCBSZWdpc3RlcmVkIGluIEVuZ2xhbmQgYW5kCj4gR0UgSW50ZWxsaWdl
bnQgUGxhdGZvcm1zIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHwgwqAgV2FsZXMgKDM4
Mjg2NDIpIGF0IDEwMAo+IFQgKzQ0KDApMTI3MzIyNzQ4IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgfCDCoCBCYXJiaXJvbGxpIFNxdWFyZSwgTWFuY2hlc3RlciwKPiBF
IG1hcnR5bi53ZWxjaEBnZS5jb20gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB8
IMKgIE0yIDNBQiDCoFZBVDpHQiA5Mjc1NTkxODkKPgo+IF9fX19fX19fX19fX19fX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fCj4gTGludXhwcGMtZGV2IG1haWxpbmcgbGlzdAo+IExp
bnV4cHBjLWRldkBsaXN0cy5vemxhYnMub3JnCj4gaHR0cHM6Ly9saXN0cy5vemxhYnMub3JnL2xp
c3RpbmZvL2xpbnV4cHBjLWRldgo+CgoKCi0tIApKaW0gQmxhY2sKU2VuaW9yIFNvZnR3YXJlIEVu
Z2luZWVyCkF6dGVrIE5ldHdvcmtzLCBJbmMuCjI0NzcgNTV0aCBTdHJlZXQsIFN1aXRlIDIwMgpC
b3VsZGVyLCBDTyA4MDMwMQp3d3cuYXp0ZWtuZXR3b3Jrcy5jb20K

^ permalink raw reply

* Re: [PATCH v21 011/100] eclone (11/11): Document sys_eclone
From: Sukadev Bhattiprolu @ 2010-06-09 18:14 UTC (permalink / raw)
  To: Albert Cahalan
  Cc: randy.dunlap, arnd, linux-kernel, hpa, linuxppc-dev, roland
In-Reply-To: <AANLkTinFGblE4fW35O0LchJZ22tz_5-qervpGC_lpUj_@mail.gmail.com>

Albert Cahalan [acahalan@gmail.com] wrote:
| On Tue, Jun 1, 2010 at 9:38 PM, Sukadev Bhattiprolu
| <sukadev@linux.vnet.ibm.com> wrote:
| > | Come on, seriously, you know it's ia64 and hppa that
| > | have issues. Maybe the nommu ports also have issues.
| > |
| > | The only portable way to specify the stack is base and offset,
| > | with flags or magic values for "share" and "kernel managed".
| >
| > Ah, ok, we have not yet ported to IA64 and I see now where the #ifdef
| > comes in.
| >
| > But are you saying that we should force x86 and other architectures to
| > specify base and offset for eclone() even though they currently specify
| > just the stack pointer to clone() ?
| 
| Even for x86, it's an easier API. Callers would be specifying
| two numbers they already have: the argument and return value
| for malloc. Currently the numbers must be added together,
| destroying information, except on hppa (must not add size)
| and ia64 (must use what I'm proposing already).

I agree its easier and would avoid #ifdefs in the applications.

Peter, Arnd, Roland - do you have any concerns with requiring all
architectures to specify the stack to eclone() as [base, offset]

To recap, currently we have 

struct clone_args {
	u64 clone_flags_high;
	/*
	 * Architectures can use child_stack for either the stack pointer or
	 * the base of of stack. If child_stack is used as the stack pointer,
	 * child_stack_size must be 0. Otherwise child_stack_size must be
	 * set to size of allocated stack.
	 */
	u64 child_stack;
	u64 child_stack_size;
	u64 parent_tid_ptr;
	u64 child_tid_ptr;
	u32 nr_pids;
	u32 reserved0;
};

sys_eclone(u32 flags_low, struct clone_args * __user cargs, int cargs_size,
		pid_t * __user pids)


Most architecutres would specify the stack pointer in ->child_stack and
ignore the ->child_stack_size.

IA64 specifies the *stack-base* in ->child_stack and the stack size in
->child_stack_size.

Albert and Randy point out that this would require #ifdefs in the
application code that intends to be portable across say IA64 and x86.

Can we instead have all architectures specify [base, size] ?

Thanks

Sukadev

^ permalink raw reply


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