LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* 2.6.21-git5 -- powerpc link failure
From: Andy Whitcroft @ 2007-05-10 13:49 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxppc-dev, Andrew Morton, Linus Torvalds, Paul Mackerras

Since 2.6.21-git5 we've been getting the following link failure on powerpc:

  CC      drivers/pci/hotplug/rpadlpar_core.o
  CC      drivers/pci/hotplug/rpadlpar_sysfs.o
drivers/pci/hotplug/rpadlpar_sysfs.c:132: error: unknown field
‘subsys’ specified in initializer
drivers/pci/hotplug/rpadlpar_sysfs.c:132: warning: initialization from
incompatible pointer type
make[3]: *** [drivers/pci/hotplug/rpadlpar_sysfs.o] Error 1
make[2]: *** [drivers/pci/hotplug] Error 2
make[1]: *** [drivers/pci] Error 2
make: *** [drivers] Error 2


I would think this is caused by the changes in the commit below:

commit 823bccfc4002296ba88c3ad0f049e1abd8108d30
Author: Greg Kroah-Hartman <gregkh@suse.de>
Date:   Fri Apr 13 13:15:19 2007 -0700

    remove "struct subsystem" as it is no longer needed

-apw

^ permalink raw reply

* Re: [PATCH] Move reg_booke.h to include/asm-powerpc
From: Becky Bruce @ 2007-05-10 13:44 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: linuxppc-dev
In-Reply-To: <20070510091138.6e4fe0e6.sfr@canb.auug.org.au>


On May 9, 2007, at 6:11 PM, Stephen Rothwell wrote:

> On Wed,  9 May 2007 14:31:19 -0500 Becky Bruce  
> <becky.bruce@freescale.com> wrote:
>>
>> This patch moves reg_booke.h from include/asm-ppc to include/asm- 
>> powerpc.  This is
>> just a git-mv of the file; no changes were made.  Tested builds of  
>> 8540 ADS and
>> Ebony platforms with ARCH=ppc and ARCH=powerpc.
>>
>> Signed-off-by: Becky Bruce <becky.bruce@freescale.com>
>> ---
>>  include/{asm-ppc => asm-powerpc}/reg_booke.h |    0
>>  1 files changed, 0 insertions(+), 0 deletions(-)
>>  rename include/{asm-ppc => asm-powerpc}/reg_booke.h (100%)
>>
>> diff --git a/include/asm-ppc/reg_booke.h b/include/asm-powerpc/ 
>> reg_booke.h
>> similarity index 100%
>> rename from include/asm-ppc/reg_booke.h
>> rename to include/asm-powerpc/reg_booke.h
>
> Could you please change the self inclusion protection defines?

Certainement.  I meant to send a second patch to do that, so the  
first one was *just* a move (who can resist the urge to put out a 0- 
line patch :).  Will follow up.

Thanks!
-B

^ permalink raw reply

* Re: [PATCH] Performance Stats: Kernel patch
From: Josh Boyer @ 2007-05-10 12:38 UTC (permalink / raw)
  To: Maxim Uvarov; +Cc: linuxppc-dev, Andrew Morton, wli, pavel, dada1
In-Reply-To: <20070510123950.7984.24745.stgit@localhost.localdomain>

On Thu, 2007-05-10 at 12:39 +0000, Maxim Uvarov wrote:
> Patch makes available to the user the following
> task and process performance statistics:
> 	* Involuntary Context Switches (task_struct->nivcsw)
> 	* Voluntary Context Switches (task_struct->nvcsw)
> 	* Number of system calls (added new counter
> 	  thread_info->sysall_count)
> 	           
> Statistics information is available from:
>         1. taskstats interface (Documentation/accounting/)
> 	2. /proc/PID/status (task only).
> 
> This data is useful for detecting hyperactivity
> patterns between processes.

This should be sent to the linux-kernel list I think...  Or at least
CCd.

josh

^ permalink raw reply

* [PATCH] Performance Stats: Kernel patch
From: Maxim Uvarov @ 2007-05-10 12:39 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linuxppc-dev, pavel, wli, dada1


Patch makes available to the user the following
task and process performance statistics:
	* Involuntary Context Switches (task_struct->nivcsw)
	* Voluntary Context Switches (task_struct->nvcsw)
	* Number of system calls (added new counter
	  thread_info->sysall_count)
	           
Statistics information is available from:
        1. taskstats interface (Documentation/accounting/)
	2. /proc/PID/status (task only).

This data is useful for detecting hyperactivity
patterns between processes.

Signed-off-by: Maxim Uvarov <muvarov@ru.mvista.com>

Changing nvcsw to voluntary_ctxt_switches.


Signed-off-by: Maxim Uvarov <muvarov@ru.mvista.com>                                                                                  
---

 Documentation/accounting/getdelays.c          |   20 ++++++++++++++++++--
 Documentation/accounting/taskstats-struct.txt |    7 +++++++
 arch/i386/kernel/asm-offsets.c                |    1 +
 arch/i386/kernel/entry.S                      |    3 +++
 arch/powerpc/kernel/asm-offsets.c             |    2 ++
 arch/powerpc/kernel/entry_32.S                |    5 +++++
 arch/powerpc/kernel/entry_64.S                |    5 +++++
 arch/x86_64/kernel/asm-offsets.c              |    1 +
 arch/x86_64/kernel/entry.S                    |    3 +++
 fs/proc/array.c                               |   14 ++++++++++++++
 include/asm-i386/thread_info.h                |    1 +
 include/asm-powerpc/thread_info.h             |    1 +
 include/asm-x86_64/thread_info.h              |    1 +
 include/linux/taskstats.h                     |    6 +++++-
 kernel/fork.c                                 |    3 +++
 kernel/taskstats.c                            |    6 ++++++
 16 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
index e9126e7..1be7d65 100644
--- a/Documentation/accounting/getdelays.c
+++ b/Documentation/accounting/getdelays.c
@@ -49,6 +49,7 @@ char name[100];
 int dbg;
 int print_delays;
 int print_io_accounting;
+int print_task_stats;
 __u64 stime, utime;
 
 #define PRINTF(fmt, arg...) {			\
@@ -187,7 +188,7 @@ void print_delayacct(struct taskstats *t)
 	       "IO    %15s%15s\n"
 	       "      %15llu%15llu\n"
 	       "MEM   %15s%15s\n"
-	       "      %15llu%15llu\n\n",
+	       "      %15llu%15llu\n"
 	       "count", "real total", "virtual total", "delay total",
 	       t->cpu_count, t->cpu_run_real_total, t->cpu_run_virtual_total,
 	       t->cpu_delay_total,
@@ -196,6 +197,15 @@ void print_delayacct(struct taskstats *t)
 	       "count", "delay total", t->swapin_count, t->swapin_delay_total);
 }
 
+void print_taskstats(struct taskstats *t)
+{
+	printf("\n\nTask  %15s%15s%15s\n"
+	       "      %15lu%15lu%15lu\n",
+	       "syscalls", "voluntary", "nonvoluntary",
+	       t->syscall_counter, t->nvcsw, t->nivcsw);
+
+}
+
 void print_ioacct(struct taskstats *t)
 {
 	printf("%s: read=%llu, write=%llu, cancelled_write=%llu\n",
@@ -227,7 +237,7 @@ int main(int argc, char *argv[])
 	struct msgtemplate msg;
 
 	while (1) {
-		c = getopt(argc, argv, "diw:r:m:t:p:v:l");
+		c = getopt(argc, argv, "qdiw:r:m:t:p:v:l");
 		if (c < 0)
 			break;
 
@@ -240,6 +250,10 @@ int main(int argc, char *argv[])
 			printf("printing IO accounting\n");
 			print_io_accounting = 1;
 			break;
+		case 'q':
+			printf("printing task/process stasistics:\n");
+			print_task_stats = 1;
+			break;
 		case 'w':
 			strncpy(logfile, optarg, MAX_FILENAME);
 			printf("write to file %s\n", logfile);
@@ -381,6 +395,8 @@ int main(int argc, char *argv[])
 							print_delayacct((struct taskstats *) NLA_DATA(na));
 						if (print_io_accounting)
 							print_ioacct((struct taskstats *) NLA_DATA(na));
+						if (print_task_stats)
+							print_taskstats((struct taskstats *) NLA_DATA(na));
 						if (fd) {
 							if (write(fd, NLA_DATA(na), na->nla_len) < 0) {
 								err(1,"write error\n");
diff --git a/Documentation/accounting/taskstats-struct.txt b/Documentation/accounting/taskstats-struct.txt
index 661c797..5dac173 100644
--- a/Documentation/accounting/taskstats-struct.txt
+++ b/Documentation/accounting/taskstats-struct.txt
@@ -22,6 +22,8 @@ There are three different groups of fields in the struct taskstats:
     /* Extended accounting fields end */
     Their values are collected if CONFIG_TASK_XACCT is set.
 
+4) Per-task and per-thread statistics
+
 Future extension should add fields to the end of the taskstats struct, and
 should not change the relative position of each field within the struct.
 
@@ -158,4 +160,9 @@ struct taskstats {
 
 	/* Extended accounting fields end */
 
+4) Per-task and per-thread statiscits
+	__u32	syscall_counter;	/* Syscall counter */
+	__u32	nvcsw;			/* Context voluntary switch counter */
+	__u32	nivcsw;			/* Context involuntary switch counter */
+
 }
diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c
index 1b2f3cd..4ad49d2 100644
--- a/arch/i386/kernel/asm-offsets.c
+++ b/arch/i386/kernel/asm-offsets.c
@@ -56,6 +56,7 @@ void foo(void)
 	OFFSET(TI_addr_limit, thread_info, addr_limit);
 	OFFSET(TI_restart_block, thread_info, restart_block);
 	OFFSET(TI_sysenter_return, thread_info, sysenter_return);
+	OFFSET(TI_syscall_count, thread_info, syscall_count);
 	BLANK();
 
 	OFFSET(GDS_size, Xgt_desc_struct, size);
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 5e47683..836961f 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -332,6 +332,9 @@ sysenter_past_esp:
 	SAVE_ALL
 	GET_THREAD_INFO(%ebp)
 
+#ifdef CONFIG_TASKSTATS
+	incl	TI_syscall_count(%ebp)	# Increment syscalls counter
+#endif
 	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
 	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
 	jnz syscall_trace_entry
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 030d300..b640039 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -94,6 +94,8 @@ int main(void)
 	DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags));
 	DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
 	DEFINE(TI_TASK, offsetof(struct thread_info, task));
+	DEFINE(TI_SYSCALL_COUNT, offsetof(struct thread_info, syscall_count));
+
 #ifdef CONFIG_PPC32
 	DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
 	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index c03e829..5d919e4 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -202,6 +202,11 @@ _GLOBAL(DoSyscall)
 	bl	do_show_syscall
 #endif /* SHOW_SYSCALLS */
 	rlwinm	r10,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
+#ifdef CONFIG_TASKSTATS 
+	lwz r11,TI_SYSC_CNT(r10)
+	addi r11,r11,1
+	stw r11,TI_SYSC_CNT(r10)
+#endif
 	lwz	r11,TI_FLAGS(r10)
 	andi.	r11,r11,_TIF_SYSCALL_T_OR_A
 	bne-	syscall_dotrace
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2551c08..5907f76 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -115,6 +115,11 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 	addi	r9,r1,STACK_FRAME_OVERHEAD
 #endif
 	clrrdi	r11,r1,THREAD_SHIFT
+#ifdef CONFIG_TASKSTATS
+	ld r10,TI_SYSCALL_COUNT(r11)
+	addi r10,r10,1
+	std r10,TI_SYSCALL_COUNT(r11)
+#endif
 	ld	r10,TI_FLAGS(r11)
 	andi.	r11,r10,_TIF_SYSCALL_T_OR_A
 	bne-	syscall_dotrace
diff --git a/arch/x86_64/kernel/asm-offsets.c b/arch/x86_64/kernel/asm-offsets.c
index 96687e2..da57356 100644
--- a/arch/x86_64/kernel/asm-offsets.c
+++ b/arch/x86_64/kernel/asm-offsets.c
@@ -35,6 +35,7 @@ int main(void)
 	ENTRY(addr_limit);
 	ENTRY(preempt_count);
 	ENTRY(status);
+	ENTRY(syscall_count);
 	BLANK();
 #undef ENTRY
 #define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry))
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 9f5dac6..af40ead 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -229,6 +229,9 @@ ENTRY(system_call)
 	movq  %rcx,RIP-ARGOFFSET(%rsp)
 	CFI_REL_OFFSET rip,RIP-ARGOFFSET
 	GET_THREAD_INFO(%rcx)
+#ifdef CONFIG_TASKSTATS
+	addq $1, threadinfo_syscall_count(%rcx)   # Increment syscalls counter
+#endif
 	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
 	jnz tracesys
 	cmpq $__NR_syscall_max,%rax
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 70e4fab..c805c08 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -290,6 +290,19 @@ static inline char *task_cap(struct task_struct *p, char *buffer)
 			    cap_t(p->cap_permitted),
 			    cap_t(p->cap_effective));
 }
+static inline char *task_perf(struct task_struct *p, char *buffer)
+{
+	/* Syscall counter adds 1 line overhead on each syscall execution
+	 * in entry.S, so probably it is the leave this stuff under ifdefs.
+	 */
+#ifdef CONFIG_TASKSTATS
+	buffer += sprintf(buffer, "Syscalls:\t%lu\n", p->thread_info->syscall_count);
+#endif
+	return buffer + sprintf(buffer, "voluntary_ctxt_switches:\t%lu\n"
+			    "nonvoluntary_ctxt_switches:\t%lu\n",
+			    p->nvcsw,
+			    p->nivcsw);
+}
 
 int proc_pid_status(struct task_struct *task, char * buffer)
 {
@@ -309,6 +322,7 @@ int proc_pid_status(struct task_struct *task, char * buffer)
 #if defined(CONFIG_S390)
 	buffer = task_show_regs(task, buffer);
 #endif
+	buffer = task_perf(task, buffer);
 	return buffer - orig;
 }
 
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index 4b187bb..bccfd6a 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -33,6 +33,7 @@ struct thread_info {
 	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 
 
+	unsigned long		syscall_count;	/* Syscall counter */
 	mm_segment_t		addr_limit;	/* thread address space:
 					 	   0-0xBFFFFFFF for user-thead
 						   0-0xFFFFFFFF for kernel-thread
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index 3f32ca8..5306ac2 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -35,6 +35,7 @@ struct thread_info {
 	int		cpu;			/* cpu we're on */
 	int		preempt_count;		/* 0 => preemptable,
 						   <0 => BUG */
+	unsigned long	syscall_count;		/* Syscall counter */
 	struct restart_block restart_block;
 	unsigned long	local_flags;		/* private flags for thread */
 
diff --git a/include/asm-x86_64/thread_info.h b/include/asm-x86_64/thread_info.h
index 74a6c74..e53022d 100644
--- a/include/asm-x86_64/thread_info.h
+++ b/include/asm-x86_64/thread_info.h
@@ -31,6 +31,7 @@ struct thread_info {
 	__u32			cpu;		/* current CPU */
 	int 			preempt_count;	/* 0 => preemptable, <0 => BUG */
 
+	unsigned long		syscall_count;	/* Syscall counter */
 	mm_segment_t		addr_limit;	
 	struct restart_block    restart_block;
 };
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h
index 3fced47..e3341b6 100644
--- a/include/linux/taskstats.h
+++ b/include/linux/taskstats.h
@@ -31,7 +31,7 @@
  */
 
 
-#define TASKSTATS_VERSION	3
+#define TASKSTATS_VERSION	4
 #define TS_COMM_LEN		32	/* should be >= TASK_COMM_LEN
 					 * in linux/sched.h */
 
@@ -141,6 +141,10 @@ struct taskstats {
 	__u64	write_syscalls;		/* write syscalls */
 	/* Extended accounting fields end */
 
+	__u32  syscall_counter;   /* Syscall counter */
+	__u32  nvcsw;
+	__u32  nivcsw;
+
 #define TASKSTATS_HAS_IO_ACCOUNTING
 	/* Per-task storage I/O accounting starts */
 	__u64	read_bytes;		/* bytes of read I/O */
diff --git a/kernel/fork.c b/kernel/fork.c
index fc723e5..5213738 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1042,6 +1042,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 	p->wchar = 0;		/* I/O counter: bytes written */
 	p->syscr = 0;		/* I/O counter: read syscalls */
 	p->syscw = 0;		/* I/O counter: write syscalls */
+#ifdef CONFIG_TASKSTATS
+	p->thread_info->syscall_count = 0; /* Syscall counter: total numbers of syscalls */
+#endif
 	task_io_accounting_init(p);
 	acct_clear_integrals(p);
 
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 4c3476f..d7bf33f 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -196,6 +196,9 @@ static int fill_pid(pid_t pid, struct task_struct *tsk,
 
 	/* fill in basic acct fields */
 	stats->version = TASKSTATS_VERSION;
+	stats->syscall_counter = tsk->thread_info->syscall_count;
+	stats->nvcsw = tsk->nvcsw;
+	stats->nivcsw = tsk->nivcsw;
 	bacct_add_tsk(stats, tsk);
 
 	/* fill in extended acct fields */
@@ -242,6 +245,9 @@ static int fill_tgid(pid_t tgid, struct task_struct *first,
 		 */
 		delayacct_add_tsk(stats, tsk);
 
+		stats->syscall_counter += tsk->thread_info->syscall_count;
+		stats->nvcsw += tsk->nvcsw;
+		stats->nivcsw += tsk->nivcsw;
 	} while_each_thread(first, tsk);
 
 	unlock_task_sighand(first, &flags);

^ permalink raw reply related

* Please pull powerpc.git master branch
From: Paul Mackerras @ 2007-05-10 12:29 UTC (permalink / raw)
  To: torvalds; +Cc: linuxppc-dev

Linus,

Please do:

git pull \
git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc.git master

to get some more powerpc patches for 2.6.22.  There are various bug
fixes and a few minor cleanups there, plus a 3-liner to wire up
sys_utimensat.

Thanks,
Paul.

 arch/powerpc/boot/dts/mpc832x_mds.dts       |    2 
 arch/powerpc/boot/dts/mpc834x_mds.dts       |    4 
 arch/powerpc/configs/celleb_defconfig       |  129 +++--
 arch/powerpc/kernel/pci_64.c                |   37 +
 arch/powerpc/kernel/prom.c                  |   47 +-
 arch/powerpc/lib/Makefile                   |    2 
 arch/powerpc/lib/rheap.c                    |  117 +++--
 arch/powerpc/mm/hash_native_64.c            |   37 +
 arch/powerpc/platforms/83xx/mpc8313_rdb.c   |    2 
 arch/powerpc/platforms/83xx/mpc832x_rdb.c   |    2 
 arch/powerpc/platforms/83xx/mpc834x_itx.c   |    2 
 arch/powerpc/platforms/83xx/mpc834x_mds.c   |    2 
 arch/powerpc/platforms/86xx/mpc86xx_hpcn.c  |    7 
 arch/powerpc/platforms/celleb/pci.c         |    1 
 arch/powerpc/platforms/celleb/scc_epci.c    |    8 
 arch/powerpc/platforms/celleb/setup.c       |    2 
 arch/powerpc/platforms/pseries/eeh.c        |   13 -
 arch/powerpc/platforms/pseries/eeh_driver.c |    7 
 arch/powerpc/platforms/pseries/iommu.c      |    3 
 arch/powerpc/platforms/pseries/kexec.c      |    1 
 arch/powerpc/sysdev/commproc.c              |   20 -
 arch/powerpc/sysdev/cpm2_common.c           |   21 -
 arch/powerpc/sysdev/qe_lib/qe.c             |   29 +
 arch/powerpc/sysdev/qe_lib/ucc_fast.c       |    5 
 arch/powerpc/sysdev/qe_lib/ucc_slow.c       |    7 
 arch/ppc/8xx_io/commproc.c                  |   22 -
 arch/ppc/lib/Makefile                       |    3 
 arch/ppc/lib/rheap.c                        |  692 ---------------------------
 arch/ppc/syslib/cpm2_common.c               |   23 -
 drivers/net/fs_enet/mac-scc.c               |    2 
 drivers/net/ucc_geth.c                      |   30 +
 drivers/serial/cpm_uart/cpm_uart.h          |    2 
 drivers/serial/cpm_uart/cpm_uart_core.c     |    3 
 drivers/serial/cpm_uart/cpm_uart_cpm1.c     |    6 
 drivers/serial/cpm_uart/cpm_uart_cpm2.c     |    6 
 include/asm-powerpc/mmu-hash64.h            |   12 
 include/asm-powerpc/mmzone.h                |    4 
 include/asm-powerpc/ppc-pci.h               |   18 +
 include/asm-powerpc/ps3.h                   |    5 
 include/asm-powerpc/qe.h                    |   13 -
 include/asm-powerpc/reg_booke.h             |  469 ++++++++++++++++++
 include/asm-powerpc/rheap.h                 |   20 -
 include/asm-powerpc/systbl.h                |    1 
 include/asm-powerpc/unistd.h                |    3 
 include/asm-ppc/commproc.h                  |   13 -
 include/asm-ppc/cpm2.h                      |   13 -
 include/linux/pmu.h                         |    2 
 47 files changed, 867 insertions(+), 1002 deletions(-)
 delete mode 100644 arch/ppc/lib/rheap.c
 create mode 100644 include/asm-powerpc/reg_booke.h
 rename include/{asm-ppc/rheap.h => asm-powerpc/rheap.h} (75%)

Becky Bruce (1):
      [POWERPC] Move reg_booke.h to include/asm-powerpc

Geoff Levand (1):
      [POWERPC] PS3: Fix sys manager build error

Ishizaki Kou (4):
      [POWERPC] celleb: Fix support for multiple PCI domains
      [POWERPC] celleb: Fix PCI config space accesses to subordinate buses
      [POWERPC] celleb: Fix parsing of machine type hack command line option
      [POWERPC] celleb: Update celleb_defconfig

Jason Jin (1):
      [POWERPC] 86xx: Enable the AC97 interface on 8641D board.

Kumar Gala (3):
      [POWERPC] 83xx: Suppress warning when CONFIG_ options aren't defined
      [POWERPC] User rheap from arch/powerpc/lib
      [POWERPC] CPM_UART: Removed __init from cpm_uart_init_portdesc to fix warning

Li Yang (1):
      [POWERPC] 83xx: Suppress warning when CONFIG_PCI is not defined

Linas Vepstas (1):
      [POWERPC] Assorted janitorial EEH cleanups

Michael Ellerman (1):
      [POWERPC] Split initrd logic out of early_init_dt_scan_chosen() to fix warning

Michael Neuling (1):
      [POWERPC] Minor pSeries IOMMU debug cleanup

Paul Mackerras (3):
      [POWERPC] Fix incorrect calculation of I/O window addresses
      [POWERPC] Fix warning in hpte_decode(), and generalize it
      [POWERPC] Fix compile error with kexec and CONFIG_SMP=n

Scott Wood (3):
      [POWERPC] CPM_UART: cpm_uart_set_termios should take ktermios, not termios
      [POWERPC] 83xx: Fix the PCI ranges in the MPC832x_MDS device tree.
      [POWERPC] 83xx: Fix the PCI ranges in the MPC834x_MDS device tree.

Stephen Rothwell (3):
      [POWERPC] Wire up sys_utimensat
      [POWERPC] pmu_sys_suspended is only defined for PPC32
      [POWERPC] We don't define CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID

Timur Tabi (1):
      [POWERPC] Change rheap functions to use ulongs instead of pointers

^ permalink raw reply

* Re: 2.6.21-mm2 -- powerpc missing kset
From: Stephen Rothwell @ 2007-05-10 12:16 UTC (permalink / raw)
  To: Andy Whitcroft; +Cc: linuxppc-dev, Andrew Morton, paulus, linux-kernel
In-Reply-To: <4643068C.8010302@shadowen.org>

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

On Thu, 10 May 2007 12:48:28 +0100 Andy Whitcroft <apw@shadowen.org> wrote:
>
> arch/powerpc/platforms/pseries/power.c:31: warning: `struct subsystem'
> declared inside parameter list

There is no explicit reference to struct subsystem in the current version
of that file.

--
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH] Performance Stats: Kernel patch
From: Pavel Machek @ 2007-05-10 12:03 UTC (permalink / raw)
  To: Maxim Uvarov; +Cc: linuxppc-dev, Andrew Morton, wli, dada1
In-Reply-To: <20070510114221.7576.67522.stgit@localhost.localdomain>

Hi!

> Patch makes available to the user the following
> task and process performance statistics:
> 	* Involuntary Context Switches (task_struct->nivcsw)
> 	* Voluntary Context Switches (task_struct->nvcsw)
> 	* Number of system calls (added new counter
> 	  thread_info->sysall_count)
> 	           
> Statistics information is available from:
>         1. taskstats interface (Documentation/accounting/)
> 	2. /proc/PID/status (task only).
> 
> This data is useful for detecting hyperactivity
> patterns between processes.

I was told nvcsw is standard name, but given how other fields are
named ("syscall_counter") I think we should use some more reasonable
name (like "voluntary_ctxt_switches" or something).
								Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* Re: 2.6.21-mm2 -- powerpc missing kset
From: Andy Whitcroft @ 2007-05-10 11:48 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linuxppc-dev, paulus, linux-kernel
In-Reply-To: <20070509012322.199f292b.akpm@linux-foundation.org>

Getting this new compile failure on powerpc:

-apw

arch/powerpc/platforms/pseries/power.c:31: warning: `struct subsystem'
declared inside parameter list
arch/powerpc/platforms/pseries/power.c:31: warning: its scope is only
this definition or declaration, which is probably not what you want
arch/powerpc/platforms/pseries/power.c:37: warning: `struct subsystem'
declared inside parameter list
arch/powerpc/platforms/pseries/power.c:55: warning: initialization from
incompatible pointer type
arch/powerpc/platforms/pseries/power.c:56: warning: initialization from
incompatible pointer type
arch/powerpc/platforms/pseries/power.c: In function `pm_init':
arch/powerpc/platforms/pseries/power.c:75: error: structure has no
member named `kset'
make[2]: *** [arch/powerpc/platforms/pseries/power.o] Error 1
make[1]: *** [arch/powerpc/platforms/pseries] Error 2
make: *** [arch/powerpc/platforms] Error 2

^ permalink raw reply

* [PATCH] Performance Stats: Kernel patch
From: Maxim Uvarov @ 2007-05-10 11:42 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linuxppc-dev, pavel, wli, dada1


Patch makes available to the user the following
task and process performance statistics:
	* Involuntary Context Switches (task_struct->nivcsw)
	* Voluntary Context Switches (task_struct->nvcsw)
	* Number of system calls (added new counter
	  thread_info->sysall_count)
	           
Statistics information is available from:
        1. taskstats interface (Documentation/accounting/)
	2. /proc/PID/status (task only).

This data is useful for detecting hyperactivity
patterns between processes.

Signed-off-by: Maxim Uvarov <muvarov@ru.mvista.com>

Signed-off-by: Maxim Uvarov <muvarov@ru.mvista.com>                                                                                  
---

 Documentation/accounting/getdelays.c          |   20 ++++++++++++++++++--
 Documentation/accounting/taskstats-struct.txt |    7 +++++++
 arch/i386/kernel/asm-offsets.c                |    1 +
 arch/i386/kernel/entry.S                      |    3 +++
 arch/powerpc/kernel/asm-offsets.c             |    2 ++
 arch/powerpc/kernel/entry_32.S                |    5 +++++
 arch/powerpc/kernel/entry_64.S                |    5 +++++
 arch/x86_64/kernel/asm-offsets.c              |    1 +
 arch/x86_64/kernel/entry.S                    |    3 +++
 fs/proc/array.c                               |   14 ++++++++++++++
 include/asm-i386/thread_info.h                |    1 +
 include/asm-powerpc/thread_info.h             |    1 +
 include/asm-x86_64/thread_info.h              |    1 +
 include/linux/taskstats.h                     |    6 +++++-
 kernel/fork.c                                 |    3 +++
 kernel/taskstats.c                            |    6 ++++++
 16 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
index e9126e7..1be7d65 100644
--- a/Documentation/accounting/getdelays.c
+++ b/Documentation/accounting/getdelays.c
@@ -49,6 +49,7 @@ char name[100];
 int dbg;
 int print_delays;
 int print_io_accounting;
+int print_task_stats;
 __u64 stime, utime;
 
 #define PRINTF(fmt, arg...) {			\
@@ -187,7 +188,7 @@ void print_delayacct(struct taskstats *t)
 	       "IO    %15s%15s\n"
 	       "      %15llu%15llu\n"
 	       "MEM   %15s%15s\n"
-	       "      %15llu%15llu\n\n",
+	       "      %15llu%15llu\n"
 	       "count", "real total", "virtual total", "delay total",
 	       t->cpu_count, t->cpu_run_real_total, t->cpu_run_virtual_total,
 	       t->cpu_delay_total,
@@ -196,6 +197,15 @@ void print_delayacct(struct taskstats *t)
 	       "count", "delay total", t->swapin_count, t->swapin_delay_total);
 }
 
+void print_taskstats(struct taskstats *t)
+{
+	printf("\n\nTask  %15s%15s%15s\n"
+	       "      %15lu%15lu%15lu\n",
+	       "syscalls", "voluntary", "nonvoluntary",
+	       t->syscall_counter, t->nvcsw, t->nivcsw);
+
+}
+
 void print_ioacct(struct taskstats *t)
 {
 	printf("%s: read=%llu, write=%llu, cancelled_write=%llu\n",
@@ -227,7 +237,7 @@ int main(int argc, char *argv[])
 	struct msgtemplate msg;
 
 	while (1) {
-		c = getopt(argc, argv, "diw:r:m:t:p:v:l");
+		c = getopt(argc, argv, "qdiw:r:m:t:p:v:l");
 		if (c < 0)
 			break;
 
@@ -240,6 +250,10 @@ int main(int argc, char *argv[])
 			printf("printing IO accounting\n");
 			print_io_accounting = 1;
 			break;
+		case 'q':
+			printf("printing task/process stasistics:\n");
+			print_task_stats = 1;
+			break;
 		case 'w':
 			strncpy(logfile, optarg, MAX_FILENAME);
 			printf("write to file %s\n", logfile);
@@ -381,6 +395,8 @@ int main(int argc, char *argv[])
 							print_delayacct((struct taskstats *) NLA_DATA(na));
 						if (print_io_accounting)
 							print_ioacct((struct taskstats *) NLA_DATA(na));
+						if (print_task_stats)
+							print_taskstats((struct taskstats *) NLA_DATA(na));
 						if (fd) {
 							if (write(fd, NLA_DATA(na), na->nla_len) < 0) {
 								err(1,"write error\n");
diff --git a/Documentation/accounting/taskstats-struct.txt b/Documentation/accounting/taskstats-struct.txt
index 661c797..5dac173 100644
--- a/Documentation/accounting/taskstats-struct.txt
+++ b/Documentation/accounting/taskstats-struct.txt
@@ -22,6 +22,8 @@ There are three different groups of fields in the struct taskstats:
     /* Extended accounting fields end */
     Their values are collected if CONFIG_TASK_XACCT is set.
 
+4) Per-task and per-thread statistics
+
 Future extension should add fields to the end of the taskstats struct, and
 should not change the relative position of each field within the struct.
 
@@ -158,4 +160,9 @@ struct taskstats {
 
 	/* Extended accounting fields end */
 
+4) Per-task and per-thread statiscits
+	__u32	syscall_counter;	/* Syscall counter */
+	__u32	nvcsw;			/* Context voluntary switch counter */
+	__u32	nivcsw;			/* Context involuntary switch counter */
+
 }
diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c
index 1b2f3cd..4ad49d2 100644
--- a/arch/i386/kernel/asm-offsets.c
+++ b/arch/i386/kernel/asm-offsets.c
@@ -56,6 +56,7 @@ void foo(void)
 	OFFSET(TI_addr_limit, thread_info, addr_limit);
 	OFFSET(TI_restart_block, thread_info, restart_block);
 	OFFSET(TI_sysenter_return, thread_info, sysenter_return);
+	OFFSET(TI_syscall_count, thread_info, syscall_count);
 	BLANK();
 
 	OFFSET(GDS_size, Xgt_desc_struct, size);
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 5e47683..836961f 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -332,6 +332,9 @@ sysenter_past_esp:
 	SAVE_ALL
 	GET_THREAD_INFO(%ebp)
 
+#ifdef CONFIG_TASKSTATS
+	incl	TI_syscall_count(%ebp)	# Increment syscalls counter
+#endif
 	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
 	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
 	jnz syscall_trace_entry
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 030d300..b640039 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -94,6 +94,8 @@ int main(void)
 	DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags));
 	DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
 	DEFINE(TI_TASK, offsetof(struct thread_info, task));
+	DEFINE(TI_SYSCALL_COUNT, offsetof(struct thread_info, syscall_count));
+
 #ifdef CONFIG_PPC32
 	DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
 	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index c03e829..5d919e4 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -202,6 +202,11 @@ _GLOBAL(DoSyscall)
 	bl	do_show_syscall
 #endif /* SHOW_SYSCALLS */
 	rlwinm	r10,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
+#ifdef CONFIG_TASKSTATS 
+	lwz r11,TI_SYSC_CNT(r10)
+	addi r11,r11,1
+	stw r11,TI_SYSC_CNT(r10)
+#endif
 	lwz	r11,TI_FLAGS(r10)
 	andi.	r11,r11,_TIF_SYSCALL_T_OR_A
 	bne-	syscall_dotrace
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2551c08..5907f76 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -115,6 +115,11 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 	addi	r9,r1,STACK_FRAME_OVERHEAD
 #endif
 	clrrdi	r11,r1,THREAD_SHIFT
+#ifdef CONFIG_TASKSTATS
+	ld r10,TI_SYSCALL_COUNT(r11)
+	addi r10,r10,1
+	std r10,TI_SYSCALL_COUNT(r11)
+#endif
 	ld	r10,TI_FLAGS(r11)
 	andi.	r11,r10,_TIF_SYSCALL_T_OR_A
 	bne-	syscall_dotrace
diff --git a/arch/x86_64/kernel/asm-offsets.c b/arch/x86_64/kernel/asm-offsets.c
index 96687e2..da57356 100644
--- a/arch/x86_64/kernel/asm-offsets.c
+++ b/arch/x86_64/kernel/asm-offsets.c
@@ -35,6 +35,7 @@ int main(void)
 	ENTRY(addr_limit);
 	ENTRY(preempt_count);
 	ENTRY(status);
+	ENTRY(syscall_count);
 	BLANK();
 #undef ENTRY
 #define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry))
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 9f5dac6..af40ead 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -229,6 +229,9 @@ ENTRY(system_call)
 	movq  %rcx,RIP-ARGOFFSET(%rsp)
 	CFI_REL_OFFSET rip,RIP-ARGOFFSET
 	GET_THREAD_INFO(%rcx)
+#ifdef CONFIG_TASKSTATS
+	addq $1, threadinfo_syscall_count(%rcx)   # Increment syscalls counter
+#endif
 	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
 	jnz tracesys
 	cmpq $__NR_syscall_max,%rax
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 70e4fab..30f6fd5 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -290,6 +290,19 @@ static inline char *task_cap(struct task_struct *p, char *buffer)
 			    cap_t(p->cap_permitted),
 			    cap_t(p->cap_effective));
 }
+static inline char *task_perf(struct task_struct *p, char *buffer)
+{
+	/* Syscall counter adds 1 line overhead on each syscall execution
+	 * in entry.S, so probably it is the leave this stuff under ifdefs.
+	 */
+#ifdef CONFIG_TASKSTATS
+	buffer += sprintf(buffer, "Syscalls:\t%lu\n", p->thread_info->syscall_count);
+#endif
+	return buffer + sprintf(buffer, "Nvcsw:\t%lu\n"
+                           "Nivcsw:\t%lu\n",
+                           p->nvcsw,
+                           p->nivcsw);
+}
 
 int proc_pid_status(struct task_struct *task, char * buffer)
 {
@@ -309,6 +322,7 @@ int proc_pid_status(struct task_struct *task, char * buffer)
 #if defined(CONFIG_S390)
 	buffer = task_show_regs(task, buffer);
 #endif
+	buffer = task_perf(task, buffer);
 	return buffer - orig;
 }
 
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index 4b187bb..bccfd6a 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -33,6 +33,7 @@ struct thread_info {
 	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 
 
+	unsigned long		syscall_count;	/* Syscall counter */
 	mm_segment_t		addr_limit;	/* thread address space:
 					 	   0-0xBFFFFFFF for user-thead
 						   0-0xFFFFFFFF for kernel-thread
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index 3f32ca8..5306ac2 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -35,6 +35,7 @@ struct thread_info {
 	int		cpu;			/* cpu we're on */
 	int		preempt_count;		/* 0 => preemptable,
 						   <0 => BUG */
+	unsigned long	syscall_count;		/* Syscall counter */
 	struct restart_block restart_block;
 	unsigned long	local_flags;		/* private flags for thread */
 
diff --git a/include/asm-x86_64/thread_info.h b/include/asm-x86_64/thread_info.h
index 74a6c74..e53022d 100644
--- a/include/asm-x86_64/thread_info.h
+++ b/include/asm-x86_64/thread_info.h
@@ -31,6 +31,7 @@ struct thread_info {
 	__u32			cpu;		/* current CPU */
 	int 			preempt_count;	/* 0 => preemptable, <0 => BUG */
 
+	unsigned long		syscall_count;	/* Syscall counter */
 	mm_segment_t		addr_limit;	
 	struct restart_block    restart_block;
 };
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h
index 3fced47..e3341b6 100644
--- a/include/linux/taskstats.h
+++ b/include/linux/taskstats.h
@@ -31,7 +31,7 @@
  */
 
 
-#define TASKSTATS_VERSION	3
+#define TASKSTATS_VERSION	4
 #define TS_COMM_LEN		32	/* should be >= TASK_COMM_LEN
 					 * in linux/sched.h */
 
@@ -141,6 +141,10 @@ struct taskstats {
 	__u64	write_syscalls;		/* write syscalls */
 	/* Extended accounting fields end */
 
+	__u32  syscall_counter;   /* Syscall counter */
+	__u32  nvcsw;
+	__u32  nivcsw;
+
 #define TASKSTATS_HAS_IO_ACCOUNTING
 	/* Per-task storage I/O accounting starts */
 	__u64	read_bytes;		/* bytes of read I/O */
diff --git a/kernel/fork.c b/kernel/fork.c
index fc723e5..5213738 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1042,6 +1042,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 	p->wchar = 0;		/* I/O counter: bytes written */
 	p->syscr = 0;		/* I/O counter: read syscalls */
 	p->syscw = 0;		/* I/O counter: write syscalls */
+#ifdef CONFIG_TASKSTATS
+	p->thread_info->syscall_count = 0; /* Syscall counter: total numbers of syscalls */
+#endif
 	task_io_accounting_init(p);
 	acct_clear_integrals(p);
 
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 4c3476f..d7bf33f 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -196,6 +196,9 @@ static int fill_pid(pid_t pid, struct task_struct *tsk,
 
 	/* fill in basic acct fields */
 	stats->version = TASKSTATS_VERSION;
+	stats->syscall_counter = tsk->thread_info->syscall_count;
+	stats->nvcsw = tsk->nvcsw;
+	stats->nivcsw = tsk->nivcsw;
 	bacct_add_tsk(stats, tsk);
 
 	/* fill in extended acct fields */
@@ -242,6 +245,9 @@ static int fill_tgid(pid_t tgid, struct task_struct *first,
 		 */
 		delayacct_add_tsk(stats, tsk);
 
+		stats->syscall_counter += tsk->thread_info->syscall_count;
+		stats->nvcsw += tsk->nvcsw;
+		stats->nivcsw += tsk->nivcsw;
 	} while_each_thread(first, tsk);
 
 	unlock_task_sighand(first, &flags);

^ permalink raw reply related

* Re: [PATCH 2/3] Add hard_irq_disable()
From: Josh Boyer @ 2007-05-10 11:01 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev, akpm, rusty, David Miller, linux-kernel
In-Reply-To: <1178789346.5575.2.camel@localhost.localdomain>

On Thu, 2007-05-10 at 19:29 +1000, Benjamin Herrenschmidt wrote:
> On Thu, 2007-05-10 at 01:53 -0700, David Miller wrote:
> > From: Andrew Morton <akpm@linux-foundation.org>
> > Date: Thu, 10 May 2007 01:50:36 -0700
> > 
> > > We discussed this a couple of months back.  davem landed firmly in the
> > > second camp and everyone then shut up ;)
> > 
> > No I landed in the first :-)))
> > 
> > I think the empty lines are a waste and only serve to eat
> > up precious screen real-estate when reading code.
> > 
> > It is possible that I used to use the empty line thing in
> > the past, but I definitely don't do that any more.
> 
> Yup, I used to do the other one too but nowadays, I much prefer not
> wasting that additional line unless specific circumstances, like I
> want a kind of "title" in front of a whole block of other definitions
> with their own comments.
> 
> Something like:
> 
> 
> /*
>  * foo management stuff
>  */
> 
> 
> /* This puts the bar in the foo
>  */
> code code code code
> 
> /* This does something you don't want to know about
>  */
> code code code code

Now your examples are just wrong.  One liners should be:

/* This puts the bar in the foo */

Are we having fun yet? ;)

/me goes to look for something better to do

josh

^ permalink raw reply

* RTC drift in PPC
From: pjmaiya @ 2007-05-10 11:16 UTC (permalink / raw)
  To: linuxppc-embedded

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

hi,
  We are running RTC on mpc860 board with external crystal. During boot we get date and time from h/w RTC chip and then it runs pn software tick, which is handled by kernel. We are getting 4 minutes drift for 21 hours. Can any one suggest, how to reduce the drift.

thnax in advance,
pjmaiya

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

^ permalink raw reply

* Re: [PATCH] Performance Stats: Kernel patch
From: Maxim Uvarov @ 2007-05-10 11:11 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linuxppc-dev, wli, pavel, dada1
In-Reply-To: <20070508123214.11b4f25c.akpm@linux-foundation.org>

Andrew Morton wrote:

>On Tue, 08 May 2007 16:26:51 +0000
>Maxim Uvarov <muvarov@ru.mvista.com> wrote:
>
>  
>
>>From: Maxim Uvarov <muvarov@ru.mvista.com>
>>To: Andrew Morton <akpm@linux-foundation.org>
>>Cc: pavel@ucw.cz
>>Cc: linuxppc-dev@ozlabs.org
>>Cc: wli@holomorphy.com
>>Cc: dada1@cosmosbay.com
>>Cc: pavel@ucw.cz
>>    
>>
>
>Strange that linux-ppc was the only mailing list you copied?
>
>  
>
Very strange. Possible stgit mail have limitation of CC.

>>Subject: [PATCH] Performance Stats: Kernel patch
>>Date: Tue, 08 May 2007 16:26:51 +0000
>>User-Agent: StGIT/0.12.1
>>
>>
>>Patch makes available to the user the following
>>task and process performance statistics:
>>	* Involuntary Context Switches (task_struct->nivcsw)
>>	* Voluntary Context Switches (task_struct->nvcsw)
>>	* Number of system calls (added new counter
>>	  thread_info->sysall_count)
>>	           
>>Statistics information is available from:
>>        1. taskstats interface (Documentation/accounting/)
>>	2. /proc/PID/status (task only).
>>
>>This data is useful for detecting hyperactivity
>>patterns between processes.
>>    
>>
>
>syscall entry is a super-hotpath and there will be a developer revolt
>if we go adding an incl to that path, sorry.
>
>  
>
Yes, I know that it is very critical part of code. May be protection with
ifdef CONFIG_TASKSTATS  in all entry.S can be solution?
In that case we can be sure that nothing wrong can not happen,
and if this functionality is needed we can turn on this.

>(Did that incl also cover the int 80 entry?)
>  
>
Actually not. But counter increments each time when syscall  calls.
But it is in very save place, just after
        SAVE_ALL
        GET_THREAD_INFO(%ebp)
So it is very hard to break something.

(I'm going to update patch.)

^ permalink raw reply

* Re: [PATCH] Performance Stats: Kernel patch
From: Maxim Uvarov @ 2007-05-10 10:22 UTC (permalink / raw)
  To: Linas Vepstas; +Cc: linuxppc-dev, Andrew Morton, pavel, wli, dada1
In-Reply-To: <20070508233200.GO4452@austin.ibm.com>

Linas Vepstas wrote:

>Hi,
>
>On Tue, May 08, 2007 at 04:26:51PM +0000, Maxim Uvarov wrote:
>  
>
>>Patch makes available to the user the following
>>task and process performance statistics:
>>    
>>
>
>[...]
>
>  
>
>>diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
>>index 5e47683..26f0cc0 100644
>>--- a/arch/i386/kernel/entry.S
>>+++ b/arch/i386/kernel/entry.S
>>@@ -331,6 +331,7 @@ sysenter_past_esp:
>> 	CFI_ADJUST_CFA_OFFSET 4
>> 	SAVE_ALL
>> 	GET_THREAD_INFO(%ebp)
>>+	incl	TI_syscall_count(%ebp)	# Increment syscalls counter
>>    
>>
>
>Other arches have this protected with #ifdef CONFIG_TASKSTATS
>why not here?
>
>  
>
Thank you. It should be protected.

>>diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
>>index c03e829..329c2f8 100644
>>--- a/arch/powerpc/kernel/entry_32.S
>>+++ b/arch/powerpc/kernel/entry_32.S
>>@@ -202,6 +202,11 @@ _GLOBAL(DoSyscall)
>> 	bl	do_show_syscall
>> #endif /* SHOW_SYSCALLS */
>> 	rlwinm	r10,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
>>+#ifdef CONFIG_THREAD_PERF_STAT_SYSC
>>+	lwz r11,TI_SYSC_CNT(r10)
>>+	addi r11,r11,1
>>+	stw r11,TI_SYSC_CNT(r10)
>>+#endif /* CONFIG_THREAD_PERF_STAT_SYSC */
>>    
>>
>
>Why not CONFIG_TASKSTATS, as in entry_64.S ?
>
>Actually, grep shows that CONFIG_THREAD_PERF_STAT_SYSC is not defined
>anywhere.
>
>  
>
This is mistake, thank you. I have to be more considerate.

>>diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
>>index 9f5dac6..9fd97df 100644
>>--- a/arch/x86_64/kernel/entry.S
>>+++ b/arch/x86_64/kernel/entry.S
>>@@ -229,6 +229,7 @@ ENTRY(system_call)
>> 	movq  %rcx,RIP-ARGOFFSET(%rsp)
>> 	CFI_REL_OFFSET rip,RIP-ARGOFFSET
>> 	GET_THREAD_INFO(%rcx)
>>+	addq $1, threadinfo_syscall_count(%rcx)   # Increment syscalls counter
>>    
>>
>
>again, #ifdef CONFIG_TASKSTATS,
>
>--linas
>  
>

In general I had the following idea. Defend with CONFIG_TASKSTATS all
syscall increment counters in  arch/*/entry.S  code.  It will allow to
avoid this overhead if task stats interface is not supported by kernel.
The overhead is too small but,  it is not needed to increment counters 
without interface
to get them.

In first version of patch I have used only /proc interface. And it is 
available now.
So I don't really sure if  defines are needed in  entry.S code. I tried 
to do
some tests and  it is impossible to catch the performance difference (small
overhead).

^ permalink raw reply

* Re: [PATCH] i2c: adds support for i2c bus on 8xx
From: Vitaly Bordug @ 2007-05-10 10:35 UTC (permalink / raw)
  To: Jean Delvare; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20070510112835.60fb1c2a@hyperion.delvare>

On Thu, 10 May 2007 11:28:35 +0200
Jean Delvare wrote:

> Hi Vitaly,
> 
> There is a mailing list dedicated to Linux I2C development (check
> MAINTAINERS), so why don't you use it instead of the already cluttered
> LKML?
> 
because it's both arch-specific and drivers/ thing. I'll Cc that ML next time.

> On Tue, 08 May 2007 10:31:31 +0400, Vitaly Bordug wrote:
> > Utilized devicetree to store I2C data, ported i2c-algo-8xx.c from
> > 2.4 approach(which remains nearly intact), refined i2c-rpx.c. I2C
> > functionality has been validated on mpc885ads with EEPROM access.
> > 
> > Interface has been reworked to of_device as well as other feedback
> > addressed. Repeated start ability is missing from the
> > implementation.
> 
> Did you check the hardware documentation? Is is a hardware limitation?
> It is likely to cause problems, so it should be investigated, and if
> it really cannot be fixed, then this must be clearly documented (in
> Kconfig and in the driver) and the advertised functionalities  of the
> driver should be reduced accordingly (most SMBus transactions include
> a repeated start.)
> 
Yes, I've checked RM about I2C controller, and cannot find anything about repeated
start. There are a few words about multi-master considerations, that SoC features bus arbitration,
but to avoid collisions, "higher-level handshake protocol must be used" (MPC885 RM, p. 32-6).

How the driver should advertise this case, can you suggest?

> > 
> > Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
> > 
> > ---
> > 
> >  arch/powerpc/platforms/8xx/mpc885ads_setup.c |   15 +
> >  arch/powerpc/sysdev/fsl_soc.c                |   15 +
> >  drivers/i2c/algos/Kconfig                    |    2 
> >  drivers/i2c/algos/Makefile                   |    1 
> >  drivers/i2c/algos/i2c-algo-8xx.c             |  520
> > ++++++++++++++++++++++++++
> > drivers/i2c/busses/Kconfig                   |    2
> > drivers/i2c/busses/i2c-rpx.c                 |  143 +++++--
> > include/linux/i2c-algo-8xx.h                 |   29 + 8 files
> > changed, 683 insertions(+), 44 deletions(-)
> 
> After my original review, we had agreed that having a separate
> algorithm driver wasn't needed. You didn't change that though. Why? I
> will not consider applying this patch until that change is done (or a
> good reason not to do it is given.)
> 

yes, that's correct, missed this point...

> > diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
> > b/arch/powerpc/platforms/8xx/mpc885ads_setup.c index
> > a57b577..40d12a2 100644 ---
> > a/arch/powerpc/platforms/8xx/mpc885ads_setup.c +++
> > b/arch/powerpc/platforms/8xx/mpc885ads_setup.c @@ -51,6 +51,17 @@
> > static void init_smc1_uart_ioports(struct fs_uart_platform_info*
> > fpi); static void init_smc2_uart_ioports(struct
> > fs_uart_platform_info* fpi); static void init_scc3_ioports(struct
> > fs_platform_info* ptr); +#ifdef CONFIG_I2C_RPXLITE
> > +static void init_i2c_ioports()
> > +{
> > +	cpm8xx_t *cp = (cpm8xx_t *)immr_map(im_cpm);
> > +
> > +	setbits32(&cp->cp_pbpar, 0x00000030);
> > +	setbits32(&cp->cp_pbdir, 0x00000030);
> > +	setbits16(&cp->cp_pbodr, 0x0030);
> > +}
> > +#endif
> > +
> >  void __init mpc885ads_board_setup(void)
> >  {
> >  	cpm8xx_t *cp;
> > @@ -115,6 +126,10 @@ void __init mpc885ads_board_setup(void)
> >  	immr_unmap(io_port);
> >  
> >  #endif
> > +
> > +#ifdef CONFIG_I2C_RPXLITE
> > +	init_i2c_ioports();
> > +#endif
> >  }
> >  
> >  
> > diff --git a/arch/powerpc/sysdev/fsl_soc.c
> > b/arch/powerpc/sysdev/fsl_soc.c index 8a123c7..be60db7 100644
> > --- a/arch/powerpc/sysdev/fsl_soc.c
> > +++ b/arch/powerpc/sysdev/fsl_soc.c
> > @@ -33,6 +33,7 @@
> >  #include <asm/irq.h>
> >  #include <asm/time.h>
> >  #include <asm/prom.h>
> > +#include <asm/of_platform.h>
> >  #include <sysdev/fsl_soc.h>
> >  #include <mm/mmu_decl.h>
> >  #include <asm/cpm2.h>
> > @@ -1102,4 +1103,18 @@ err:
> >  
> >  arch_initcall(cpm_smc_uart_of_init);
> >  
> > +static int __init fsl_i2c_cpm_of_init(void)
> > +{
> > +	struct device_node *np = NULL;
> > +	/*
> > +	 * Register all the devices which type is "i2c-cpm"
> > +	 */
> > +	while ((np = of_find_compatible_node(np, "i2c",
> > "fsl,i2c-cpm")) != NULL)
> > +		of_platform_device_create(np, "fsl-i2c-cpm", NULL);
> > +	return 0;
> > +}
> > +
> > +arch_initcall(fsl_i2c_cpm_of_init);
> > +
> > +
> >  #endif /* CONFIG_8xx */
> > diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig
> > index af02034..11e37ff 100644
> > --- a/drivers/i2c/algos/Kconfig
> > +++ b/drivers/i2c/algos/Kconfig
> > @@ -41,6 +41,8 @@ config I2C_ALGOPCA
> >  config I2C_ALGO8XX
> >  	tristate "MPC8xx CPM I2C interface"
> >  	depends on 8xx && I2C
> > +	help
> > +	  8xx I2C Algorithm,supports the CPM I2C interface for
> > mpc8xx CPUs. 
> >  config I2C_ALGO_SGI
> >  	tristate "I2C SGI interfaces"
> > diff --git a/drivers/i2c/algos/Makefile b/drivers/i2c/algos/Makefile
> > index cac1051..1bd3b37 100644
> > --- a/drivers/i2c/algos/Makefile
> > +++ b/drivers/i2c/algos/Makefile
> > @@ -6,6 +6,7 @@ obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
> >  obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
> >  obj-$(CONFIG_I2C_ALGOPCA)	+= i2c-algo-pca.o
> >  obj-$(CONFIG_I2C_ALGO_SGI)	+= i2c-algo-sgi.o
> > +obj-$(CONFIG_I2C_ALGO8XX)	+= i2c-algo-8xx.o
> >  
> >  ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
> >  EXTRA_CFLAGS += -DDEBUG
> > diff --git a/drivers/i2c/algos/i2c-algo-8xx.c
> > b/drivers/i2c/algos/i2c-algo-8xx.c new file mode 100644
> > index 0000000..01ffcee
> > --- /dev/null
> > +++ b/drivers/i2c/algos/i2c-algo-8xx.c
> > @@ -0,0 +1,520 @@
> > +/*
> > + * i2c-algo-8xx.c i2x driver algorithms for MPC8XX CPM
> > + * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
> > + *
> > +    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., 675 Mass Ave, Cambridge, MA 02139, USA.
> > + *
> > + * moved into proper i2c interface; separated out platform specific
> > + * parts into i2c-rpx.c
> > + * Brad Parker (brad@heeltoe.com)
> > + * 
> > + * (C) 2007 Montavista Software, Inc.
> > + * Vitaly Bordug <vitb@kernel.crashing.org>
> > + */
> > +
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/delay.h>
> > +#include <linux/slab.h>
> > +#include <linux/init.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/errno.h>
> > +#include <linux/sched.h>
> > +#include <linux/i2c.h>
> > +#include <linux/i2c-algo-8xx.h>
> > +#include <asm/io.h>
> > +#include <asm/cacheflush.h>
> > +#include <asm/time.h>
> > +#include <asm/mpc8xx.h>
> > +
> > +/* Try to define this if you have an older CPU (earlier than rev
> > D4) */ +#undef	I2C_CHIP_ERRATA
> > +
> > +static wait_queue_head_t iic_wait;
> > +static ushort r_tbase, r_rbase;
> > +
> > +static int cpm_debug;
> > +
> > +static irqreturn_t cpm_iic_interrupt(int irq, void *dev_id)
> > +{
> > +	i2c8xx_t *i2c = (i2c8xx_t *) dev_id;
> > +
> > +#if 0
> > +	/* Chip errata, clear enable. This is not needed on rev D4
> > CPUs */
> > +	/* This should probably be removed and replaced by
> > I2C_CHIP_ERRATA stuff */
> > +	/* Someone with a buggy CPU needs to confirm that */
> > +	out_8(&i2c->i2c_i2mod, in_8(&i2c->i2c_i2mod) | ~1);
> > +#endif
> > +	/* Clear interrupt.
> > +	 */
> > +	out_8(&i2c->i2c_i2cer, 0xff);
> > +
> > +	/* Get 'me going again.
> > +	 */
> > +	wake_up_interruptible(&iic_wait);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static int cpm_iic_init(struct i2c_adapter *adap)
> > +{
> > +	struct i2c_algo_8xx_data *cpm = adap->algo_data;
> > +	iic_t *iip = cpm->iip;
> > +	i2c8xx_t *i2c = cpm->i2c;
> > +	unsigned char brg;
> > +
> > +	if (cpm_debug)
> > +		dev_dbg(adap->dev, "cpm_iic_init()\n");
> 
> Should be "&adap->dev". Same for all other calls. This means you never
> tried to compile your code with debugging enabled. Please do (there
> are options in the I2C Support menu for this.)
> 
OK

> > +
> > +	init_waitqueue_head(&iic_wait);
> > +
> > +	/* Initialize the parameter ram.
> > +	 * We need to make sure many things are initialized to
> > zero,
> > +	 * especially in the case of a microcode patch.
> > +	 */
> > +	iip->iic_rstate = 0;
> > +	iip->iic_rdp = 0;
> > +	iip->iic_rbptr = 0;
> > +	iip->iic_rbc = 0;
> > +	iip->iic_rxtmp = 0;
> > +	iip->iic_tstate = 0;
> > +	iip->iic_tdp = 0;
> > +	iip->iic_tbptr = 0;
> > +	iip->iic_tbc = 0;
> > +	iip->iic_txtmp = 0;
> > +
> > +	/* Set up the IIC parameters in the parameter ram.
> > +	 */
> > +	iip->iic_tbase = r_tbase = cpm->dp_addr;
> > +	iip->iic_rbase = r_rbase = cpm->dp_addr + sizeof(cbd_t) *
> > 2; +
> > +	if (cpm_debug) {
> > +		dev_dbg(adap->dev, "iip %p, dp_addr 0x%x\n",
> > cpm->iip,
> > +			cpm->dp_addr);
> > +		dev_dbg(adap->dev, "iic_tbase %d, r_tbase %d\n",
> > iip->iic_tbase,
> > +			r_tbase);
> > +	}
> > +
> > +	iip->iic_tfcr = SMC_EB;
> > +	iip->iic_rfcr = SMC_EB;
> > +
> > +	/* Set maximum receive size.
> > +	 */
> > +	iip->iic_mrblr = CPM_MAX_READ;
> > +
> > +	/* Initialize Tx/Rx parameters.
> > +	 */
> > +	if (cpm->reloc == 0) {
> > +		cpm8xx_t *cp = cpm->cp;
> > +		int res;
> > +
> > +		u16 v = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX)
> > | CPM_CR_FLG; +
> > +		out_be16(&cp->cp_cpcr, v);
> > +		res = wait_event_timeout(iic_wait,
> > +					 !(in_be16(&cp->cp_cpcr) &
> > CPM_CR_FLG),
> > +					 HZ * 10);
> 
> This is a pretty long timeout. Can it realistically take that long?
> 
In fact, it can. Especially when CPM is loaded with Ethernet/UART/Etc transactions. If you feel it is overkill
and I2C shouldn't do that, I'll trim it down though.

> > +		if (!res)
> > +			return -EIO;
> > +
> > +	} else {
> > +		iip->iic_rbptr = iip->iic_rbase;
> > +		iip->iic_tbptr = iip->iic_tbase;
> > +		iip->iic_rstate = 0;
> > +		iip->iic_tstate = 0;
> > +	}
> > +
> > +	/* Select an arbitrary address.  Just make sure it is
> > unique.
> > +	 */
> > +	out_8(&i2c->i2c_i2add, 0xfe);
> > +
> > +	/* Make clock run at 60 kHz.
> > +	 */
> > +	brg = ppc_proc_freq / (32 * 2 * 60000) - 3;
> > +	out_8(&i2c->i2c_i2brg, brg);
> > +
> > +	out_8(&i2c->i2c_i2mod, 0x00);
> > +	out_8(&i2c->i2c_i2com, 0x01);	/* Master mode */
> > +
> > +	/* Disable interrupts.
> > +	 */
> > +	out_8(&i2c->i2c_i2cmr, 0);
> > +	out_8(&i2c->i2c_i2cer, 0xff);
> > +
> > +	/* Install interrupt handler.
> > +	 */
> > +	request_irq(cpm->irq, cpm_iic_interrupt, 0, "8xx_i2c",
> > i2c); +
> > +	return 0;
> > +}
> > +
> > +static int cpm_iic_shutdown(struct i2c_algo_8xx_data *cpm)
> > +{
> > +	i2c8xx_t *i2c = cpm->i2c;
> > +
> > +	/* Shut down IIC.
> > +	 */
> > +	out_8(&i2c->i2c_i2mod, in_8(&i2c->i2c_i2mod) | ~1);
> > +	out_8(&i2c->i2c_i2cmr, 0);
> > +	out_8(&i2c->i2c_i2cer, 0xff);
> > +
> > +	return (0);
> > +}
> 
> Should return void, it cannot fail.
> 
OK
> > +
> > +static void cpm_reset_iic_params(iic_t * iip)
> > +{
> > +	iip->iic_tbase = r_tbase;
> > +	iip->iic_rbase = r_rbase;
> > +
> > +	iip->iic_tfcr = SMC_EB;
> > +	iip->iic_rfcr = SMC_EB;
> > +
> > +	iip->iic_mrblr = CPM_MAX_READ;
> > +
> > +	iip->iic_rstate = 0;
> > +	iip->iic_rdp = 0;
> > +	iip->iic_rbptr = iip->iic_rbase;
> > +	iip->iic_rbc = 0;
> > +	iip->iic_rxtmp = 0;
> > +	iip->iic_tstate = 0;
> > +	iip->iic_tdp = 0;
> > +	iip->iic_tbptr = iip->iic_tbase;
> > +	iip->iic_tbc = 0;
> > +	iip->iic_txtmp = 0;
> > +}
> > +
> > +#define BD_SC_NAK		((ushort)0x0004)	/* NAK -
> > did not respond */ +#define BD_SC_OV
> > ((ushort)0x0002)	/* OV - receive overrun */ +#define
> > CPM_CR_CLOSE_RXBD	((ushort)0x0007) +
> > +static void force_close(struct i2c_adapter *adap)
> > +{
> > +	struct i2c_algo_8xx_data *cpm = adap->algo_data;
> > +	i2c8xx_t *i2c = cpm->i2c;
> > +	if (cpm->reloc == 0) {	/* micro code disabled */
> > +		cpm8xx_t *cp = cpm->cp;
> > +		u16 v =
> > +		    mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_CLOSE_RXBD) |
> > CPM_CR_FLG; +
> > +		if (cpm_debug)
> > +			printk("force_close()\n");
> > +
> > +		out_be16(&cp->cp_cpcr, v);
> > +		wait_event_timeout(iic_wait,
> > +				   !(in_be16(&cp->cp_cpcr) &
> > CPM_CR_FLG),
> > +				   HZ * 5);
> > +	}
> > +	out_8(&i2c->i2c_i2cmr, 0x00);	/* Disable all
> > interrupts */
> > +	out_8(&i2c->i2c_i2cer, 0xff);
> > +}
> > +
> > +/* Read from IIC...
> > + * abyte = address byte, with r/w flag already set
> > + */
> > +static int
> > +cpm_iic_read(struct i2c_adapter *adap, u_char abyte, char *buf,
> > int count) +{
> > +	struct i2c_algo_8xx_data *cpm = adap->algo_data;
> > +	iic_t *iip = cpm->iip;
> > +	i2c8xx_t *i2c = cpm->i2c;
> > +	cbd_t *tbdf, *rbdf;
> > +	u_char *tb;
> > +	int res = 0;
> > +
> > +	if (count >= CPM_MAX_READ)
> > +		return -EINVAL;
> > +
> > +	/* check for and use a microcode relocation patch */
> > +	if (cpm->reloc) {
> > +		cpm_reset_iic_params(iip);
> > +	}
> > +
> > +	tbdf = (cbd_t *) cpm_dpram_addr(iip->iic_tbase);
> > +	rbdf = (cbd_t *) cpm_dpram_addr(iip->iic_rbase);
> > +
> > +	/* To read, we need an empty buffer of the proper length.
> > +	 * All that is used is the first byte for address, the
> > remainder
> > +	 * is just used for timing (and doesn't really have to
> > exist).
> > +	 */
> > +	tb = cpm->temp;
> > +	tb = (u_char *) (((uint) tb + 15) & ~15);
> > +	tb[0] = abyte;		/* Device address byte w/rw
> > flag */ +
> > +	flush_dcache_range((unsigned long)tb, (unsigned long)(tb +
> > 1)); +
> > +	if (cpm_debug)
> > +		dev_dbg(adap->dev, "cpm_iic_read(abyte=0x%x)\n",
> > abyte); +
> > +	tbdf->cbd_bufaddr = __pa(tb);
> > +	tbdf->cbd_datlen = count + 1;
> > +	tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP |
> > BD_IIC_START; +
> > +	iip->iic_mrblr = count + 1;	/* prevent excessive
> > read, +1
> > +					   is needed otherwise
> > will the
> > +					   RXB interrupt come too
> > early */ +
> > +	/* flush will invalidate too. */
> > +	flush_dcache_range((unsigned long)buf, (unsigned long)(buf
> > + count)); +
> > +	rbdf->cbd_datlen = 0;
> > +	rbdf->cbd_bufaddr = __pa(buf);
> > +	rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP | BD_SC_INTRPT;
> > +
> > +	/* Chip bug, set enable here */
> > +	out_8(&i2c->i2c_i2cmr, 0x13);	/* Enable some
> > interupts */
> > +	out_8(&i2c->i2c_i2cer, 0xff);
> > +	out_8(&i2c->i2c_i2mod, in_8(&i2c->i2c_i2mod) |
> > 1);	/* Enable */
> > +	out_8(&i2c->i2c_i2com, in_8(&i2c->i2c_i2com) |
> > 0x80);	/* Begin transmission */ +
> > +	/* Wait for IIC transfer */
> > +	res = wait_event_interruptible_timeout(iic_wait, 0, 1 *
> > HZ); +
> > +	if (res < 0) {
> 
> The usual style is no blank line between the action and the test.
> 
OK

[snip]
> > pmsg->len,
> > +				(unsigned long)pmsg->buf);
> > +
> > +		addr = pmsg->addr << 1;
> > +		if (pmsg->flags & I2C_M_RD)
> > +			addr |= 1;
> > +		if (pmsg->flags & I2C_M_REV_DIR_ADDR)
> > +			addr ^= 1;
> 
> You didn't drop this?
> 
Correct, missed the cleanup.
> > +
> > +		if (pmsg->flags & I2C_M_RD) {
> > +			/* read bytes into buffer */
> > +			ret = cpm_iic_read(adap, addr, pmsg->buf,
> > pmsg->len);
> > +			if (cpm_debug)
> > +				dev_dbg(adap->dev,
> > +					"i2c-algo-8xx.o: read %d
> > bytes\n", ret);
> > +			if (ret < pmsg->len) {
> > +				return (ret < 0) ? ret :
> > -EREMOTEIO;
> > +			}
> > +		} else {
> > +			/* write bytes from buffer */
> > +			ret = cpm_iic_write(adap, addr, pmsg->buf,
> > pmsg->len);
> > +			if (cpm_debug)
> > +				dev_dbg(adap->dev,
> > "i2c-algo-8xx.o: wrote %d\n",
> > +					ret);
> > +			if (ret < pmsg->len) {
> > +				return (ret < 0) ? ret :
> > -EREMOTEIO;
> > +			}
> > +		}
> > +	}
> > +	return (num);
> 
> Useless parentheses.
> 
yeah...
> > +}
> > +
> > +static u32 cpm_func(struct i2c_adapter *adap)
> > +{
> > +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
> > +}
> > +
> > +/* -----exported algorithm data:
> > -------------------------------------	*/ +
> > +static struct i2c_algorithm cpm_algo = {
> > +	.master_xfer = cpm_xfer,
> > +	.functionality = cpm_func,
> > +};
> > +
> > +/*
> > + * registering functions to load algorithms at runtime
> > + */
> > +int i2c_8xx_add_bus(struct i2c_adapter *adap)
> > +{
> > +	int res;
> > +
> > +	if (cpm_debug)
> > +		dev_dbg(adap->dev,
> > +			"i2c-algo-8xx.o: hw routines for %s
> > registered.\n",
> > +			adap->name);
> > +
> > +	/* register new adapter to i2c module... */
> > +
> > +	adap->algo = &cpm_algo;
> > +
> > +	res = cpm_iic_init(adap);
> > +
> > +	if (res)
> > +		return res;
> > +
> > +	return i2c_add_adapter(adap);
> > +}
> > +
> > +int i2c_8xx_del_bus(struct i2c_adapter *adap)
> > +{
> > +	struct i2c_algo_8xx_data *cpm = adap->algo_data;
> > +
> > +	i2c_del_adapter(adap);
> > +
> > +	return cpm_iic_shutdown(cpm);
> > +}
> 
> Should return void.
> 
OK.
> > +
> > +EXPORT_SYMBOL(i2c_8xx_add_bus);
> > +EXPORT_SYMBOL(i2c_8xx_del_bus);
> > +
> > +MODULE_AUTHOR("Brad Parker <brad@heeltoe.com>");
> > +MODULE_DESCRIPTION("I2C-Bus MPC8XX algorithm");
> > +MODULE_LICENSE("GPL");
> > diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
> > index ece31d2..df29fb5 100644
> > --- a/drivers/i2c/busses/Kconfig
> > +++ b/drivers/i2c/busses/Kconfig
> > @@ -365,7 +365,7 @@ config I2C_PROSAVAGE
> >  
> >  config I2C_RPXLITE
> >  	tristate "Embedded Planet RPX Lite/Classic support"
> > -	depends on (RPXLITE || RPXCLASSIC) && I2C
> > +	depends on (RPXLITE || RPXCLASSIC || MPC86XADS ||
> > MPC885ADS) && I2C select I2C_ALGO8XX
> 
> A recent change to the i2c Kconfig files make it no longer needed to
> have all options depend on I2C explicitly. When you regenerate your
> patch on top of Linus' latest tree, you'll have to update this.
> 
> The help text for this option is still missing.
> 

OK, good point.
> >  
[snip]
> Question: once this is merged, will we possibly get rid of
> arch/ppc/boot/simple/iic.c?
> 
yes of course. In fact, this layer being obsoleted by powerpc works,
and may be broken in numerous ways (I am regularly asked why make fail somewhere in arch/ppc/boot,
and common ans is just to use uImage that does not compile this part).

There still may be boards that neither have u-boot as firmware, nor able to update what's existing. I think
declare stuff as feature to be removed would be enough for concerned folks to react. 
OTOH, there's good chance that nobody will even care :)


-- 
Sincerely, Vitaly

^ permalink raw reply

* Re: [PATCH 2/3] Add hard_irq_disable()
From: Benjamin Herrenschmidt @ 2007-05-10  9:29 UTC (permalink / raw)
  To: David Miller; +Cc: linuxppc-dev, akpm, rusty, linux-kernel
In-Reply-To: <20070510.015328.104645983.davem@davemloft.net>

On Thu, 2007-05-10 at 01:53 -0700, David Miller wrote:
> From: Andrew Morton <akpm@linux-foundation.org>
> Date: Thu, 10 May 2007 01:50:36 -0700
> 
> > We discussed this a couple of months back.  davem landed firmly in the
> > second camp and everyone then shut up ;)
> 
> No I landed in the first :-)))
> 
> I think the empty lines are a waste and only serve to eat
> up precious screen real-estate when reading code.
> 
> It is possible that I used to use the empty line thing in
> the past, but I definitely don't do that any more.

Yup, I used to do the other one too but nowadays, I much prefer not
wasting that additional line unless specific circumstances, like I
want a kind of "title" in front of a whole block of other definitions
with their own comments.

Something like:


/*
 * foo management stuff
 */


/* This puts the bar in the foo
 */
code code code code

/* This does something you don't want to know about
 */
code code code code


But does it realy matter that much ? :-)

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH] i2c: adds support for i2c bus on 8xx
From: Jean Delvare @ 2007-05-10  9:28 UTC (permalink / raw)
  To: Vitaly Bordug; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20070508063131.19179.47548.stgit@localhost.localdomain>

Hi Vitaly,

There is a mailing list dedicated to Linux I2C development (check
MAINTAINERS), so why don't you use it instead of the already cluttered
LKML?

On Tue, 08 May 2007 10:31:31 +0400, Vitaly Bordug wrote:
> Utilized devicetree to store I2C data, ported i2c-algo-8xx.c from 2.4
> approach(which remains nearly intact), refined i2c-rpx.c. I2C functionality
> has been validated on mpc885ads with EEPROM access.
> 
> Interface has been reworked to of_device as well as other feedback
> addressed. Repeated start ability is missing from the implementation.

Did you check the hardware documentation? Is is a hardware limitation?
It is likely to cause problems, so it should be investigated, and if it
really cannot be fixed, then this must be clearly documented (in
Kconfig and in the driver) and the advertised functionalities  of the
driver should be reduced accordingly (most SMBus transactions include a
repeated start.)

> 
> Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
> 
> ---
> 
>  arch/powerpc/platforms/8xx/mpc885ads_setup.c |   15 +
>  arch/powerpc/sysdev/fsl_soc.c                |   15 +
>  drivers/i2c/algos/Kconfig                    |    2 
>  drivers/i2c/algos/Makefile                   |    1 
>  drivers/i2c/algos/i2c-algo-8xx.c             |  520 ++++++++++++++++++++++++++
>  drivers/i2c/busses/Kconfig                   |    2 
>  drivers/i2c/busses/i2c-rpx.c                 |  143 +++++--
>  include/linux/i2c-algo-8xx.h                 |   29 +
>  8 files changed, 683 insertions(+), 44 deletions(-)

After my original review, we had agreed that having a separate
algorithm driver wasn't needed. You didn't change that though. Why? I
will not consider applying this patch until that change is done (or a
good reason not to do it is given.)

> diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
> index a57b577..40d12a2 100644
> --- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
> +++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
> @@ -51,6 +51,17 @@ static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi);
>  static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi);
>  static void init_scc3_ioports(struct fs_platform_info* ptr);
>  
> +#ifdef CONFIG_I2C_RPXLITE
> +static void init_i2c_ioports()
> +{
> +	cpm8xx_t *cp = (cpm8xx_t *)immr_map(im_cpm);
> +
> +	setbits32(&cp->cp_pbpar, 0x00000030);
> +	setbits32(&cp->cp_pbdir, 0x00000030);
> +	setbits16(&cp->cp_pbodr, 0x0030);
> +}
> +#endif
> +
>  void __init mpc885ads_board_setup(void)
>  {
>  	cpm8xx_t *cp;
> @@ -115,6 +126,10 @@ void __init mpc885ads_board_setup(void)
>  	immr_unmap(io_port);
>  
>  #endif
> +
> +#ifdef CONFIG_I2C_RPXLITE
> +	init_i2c_ioports();
> +#endif
>  }
>  
>  
> diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
> index 8a123c7..be60db7 100644
> --- a/arch/powerpc/sysdev/fsl_soc.c
> +++ b/arch/powerpc/sysdev/fsl_soc.c
> @@ -33,6 +33,7 @@
>  #include <asm/irq.h>
>  #include <asm/time.h>
>  #include <asm/prom.h>
> +#include <asm/of_platform.h>
>  #include <sysdev/fsl_soc.h>
>  #include <mm/mmu_decl.h>
>  #include <asm/cpm2.h>
> @@ -1102,4 +1103,18 @@ err:
>  
>  arch_initcall(cpm_smc_uart_of_init);
>  
> +static int __init fsl_i2c_cpm_of_init(void)
> +{
> +	struct device_node *np = NULL;
> +	/*
> +	 * Register all the devices which type is "i2c-cpm"
> +	 */
> +	while ((np = of_find_compatible_node(np, "i2c", "fsl,i2c-cpm")) != NULL)
> +		of_platform_device_create(np, "fsl-i2c-cpm", NULL);
> +	return 0;
> +}
> +
> +arch_initcall(fsl_i2c_cpm_of_init);
> +
> +
>  #endif /* CONFIG_8xx */
> diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig
> index af02034..11e37ff 100644
> --- a/drivers/i2c/algos/Kconfig
> +++ b/drivers/i2c/algos/Kconfig
> @@ -41,6 +41,8 @@ config I2C_ALGOPCA
>  config I2C_ALGO8XX
>  	tristate "MPC8xx CPM I2C interface"
>  	depends on 8xx && I2C
> +	help
> +	  8xx I2C Algorithm,supports the CPM I2C interface for mpc8xx CPUs.
>  
>  config I2C_ALGO_SGI
>  	tristate "I2C SGI interfaces"
> diff --git a/drivers/i2c/algos/Makefile b/drivers/i2c/algos/Makefile
> index cac1051..1bd3b37 100644
> --- a/drivers/i2c/algos/Makefile
> +++ b/drivers/i2c/algos/Makefile
> @@ -6,6 +6,7 @@ obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
>  obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
>  obj-$(CONFIG_I2C_ALGOPCA)	+= i2c-algo-pca.o
>  obj-$(CONFIG_I2C_ALGO_SGI)	+= i2c-algo-sgi.o
> +obj-$(CONFIG_I2C_ALGO8XX)	+= i2c-algo-8xx.o
>  
>  ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
>  EXTRA_CFLAGS += -DDEBUG
> diff --git a/drivers/i2c/algos/i2c-algo-8xx.c b/drivers/i2c/algos/i2c-algo-8xx.c
> new file mode 100644
> index 0000000..01ffcee
> --- /dev/null
> +++ b/drivers/i2c/algos/i2c-algo-8xx.c
> @@ -0,0 +1,520 @@
> +/*
> + * i2c-algo-8xx.c i2x driver algorithms for MPC8XX CPM
> + * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
> + *
> +    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., 675 Mass Ave, Cambridge, MA 02139, USA.
> + *
> + * moved into proper i2c interface; separated out platform specific
> + * parts into i2c-rpx.c
> + * Brad Parker (brad@heeltoe.com)
> + * 
> + * (C) 2007 Montavista Software, Inc.
> + * Vitaly Bordug <vitb@kernel.crashing.org>
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/delay.h>
> +#include <linux/slab.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/errno.h>
> +#include <linux/sched.h>
> +#include <linux/i2c.h>
> +#include <linux/i2c-algo-8xx.h>
> +#include <asm/io.h>
> +#include <asm/cacheflush.h>
> +#include <asm/time.h>
> +#include <asm/mpc8xx.h>
> +
> +/* Try to define this if you have an older CPU (earlier than rev D4) */
> +#undef	I2C_CHIP_ERRATA
> +
> +static wait_queue_head_t iic_wait;
> +static ushort r_tbase, r_rbase;
> +
> +static int cpm_debug;
> +
> +static irqreturn_t cpm_iic_interrupt(int irq, void *dev_id)
> +{
> +	i2c8xx_t *i2c = (i2c8xx_t *) dev_id;
> +
> +#if 0
> +	/* Chip errata, clear enable. This is not needed on rev D4 CPUs */
> +	/* This should probably be removed and replaced by I2C_CHIP_ERRATA stuff */
> +	/* Someone with a buggy CPU needs to confirm that */
> +	out_8(&i2c->i2c_i2mod, in_8(&i2c->i2c_i2mod) | ~1);
> +#endif
> +	/* Clear interrupt.
> +	 */
> +	out_8(&i2c->i2c_i2cer, 0xff);
> +
> +	/* Get 'me going again.
> +	 */
> +	wake_up_interruptible(&iic_wait);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int cpm_iic_init(struct i2c_adapter *adap)
> +{
> +	struct i2c_algo_8xx_data *cpm = adap->algo_data;
> +	iic_t *iip = cpm->iip;
> +	i2c8xx_t *i2c = cpm->i2c;
> +	unsigned char brg;
> +
> +	if (cpm_debug)
> +		dev_dbg(adap->dev, "cpm_iic_init()\n");

Should be "&adap->dev". Same for all other calls. This means you never
tried to compile your code with debugging enabled. Please do (there are
options in the I2C Support menu for this.)

> +
> +	init_waitqueue_head(&iic_wait);
> +
> +	/* Initialize the parameter ram.
> +	 * We need to make sure many things are initialized to zero,
> +	 * especially in the case of a microcode patch.
> +	 */
> +	iip->iic_rstate = 0;
> +	iip->iic_rdp = 0;
> +	iip->iic_rbptr = 0;
> +	iip->iic_rbc = 0;
> +	iip->iic_rxtmp = 0;
> +	iip->iic_tstate = 0;
> +	iip->iic_tdp = 0;
> +	iip->iic_tbptr = 0;
> +	iip->iic_tbc = 0;
> +	iip->iic_txtmp = 0;
> +
> +	/* Set up the IIC parameters in the parameter ram.
> +	 */
> +	iip->iic_tbase = r_tbase = cpm->dp_addr;
> +	iip->iic_rbase = r_rbase = cpm->dp_addr + sizeof(cbd_t) * 2;
> +
> +	if (cpm_debug) {
> +		dev_dbg(adap->dev, "iip %p, dp_addr 0x%x\n", cpm->iip,
> +			cpm->dp_addr);
> +		dev_dbg(adap->dev, "iic_tbase %d, r_tbase %d\n", iip->iic_tbase,
> +			r_tbase);
> +	}
> +
> +	iip->iic_tfcr = SMC_EB;
> +	iip->iic_rfcr = SMC_EB;
> +
> +	/* Set maximum receive size.
> +	 */
> +	iip->iic_mrblr = CPM_MAX_READ;
> +
> +	/* Initialize Tx/Rx parameters.
> +	 */
> +	if (cpm->reloc == 0) {
> +		cpm8xx_t *cp = cpm->cp;
> +		int res;
> +
> +		u16 v = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
> +
> +		out_be16(&cp->cp_cpcr, v);
> +		res = wait_event_timeout(iic_wait,
> +					 !(in_be16(&cp->cp_cpcr) & CPM_CR_FLG),
> +					 HZ * 10);

This is a pretty long timeout. Can it realistically take that long?

> +		if (!res)
> +			return -EIO;
> +
> +	} else {
> +		iip->iic_rbptr = iip->iic_rbase;
> +		iip->iic_tbptr = iip->iic_tbase;
> +		iip->iic_rstate = 0;
> +		iip->iic_tstate = 0;
> +	}
> +
> +	/* Select an arbitrary address.  Just make sure it is unique.
> +	 */
> +	out_8(&i2c->i2c_i2add, 0xfe);
> +
> +	/* Make clock run at 60 kHz.
> +	 */
> +	brg = ppc_proc_freq / (32 * 2 * 60000) - 3;
> +	out_8(&i2c->i2c_i2brg, brg);
> +
> +	out_8(&i2c->i2c_i2mod, 0x00);
> +	out_8(&i2c->i2c_i2com, 0x01);	/* Master mode */
> +
> +	/* Disable interrupts.
> +	 */
> +	out_8(&i2c->i2c_i2cmr, 0);
> +	out_8(&i2c->i2c_i2cer, 0xff);
> +
> +	/* Install interrupt handler.
> +	 */
> +	request_irq(cpm->irq, cpm_iic_interrupt, 0, "8xx_i2c", i2c);
> +
> +	return 0;
> +}
> +
> +static int cpm_iic_shutdown(struct i2c_algo_8xx_data *cpm)
> +{
> +	i2c8xx_t *i2c = cpm->i2c;
> +
> +	/* Shut down IIC.
> +	 */
> +	out_8(&i2c->i2c_i2mod, in_8(&i2c->i2c_i2mod) | ~1);
> +	out_8(&i2c->i2c_i2cmr, 0);
> +	out_8(&i2c->i2c_i2cer, 0xff);
> +
> +	return (0);
> +}

Should return void, it cannot fail.

> +
> +static void cpm_reset_iic_params(iic_t * iip)
> +{
> +	iip->iic_tbase = r_tbase;
> +	iip->iic_rbase = r_rbase;
> +
> +	iip->iic_tfcr = SMC_EB;
> +	iip->iic_rfcr = SMC_EB;
> +
> +	iip->iic_mrblr = CPM_MAX_READ;
> +
> +	iip->iic_rstate = 0;
> +	iip->iic_rdp = 0;
> +	iip->iic_rbptr = iip->iic_rbase;
> +	iip->iic_rbc = 0;
> +	iip->iic_rxtmp = 0;
> +	iip->iic_tstate = 0;
> +	iip->iic_tdp = 0;
> +	iip->iic_tbptr = iip->iic_tbase;
> +	iip->iic_tbc = 0;
> +	iip->iic_txtmp = 0;
> +}
> +
> +#define BD_SC_NAK		((ushort)0x0004)	/* NAK - did not respond */
> +#define BD_SC_OV		((ushort)0x0002)	/* OV - receive overrun */
> +#define CPM_CR_CLOSE_RXBD	((ushort)0x0007)
> +
> +static void force_close(struct i2c_adapter *adap)
> +{
> +	struct i2c_algo_8xx_data *cpm = adap->algo_data;
> +	i2c8xx_t *i2c = cpm->i2c;
> +	if (cpm->reloc == 0) {	/* micro code disabled */
> +		cpm8xx_t *cp = cpm->cp;
> +		u16 v =
> +		    mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_CLOSE_RXBD) | CPM_CR_FLG;
> +
> +		if (cpm_debug)
> +			printk("force_close()\n");
> +
> +		out_be16(&cp->cp_cpcr, v);
> +		wait_event_timeout(iic_wait,
> +				   !(in_be16(&cp->cp_cpcr) & CPM_CR_FLG),
> +				   HZ * 5);
> +	}
> +	out_8(&i2c->i2c_i2cmr, 0x00);	/* Disable all interrupts */
> +	out_8(&i2c->i2c_i2cer, 0xff);
> +}
> +
> +/* Read from IIC...
> + * abyte = address byte, with r/w flag already set
> + */
> +static int
> +cpm_iic_read(struct i2c_adapter *adap, u_char abyte, char *buf, int count)
> +{
> +	struct i2c_algo_8xx_data *cpm = adap->algo_data;
> +	iic_t *iip = cpm->iip;
> +	i2c8xx_t *i2c = cpm->i2c;
> +	cbd_t *tbdf, *rbdf;
> +	u_char *tb;
> +	int res = 0;
> +
> +	if (count >= CPM_MAX_READ)
> +		return -EINVAL;
> +
> +	/* check for and use a microcode relocation patch */
> +	if (cpm->reloc) {
> +		cpm_reset_iic_params(iip);
> +	}
> +
> +	tbdf = (cbd_t *) cpm_dpram_addr(iip->iic_tbase);
> +	rbdf = (cbd_t *) cpm_dpram_addr(iip->iic_rbase);
> +
> +	/* To read, we need an empty buffer of the proper length.
> +	 * All that is used is the first byte for address, the remainder
> +	 * is just used for timing (and doesn't really have to exist).
> +	 */
> +	tb = cpm->temp;
> +	tb = (u_char *) (((uint) tb + 15) & ~15);
> +	tb[0] = abyte;		/* Device address byte w/rw flag */
> +
> +	flush_dcache_range((unsigned long)tb, (unsigned long)(tb + 1));
> +
> +	if (cpm_debug)
> +		dev_dbg(adap->dev, "cpm_iic_read(abyte=0x%x)\n", abyte);
> +
> +	tbdf->cbd_bufaddr = __pa(tb);
> +	tbdf->cbd_datlen = count + 1;
> +	tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
> +
> +	iip->iic_mrblr = count + 1;	/* prevent excessive read, +1
> +					   is needed otherwise will the
> +					   RXB interrupt come too early */
> +
> +	/* flush will invalidate too. */
> +	flush_dcache_range((unsigned long)buf, (unsigned long)(buf + count));
> +
> +	rbdf->cbd_datlen = 0;
> +	rbdf->cbd_bufaddr = __pa(buf);
> +	rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP | BD_SC_INTRPT;
> +
> +	/* Chip bug, set enable here */
> +	out_8(&i2c->i2c_i2cmr, 0x13);	/* Enable some interupts */
> +	out_8(&i2c->i2c_i2cer, 0xff);
> +	out_8(&i2c->i2c_i2mod, in_8(&i2c->i2c_i2mod) | 1);	/* Enable */
> +	out_8(&i2c->i2c_i2com, in_8(&i2c->i2c_i2com) | 0x80);	/* Begin transmission */
> +
> +	/* Wait for IIC transfer */
> +	res = wait_event_interruptible_timeout(iic_wait, 0, 1 * HZ);
> +
> +	if (res < 0) {

The usual style is no blank line between the action and the test.

> +		force_close(adap);
> +		if (cpm_debug)
> +			dev_dbg(adap->dev, "IIC read: timeout!\n");
> +		return -EIO;
> +	}
> +#ifdef I2C_CHIP_ERRATA
> +	/* Chip errata, clear enable. This is not needed on rev D4 CPUs.
> +	   Disabling I2C too early may cause too short stop condition */
> +	udelay(4);
> +	out_8(&i2c->i2c_i2mod, in_8(&i2c->i2c_i2mod) | ~1);
> +#endif
> +	if (cpm_debug) {
> +		dev_dbg(adap->dev, "tx sc %04x, rx sc %04x\n",
> +			tbdf->cbd_sc, rbdf->cbd_sc);
> +	}
> +
> +	if (tbdf->cbd_sc & BD_SC_READY) {
> +		dev_dbg(adap->dev, "IIC read; complete but tbuf ready\n");
> +		force_close(adap);
> +		dev_dbg(adap->dev, "tx sc %04x, rx sc %04x\n",
> +			tbdf->cbd_sc, rbdf->cbd_sc);
> +	}
> +
> +	if (tbdf->cbd_sc & BD_SC_NAK) {
> +		if (cpm_debug)
> +			dev_dbg(adap->dev, "IIC read; no ack\n");
> +		return -EREMOTEIO;
> +	}
> +
> +	if (rbdf->cbd_sc & BD_SC_EMPTY) {
> +		/* force_close(adap); */
> +		if (cpm_debug) {
> +			dev_dbg(adap->dev,
> +				"IIC read; complete but rbuf empty\n");
> +			dev_dbg(adap->dev, "tx sc %04x, rx sc %04x\n",
> +				tbdf->cbd_sc, rbdf->cbd_sc);
> +		}
> +		return -EREMOTEIO;
> +	}
> +
> +	if (rbdf->cbd_sc & BD_SC_OV) {
> +		if (cpm_debug)
> +			dev_dbg(adap->dev, "IIC read; Overrun\n");
> +		return -EREMOTEIO;
> +	}
> +
> +	if (cpm_debug)
> +		dev_dbg(adap->dev, "read %d bytes\n", rbdf->cbd_datlen);
> +
> +	if (rbdf->cbd_datlen < count) {
> +		if (cpm_debug)
> +			dev_dbg(adap->dev,
> +				"IIC read; short, wanted %d got %d\n", count,
> +				rbdf->cbd_datlen);
> +		return 0;
> +	}
> +
> +	return count;
> +}
> +
> +/* Write to IIC...
> + * addr = address byte, with r/w flag already set
> + */
> +static int
> +cpm_iic_write(struct i2c_adapter *adap, u_char abyte, char *buf, int count)
> +{
> +	struct i2c_algo_8xx_data *cpm = adap->algo_data;
> +	iic_t *iip = cpm->iip;
> +	i2c8xx_t *i2c = cpm->i2c;
> +	cbd_t *tbdf;
> +	u_char *tb;
> +	int res = 0;
> +
> +	/* check for and use a microcode relocation patch */
> +	if (cpm->reloc) {
> +		cpm_reset_iic_params(iip);
> +	}
> +	tb = cpm->temp;
> +	tb = (u_char *) (((uint) tb + 15) & ~15);
> +	*tb = abyte;		/* Device address byte w/rw flag */
> +
> +	flush_dcache_range((unsigned long)tb, (unsigned long)(tb + 1));
> +	flush_dcache_range((unsigned long)buf, (unsigned long)(buf + count));
> +
> +	if (cpm_debug)
> +		dev_dbg(adap->dev, "cpm_iic_write(abyte=0x%x)\n", abyte);
> +
> +	/* set up 2 descriptors */
> +
> +	tbdf = (cbd_t *) cpm_dpram_addr(iip->iic_tbase);
> +
> +	tbdf[0].cbd_bufaddr = __pa(tb);
> +	tbdf[0].cbd_datlen = 1;
> +	tbdf[0].cbd_sc = BD_SC_READY | BD_IIC_START;
> +
> +	tbdf[1].cbd_bufaddr = __pa(buf);
> +	tbdf[1].cbd_datlen = count;
> +	tbdf[1].cbd_sc = BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | BD_SC_WRAP;
> +
> +	/* Chip bug, set enable here */
> +	out_8(&i2c->i2c_i2cmr, 0x13);	/* Enable some interupts */
> +	out_8(&i2c->i2c_i2cer, 0xff);
> +	out_8(&i2c->i2c_i2mod, in_8(&i2c->i2c_i2mod) | 1);	/* Enable */
> +	out_8(&i2c->i2c_i2com, in_8(&i2c->i2c_i2com) | 0x80);	/* Begin transmission */
> +
> +	/* Wait for IIC transfer */
> +	res = wait_event_interruptible_timeout(iic_wait, 0, 1 * HZ);
> +
> +	if (res < 0) {
> +		force_close(adap);
> +		if (cpm_debug)
> +			dev_dbg(adap->dev, "IIC write: timeout!\n");
> +		return -EIO;
> +	}
> +#ifdef I2C_CHIP_ERRATA
> +	/* Chip errata, clear enable. This is not needed on rev D4 CPUs.
> +	   Disabling I2C too early may cause too short stop condition */
> +	udelay(4);
> +	out_8(&i2c->i2c_i2mod, in_8(&i2c->i2c_i2mod) | ~1);
> +#endif
> +	if (cpm_debug) {
> +		dev_dbg(adap->dev, "tx0 sc %04x, tx1 sc %04x\n",
> +			tbdf[0].cbd_sc, tbdf[1].cbd_sc);
> +	}
> +
> +	if (tbdf->cbd_sc & BD_SC_NAK) {
> +		if (cpm_debug)
> +			dev_dbg(adap->dev, "IIC write; no ack\n");
> +		return 0;
> +	}
> +
> +	if (tbdf->cbd_sc & BD_SC_READY) {
> +		if (cpm_debug)
> +			dev_dbg(adap->dev,
> +				"IIC write; complete but tbuf ready\n");
> +		return 0;
> +	}
> +
> +	return count;
> +}
> +
> +static int cpm_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
> +{
> +	struct i2c_msg *pmsg;
> +	int i, ret;
> +	u_char addr;
> +
> +	for (i = 0; i < num; i++) {
> +		pmsg = &msgs[i];
> +
> +		if (cpm_debug)
> +			dev_dbg(adap->dev, "i2c-algo-8xx.o: "
> +				"#%d addr=0x%x flags=0x%x len=%d\n buf=%lx\n",
> +				i, pmsg->addr, pmsg->flags, pmsg->len,
> +				(unsigned long)pmsg->buf);
> +
> +		addr = pmsg->addr << 1;
> +		if (pmsg->flags & I2C_M_RD)
> +			addr |= 1;
> +		if (pmsg->flags & I2C_M_REV_DIR_ADDR)
> +			addr ^= 1;

You didn't drop this?

> +
> +		if (pmsg->flags & I2C_M_RD) {
> +			/* read bytes into buffer */
> +			ret = cpm_iic_read(adap, addr, pmsg->buf, pmsg->len);
> +			if (cpm_debug)
> +				dev_dbg(adap->dev,
> +					"i2c-algo-8xx.o: read %d bytes\n", ret);
> +			if (ret < pmsg->len) {
> +				return (ret < 0) ? ret : -EREMOTEIO;
> +			}
> +		} else {
> +			/* write bytes from buffer */
> +			ret = cpm_iic_write(adap, addr, pmsg->buf, pmsg->len);
> +			if (cpm_debug)
> +				dev_dbg(adap->dev, "i2c-algo-8xx.o: wrote %d\n",
> +					ret);
> +			if (ret < pmsg->len) {
> +				return (ret < 0) ? ret : -EREMOTEIO;
> +			}
> +		}
> +	}
> +	return (num);

Useless parentheses.

> +}
> +
> +static u32 cpm_func(struct i2c_adapter *adap)
> +{
> +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
> +}
> +
> +/* -----exported algorithm data: -------------------------------------	*/
> +
> +static struct i2c_algorithm cpm_algo = {
> +	.master_xfer = cpm_xfer,
> +	.functionality = cpm_func,
> +};
> +
> +/*
> + * registering functions to load algorithms at runtime
> + */
> +int i2c_8xx_add_bus(struct i2c_adapter *adap)
> +{
> +	int res;
> +
> +	if (cpm_debug)
> +		dev_dbg(adap->dev,
> +			"i2c-algo-8xx.o: hw routines for %s registered.\n",
> +			adap->name);
> +
> +	/* register new adapter to i2c module... */
> +
> +	adap->algo = &cpm_algo;
> +
> +	res = cpm_iic_init(adap);
> +
> +	if (res)
> +		return res;
> +
> +	return i2c_add_adapter(adap);
> +}
> +
> +int i2c_8xx_del_bus(struct i2c_adapter *adap)
> +{
> +	struct i2c_algo_8xx_data *cpm = adap->algo_data;
> +
> +	i2c_del_adapter(adap);
> +
> +	return cpm_iic_shutdown(cpm);
> +}

Should return void.

> +
> +EXPORT_SYMBOL(i2c_8xx_add_bus);
> +EXPORT_SYMBOL(i2c_8xx_del_bus);
> +
> +MODULE_AUTHOR("Brad Parker <brad@heeltoe.com>");
> +MODULE_DESCRIPTION("I2C-Bus MPC8XX algorithm");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
> index ece31d2..df29fb5 100644
> --- a/drivers/i2c/busses/Kconfig
> +++ b/drivers/i2c/busses/Kconfig
> @@ -365,7 +365,7 @@ config I2C_PROSAVAGE
>  
>  config I2C_RPXLITE
>  	tristate "Embedded Planet RPX Lite/Classic support"
> -	depends on (RPXLITE || RPXCLASSIC) && I2C
> +	depends on (RPXLITE || RPXCLASSIC || MPC86XADS || MPC885ADS) && I2C
>  	select I2C_ALGO8XX

A recent change to the i2c Kconfig files make it no longer needed to
have all options depend on I2C explicitly. When you regenerate your
patch on top of Linus' latest tree, you'll have to update this.

The help text for this option is still missing.

>  
>  config I2C_S3C2410
> diff --git a/drivers/i2c/busses/i2c-rpx.c b/drivers/i2c/busses/i2c-rpx.c
> index 8764df0..97cbd2c 100644
> --- a/drivers/i2c/busses/i2c-rpx.c
> +++ b/drivers/i2c/busses/i2c-rpx.c
> @@ -5,6 +5,9 @@
>   * moved into proper i2c interface;
>   * Brad Parker (brad@heeltoe.com)
>   *
> + * (C) 2007 Montavista Software, Inc.
> + * Vitaly Bordug <vitb@kernel.crashing.org>
> + *
>   * RPX lite specific parts of the i2c interface
>   * Update:  There actually isn't anything RPXLite-specific about this module.
>   * This should work for most any 8xx board.  The console messages have been 
> @@ -14,88 +17,142 @@
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/init.h>
> +#include <linux/io.h>
>  #include <linux/stddef.h>
> +#include <linux/platform_device.h>
>  #include <linux/i2c.h>
>  #include <linux/i2c-algo-8xx.h>
> +#include <asm/of_device.h>
> +#include <asm/of_platform.h>
>  #include <asm/mpc8xx.h>
>  #include <asm/commproc.h>
> +#include <asm/fs_pd.h>
> +
> +
> +struct m8xx_i2c {
> +	char *base;
> +	struct of_device *ofdev;
> +	struct i2c_adapter adap;
> +	struct i2c_algo_8xx_data *algo_8xx;
> +};
>  
> +static struct i2c_algo_8xx_data rpx_data;
>  
> -static void
> -rpx_iic_init(struct i2c_algo_8xx_data *data)
> +static const struct i2c_adapter rpx_ops = {
> +	.owner		= THIS_MODULE,
> +	.name		= "i2c-rpx",
> +	.id		= I2C_HW_MPC8XX_EPON,
> +	.algo_data	= &rpx_data,
> +};
> +
> +static int rpx_iic_init(struct m8xx_i2c *i2c)
>  {
>  	volatile cpm8xx_t *cp;
> -	volatile immap_t *immap;
> +	struct resource r;
> +	struct i2c_algo_8xx_data *data = i2c->algo_8xx;
> +	struct of_device *ofdev = i2c->ofdev;
> +	struct device_node *np = ofdev->node;
> +
> +	/* Pointer to Communication Processor 
> +	 */
> +	cp = data->cp = (cpm8xx_t *)immr_map(im_cpm);
>  
> -	cp = cpmp;	/* Get pointer to Communication Processor */
> -	immap = (immap_t *)IMAP_ADDR;	/* and to internal registers */
> +	data->irq = irq_of_parse_and_map(np, 0);
> +  	if (data->irq < 0)
> +		return -EINVAL;
>  
> -	data->iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
> +	if (of_address_to_resource(np, 1, &r))
> +		return -EINVAL;
> +
> +	data->iip = ioremap(r.start, r.end - r.start + 1);
> +	if (data->iip == NULL)
> +		return -EINVAL;
>  
>  	/* Check for and use a microcode relocation patch.
> -	*/
> +	 */
>  	if ((data->reloc = data->iip->iic_rpbase))
>  		data->iip = (iic_t *)&cp->cp_dpmem[data->iip->iic_rpbase];
>  		
> -	data->i2c = (i2c8xx_t *)&(immap->im_i2c);
> -	data->cp = cp;
> +	if (of_address_to_resource(np, 0, &r))
> +		return -EINVAL;
>  
> -	/* Initialize Port B IIC pins.
> -	*/
> -	cp->cp_pbpar |= 0x00000030;
> -	cp->cp_pbdir |= 0x00000030;
> -	cp->cp_pbodr |= 0x00000030;
> +	data->i2c = ioremap(r.start, r.end - r.start + 1);
> +	if (data->i2c == NULL)
> +		return -EINVAL;
>  
>  	/* Allocate space for two transmit and two receive buffer
>  	 * descriptors in the DP ram.
>  	 */
>  	data->dp_addr = cpm_dpalloc(sizeof(cbd_t) * 4, 8);
> -		
> -	/* ptr to i2c area */
> -	data->i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c);
>  }
>  
> -static int rpx_install_isr(int irq, void (*func)(void *), void *data)
> +static int i2c_rpx_probe(struct of_device* ofdev, const struct of_device_id *match)
>  {
> -	/* install interrupt handler */
> -	cpm_install_handler(irq, func, data);
> +	int result;
> +	struct m8xx_i2c *i2c;
>  
> -	return 0;
> -}
> +	if (!(i2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) {
> +		return -ENOMEM;
> +	}
> +	i2c->ofdev = ofdev;
> +	i2c->algo_8xx = &rpx_data;
>  
> -static struct i2c_algo_8xx_data rpx_data = {
> -	.setisr = rpx_install_isr
> -};
> +	rpx_iic_init(i2c);
>  
> -static struct i2c_adapter rpx_ops = {
> -	.owner		= THIS_MODULE,
> -	.name		= "m8xx",
> -	.id		= I2C_HW_MPC8XX_EPON,
> -	.algo_data	= &rpx_data,
> -};
> -
> -int __init i2c_rpx_init(void)
> -{
> -	printk(KERN_INFO "i2c-rpx: i2c MPC8xx driver\n");
> +	dev_set_drvdata(&ofdev->dev, i2c);
>  
> -	/* reset hardware to sane state */
> -	rpx_iic_init(&rpx_data);
> +	i2c->adap = rpx_ops;
> +	i2c_set_adapdata(&i2c->adap, i2c);
> +	i2c->adap.dev.parent = &ofdev->dev;
>  
> -	if (i2c_8xx_add_bus(&rpx_ops) < 0) {
> +	if ((result = i2c_8xx_add_bus(&i2c->adap) < 0)) {
>  		printk(KERN_ERR "i2c-rpx: Unable to register with I2C\n");
> -		return -ENODEV;
> +		kfree(i2c);
>  	}
>  
> +	return result;
> +}
> +
> +static int i2c_rpx_remove(struct of_device* ofdev)
> +{
> +	struct m8xx_i2c *i2c = dev_get_drvdata(&ofdev->dev);
> +
> +	i2c_8xx_del_bus(&i2c->adap);
> +	dev_set_drvdata(&ofdev->dev, NULL);
> +
> +	kfree(i2c);
>  	return 0;
>  }
>  
> -void __exit i2c_rpx_exit(void)
> +static struct of_device_id i2c_rpx_match[] = {
> +	{
> +		.type = "i2c",
> +		.compatible = "fsl,i2c-cpm",
> +	},
> +	{},
> +};
> +
> +MODULE_DEVICE_TABLE(of, i2c_rpx_match);
> +
> +static struct of_platform_driver i2c_rpx_driver = {
> +	.name		= "fsl-i2c-cpm",
> +	.match_table	= i2c_rpx_match,
> +	.probe		= i2c_rpx_probe,
> +	.remove		= i2c_rpx_remove,
> +};
> +
> +static int __init i2c_rpx_init(void)
>  {
> -	i2c_8xx_del_bus(&rpx_ops);
> +	return of_register_platform_driver(&i2c_rpx_driver);
>  }
>  
> -MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>");
> -MODULE_DESCRIPTION("I2C-Bus adapter routines for MPC8xx boards");
> +static void __exit i2c_rpx_exit(void)
> +{
> +	of_unregister_platform_driver(&i2c_rpx_driver);
> +}
>  
>  module_init(i2c_rpx_init);
>  module_exit(i2c_rpx_exit);
> +
> +MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>");
> +MODULE_DESCRIPTION("I2C-Bus adapter routines for MPC8xx boards");
> diff --git a/include/linux/i2c-algo-8xx.h b/include/linux/i2c-algo-8xx.h
> new file mode 100644
> index 0000000..c63a739
> --- /dev/null
> +++ b/include/linux/i2c-algo-8xx.h
> @@ -0,0 +1,29 @@
> +/* ------------------------------------------------------------------------- */
> +/* i2c-algo-8xx.h i2c driver algorithms for MPX8XX CPM			     */
> +/* ------------------------------------------------------------------------- */
> +
> +#ifndef I2C_ALGO_8XX_H
> +#define I2C_ALGO_8XX_H
> +
> +#include <linux/i2c.h>
> +#include <asm/8xx_immap.h>
> +#include <asm/commproc.h>
> +
> +#define CPM_MAX_READ    513
> +
> +struct i2c_algo_8xx_data {
> +	uint dp_addr;
> +	int reloc;
> +	int irq;
> +	i2c8xx_t *i2c;
> +	iic_t *iip;
> +	cpm8xx_t *cp;
> +
> +	u_char temp[CPM_MAX_READ];
> +};
> +
> +extern int i2c_8xx_add_bus(struct i2c_adapter *);
> +extern int i2c_8xx_del_bus(struct i2c_adapter *);
> +
> +#endif /* I2C_ALGO_8XX_H */
> +

Question: once this is merged, will we possibly get rid of
arch/ppc/boot/simple/iic.c?

-- 
Jean Delvare

^ permalink raw reply

* Re: MPC832xEMDS: ttyS0 output stops mid boot
From: Alex Zeffertt @ 2007-05-10  8:22 UTC (permalink / raw)
  Cc: u-boot-users, linuxppc-embedded
In-Reply-To: <8c4dd9590705030939i5df99f3fw83a59698fe3d30cc@mail.gmail.com>

Hi,

For the record, I've just merged powerpc.git from kernel.org and it has started
working now!  Clearly this means it was a kernel issue rather than a bootloader
issue.

Regards,

Alex

Alex Zeffertt wrote:
> Hi,
> 
> Sorry about the cross posting, but I'm not sure which list I should send 
> to....
> 
> I'm trying to boot an up-to-date kernel on my MPC8323E-MDS-PB board, but 
> I the
> console output stops early on during the kernel boot.
> 
> I'm running the latest u-boot (git://www.denx.de/git/u-boot-mpc83xx.git) 
> with
> its default environment.  The kernel is built from Paulus' powerpc.git, 
> after
> checking out tag 2.6.21-rc5.  The dtb is build from
> arch/powerpc/boot/dts/mpc832x_mds.dts
> with the latest compiler (git://www.jdl.com/software/dtc.git).
> 
> Has anyone else been here before...?  If so I'd appreciate any help you can
> offer.
> 
> TIA,
> 
> Alex
> 
> -------------------my ttyS0 output------------------
> =>
> => printenv
> bootcmd=setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath
> ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off
> console=$consoledev,$baudrate $othbootargs;tftp $loadaddr
> $bootfile;tftp $fdtaddr $fdtfile;bootm $loadaddr - $fdtaddr
> ramboot=setenv bootargs root=/dev/ram rw console=$consoledev,$baudrate
> $othbootargs;tftp $ramdiskaddr $ramdiskfile;tftp $loadaddr
> $bootfile;tftp $fdtaddr $fdtfile;bootm $loadaddr $ramdiskaddr $fdtaddr
> nfsboot=setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath
> ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off
> console=$consoledev,$baudrate $othbootargs;tftp $loadaddr
> $bootfile;tftp $fdtaddr $fdtfile;bootm $loadaddr - $fdtaddr
> bootdelay=6
> baudrate=115200
> loads_echo=1
> ethaddr=00:04:9f:ef:03:01
> eth1addr=00:04:9f:ef:03:02
> loadaddr=200000
> netdev=eth0
> consoledev=ttyS0
> ramdiskaddr=1000000
> ramdiskfile=ramfs.83xx
> fdtaddr=400000
> fdtfile=mpc832xemds.dtb
> stdin=serial
> stdout=serial
> stderr=serial
> ethact=FSL UEC0
> 
> Environment size: 979/8188 bytes
> => setenv ramdiskfile uRamdisk
> => setenv fdtfile mpc832x_mds.dtb
> => setenv bootfile uImage
> => setenv serverip 10.0.0.107
> => setenv ipaddr 10.0.6.65
> => run ramboot
> Using FSL UEC0 device
> TFTP from server 10.0.0.107; our IP address is 10.0.6.65
> Filename 'uRamdisk'.
> Load address: 0x1000000
> Loading: #################################################################
>         #################################################################
>         #################################################################
>         #################################################################
>         #################################################################
>         #################################################################
>         #################################################################
>         #################################################################
>         #################################################################
>         ###########################################################
> done
> Bytes transferred = 3296770 (324e02 hex)
> Using FSL UEC0 device
> TFTP from server 10.0.0.107; our IP address is 10.0.6.65
> Filename 'uImage'.
> Load address: 0x200000
> Loading: #################################################################
>         #################################################################
>         #################################################################
>         ##########################################
> done
> Bytes transferred = 1212615 (1280c7 hex)
> Using FSL UEC0 device
> TFTP from server 10.0.0.107; our IP address is 10.0.6.65
> Filename 'mpc832x_mds.dtb'.
> Load address: 0x400000
> Loading: ###
> done
> Bytes transferred = 12288 (3000 hex)
> ## Booting image at 00200000 ...
>   Image Name:   Linux-2.6.21-rc5
>   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
>   Data Size:    1212551 Bytes =  1.2 MB
>   Load Address: 00000000
>   Entry Point:  00000000
>   Verifying Checksum ... OK
>   Uncompressing Kernel Image ... OK
> ## Loading RAMDisk Image at 01000000 ...
>   Image Name:   uboot ext2 ramdisk rootfs
>   Image Type:   PowerPC Linux RAMDisk Image (gzip compressed)
>   Data Size:    3296706 Bytes =  3.1 MB
>   Load Address: 00000000
>   Entry Point:  00000000
>   Verifying Checksum ... OK
>   Booting using flat device tree at 0x400000
>   Loading Ramdisk to 07c87000, end 07fabdc2 ... OK
> Using MPC832x MDS machine description
> Linux version 2.6.21-rc5 (ajz@zambia) (gcc version 3.4.3) #2 Thu May 3
> 16:42:54 BST 2007
> Found initrd at 0xc7c87000:0xc7fabdc2
> setup_arch: bootmem
> mpc832x_sys_setup_arch()
> Found MPC83xx PCI host bridge at 0x00000000e0008500. Firmware bus 
> number: 0->0
> arch: exit
> Zone PFN ranges:
>  DMA             0 ->    32768
>  Normal      32768 ->    32768
> early_node_map[1] active PFN ranges
>    0:        0 ->    32768
> Built 1 zonelists.  Total pages: 32512
> Kernel command line: root=/dev/ram rw console=ttyS0,115200
> IPIC (128 IRQ sources) at fddf3700
> QEIC (64 IRQ sources) at fddf2080
> PID hash table entries: 512 (order: 9, 2048 bytes)

^ permalink raw reply

* [PATCH] phy_ethtool_{sset,gset} -- check phydev for NULL
From: Matvejchikov Ilya @ 2007-05-10  8:57 UTC (permalink / raw)
  To: linuxppc-embedded

Good Day!

The command 'brctl addbr br0 eth0' brings the kernel oops if the eth0
has PHY, but the phydev is NULL (for ex., ifconfig eth0 0.0.0.0 was
not issued firstly)

Call Trace:
[C02CFBD0] [7FFFFFFF] 0x7fffffff (unreliable)
[C02CFBE0] [C0109634] dev_ethtool+0x1b0/0xfac
[C02CFCD0] [C0155EF0] port_cost+0x5c/0x130
[C02CFD40] [C01561FC] br_add_if+0x17c/0x308
[C02CFD70] [C01569E0] add_del_if+0x70/0xa0
[C02CFD90] [C0156A58] br_dev_ioctl+0x48/0x9fc
[C02CFE10] [C0106FCC] dev_ifsioc+0x144/0x3ac
[C02CFE30] [C01080D8] dev_ioctl+0x3b8/0x4c8
[C02CFEB0] [C00F9BC0] sock_ioctl+0x78/0x260
[C02CFED0] [C006889C] do_ioctl+0x38/0x84
[C02CFEE0] [C006896C] vfs_ioctl+0x84/0x3d8
[C02CFF10] [C0068D00] sys_ioctl+0x40/0x74
[C02CFF40] [C000EF48] ret_from_syscall+0x0/0x38

The following patch fixes the problem.

Signed-off-by: Matvejchikov Ilya <matvejchikov <at> gmail.com>

===================================================================
diff -purN linux-2.6.21-clean/drivers/net/phy/phy.c
linux-2.6.21/drivers/net/phy/phy.c
--- linux-2.6.21-clean/drivers/net/phy/phy.c	2007-04-26 07:08:32.000000000 +0400
+++ linux-2.6.21/drivers/net/phy/phy.c	2007-05-04 08:22:01.000000000 +0400
@@ -245,6 +245,9 @@ EXPORT_SYMBOL(phy_sanitize_settings);
  */
  int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
 {
+	if (unlikely(NULL == phydev))
+		return -EINVAL;
+
  	if (cmd->phy_address != phydev->addr)
  		return -EINVAL;

@@ -289,6 +292,9 @@ EXPORT_SYMBOL(phy_ethtool_sset);

  int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
 {
+	if (unlikely(NULL == phydev))
+		return -EINVAL;
+
  	cmd->supported = phydev->supported;

  	cmd->advertising = phydev->advertising;

^ permalink raw reply

* Re: [PATCH 1/6] IB/ehca: Serialize hypervisor calls in ehca_register_mr()
From: Joachim Fenkes @ 2007-05-10  8:55 UTC (permalink / raw)
  To: LinuxPPC-Dev; +Cc: LKML, Christoph Raisch, OF-General, Stefan Roscher
In-Reply-To: <200705091347.57470.fenkes@de.ibm.com>

On Wednesday 09 May 2007 13:47, Joachim Fenkes wrote:

> --- a/drivers/infiniband/hw/ehca/hcp_if.c
> +++ b/drivers/infiniband/hw/ehca/hcp_if.c
> @@ -154,7 +154,9 @@ static long ehca_plpar_hcall9(unsigned l
>  			      unsigned long arg9)
>  {
>  	long ret;
> -	int i, sleep_msecs;
> +	int i, sleep_msecs, lock_is_set =3D 0;
> +	unsigned long flags;
> +
> =20
>  	ehca_gen_dbg("opcode=3D%lx arg1=3D%lx arg2=3D%lx arg3=3D%lx arg4=3D%lx "
>  		     "arg5=3D%lx arg6=3D%lx arg7=3D%lx arg8=3D%lx arg9=3D%lx",
> @@ -162,10 +164,18 @@ static long ehca_plpar_hcall9(unsigned l

Whoops, that's one too many empty line...
Roland, when you apply this patch, could you apply the following patch on t=
op:

=2D-- a/drivers/infiniband/hw/ehca/hcp_if.c
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -157,7 +157,6 @@ static long ehca_plpar_hcall9(unsigned l
        int i, sleep_msecs, lock_is_set =3D 0;
        unsigned long flags;

=2D
        ehca_gen_dbg("opcode=3D%lx arg1=3D%lx arg2=3D%lx arg3=3D%lx arg4=3D=
%lx "
                     "arg5=3D%lx arg6=3D%lx arg7=3D%lx arg8=3D%lx arg9=3D%l=
x",
                     opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7,


Thanks!
  Joachim

=2D-=20
Joachim Fenkes =A0-- =A0eHCA Linux Driver Developer and Hardware Tamer
IBM Deutschland Entwicklung GmbH =A0-- =A0Dept. 3627 (I/O Firmware Dev. 2)
Schoenaicher Strasse 220 =A0-- =A071032 Boeblingen =A0-- =A0Germany
eMail: fenkes@de.ibm.com =A0-- =A0Phone: +49 7031 16 1239

^ permalink raw reply

* Re: [PATCH 2/3] Add hard_irq_disable()
From: David Miller @ 2007-05-10  8:53 UTC (permalink / raw)
  To: akpm; +Cc: rusty, linux-kernel, linuxppc-dev
In-Reply-To: <20070510015036.ebded3ac.akpm@linux-foundation.org>

From: Andrew Morton <akpm@linux-foundation.org>
Date: Thu, 10 May 2007 01:50:36 -0700

> We discussed this a couple of months back.  davem landed firmly in the
> second camp and everyone then shut up ;)

No I landed in the first :-)))

I think the empty lines are a waste and only serve to eat
up precious screen real-estate when reading code.

It is possible that I used to use the empty line thing in
the past, but I definitely don't do that any more.

^ permalink raw reply

* Re: [PATCH 2/3] Add hard_irq_disable()
From: Andrew Morton @ 2007-05-10  8:50 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Rusty Russell, linux-kernel
In-Reply-To: <1178786505.14928.225.camel@localhost.localdomain>

On Thu, 10 May 2007 18:41:45 +1000 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:

> 
> > > What about my comment layout style ? I've been using that forever ... Or
> > > do you mean I should use a function documentation style layout there ?
> > 
> > /* This
> >  * is
> >  * wrong
> >  */
> > 
> > /*
> >  * This
> >  * is
> >  * right
> >  */
> 
> Hrm... how bad are you about that one ? I must say I prefer my style :-)
> 

I usually shrug and ignore it.  It's more a matter of informing people
about it than going in there and fixing them all.

We discussed this a couple of months back.  davem landed firmly in the
second camp and everyone then shut up ;)

^ permalink raw reply

* Re: [PATCH 2/3] Add hard_irq_disable()
From: David Miller @ 2007-05-10  8:49 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, akpm, rusty, linux-kernel
In-Reply-To: <1178786505.14928.225.camel@localhost.localdomain>

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: Thu, 10 May 2007 18:41:45 +1000

> 
> > > What about my comment layout style ? I've been using that forever ... Or
> > > do you mean I should use a function documentation style layout there ?
> > 
> > /* This
> >  * is
> >  * wrong
> >  */
> > 
> > /*
> >  * This
> >  * is
> >  * right
> >  */
> 
> Hrm... how bad are you about that one ? I must say I prefer my style :-)

I think the "wrong" one is right because screen real-estate matters.
In fact that's the one I use and enforce throughout the networking
and sparc ports.

I even hand edit out those empty comment lines in patches submitted
to me when I spot them.

^ permalink raw reply

* Re: [PATCH 2/3] Add hard_irq_disable()
From: Benjamin Herrenschmidt @ 2007-05-10  8:46 UTC (permalink / raw)
  To: Satyam Sharma; +Cc: linuxppc-dev, Andrew Morton, Rusty Russell, linux-kernel
In-Reply-To: <a781481a0705100054r45c373a0lfd35b8b31b0e6032@mail.gmail.com>

On Thu, 2007-05-10 at 13:24 +0530, Satyam Sharma wrote:
> But then, what _is_ the problem with your approach above? An arch that
> wants (and implements) hard_irq_disable will also #define that dummy
> macro, so we just need to pull in the appropriate header (directly,
> indirectly, anyhow -- we don't really care) into
> include/linux/interrupt.h and then just do the exact same "#ifndef
> hard_irq_disable" check that you're doing right now. I must be missing
> something trivial (either that or I need to go and have a coffee :-)
> because I don't see the possibility of hitting multiple _different_
> definitions with the approach you mentioned just now.

Sure, the only problem is that I don't want to pull asm/hw_irq.h
directly from linux/interrupts.h unless all arch maintainers around
verify it's ok, because those headers are a bit of a can of worm at the
moment ...

So I'd rather say that if your arch has a custom version of
hard_irq_disable(), make sure that asm/system.h pulls it in a way or
another. And that's already included.

Ben.

^ permalink raw reply

* RE: zImage.elf loads but does not start
From: Mirek23 @ 2007-05-10  8:45 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <9F3F0A752CAEBE4FA7E906CC2FBFF57C06A207@MERCURY.inside.istor.com>


Thank you for all of the advices.
I did more study on that problem but still without the success.

1. I did redd the ELDK manual and I have invoked :
ELDK_FIXOWNER
ELDK_MAKEDEV

in the "dev" directory there were created many nodes like that:

crw-rw-rw-    1 root     root       5,   1 May  8 15:42 console
crw-rw-rw-    1 root     root       4,  64 May  8 15:42 ttyS0

In the kernel command line configuration I have the entry :
CONFIG_CMDLINE="console=ttyUL0,9600 root=/dev/nfs rw nfsroo ...

so I have created by hand the node:
crw-rw-rw-    1 root     root     204, 187 May  8 15:44 ttyUL0

Unfortunately the kernel boots to the point:

[    9.130834] Looking up port of RPC 100003/2 on 129.129.130.106
[    9.207363] Looking up port of RPC 100005/1 on 129.129.130.106
[    9.303794] VFS: Mounted root (nfs filesystem).
[    9.359316] Freeing unused kernel memory: 96k init

and after that it hangs.

I have made some modifications to the kernel init/main.c file. In that file
I have inserted the printk statements to
see how far the kernel goes. It seems to be that the last thing it does it
executes the sbin/init command and it hangs.

Instead of the sbin/init I have tried to execute other commands like
bin/echo this_is_text_string
and bin/echo this_is_test >> /var/log/messages

the modification looks like (init/main.c):
before modification:
        printk("test 3\n");
        run_init_process("/sbin/init");
        printk("test 4\n");
after modification
        printk("test 3\n");
        run_init_process("/bin/echo ala");
        run_init_process("/bin/echo buba >> /var/log/messages");
        printk("test 4\n");



In both cases the last thing which was printed is "test 3"
The /var/log/messages remains empty.

I thought that it might be the uart_lite driver is the source of the
problem. I rebuild the kernel configuring it for the
standard UART driver instead of the uart_lite.
This time my command line looks like:
CONFIG_CMDLINE="console=ttyS0,9600 root=/dev/nfs rw nfsroo ...

When booting the kernel configured with the UART  I see anything printed  
on the screen so it is even worse than before.

Do you have any suggestions.

Best Regards

Mirek



Charles Krinke wrote:
> 
> I find this usually happens when /dev/tty, /dev/console or /dev/ttyS0
> are not setup properly. That is, they are files instead of nodes. This
> menas you have mounted the root filesystem and init is running on that
> root filesystem.
> 
> Charles
> 
> 
> -----Original Message-----
> From: linuxppc-embedded-bounces+ckrinke=istor.com@ozlabs.org
> [mailto:linuxppc-embedded-bounces+ckrinke=istor.com@ozlabs.org] On
> Behalf Of Adrian Craine
> Sent: Tuesday, May 08, 2007 2:50 PM
> To: Leonid
> Cc: linuxppc-embedded@ozlabs.org; Mirek23
> Subject: Re: zImage.elf loads but does not start
> 
> Leonid wrote:
>> rootpath=
>> [    9.130834] Looking up port of RPC 100003/2 on 129.129.130.106
>> [    9.207363] Looking up port of RPC 100005/1 on 129.129.130.106
>> [    9.303794] VFS: Mounted root (nfs filesystem).
>> [    9.359316] Freeing unused kernel memory: 96k init
>> [    9.422162] Warning: unable to open an initial console.
>>
>>   
> The exact device node this requires is /dev/console c 5 1
> That should solve your issue.
> 
> Cheers,
>              Adrian.
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> 
> 

-- 
View this message in context: http://www.nabble.com/zImage.elf-loads-but-not-starts-tf3607582.html#a10409434
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply

* Re: [PATCH 1/3] powerpc: Fixup hard_irq_disable semantics
From: Benjamin Herrenschmidt @ 2007-05-10  8:44 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: linuxppc-dev, Andrew Morton, Rusty Russell, linux-kernel
In-Reply-To: <Pine.LNX.4.62.0705100942590.32241@pademelon.sonytel.be>

On Thu, 2007-05-10 at 09:44 +0200, Geert Uytterhoeven wrote:
> On Thu, 10 May 2007, Benjamin Herrenschmidt wrote:
> > This patch renames the raw hard_irq_{enable,disable} into
> > __hard_irq_{enable,disable} and introduces a higher level
> > hard_irq_disable() function that can be used by any code
> > to enforce that IRQs are fully disabled, not only lazy
> > disabled.
> 
> Why did you rename hard_irq_enable() too?
> 
> Isn't it more logical to have high-level hard_irq_disable() and
> hard_irq_enable(), and a special low-level __hard_irq_disable()?

Not really. If you see my subsequent patch, the idea is to introduce a
single generic hard_irq_disable() which is meant to be called with
irqs already disabled (that is within a local_irq_disable section) to
enforce that if the arch does lazy disabling, it gets hard disabled
at this point.

If we start adding hard_irq_enable() we end up in a can of worms:

 - Do we want all the full set of save/restore etc... ?
 - What if somebody does hard_enable while we are soft-disabled
   -and- have been hard disabled because of a pending interrupt ?
 - What's the point ? :-)

So overall, I want to keep the semantics as simple as they can be. Maybe
I can even add some WARN_ON() to make sure we are in a
local_irq_disable'd section even in the generic one instead of just a
NOP to enfore that.

Cheers,
Ben.

^ 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