[PATCH 2/2] powerpc: Dynamically allocate most lppaca structs

2010-08-13 Thread Paul Mackerras
This arranges for the lppaca structs for most cpus to be dynamically
allocated in the same manner as the paca structs.  If we don't include
support for legacy iSeries, only the first lppaca is statically
allocated; the rest are dynamically allocated.  If we include legacy
iSeries support, then we statically allocate the first 64 lppaca
structs, since the iSeries hypervisor requires that the lppaca
structs be present in the data section of the kernel image, but
legacy iSeries supports at most 64 cpus.

With CONFIG_NR_CPUS, the kernel image size for a typical pSeries config
went from:

   textdata bss dec hex filename
9524478 4734564 8469944 2272898615ad11a ../test-1024/vmlinux

to:

   textdata bss dec hex filename
9524482 3751508 8469944 2174593414bd10e ../test-1024/vmlinux

a reduction of 983052 bytes overall.

Signed-off-by: Paul Mackerras pau...@samba.org
---
 arch/powerpc/include/asm/lppaca.h |2 +-
 arch/powerpc/kernel/paca.c|   70 +++-
 2 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/lppaca.h 
b/arch/powerpc/include/asm/lppaca.h
index 6b73554..6d02624 100644
--- a/arch/powerpc/include/asm/lppaca.h
+++ b/arch/powerpc/include/asm/lppaca.h
@@ -153,7 +153,7 @@ struct lppaca {
 
 extern struct lppaca lppaca[];
 
-#define lppaca_of(cpu) (lppaca[cpu])
+#define lppaca_of(cpu) (*paca[cpu].lppaca_ptr)
 
 /*
  * SLB shadow buffer structure as defined in the PAPR.  The save_area
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index d0a26f1..1e068a4 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -27,6 +27,20 @@ extern unsigned long __toc_start;
 #ifdef CONFIG_PPC_BOOK3S
 
 /*
+ * We only have to have statically allocated lppaca structs on
+ * legacy iSeries, which supports at most 64 cpus.
+ */
+#ifdef CONFIG_PPC_ISERIES
+#if NR_CPUS  64
+#define NR_LPPACAS NR_CPUS
+#else
+#define NR_LPPACAS 64
+#endif
+#else /* not iSeries */
+#define NR_LPPACAS 1
+#endif
+
+/*
  * The structure which the hypervisor knows about - this structure
  * should not cross a page boundary.  The vpa_init/register_vpa call
  * is now known to fail if the lppaca structure crosses a page
@@ -36,7 +50,7 @@ extern unsigned long __toc_start;
  * will suffice to ensure that it doesn't cross a page boundary.
  */
 struct lppaca lppaca[] = {
-   [0 ... (NR_CPUS-1)] = {
+   [0 ... (NR_LPPACAS-1)] = {
.desc = 0xd397d781, /* LpPa */
.size = sizeof(struct lppaca),
.dyn_proc_status = 2,
@@ -49,6 +63,54 @@ struct lppaca lppaca[] = {
},
 };
 
+static struct lppaca *extra_lppacas;
+static long __initdata lppaca_size;
+
+static void allocate_lppacas(int nr_cpus, unsigned long limit)
+{
+   if (nr_cpus = NR_LPPACAS)
+   return;
+
+   lppaca_size = PAGE_ALIGN(sizeof(struct lppaca) *
+(nr_cpus - NR_LPPACAS));
+   extra_lppacas = __va(memblock_alloc_base(lppaca_size,
+PAGE_SIZE, limit));
+}
+
+static struct lppaca *new_lppaca(int cpu)
+{
+   struct lppaca *lp;
+
+   if (cpu  NR_LPPACAS)
+   return lppaca[cpu];
+
+   lp = extra_lppacas + (cpu - NR_LPPACAS);
+   *lp = lppaca[0];
+
+   return lp;
+}
+
+static void free_lppacas(void)
+{
+   long new_size = 0, nr;
+
+   if (!lppaca_size)
+   return;
+   nr = num_possible_cpus() - NR_LPPACAS;
+   if (nr  0)
+   new_size = PAGE_ALIGN(nr * sizeof(struct lppaca));
+   if (new_size = lppaca_size)
+   return;
+
+   memblock_free(__pa(extra_lppacas) + new_size, lppaca_size - new_size);
+   lppaca_size = new_size;
+}
+
+#else
+
+static inline void allocate_lppacas(int, unsigned long) { }
+static inline void free_lppacas(void) { }
+
 #endif /* CONFIG_PPC_BOOK3S */
 
 #ifdef CONFIG_PPC_STD_MMU_64
@@ -88,7 +150,7 @@ void __init initialise_paca(struct paca_struct *new_paca, 
int cpu)
unsigned long kernel_toc = (unsigned long)(__toc_start) + 0x8000UL;
 
 #ifdef CONFIG_PPC_BOOK3S
-   new_paca-lppaca_ptr = lppaca[cpu];
+   new_paca-lppaca_ptr = new_lppaca(cpu);
 #else
new_paca-kernel_pgd = swapper_pg_dir;
 #endif
@@ -144,6 +206,8 @@ void __init allocate_pacas(void)
printk(KERN_DEBUG Allocated %u bytes for %d pacas at %p\n,
paca_size, nr_cpus, paca);
 
+   allocate_lppacas(nr_cpus, limit);
+
/* Can't use for_each_*_cpu, as they aren't functional yet */
for (cpu = 0; cpu  nr_cpus; cpu++)
initialise_paca(paca[cpu], cpu);
@@ -164,4 +228,6 @@ void __init free_unused_pacas(void)
paca_size - new_size);
 
paca_size = new_size;
+
+   free_lppacas();
 }
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org

[PATCH 1/2] powerpc: Abstract indexing of lppaca structs

2010-08-13 Thread Paul Mackerras
Currently we have the lppaca structs as a simple array of NR_CPUS
entries, taking up space in the data section of the kernel image.
In future we would like to allocate them dynamically, so this
abstracts out the accesses to the array, making it easier to
change how we locate the lppaca for a given cpu in future.
Specifically, lppaca[cpu] changes to lppaca_of(cpu).

Signed-off-by: Paul Mackerras pau...@samba.org
---
 arch/powerpc/include/asm/lppaca.h |2 ++
 arch/powerpc/kernel/lparcfg.c |   14 +++---
 arch/powerpc/lib/locks.c  |4 ++--
 arch/powerpc/platforms/iseries/dt.c   |4 ++--
 arch/powerpc/platforms/iseries/smp.c  |2 +-
 arch/powerpc/platforms/pseries/dtl.c  |8 
 arch/powerpc/platforms/pseries/lpar.c |4 ++--
 7 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/include/asm/lppaca.h 
b/arch/powerpc/include/asm/lppaca.h
index 14b592d..6b73554 100644
--- a/arch/powerpc/include/asm/lppaca.h
+++ b/arch/powerpc/include/asm/lppaca.h
@@ -153,6 +153,8 @@ struct lppaca {
 
 extern struct lppaca lppaca[];
 
+#define lppaca_of(cpu) (lppaca[cpu])
+
 /*
  * SLB shadow buffer structure as defined in the PAPR.  The save_area
  * contains adjacent ESID and VSID pairs for each shadowed SLB.  The
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 50362b6..8d9e3b9 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -56,7 +56,7 @@ static unsigned long get_purr(void)
 
for_each_possible_cpu(cpu) {
if (firmware_has_feature(FW_FEATURE_ISERIES))
-   sum_purr += lppaca[cpu].emulated_time_base;
+   sum_purr += lppaca_of(cpu).emulated_time_base;
else {
struct cpu_usage *cu;
 
@@ -263,7 +263,7 @@ static void parse_ppp_data(struct seq_file *m)
   ppp_data.active_system_procs);
 
/* pool related entries are apropriate for shared configs */
-   if (lppaca[0].shared_proc) {
+   if (lppaca_of(0).shared_proc) {
unsigned long pool_idle_time, pool_procs;
 
seq_printf(m, pool=%d\n, ppp_data.pool_num);
@@ -460,8 +460,8 @@ static void pseries_cmo_data(struct seq_file *m)
return;
 
for_each_possible_cpu(cpu) {
-   cmo_faults += lppaca[cpu].cmo_faults;
-   cmo_fault_time += lppaca[cpu].cmo_fault_time;
+   cmo_faults += lppaca_of(cpu).cmo_faults;
+   cmo_fault_time += lppaca_of(cpu).cmo_fault_time;
}
 
seq_printf(m, cmo_faults=%lu\n, cmo_faults);
@@ -479,8 +479,8 @@ static void splpar_dispatch_data(struct seq_file *m)
unsigned long dispatch_dispersions = 0;
 
for_each_possible_cpu(cpu) {
-   dispatches += lppaca[cpu].yield_count;
-   dispatch_dispersions += lppaca[cpu].dispersion_count;
+   dispatches += lppaca_of(cpu).yield_count;
+   dispatch_dispersions += lppaca_of(cpu).dispersion_count;
}
 
seq_printf(m, dispatches=%lu\n, dispatches);
@@ -545,7 +545,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
seq_printf(m, partition_potential_processors=%d\n,
   partition_potential_processors);
 
-   seq_printf(m, shared_processor_mode=%d\n, lppaca[0].shared_proc);
+   seq_printf(m, shared_processor_mode=%d\n, lppaca_of(0).shared_proc);
 
seq_printf(m, slb_size=%d\n, mmu_slb_size);
 
diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c
index 58e14fb..9b8182e 100644
--- a/arch/powerpc/lib/locks.c
+++ b/arch/powerpc/lib/locks.c
@@ -34,7 +34,7 @@ void __spin_yield(arch_spinlock_t *lock)
return;
holder_cpu = lock_value  0x;
BUG_ON(holder_cpu = NR_CPUS);
-   yield_count = lppaca[holder_cpu].yield_count;
+   yield_count = lppaca_of(holder_cpu).yield_count;
if ((yield_count  1) == 0)
return; /* virtual cpu is currently running */
rmb();
@@ -65,7 +65,7 @@ void __rw_yield(arch_rwlock_t *rw)
return; /* no write lock at present */
holder_cpu = lock_value  0x;
BUG_ON(holder_cpu = NR_CPUS);
-   yield_count = lppaca[holder_cpu].yield_count;
+   yield_count = lppaca_of(holder_cpu).yield_count;
if ((yield_count  1) == 0)
return; /* virtual cpu is currently running */
rmb();
diff --git a/arch/powerpc/platforms/iseries/dt.c 
b/arch/powerpc/platforms/iseries/dt.c
index 7f45a51..fdb7384 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -243,7 +243,7 @@ static void __init dt_cpus(struct iseries_flat_dt *dt)
pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE);
 
for (i = 0; i  NR_CPUS; i++) {
-   if (lppaca[i].dyn_proc_status = 2)
+   if 

Re: 2.6.35-stable/ppc64/p7: suspicious rcu_dereference_check() usage detected during 2.6.35-stable boot

2010-08-13 Thread Subrata Modak
Hi Paul,

Is there any specific person(s) whom we whom we should direct this mail
to ? We have not received any response from CGROUP developers on this.
Kindly let me know whom to contact for this. I am adding few more people
i know :-)

Regards--
Subrata

On Mon, 2010-08-09 at 09:12 -0700, Paul E. McKenney wrote:
 On Mon, Aug 02, 2010 at 02:22:12PM +0530, Subrata Modak wrote:
  Hi,
  
  The following suspicious rcu_dereference_check() usage is detected
  during 2.6.35-stable boot on my ppc64/p7 machine:
  
  ==
  [ INFO: suspicious rcu_dereference_check() usage. ]
  ---
  kernel/sched.c:616 invoked rcu_dereference_check() without protection!
  other info that might help us debug this:
  
  rcu_scheduler_active = 1, debug_locks = 0
  1 lock held by swapper/1:
   #0:  (rq-lock){-.}, at: [c07ca2f8] .init_idle+0x78/0x4a8
  stack backtrace:
  Call Trace:
  [c00f392bf990] [c0014f04] .show_stack+0xb0/0x1a0 (unreliable)
  [c00f392bfa50] [c07c87b4] .dump_stack+0x28/0x3c
  [c00f392bfad0] [c0103e1c] .lockdep_rcu_dereference+0xbc/0xe4
  [c00f392bfb70] [c07ca434] .init_idle+0x1b4/0x4a8
  [c00f392bfc30] [c07cad04] .fork_idle+0xa4/0xd0
  [c00f392bfe30] [c0aefaac] .smp_prepare_cpus+0x23c/0x2f4
  [c00f392bfed0] [c0ae1424] .kernel_init+0xec/0x32c
  [c00f392bff90] [c0033f40] .kernel_thread+0x54/0x70
  ==
  
  Please note that this was reported earlier on 2.6.34-rc6:
  http://marc.info/?l=linux-kernelm=127313031922395w=2,
  The issue was fixed with:
  commit 1ce7e4ff24fe338438bc7837e02780f202bf202b
  Author: Li Zefan l...@cn.fujitsu.com
  Date:   Fri Apr 23 10:35:52 2010 +0800
  cgroup: Check task_lock in task_subsys_state()
  
  According to:
  http://lkml.org/lkml/2010/7/1/883,
  commit dc61b1d65e353d638b2445f71fb8e5b5630f2415
  Author: Peter Zijlstra a.p.zijls...@chello.nl
  Date:   Tue Jun 8 11:40:42 2010 +0200
  sched: Fix PROVE_RCU vs cpu_cgroup
  should have fixed this. But this is reproducible on 2.6.35-stable.
  
  Please also see the config file attached.
 
 Hello, Subrata,
 
 Thank you for locating this one!  This looks like the same issue that
 Ilia Mirkin located.  Please see below for my analysis -- no fix yet,
 as I need confirmation from cgroups experts.  I can easily create a
 patch that suppresses the warning, but I don't yet know whether this is
 the right thing to do.
 
   Thanx, Paul
 
 
 
 On Thu, Aug 05, 2010 at 01:31:10PM -0400, Ilia Mirkin wrote:
  On Thu, Jul 1, 2010 at 6:18 PM, Paul E. McKenney
  paul...@linux.vnet.ibm.com wrote:
   On Thu, Jul 01, 2010 at 08:21:43AM -0400, Miles Lane wrote:
   [ INFO: suspicious rcu_dereference_check() usage. ]
   ---
   kernel/sched.c:616 invoked rcu_dereference_check() without protection!
  
   other info that might help us debug this:
  
   rcu_scheduler_active = 1, debug_locks = 1
   3 locks held by swapper/1:
 #0:  (cpu_add_remove_lock){+.+.+.}, at: [81042914]
   cpu_maps_update_begin+0x12/0x14
 #1:  (cpu_hotplug.lock){+.+.+.}, at: [8104294f]
   cpu_hotplug_begin+0x27/0x4e
 #2:  (rq-lock){-.-...}, at: [812f8502] init_idle+0x2b/0x114
  
   Hello, Miles!
  
   I believe that this one is fixed by commit dc61b1d6 in -tip.
  
  Hi Paul,
  
  Looks like that commit made it into 2.6.35:
  
  git tag -l --contains dc61b1d65e353d638b2445f71fb8e5b5630f2415 v2.6.35*
  v2.6.35
  v2.6.35-rc4
  v2.6.35-rc5
  v2.6.35-rc6
  
  However I still get:
  
  [0.051203] CPU0: AMD QEMU Virtual CPU version 0.12.4 stepping 03
  [0.052999] lockdep: fixing up alternatives.
  [0.054105]
  [0.054106] ===
  [0.054999] [ INFO: suspicious rcu_dereference_check() usage. ]
  [0.054999] ---
  [0.054999] kernel/sched.c:616 invoked rcu_dereference_check()
  without protection
  !
  [0.054999]
  [0.054999] other info that might help us debug this:
  [0.054999]
  [0.054999]
  [0.054999] rcu_scheduler_active = 1, debug_locks = 1
  [0.054999] 3 locks held by swapper/1:
  [0.054999]  #0:  (cpu_add_remove_lock){+.+.+.}, at:
  [814be933] cpu_up+
  0x42/0x6a
  [0.054999]  #1:  (cpu_hotplug.lock){+.+.+.}, at:
  [810400d8] cpu_hotplu
  g_begin+0x2a/0x51
  [0.054999]  #2:  (rq-lock){-.-...}, at: [814be2f7]
  init_idle+0x2f/0x
  113
  [0.054999]
  [0.054999] stack backtrace:
  [0.054999] Pid: 1, comm: swapper Not tainted 2.6.35 #1
  [0.054999] Call Trace:
  [0.054999]  [81068054] lockdep_rcu_dereference+0x9b/0xa3

[PATCH] powerpc: Initialise paca-kstack before early_setup_secondary

2010-08-13 Thread Matt Evans
As early setup calls down to slb_initialize(), we must have kstack
initialised before checking should we add a bolted SLB entry for our kstack?

Failing to do so means stack access requires an SLB miss exception to refill
an entry dynamically, if the stack isn't accessible via SLB(0) (kernel text
 static data).  It's not always allowable to take such a miss, and
intermittent crashes will result.

Primary CPUs don't have this issue; an SLB entry is not bolted for their
stack anyway (as that lives within SLB(0)).  This patch therefore only
affects the init of secondaries.

Signed-off-by: Matt Evans m...@ozlabs.org
Cc: stable sta...@kernel.org
---
 arch/powerpc/kernel/head_64.S |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 844a44b..4d6681d 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -572,9 +572,6 @@ __secondary_start:
/* Set thread priority to MEDIUM */
HMT_MEDIUM
 
-   /* Do early setup for that CPU (stab, slb, hash table pointer) */
-   bl  .early_setup_secondary
-
/* Initialize the kernel stack.  Just a repeat for iSeries.  */
LOAD_REG_ADDR(r3, current_set)
sldir28,r24,3   /* get current_set[cpu#] */
@@ -582,6 +579,9 @@ __secondary_start:
addir1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
std r1,PACAKSAVE(r13)
 
+   /* Do early setup for that CPU (stab, slb, hash table pointer) */
+   bl  .early_setup_secondary
+
/* Clear backchain so we get nice backtraces */
li  r7,0
mtlrr7
-- 
1.7.0.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: 2.6.35-stable/ppc64/p7: suspicious rcu_dereference_check() usage detected during 2.6.35-stable boot

2010-08-13 Thread Dhaval Giani
On Fri, Aug 13, 2010 at 8:55 AM, Subrata Modak
subr...@linux.vnet.ibm.com wrote:
 Hi Paul,

 Is there any specific person(s) whom we whom we should direct this mail
 to ? We have not received any response from CGROUP developers on this.
 Kindly let me know whom to contact for this. I am adding few more people
 i know :-)


It would help if you would add in the cgroup maintainers and the
containers mailing list to the cc as well.

 Regards--
 Subrata

 On Mon, 2010-08-09 at 09:12 -0700, Paul E. McKenney wrote:
 On Mon, Aug 02, 2010 at 02:22:12PM +0530, Subrata Modak wrote:
  Hi,
 
  The following suspicious rcu_dereference_check() usage is detected
  during 2.6.35-stable boot on my ppc64/p7 machine:
 
  ==
  [ INFO: suspicious rcu_dereference_check() usage. ]
  ---
  kernel/sched.c:616 invoked rcu_dereference_check() without protection!
  other info that might help us debug this:
 
  rcu_scheduler_active = 1, debug_locks = 0
  1 lock held by swapper/1:
   #0:  (rq-lock){-.}, at: [c07ca2f8] .init_idle+0x78/0x4a8
  stack backtrace:
  Call Trace:
  [c00f392bf990] [c0014f04] .show_stack+0xb0/0x1a0 (unreliable)
  [c00f392bfa50] [c07c87b4] .dump_stack+0x28/0x3c
  [c00f392bfad0] [c0103e1c] .lockdep_rcu_dereference+0xbc/0xe4
  [c00f392bfb70] [c07ca434] .init_idle+0x1b4/0x4a8
  [c00f392bfc30] [c07cad04] .fork_idle+0xa4/0xd0
  [c00f392bfe30] [c0aefaac] .smp_prepare_cpus+0x23c/0x2f4
  [c00f392bfed0] [c0ae1424] .kernel_init+0xec/0x32c
  [c00f392bff90] [c0033f40] .kernel_thread+0x54/0x70
  ==
 
  Please note that this was reported earlier on 2.6.34-rc6:
  http://marc.info/?l=linux-kernelm=127313031922395w=2,
  The issue was fixed with:
      commit 1ce7e4ff24fe338438bc7837e02780f202bf202b
      Author: Li Zefan l...@cn.fujitsu.com
      Date:   Fri Apr 23 10:35:52 2010 +0800
      cgroup: Check task_lock in task_subsys_state()
 
  According to:
      http://lkml.org/lkml/2010/7/1/883,
      commit dc61b1d65e353d638b2445f71fb8e5b5630f2415
      Author: Peter Zijlstra a.p.zijls...@chello.nl
      Date:   Tue Jun 8 11:40:42 2010 +0200
      sched: Fix PROVE_RCU vs cpu_cgroup
  should have fixed this. But this is reproducible on 2.6.35-stable.
 
  Please also see the config file attached.

 Hello, Subrata,

 Thank you for locating this one!  This looks like the same issue that
 Ilia Mirkin located.  Please see below for my analysis -- no fix yet,
 as I need confirmation from cgroups experts.  I can easily create a
 patch that suppresses the warning, but I don't yet know whether this is
 the right thing to do.

                                                       Thanx, Paul

 

 On Thu, Aug 05, 2010 at 01:31:10PM -0400, Ilia Mirkin wrote:
  On Thu, Jul 1, 2010 at 6:18 PM, Paul E. McKenney
  paul...@linux.vnet.ibm.com wrote:
   On Thu, Jul 01, 2010 at 08:21:43AM -0400, Miles Lane wrote:
   [ INFO: suspicious rcu_dereference_check() usage. ]
   ---
   kernel/sched.c:616 invoked rcu_dereference_check() without protection!
  
   other info that might help us debug this:
  
   rcu_scheduler_active = 1, debug_locks = 1
   3 locks held by swapper/1:
     #0:  (cpu_add_remove_lock){+.+.+.}, at: [81042914]
   cpu_maps_update_begin+0x12/0x14
     #1:  (cpu_hotplug.lock){+.+.+.}, at: [8104294f]
   cpu_hotplug_begin+0x27/0x4e
     #2:  (rq-lock){-.-...}, at: [812f8502] 
   init_idle+0x2b/0x114
  
   Hello, Miles!
  
   I believe that this one is fixed by commit dc61b1d6 in -tip.
 
  Hi Paul,
 
  Looks like that commit made it into 2.6.35:
 
  git tag -l --contains dc61b1d65e353d638b2445f71fb8e5b5630f2415 v2.6.35*
  v2.6.35
  v2.6.35-rc4
  v2.6.35-rc5
  v2.6.35-rc6
 
  However I still get:
 
  [    0.051203] CPU0: AMD QEMU Virtual CPU version 0.12.4 stepping 03
  [    0.052999] lockdep: fixing up alternatives.
  [    0.054105]
  [    0.054106] ===
  [    0.054999] [ INFO: suspicious rcu_dereference_check() usage. ]
  [    0.054999] ---
  [    0.054999] kernel/sched.c:616 invoked rcu_dereference_check()
  without protection
  !
  [    0.054999]
  [    0.054999] other info that might help us debug this:
  [    0.054999]
  [    0.054999]
  [    0.054999] rcu_scheduler_active = 1, debug_locks = 1
  [    0.054999] 3 locks held by swapper/1:
  [    0.054999]  #0:  (cpu_add_remove_lock){+.+.+.}, at:
  [814be933] cpu_up+
  0x42/0x6a
  [    0.054999]  #1:  (cpu_hotplug.lock){+.+.+.}, at:
  [810400d8] cpu_hotplu
  g_begin+0x2a/0x51
  [    0.054999]  #2:  (rq-lock){-.-...}, at: [814be2f7]
  init_idle+0x2f/0x
  113
  [    0.054999]
  [    

Re: 2.6.35-stable/ppc64/p7: suspicious rcu_dereference_check() usage detected during 2.6.35-stable boot

2010-08-13 Thread Subrata Modak
Adding CONTROL GROUP Maintainers/Mailing list..

Regards--
Subrata

On Mon, 2010-08-09 at 09:12 -0700, Paul E. McKenney wrote:
 On Mon, Aug 02, 2010 at 02:22:12PM +0530, Subrata Modak wrote:
  Hi,
  
  The following suspicious rcu_dereference_check() usage is detected
  during 2.6.35-stable boot on my ppc64/p7 machine:
  
  ==
  [ INFO: suspicious rcu_dereference_check() usage. ]
  ---
  kernel/sched.c:616 invoked rcu_dereference_check() without protection!
  other info that might help us debug this:
  
  rcu_scheduler_active = 1, debug_locks = 0
  1 lock held by swapper/1:
   #0:  (rq-lock){-.}, at: [c07ca2f8] .init_idle+0x78/0x4a8
  stack backtrace:
  Call Trace:
  [c00f392bf990] [c0014f04] .show_stack+0xb0/0x1a0 (unreliable)
  [c00f392bfa50] [c07c87b4] .dump_stack+0x28/0x3c
  [c00f392bfad0] [c0103e1c] .lockdep_rcu_dereference+0xbc/0xe4
  [c00f392bfb70] [c07ca434] .init_idle+0x1b4/0x4a8
  [c00f392bfc30] [c07cad04] .fork_idle+0xa4/0xd0
  [c00f392bfe30] [c0aefaac] .smp_prepare_cpus+0x23c/0x2f4
  [c00f392bfed0] [c0ae1424] .kernel_init+0xec/0x32c
  [c00f392bff90] [c0033f40] .kernel_thread+0x54/0x70
  ==
  
  Please note that this was reported earlier on 2.6.34-rc6:
  http://marc.info/?l=linux-kernelm=127313031922395w=2,
  The issue was fixed with:
  commit 1ce7e4ff24fe338438bc7837e02780f202bf202b
  Author: Li Zefan l...@cn.fujitsu.com
  Date:   Fri Apr 23 10:35:52 2010 +0800
  cgroup: Check task_lock in task_subsys_state()
  
  According to:
  http://lkml.org/lkml/2010/7/1/883,
  commit dc61b1d65e353d638b2445f71fb8e5b5630f2415
  Author: Peter Zijlstra a.p.zijls...@chello.nl
  Date:   Tue Jun 8 11:40:42 2010 +0200
  sched: Fix PROVE_RCU vs cpu_cgroup
  should have fixed this. But this is reproducible on 2.6.35-stable.
  
  Please also see the config file attached.
 
 Hello, Subrata,
 
 Thank you for locating this one!  This looks like the same issue that
 Ilia Mirkin located.  Please see below for my analysis -- no fix yet,
 as I need confirmation from cgroups experts.  I can easily create a
 patch that suppresses the warning, but I don't yet know whether this is
 the right thing to do.
 
   Thanx, Paul
 
 
 
 On Thu, Aug 05, 2010 at 01:31:10PM -0400, Ilia Mirkin wrote:
  On Thu, Jul 1, 2010 at 6:18 PM, Paul E. McKenney
  paul...@linux.vnet.ibm.com wrote:
   On Thu, Jul 01, 2010 at 08:21:43AM -0400, Miles Lane wrote:
   [ INFO: suspicious rcu_dereference_check() usage. ]
   ---
   kernel/sched.c:616 invoked rcu_dereference_check() without protection!
  
   other info that might help us debug this:
  
   rcu_scheduler_active = 1, debug_locks = 1
   3 locks held by swapper/1:
 #0:  (cpu_add_remove_lock){+.+.+.}, at: [81042914]
   cpu_maps_update_begin+0x12/0x14
 #1:  (cpu_hotplug.lock){+.+.+.}, at: [8104294f]
   cpu_hotplug_begin+0x27/0x4e
 #2:  (rq-lock){-.-...}, at: [812f8502] init_idle+0x2b/0x114
  
   Hello, Miles!
  
   I believe that this one is fixed by commit dc61b1d6 in -tip.
  
  Hi Paul,
  
  Looks like that commit made it into 2.6.35:
  
  git tag -l --contains dc61b1d65e353d638b2445f71fb8e5b5630f2415 v2.6.35*
  v2.6.35
  v2.6.35-rc4
  v2.6.35-rc5
  v2.6.35-rc6
  
  However I still get:
  
  [0.051203] CPU0: AMD QEMU Virtual CPU version 0.12.4 stepping 03
  [0.052999] lockdep: fixing up alternatives.
  [0.054105]
  [0.054106] ===
  [0.054999] [ INFO: suspicious rcu_dereference_check() usage. ]
  [0.054999] ---
  [0.054999] kernel/sched.c:616 invoked rcu_dereference_check()
  without protection
  !
  [0.054999]
  [0.054999] other info that might help us debug this:
  [0.054999]
  [0.054999]
  [0.054999] rcu_scheduler_active = 1, debug_locks = 1
  [0.054999] 3 locks held by swapper/1:
  [0.054999]  #0:  (cpu_add_remove_lock){+.+.+.}, at:
  [814be933] cpu_up+
  0x42/0x6a
  [0.054999]  #1:  (cpu_hotplug.lock){+.+.+.}, at:
  [810400d8] cpu_hotplu
  g_begin+0x2a/0x51
  [0.054999]  #2:  (rq-lock){-.-...}, at: [814be2f7]
  init_idle+0x2f/0x
  113
  [0.054999]
  [0.054999] stack backtrace:
  [0.054999] Pid: 1, comm: swapper Not tainted 2.6.35 #1
  [0.054999] Call Trace:
  [0.054999]  [81068054] lockdep_rcu_dereference+0x9b/0xa3
  [0.054999]  [810325c3] task_group+0x7b/0x8a
  [0.054999]  [810325e5] set_task_rq+0x13/0x40
  [0.054999]  [814be39a] init_idle+0xd2/0x113
  [

Re: [PATCH 08/12] ptp: Added a brand new class driver for ptp clocks.

2010-08-13 Thread Richard Cochran
On Tue, Jun 15, 2010 at 01:11:30PM -0600, Grant Likely wrote:
 On Tue, Jun 15, 2010 at 10:09 AM, Richard Cochran
  +static DEFINE_SPINLOCK(clocks_lock); /* protects 'clocks' */
 
 Doesn't appear that clocks is manipulated at atomic context.  Mutex instead?
...
 If the spinlock is changed to a mutex that is held for the entire
 function call, then the logic here can be simpler.

Grant,

I am working on another go at this patch series. Stupid question:

The caller of ptp_clock_register(), which takes the clocks_lock, is
always a module_init() function. Is this always a safe context in
which to call mutex_lock?

Thanks,

Richard

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: How to use mpc8xxx_gpio.c device driver

2010-08-13 Thread Ravi Gupta
On Wed, Aug 11, 2010 at 10:15 PM, Anton Vorontsov cbouatmai...@gmail.comwrote:

 Hi,

 On Wed, Aug 11, 2010 at 06:57:16PM +0530, Ravi Gupta wrote:
  I am new to device driver development. I am trying to access the GPIO of
  MPC837xERDB eval board. I have upgraded its kernel to linux-2.6.28.9 and
  enable support for mpc8xxx_gpio.c. On boot up, it successfully detect two
  gpio controllers. Now my question is how I am going to use it to
 communicate
  with the gpio pins? Do I have to modify the code in mpc8xxx_gpio.c file
 to
  do whatever I want to do with gpios or I can use the standard gpio API
  provided in kernel ( gpio_request()/gpio_free() ). I also tries the
 standard
  kernel API, but it fails. Here is my code :

 No, you don't have to modify anything, and yes, you can
 use standard kernel GPIO API.

  #include linux/module.h
  #include linux/errno.h  /* error codes */
  #include linux/gpio.h
 
  static __init int sample_module_init(void)
  {
int ret;
 
int i;
for (i=1; i32; i++) {
  ret = gpio_request(i, Sample Driver);

 Before issing gpio_request() you must get GPIO number from the
 of_get_gpio() or of_get_gpio_flags() calls (the _flags variant
 will also retreive flags such as 'active-low').

 The calls assume that you have gpio =  specifier in the
 device tree, see arch/powerpc/boot/dts/mpc8377_rdb.dts's
 leds node as an example.

 As you want GPIO LEDs, you can use drivers/leds/leds-gpio.c
 (see of_gpio_leds_probe() call, it gets gpio numbers via
 of_get_gpio_flags() and then requests them via gpio_request()).

 Also see

 Documentation/powerpc/dts-bindings/gpio/gpio.txt
 Documentation/powerpc/dts-bindings/gpio/led.txt

  if (ret) {
printk(KERN_WARNING sample_driver: unable to request GPIO_PG%d\n,
  i);
//return ret;
  }
}
 
return 0;
  }


 On Wed, Aug 11, 2010 at 07:49:40PM +0530, Ravi Gupta wrote:
  Also, when I try to export a gpio in sysfs
 
  echo 9  /sys/class/gpio/export

 The gpio numbers are global, i.e. GPIO controller base + GPIO
 number within the controller.

 [...]
  drwxr-xr-x3 root root0 Jan  1 00:00 gpiochip192

 So, if you want GPIO9 within gpiochip192, you should issue
 echo 201  export.

 Thanks,

 --
 Anton Vorontsov
 email: cbouatmai...@gmail.com
 irc://irc.freenode.net/bd2


Hi Anton,

Thanks for the reply.
I had added the entries for gpio pin 9 for both controllers(I was not sure
with controller's pin is connected to LED, but now I know it is pin no. 233
i.e 224+9) in the mpc8377_rdb.dts file. Below is a portion of my dts file, I
have attached the complete dts file as attachment.

i...@e000 {
#address-cells = 1;
#size-cells = 1;
device_type = soc;
compatible = simple-bus;
ranges = 0x0 0xe000 0x0010;
reg = 0xe000 0x0200;
bus-frequency = 0;

w...@200 {
device_type = watchdog;
compatible = mpc83xx_wdt;
reg = 0x200 0x100;
};

gpio1: gpio-control...@c00 {
#gpio-cells = 2;
compatible = fsl,mpc8377-gpio, fsl,mpc8349-gpio;
reg = 0xc00 0x100;
interrupts = 74 0x8;
interrupt-parent = ipic;
gpio-controller;
};

gpio2: gpio-control...@d00 {
#gpio-cells = 2;
compatible = fsl,mpc8377-gpio, fsl,mpc8349-gpio;
reg = 0xd00 0x100;
interrupts = 75 0x8;
interrupt-parent = ipic;
gpio-controller;
};

   * l...@0 {
compatible = gpio-leds;
label = hdd;
gpios = gpio1 9 0;
};

l...@1 {
compatible = gpio-leds;
label = rom;
gpios = gpio2 9 0;
};*
.
.
.
.
};


Also I have enabled drivers/leds/leds-gpio.c in my kernel. To test whether
the leds entires in dts file get attached to leds-gpio driver, I added
printks in the probe function of the driver.

static int gpio_led_probe(struct platform_device *pdev)
{
  struct gpio_led_platform_data *pdata = pdev-dev.platform_data;
  struct gpio_led *cur_led;
  struct gpio_led_data *leds_data, *led_dat;
  int i, ret = 0;

  *printk(KERN_INFO led: inside gpio_led_probe.\n);*

  
}

But I couldn't see led: inside gpio_led_probe. message in dmesg. I checked
sysfs and I can see entries of leds. Here is contents of sysfs on my
machine.

# ls /sys/devices/ -la
drwxr-xr-x7 root root0 Jan  1 01:58 .
drwxr-xr-x   12 root root0 Jan  1 00:00 ..
drwxr-xr-x   22 root root0 Jan  1 01:58 *e000.immr*
drwxr-xr-x5 root root0 Jan  1 01:58 e0005000.localbus
drwxr-xr-x4 root root0 Jan  1 01:58 pci:00
drwxr-xr-x9 root root0 Jan  1 01:58 platform
drwxr-xr-x8 root root0 Jan  1 01:58 system


# ls /sys/devices/e000.immr/
bus   e0004600.serial   *led1.0*
devspece0007000.spi   *led2.1*
e200.wdte00082a8.dma modalias

Re: How to use mpc8xxx_gpio.c device driver

2010-08-13 Thread Ravi Gupta
 Looking at the device tree for this board, it appears U-Boot remaps the
 IMMR registers to 0xe000. They are no longer accessible at
 0xff40.

 I would recommend studying arch/powerpc/boot/dts/mpc8377_rdb.dts in the
 Linux source code. That describes the device layout on your board after
 U-Boot has run.

 A wonderful tool for testing devices from userspace is busybox devmem.
 It allows you to poke any physical address with any value. The output of
 busybox devmem --help should get you started. As a quick example,
 busybox devmem 0xec00 w 0x1 will write the 32-bit value 0x1 to
 address 0xec00.

 I would also recommend using the built-in Linux GPIO API. It works, you
 just need to figure out how to use it. It will be much easier to get
 your code upstream if you use the provided APIs.

 The Documentation/gpio.txt file should help you in understanding the
 in-kernel Linux GPIO API. I'm afraid I don't have much experience other
 than accessing it via sysfs from userspace.

 Ira


Hi Ira,

Thanks for another great reply. Now I can also access gpio memory map
registers.

Thanks and Regards,
Ravi Gupta
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: How to use mpc8xxx_gpio.c device driver

2010-08-13 Thread Anton Vorontsov
Hi,

On Fri, Aug 13, 2010 at 03:29:11PM +0530, Ravi Gupta wrote:
[...]
 Thanks for the reply.
 I had added the entries for gpio pin 9 for both controllers(I was not sure
 with controller's pin is connected to LED, but now I know it is pin no. 233
 i.e 224+9) in the mpc8377_rdb.dts file. Below is a portion of my dts file, I
 have attached the complete dts file as attachment.
 
 i...@e000 {
[...]
* l...@0 {
 compatible = gpio-leds;
 label = hdd;
 gpios = gpio1 9 0;
 };

What kernel version you look at? Please see the latest kernel,
it has MCU GPIO LED nodes already, and you can just add some
additional nodes.

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=arch/powerpc/boot/dts/mpc8377_rdb.dts#l490

[...]
 Also I have enabled drivers/leds/leds-gpio.c in my kernel. To test whether
 the leds entires in dts file get attached to leds-gpio driver, I added
 printks in the probe function of the driver.
 
 static int gpio_led_probe(struct platform_device *pdev)
 {
   struct gpio_led_platform_data *pdata = pdev-dev.platform_data;
   struct gpio_led *cur_led;
   struct gpio_led_data *leds_data, *led_dat;
   int i, ret = 0;
 
   *printk(KERN_INFO led: inside gpio_led_probe.\n);*

You have put the printk into the wrong function. It should
have been of_gpio_leds_probe():

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=drivers/leds/leds-gpio.c#l227

If you don't have that function then you use too old kernel.

Thanks,

-- 
Anton Vorontsov
email: cbouatmai...@gmail.com
irc://irc.freenode.net/bd2
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/9] RapidIO: fix RapidIO sysfs hierarchy

2010-08-13 Thread Alexandre Bounine
Makes RapidIO devices appear in /sys/devices/rapidio directory instead of top
of /sys/devices directory.

Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com
Reviewed-by: Thomas Moll thomas.m...@sysgo.com
Cc: Matt Porter mpor...@kernel.crashing.org
Cc: Li Yang le...@freescale.com
Cc: Kumar Gala ga...@kernel.crashing.org
---
 drivers/rapidio/rio-driver.c |2 +-
 drivers/rapidio/rio-scan.c   |1 +
 include/linux/rio.h  |1 +
 3 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index 3222fa3..0f4a53b 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -192,7 +192,7 @@ static int rio_match_bus(struct device *dev, struct 
device_driver *drv)
   out:return 0;
 }
 
-static struct device rio_bus = {
+struct device rio_bus = {
.init_name = rapidio,
 };
 
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 8070e07..1123be8 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -478,6 +478,7 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
}
 
rdev-dev.bus = rio_bus_type;
+   rdev-dev.parent = rio_bus;
 
device_initialize(rdev-dev);
rdev-dev.release = rio_release_dev;
diff --git a/include/linux/rio.h b/include/linux/rio.h
index bd6eb0e..84c9f8c 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -67,6 +67,7 @@
 #define RIO_PW_MSG_SIZE64
 
 extern struct bus_type rio_bus_type;
+extern struct device rio_bus;
 extern struct list_head rio_devices;   /* list of all devices */
 
 struct rio_mport;
-- 
1.7.0.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 0/9] RapidIO: Set of patches to add Gen2 switches

2010-08-13 Thread Alexandre Bounine
This set of RapidIO patches adds support for new IDT Gen2 sRIO switch
devices - CPS-1848 and CPS-1616.
Adding these sRIO switches required to implement standard error recovery
mechanism defined by the RapidIO specification.

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/9] RapidIO, powerpc/85xx: modify RIO port-write interrupt handler

2010-08-13 Thread Alexandre Bounine
- Rearranged RIO port-write interrupt handling to perform message buffering
as soon as possible.
- Modified to disable port-write controller when clearing Transaction Error (TE)
bit.

Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com
Reviewed-by: Thomas Moll thomas.m...@sysgo.com
Cc: Matt Porter mpor...@kernel.crashing.org
Cc: Li Yang le...@freescale.com
Cc: Kumar Gala ga...@kernel.crashing.org
---
 arch/powerpc/sysdev/fsl_rio.c |   67 ++--
 1 files changed, 37 insertions(+), 30 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index cd71dc1..708d94e 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1065,18 +1065,12 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
struct rio_priv *priv = port-priv;
u32 epwisr, tmp;
 
-   ipwmr = in_be32(priv-msg_regs-pwmr);
-   ipwsr = in_be32(priv-msg_regs-pwsr);
-
epwisr = in_be32(priv-regs_win + RIO_EPWISR);
-   if (epwisr  0x8000) {
-   tmp = in_be32(priv-regs_win + RIO_LTLEDCSR);
-   pr_info(RIO_LTLEDCSR = 0x%x\n, tmp);
-   out_be32(priv-regs_win + RIO_LTLEDCSR, 0);
-   }
-
if (!(epwisr  0x0001))
-   return IRQ_HANDLED;
+   goto pw_done;
+
+   ipwmr = in_be32(priv-msg_regs-pwmr);
+   ipwsr = in_be32(priv-msg_regs-pwsr);
 
 #ifdef DEBUG_PW
pr_debug(PW Int-IPWMR: 0x%08x IPWSR: 0x%08x (, ipwmr, ipwsr);
@@ -1092,22 +1086,8 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
pr_debug( PWB);
pr_debug( )\n);
 #endif
-   out_be32(priv-msg_regs-pwsr,
-ipwsr  (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD));
-
-   if ((ipwmr  RIO_IPWMR_EIE)  (ipwsr  RIO_IPWSR_TE)) {
-   priv-port_write_msg.err_count++;
-   pr_info(RIO: Port-Write Transaction Err (%d)\n,
-priv-port_write_msg.err_count);
-   }
-   if (ipwsr  RIO_IPWSR_PWD) {
-   priv-port_write_msg.discard_count++;
-   pr_info(RIO: Port Discarded Port-Write Msg(s) (%d)\n,
-priv-port_write_msg.discard_count);
-   }
-
/* Schedule deferred processing if PW was received */
-   if (ipwsr  RIO_IPWSR_QFI) {
+   if ((ipwmr  RIO_IPWMR_QFIE)  (ipwsr  RIO_IPWSR_QFI)) {
/* Save PW message (if there is room in FIFO),
 * otherwise discard it.
 */
@@ -1117,16 +1097,43 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
 RIO_PW_MSG_SIZE);
} else {
priv-port_write_msg.discard_count++;
-   pr_info(RIO: ISR Discarded Port-Write Msg(s) (%d)\n,
+   pr_debug(RIO: ISR Discarded Port-Write Msg(s) (%d)\n,
 priv-port_write_msg.discard_count);
}
+   /* Clear interrupt and issue Clear Queue command. This allows
+* another port-write to be received.
+*/
+   out_be32(priv-msg_regs-pwsr, RIO_IPWSR_QFI);
+   out_be32(priv-msg_regs-pwmr, ipwmr | RIO_IPWMR_CQ);
+
schedule_work(priv-pw_work);
}
 
-   /* Issue Clear Queue command. This allows another
-* port-write to be received.
-*/
-   out_be32(priv-msg_regs-pwmr, ipwmr | RIO_IPWMR_CQ);
+   if ((ipwmr  RIO_IPWMR_EIE)  (ipwsr  RIO_IPWSR_TE)) {
+   priv-port_write_msg.err_count++;
+   pr_debug(RIO: Port-Write Transaction Err (%d)\n,
+priv-port_write_msg.err_count);
+   /* Clear Transaction Error: port-write controller should be
+* disabled when clearing this error
+*/
+   out_be32(priv-msg_regs-pwmr, ipwmr  ~RIO_IPWMR_PWE);
+   out_be32(priv-msg_regs-pwsr, RIO_IPWSR_TE);
+   out_be32(priv-msg_regs-pwmr, ipwmr);
+   }
+
+   if (ipwsr  RIO_IPWSR_PWD) {
+   priv-port_write_msg.discard_count++;
+   pr_debug(RIO: Port Discarded Port-Write Msg(s) (%d)\n,
+priv-port_write_msg.discard_count);
+   out_be32(priv-msg_regs-pwsr, RIO_IPWSR_PWD);
+   }
+
+pw_done:
+   if (epwisr  0x8000) {
+   tmp = in_be32(priv-regs_win + RIO_LTLEDCSR);
+   pr_debug(RIO_LTLEDCSR = 0x%x\n, tmp);
+   out_be32(priv-regs_win + RIO_LTLEDCSR, 0);
+   }
 
return IRQ_HANDLED;
 }
-- 
1.7.0.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 3/9] RapidIO: Add the ingress port number into the RIO switch data structure

2010-08-13 Thread Alexandre Bounine
A switch ingress port number has to be saved for software assisted error
recovery from the error-stopped state. Saving this information also allows
to remove several register reads from the RIO enumeration process.

Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com
Reviewed-by: Thomas Moll thomas.m...@sysgo.com
Cc: Matt Porter mpor...@kernel.crashing.org
Cc: Li Yang le...@freescale.com
Cc: Kumar Gala ga...@kernel.crashing.org
---
 drivers/rapidio/rio-scan.c |   38 --
 include/linux/rio.h|4 ++--
 2 files changed, 10 insertions(+), 32 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 1123be8..efe3519 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -389,6 +389,7 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
int ret = 0;
struct rio_dev *rdev;
struct rio_switch *rswitch = NULL;
+   u32 swpinfo;
int result, rdid;
 
rdev = kzalloc(sizeof(struct rio_dev), GFP_KERNEL);
@@ -440,7 +441,7 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
/* If a PE has both switch and other functions, show it as a switch */
if (rio_is_switch(rdev)) {
rio_mport_read_config_32(port, destid, hopcount,
-RIO_SWP_INFO_CAR, rdev-swpinfo);
+RIO_SWP_INFO_CAR, swpinfo);
rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL);
if (!rswitch)
goto cleanup;
@@ -448,6 +449,7 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
rswitch-hopcount = hopcount;
rswitch-destid = destid;
rswitch-port_ok = 0;
+   rswitch-inport = (u8)(swpinfo  RIO_SWP_INFO_PORT_NUM_MASK);
rswitch-route_table = kzalloc(sizeof(u8)*
RIO_MAX_ROUTE_ENTRIES(port-sys_size),
GFP_KERNEL);
@@ -719,25 +721,6 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport 
*port, u8 hopcount)
 }
 
 /**
- * rio_get_swpinfo_inport- Gets the ingress port number
- * @mport: Master port to send transaction
- * @destid: Destination ID associated with the switch
- * @hopcount: Number of hops to the device
- *
- * Returns port number being used to access the switch device.
- */
-static u8
-rio_get_swpinfo_inport(struct rio_mport *mport, u16 destid, u8 hopcount)
-{
-   u32 result;
-
-   rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
-result);
-
-   return (u8) (result  0xff);
-}
-
-/**
  * rio_get_swpinfo_tports- Gets total number of ports on the switch
  * @mport: Master port to send transaction
  * @destid: Destination ID associated with the switch
@@ -834,8 +817,7 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
 
if (rio_is_switch(rdev)) {
next_switchid++;
-   sw_inport = rio_get_swpinfo_inport(port,
-   RIO_ANY_DESTID(port-sys_size), hopcount);
+   sw_inport = rdev-rswitch-inport;
rio_route_add_entry(port, rdev-rswitch, RIO_GLOBAL_TABLE,
port-host_deviceid, sw_inport, 0);
rdev-rswitch-route_table[port-host_deviceid] = sw_inport;
@@ -989,8 +971,7 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, 
u16 destid,
RIO: found %s (vid %4.4x did %4.4x) with %d ports\n,
rio_name(rdev), rdev-vid, rdev-did, num_ports);
for (port_num = 0; port_num  num_ports; port_num++) {
-   if (rio_get_swpinfo_inport(port, destid, hopcount) ==
-   port_num)
+   if (rdev-rswitch-inport == port_num)
continue;
 
if (rio_sport_is_active
@@ -1092,7 +1073,6 @@ static void rio_update_route_tables(struct rio_mport 
*port)
 {
struct rio_dev *rdev;
struct rio_switch *rswitch;
-   u8 sport;
u16 destid;
 
list_for_each_entry(rdev, rio_devices, global_list) {
@@ -1109,14 +1089,12 @@ static void rio_update_route_tables(struct rio_mport 
*port)
if (rswitch-destid == destid)
continue;
 
-   sport = rio_get_swpinfo_inport(port,
-   rswitch-destid, 
rswitch-hopcount);
-
if (rswitch-add_entry) {
rio_route_add_entry(port, rswitch,
RIO_GLOBAL_TABLE, destid,
-   sport, 0);
-   

[PATCH 4/9] RapidIO: Add relation links between RIO device structures

2010-08-13 Thread Alexandre Bounine
Create back and forward links between RIO devices. These links are intended for
use by error management and hot-plug extensions.

Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com
Reviewed-by: Thomas Moll thomas.m...@sysgo.com
Cc: Matt Porter mpor...@kernel.crashing.org
Cc: Li Yang le...@freescale.com
Cc: Kumar Gala ga...@kernel.crashing.org
---
 drivers/rapidio/rio-scan.c |   55 +--
 include/linux/rio.h|6 
 2 files changed, 28 insertions(+), 33 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index efe3519..5dc33d1 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -442,7 +442,10 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
if (rio_is_switch(rdev)) {
rio_mport_read_config_32(port, destid, hopcount,
 RIO_SWP_INFO_CAR, swpinfo);
-   rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL);
+   rswitch = kzalloc(sizeof(*rswitch) +
+ RIO_GET_TOTAL_PORTS(swpinfo) *
+ sizeof(rswitch-nextdev[0]),
+ GFP_KERNEL);
if (!rswitch)
goto cleanup;
rswitch-switchid = next_switchid;
@@ -450,6 +453,7 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
rswitch-destid = destid;
rswitch-port_ok = 0;
rswitch-inport = (u8)(swpinfo  RIO_SWP_INFO_PORT_NUM_MASK);
+   rswitch-nports = (u8)RIO_GET_TOTAL_PORTS(swpinfo);
rswitch-route_table = kzalloc(sizeof(u8)*
RIO_MAX_ROUTE_ENTRIES(port-sys_size),
GFP_KERNEL);
@@ -721,25 +725,6 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport 
*port, u8 hopcount)
 }
 
 /**
- * rio_get_swpinfo_tports- Gets total number of ports on the switch
- * @mport: Master port to send transaction
- * @destid: Destination ID associated with the switch
- * @hopcount: Number of hops to the device
- *
- * Returns total numbers of ports implemented by the switch device.
- */
-static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid,
-u8 hopcount)
-{
-   u32 result;
-
-   rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
-result);
-
-   return RIO_GET_TOTAL_PORTS(result);
-}
-
-/**
  * rio_net_add_mport- Add a master port to a RIO network
  * @net: RIO network
  * @port: Master port to add
@@ -759,15 +744,16 @@ static void rio_net_add_mport(struct rio_net *net, struct 
rio_mport *port)
  * @net: RIO network being enumerated
  * @port: Master port to send transactions
  * @hopcount: Number of hops into the network
+ * @prev: Previous RIO device connected to the enumerated one
+ * @prev_port: Port on previous RIO device
  *
  * Recursively enumerates a RIO network.  Transactions are sent via the
  * master port passed in @port.
  */
 static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
-u8 hopcount)
+u8 hopcount, struct rio_dev *prev, int prev_port)
 {
int port_num;
-   int num_ports;
int cur_destid;
int sw_destid;
int sw_inport;
@@ -812,6 +798,9 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
if (rdev) {
/* Add device to the global and bus/net specific list. */
list_add_tail(rdev-net_list, net-devices);
+   rdev-prev = prev;
+   if (prev  rio_is_switch(prev))
+   prev-rswitch-nextdev[prev_port] = rdev;
} else
return -1;
 
@@ -830,14 +819,13 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
rdev-rswitch-route_table[destid] = sw_inport;
}
 
-   num_ports =
-   rio_get_swpinfo_tports(port, RIO_ANY_DESTID(port-sys_size),
-   hopcount);
pr_debug(
RIO: found %s (vid %4.4x did %4.4x) with %d ports\n,
-   rio_name(rdev), rdev-vid, rdev-did, num_ports);
+   rio_name(rdev), rdev-vid, rdev-did,
+   rdev-rswitch-nports);
sw_destid = next_destid;
-   for (port_num = 0; port_num  num_ports; port_num++) {
+   for (port_num = 0;
+port_num  rdev-rswitch-nports; port_num++) {
/*Enable Input Output Port (transmitter reviever)*/
rio_enable_rx_tx_port(port, 0,
  RIO_ANY_DESTID(port-sys_size),
@@ -862,7 +850,8 @@ static int __devinit 

[PATCH 5/9] RapidIO: Add default handler for error_stopped state

2010-08-13 Thread Alexandre Bounine
The default error-stopped state handler provides recovery mechanism as defined
by RIO specification.

Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com
Reviewed-by: Thomas Moll thomas.m...@sysgo.com
Cc: Matt Porter mpor...@kernel.crashing.org
Cc: Li Yang le...@freescale.com
Cc: Kumar Gala ga...@kernel.crashing.org
---
 drivers/rapidio/rio.c |  191 +++--
 drivers/rapidio/switches/idtcps.c |   10 ++
 drivers/rapidio/switches/tsi57x.c |4 +
 include/linux/rio_regs.h  |8 +-
 4 files changed, 179 insertions(+), 34 deletions(-)

diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 74e9d22..f58df11 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -495,6 +495,121 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, 
int lock)
 }
 
 /**
+ * rio_clr_err_stopped - Clears port Error-stopped states.
+ * @rdev: Pointer to RIO device control structure
+ * @pnum: Switch port number to clear errors
+ * @err_status: port error status (if 0 reads register from device)
+ */
+static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status)
+{
+   struct rio_mport *mport = rdev-net-hport;
+   u16 destid = rdev-rswitch-destid;
+   u8 hopcount = rdev-rswitch-hopcount;
+   struct rio_dev *nextdev = rdev-rswitch-nextdev[pnum];
+   u32 regval;
+   u32 far_ackid, far_linkstat, near_ackid;
+   int checkcount;
+
+   if (err_status == 0)
+   rio_mport_read_config_32(mport, destid, hopcount,
+   rdev-phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum),
+   err_status);
+
+   if (err_status  RIO_PORT_N_ERR_STS_PW_OUT_ES) {
+   pr_debug(RIO_EM: servicing Output Error-Stopped state\n);
+   /*
+* Send a Link-Request/Input-Status control symbol
+*/
+
+   /* Read from link maintenance response register
+* to clear valid bit */
+   rio_mport_read_config_32(mport, destid, hopcount,
+   rdev-phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum),
+   regval);
+   udelay(50);
+
+   /* Issue Input-status command */
+   rio_mport_write_config_32(mport, destid, hopcount,
+   rdev-phys_efptr + RIO_PORT_N_MNT_REQ_CSR(pnum),
+   RIO_MNT_REQ_CMD_IS);
+
+   checkcount = 3;
+   while (checkcount--) {
+   udelay(50);
+   rio_mport_read_config_32(mport, destid, hopcount,
+   rdev-phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum),
+   regval);
+   if (regval  RIO_PORT_N_MNT_RSP_RVAL)
+   break;
+   }
+
+   pr_debug(RIO_EM: SP%d_MNT_RSP_CSR=0x%08x\n, pnum, regval);
+   if (regval  RIO_PORT_N_MNT_RSP_RVAL) {
+   far_ackid = (regval  RIO_PORT_N_MNT_RSP_ASTAT)  5;
+   far_linkstat = regval  RIO_PORT_N_MNT_RSP_LSTAT;
+   rio_mport_read_config_32(mport, destid, hopcount,
+   rdev-phys_efptr + RIO_PORT_N_ACK_STS_CSR(pnum),
+   regval);
+   pr_debug(RIO_EM: SP%d_ACK_STS_CSR=0x%08x\n,
+   pnum, regval);
+   near_ackid = (regval  RIO_PORT_N_ACK_INBOUND)  24;
+   pr_debug(RIO_EM: SP%d far_ackID=0x%02x 
far_linkstat=0x%02x near_ackID=0x%02x\n,
+   pnum, far_ackid, far_linkstat, near_ackid);
+
+   /*
+* If required, synchronize ackIDs of near and
+* far sides.
+*/
+   if ((far_ackid != ((regval  RIO_PORT_N_ACK_OUTSTAND) 
 8)) ||
+   (far_ackid != (regval  RIO_PORT_N_ACK_OUTBOUND))) {
+   /* Align near outstanding/outbound ackIDs with
+* far inbound.
+*/
+   rio_mport_write_config_32(mport, destid,
+   hopcount, rdev-phys_efptr +
+   RIO_PORT_N_ACK_STS_CSR(pnum),
+   (near_ackid  24) |
+   (far_ackid  8) | far_ackid);
+   /* Align far outstanding/outbound ackIDs with
+* near inbound.
+*/
+   far_ackid++;
+   if (nextdev)
+   rio_write_config_32(nextdev,
+   nextdev-phys_efptr +
+   

[PATCH 6/9] RapidIO: Add switch-specific sysfs initialization callback

2010-08-13 Thread Alexandre Bounine
Add callback that allows to create/remove switch-specific sysfs attributes.

Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com
Reviewed-by: Thomas Moll thomas.m...@sysgo.com
Cc: Matt Porter mpor...@kernel.crashing.org
Cc: Li Yang le...@freescale.com
Cc: Kumar Gala ga...@kernel.crashing.org
---
 drivers/rapidio/rio-sysfs.c |   26 +++---
 include/linux/rio.h |2 ++
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 00b4756..bfc483b 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -40,9 +40,6 @@ static ssize_t routes_show(struct device *dev, struct 
device_attribute *attr, ch
char *str = buf;
int i;
 
-   if (!rdev-rswitch)
-   goto out;
-
for (i = 0; i  RIO_MAX_ROUTE_ENTRIES(rdev-net-hport-sys_size);
i++) {
if (rdev-rswitch-route_table[i] == RIO_INVALID_ROUTE)
@@ -52,7 +49,6 @@ static ssize_t routes_show(struct device *dev, struct 
device_attribute *attr, ch
rdev-rswitch-route_table[i]);
}
 
-  out:
return (str - buf);
 }
 
@@ -63,10 +59,11 @@ struct device_attribute rio_dev_attrs[] = {
__ATTR_RO(asm_did),
__ATTR_RO(asm_vid),
__ATTR_RO(asm_rev),
-   __ATTR_RO(routes),
__ATTR_NULL,
 };
 
+static DEVICE_ATTR(routes, S_IRUGO, routes_show, NULL);
+
 static ssize_t
 rio_read_config(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
@@ -218,7 +215,17 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev)
 {
int err = 0;
 
-   err = sysfs_create_bin_file(rdev-dev.kobj, rio_config_attr);
+   err = device_create_bin_file(rdev-dev, rio_config_attr);
+
+   if (!err  rdev-rswitch) {
+   err = device_create_file(rdev-dev, dev_attr_routes);
+   if (!err  rdev-rswitch-sw_sysfs)
+   err = rdev-rswitch-sw_sysfs(rdev, 1);
+   }
+
+   if (err)
+   pr_warning(RIO: Failed to create attribute file(s) for %s\n,
+  rio_name(rdev));
 
return err;
 }
@@ -231,5 +238,10 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev)
  */
 void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
 {
-   sysfs_remove_bin_file(rdev-dev.kobj, rio_config_attr);
+   device_remove_bin_file(rdev-dev, rio_config_attr);
+   if (rdev-rswitch) {
+   device_remove_file(rdev-dev, dev_attr_routes);
+   if (rdev-rswitch-sw_sysfs)
+   rdev-rswitch-sw_sysfs(rdev, 0);
+   }
 }
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 754895c..8f19fb2 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -233,6 +233,7 @@ struct rio_net {
  * @get_domain: Callback for switch-specific domain get function
  * @em_init: Callback for switch-specific error management initialization 
function
  * @em_handle: Callback for switch-specific error management handler function
+ * @sw_sysfs: Callback that initializes switch-specific sysfs attributes
  * @nextdev: Array of per-port pointers to the next attached device
  */
 struct rio_switch {
@@ -256,6 +257,7 @@ struct rio_switch {
   u8 *sw_domain);
int (*em_init) (struct rio_dev *dev);
int (*em_handle) (struct rio_dev *dev, u8 swport);
+   int (*sw_sysfs) (struct rio_dev *dev, int create);
struct rio_dev *nextdev[0];
 };
 
-- 
1.7.0.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 7/9] RapidIO: Add handling for PW message from a lost device

2010-08-13 Thread Alexandre Bounine
Add check if PW message source device is accessible and change PW message
handler to recover if PW message source device is not available anymore (power
down or link disconnect).
To avoid possible loss of notification, the PW message handler scans the route
back from the source device to identify end of the broken link.

Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com
Reviewed-by: Thomas Moll thomas.m...@sysgo.com
Cc: Matt Porter mpor...@kernel.crashing.org
Cc: Li Yang le...@freescale.com
Cc: Kumar Gala ga...@kernel.crashing.org
---
 drivers/rapidio/rio.c |  111 ++--
 drivers/rapidio/rio.h |2 +
 2 files changed, 108 insertions(+), 5 deletions(-)

diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index f58df11..22f7847 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -495,6 +495,90 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, 
int lock)
 }
 
 /**
+ * rio_chk_dev_route - Validate route to the specified device.
+ * @rdev: Pointer to RIO device control structure
+ * @nrdev: Pointer to last active device on the route to rdev
+ * @npnum: nrdev port number on the route to rdev
+ *
+ * Follows a route to the specified RIO device to determine the last available
+ * device (and corresponding RIO port) on the route.
+ */
+static int
+rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum)
+{
+   u32 result;
+   int p_port, rc = -EIO;
+   struct rio_dev *prev = NULL;
+
+   while (rdev-prev  (rdev-prev-pef  RIO_PEF_SWITCH)) {
+   if (rio_read_config_32(rdev-prev, RIO_DEV_ID_CAR, result)) {
+   rdev = rdev-prev;
+   continue;
+   }
+
+   prev = rdev-prev;
+   for (p_port = 0; p_port  prev-rswitch-nports; p_port++)
+   if (prev-rswitch-nextdev[p_port] == rdev)
+   break;
+
+   if (p_port  prev-rswitch-nports) {
+   pr_debug(RIO: link failed on [%s]-P%d\n,
+rio_name(prev), p_port);
+   *nrdev = prev;
+   *npnum = p_port;
+   rc = 0;
+   } else {
+   pr_debug(RIO: failed to trace route to %s\n,
+rio_name(prev));
+   }
+
+   break;
+   }
+
+   return rc;
+}
+
+/**
+ * rio_mport_chk_dev_access - Validate access to the specified device.
+ * @mport: Master port to send transactions
+ * @destid: Device destination ID in network
+ * @hopcount: Number of hops into the network
+ */
+static int
+rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount)
+{
+   int i = 0;
+   u32 tmp;
+
+   while (rio_mport_read_config_32(mport, destid, hopcount,
+   RIO_DEV_ID_CAR, tmp)) {
+   i++;
+   if (i == RIO_MAX_CHK_RETRY)
+   return -EIO;
+   mdelay(1);
+   }
+
+   return 0;
+}
+
+/**
+ * rio_chk_dev_access - Validate access to the specified device.
+ * @rdev: Pointer to RIO device control structure
+ */
+static int rio_chk_dev_access(struct rio_dev *rdev)
+{
+   u8 hopcount = 0xff;
+   u16 destid = rdev-destid;
+
+   if (rdev-rswitch) {
+   destid = rdev-rswitch-destid;
+   hopcount = rdev-rswitch-hopcount;
+   }
+
+   return rio_mport_chk_dev_access(rdev-net-hport, destid, hopcount);
+}
+
+/**
  * rio_clr_err_stopped - Clears port Error-stopped states.
  * @rdev: Pointer to RIO device control structure
  * @pnum: Switch port number to clear errors
@@ -627,8 +711,8 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg)
 
rdev = rio_get_comptag(pw_msg-em.comptag, NULL);
if (rdev == NULL) {
-   /* Someting bad here (probably enumeration error) */
-   pr_err(RIO: %s No matching device for CTag 0x%08x\n,
+   /* Device removed or enumeration error */
+   pr_debug(RIO: %s No matching device for CTag 0x%08x\n,
__func__, pw_msg-em.comptag);
return -EIO;
}
@@ -659,6 +743,26 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg)
return 0;
}
 
+   portnum = pw_msg-em.is_port  0xFF;
+
+   /* Check if device and route to it are functional:
+* Sometimes devices may send PW message(s) just before being
+* powered down (or link being lost).
+*/
+   if (rio_chk_dev_access(rdev)) {
+   pr_debug(RIO: device access failed - get link partner\n);
+   /* Scan route to the device and identify failed link.
+* This will replace device and port reported in PW message.
+* PW message should not be used after this point.
+*/
+   if (rio_chk_dev_route(rdev, 

[PATCH 8/9] RapidIO: Add device access check into the enumeration

2010-08-13 Thread Alexandre Bounine
Add explicit device access check before performing device enumeration.
This gives a chance to clear possible link error conditions by issuing safe
maintenance read request(s).

Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com
Reviewed-by: Thomas Moll thomas.m...@sysgo.com
Cc: Matt Porter mpor...@kernel.crashing.org
Cc: Li Yang le...@freescale.com
Cc: Kumar Gala ga...@kernel.crashing.org
---
 drivers/rapidio/rio-scan.c |6 ++
 drivers/rapidio/rio.c  |2 +-
 drivers/rapidio/rio.h  |2 ++
 3 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 5dc33d1..fb5324b 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -761,6 +761,12 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
u16 destid;
int tmp;
 
+   if (rio_mport_chk_dev_access(port,
+   RIO_ANY_DESTID(port-sys_size), hopcount)) {
+   pr_debug(RIO: device access check failed\n);
+   return -1;
+   }
+
if (rio_get_host_deviceid_lock(port, hopcount) == port-host_deviceid) {
pr_debug(RIO: PE already discovered by this host\n);
/*
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 22f7847..9621a7b 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -544,7 +544,7 @@ rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev 
**nrdev, int *npnum)
  * @destid: Device destination ID in network
  * @hopcount: Number of hops into the network
  */
-static int
+int
 rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount)
 {
int i = 0;
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
index bc71ba1..d249a12 100644
--- a/drivers/rapidio/rio.h
+++ b/drivers/rapidio/rio.h
@@ -24,6 +24,8 @@ extern u32 rio_mport_get_physefb(struct rio_mport *port, int 
local,
 u16 destid, u8 hopcount);
 extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid,
 u8 hopcount, u32 from);
+extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid,
+   u8 hopcount);
 extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
 extern int rio_enum_mport(struct rio_mport *mport);
 extern int rio_disc_mport(struct rio_mport *mport);
-- 
1.7.0.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 9/9] RapidIO: Add support for IDT CPS Gen2 switches

2010-08-13 Thread Alexandre Bounine
Add the RIO switch driver and definitions for IDT CPS-1848 and CPS-1616 Gen2
devices.

Signed-off-by: Alexandre Bounine alexandre.boun...@idt.com
Reviewed-by: Thomas Moll thomas.m...@sysgo.com
Cc: Matt Porter mpor...@kernel.crashing.org
Cc: Li Yang le...@freescale.com
Cc: Kumar Gala ga...@kernel.crashing.org
---
 drivers/rapidio/switches/Kconfig|7 +
 drivers/rapidio/switches/Makefile   |1 +
 drivers/rapidio/switches/idt_gen2.c |  439 +++
 include/linux/rio_ids.h |2 +
 include/linux/rio_regs.h|4 +
 5 files changed, 453 insertions(+), 0 deletions(-)
 create mode 100644 drivers/rapidio/switches/idt_gen2.c

diff --git a/drivers/rapidio/switches/Kconfig b/drivers/rapidio/switches/Kconfig
index 2b4e9b2..f47fee5 100644
--- a/drivers/rapidio/switches/Kconfig
+++ b/drivers/rapidio/switches/Kconfig
@@ -20,6 +20,13 @@ config RAPIDIO_TSI568
---help---
  Includes support for IDT Tsi568 serial RapidIO switch.
 
+config RAPIDIO_CPS_GEN2
+   bool IDT CPS Gen.2 SRIO switch support
+   depends on RAPIDIO
+   default n
+   ---help---
+ Includes support for ITD CPS Gen.2 serial RapidIO switches.
+
 config RAPIDIO_TSI500
bool Tsi500 Parallel RapidIO switch support
depends on RAPIDIO
diff --git a/drivers/rapidio/switches/Makefile 
b/drivers/rapidio/switches/Makefile
index fe4adc3..48d67a6 100644
--- a/drivers/rapidio/switches/Makefile
+++ b/drivers/rapidio/switches/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_RAPIDIO_TSI57X)+= tsi57x.o
 obj-$(CONFIG_RAPIDIO_CPS_XX)   += idtcps.o
 obj-$(CONFIG_RAPIDIO_TSI568)   += tsi568.o
 obj-$(CONFIG_RAPIDIO_TSI500)   += tsi500.o
+obj-$(CONFIG_RAPIDIO_CPS_GEN2) += idt_gen2.o
 
 ifeq ($(CONFIG_RAPIDIO_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/rapidio/switches/idt_gen2.c 
b/drivers/rapidio/switches/idt_gen2.c
new file mode 100644
index 000..0de4a9c
--- /dev/null
+++ b/drivers/rapidio/switches/idt_gen2.c
@@ -0,0 +1,439 @@
+/*
+ * IDT CPS Gen.2 Serial RapidIO switch family support
+ *
+ * Copyright 2010 Integrated Device Technology, Inc.
+ * Alexandre Bounine alexandre.boun...@idt.com
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include linux/rio.h
+#include linux/rio_drv.h
+#include linux/rio_ids.h
+#include linux/delay.h
+#include ../rio.h
+
+#define LOCAL_RTE_CONF_DESTID_SEL  0x010070
+#define LOCAL_RTE_CONF_DESTID_SEL_PSEL 0x001f
+
+#define IDT_LT_ERR_REPORT_EN   0x03100c
+
+#define IDT_PORT_ERR_REPORT_EN(n)  (0x031044 + (n)*0x40)
+#define IDT_PORT_ERR_REPORT_EN_BC  0x03ff04
+
+#define IDT_PORT_ISERR_REPORT_EN(n)(0x03104C + (n)*0x40)
+#define IDT_PORT_ISERR_REPORT_EN_BC0x03ff0c
+#define IDT_PORT_INIT_TX_ACQUIRED  0x0020
+
+#define IDT_LANE_ERR_REPORT_EN(n)  (0x038010 + (n)*0x100)
+#define IDT_LANE_ERR_REPORT_EN_BC  0x03ff10
+
+#define IDT_DEV_CTRL_1 0xf2000c
+#define IDT_DEV_CTRL_1_GENPW   0x0200
+#define IDT_DEV_CTRL_1_PRSTBEH 0x0001
+
+#define IDT_CFGBLK_ERR_CAPTURE_EN  0x020008
+#define IDT_CFGBLK_ERR_REPORT  0xf20014
+#define IDT_CFGBLK_ERR_REPORT_GENPW0x0002
+
+#define IDT_AUX_PORT_ERR_CAP_EN0x02
+#define IDT_AUX_ERR_REPORT_EN  0xf20018
+#define IDT_AUX_PORT_ERR_LOG_I2C   0x0002
+#define IDT_AUX_PORT_ERR_LOG_JTAG  0x0001
+
+#defineIDT_ISLTL_ADDRESS_CAP   0x021014
+
+#define IDT_RIO_DOMAIN 0xf20020
+#define IDT_RIO_DOMAIN_MASK0x00ff
+
+#define IDT_PW_INFO_CSR0xf20024
+
+#define IDT_SOFT_RESET 0xf20040
+#define IDT_SOFT_RESET_REQ 0x00030097
+
+#define IDT_I2C_MCTRL  0xf20050
+#define IDT_I2C_MCTRL_GENPW0x0400
+
+#define IDT_JTAG_CTRL  0xf2005c
+#define IDT_JTAG_CTRL_GENPW0x0002
+
+#define IDT_LANE_CTRL(n)   (0xff8000 + (n)*0x100)
+#define IDT_LANE_CTRL_BC   0x00
+#define IDT_LANE_CTRL_GENPW0x0020
+#define IDT_LANE_DFE_1_BC  0x18
+#define IDT_LANE_DFE_2_BC  0x1c
+
+#define IDT_PORT_OPS(n)(0xf40004 + (n)*0x100)
+#define IDT_PORT_OPS_GENPW 0x0800
+#define IDT_PORT_OPS_PL_ELOG   0x0040
+#define IDT_PORT_OPS_LL_ELOG   0x0020
+#define IDT_PORT_OPS_LT_ELOG   0x0010
+#define IDT_PORT_OPS_BC0xf4ff04
+
+#define IDT_PORT_ISERR_DET(n)  (0xf40008 + (n)*0x100)
+
+#define IDT_ERR_CAP0xfd
+#define IDT_ERR_CAP_LOG_OVERWR 0x0004
+
+#define IDT_ERR_RD 0xfd0004
+
+#define IDT_DEFAULT_ROUTE  0xde
+#define IDT_NO_ROUTE   0xdf
+
+static int
+idtg2_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+ 

help with kernel panics in task swapper on 460ex

2010-08-13 Thread Ayman El-Khashab
I have an odd problem when using the 460ex rev b processors.  Previously,
I'd used the rev A without any issues on the same pcbs.  This happens on
multiple units now.  Basically, while running the system will just 
randomly kernel panic.  We have seen this probably 4 or 5 times on a 
over the course of several days per board.  On many occasions, the CPU 
will not kernel dump at all and will just be dead after having run for
some amount of time.  The kernel is 2.6.31.5

The exact details (though I don't think they are too useful are as follows.
The one interesting item if I read it correctly, is that the CPU was 
trying to get instructions from c002 address.  However, this board only
has 512MB of memory so it seems that the address (if it is physical) isn't 
valid.  

Are there any tricks we can use to analyze this problem?  Or is there any
information we can collect to help pinpoint where this issue might lie?

Thanks 
ame

Unable to handle kernel paging request for data at address 0x8072f938
Faulting instruction address: 0xc002eac4
Oops: Kernel access of bad area, sig: 11 [#1]
PowerPC 44x Platform
Modules linked in: mapper
NIP: c002eac4 LR: c004811c CTR: c000add0
REGS: c038be60 TRAP: 0300   Not tainted  (2.6.31.5)
MSR: 00021000 ME,CE  CR: 24644324  XER: 
DEAR: 8072f938, ESR: 
TASK = c036a318[0] 'swapper' THREAD: c038a000
GPR00: 00f6 c038bf10 c036a318 fffef700 fffef6f9 00f9 00f6 00061583
GPR08: c0398070 8072f930 c0398070 c03978c0 004e 415ec006 1ffb3300 
GPR16: 1ffa6e70 1ffad780    c036b1a0 ff1ad8aa c038bf48
GPR24: 00029000 001c 262a1965 c036de50 c039269c fffef700 fffef700 2625a000
NIP [c002eac4] get_next_timer_interrupt+0x30/0x260
LR [c004811c] tick_nohz_stop_sched_tick+0x110/0x404
Call Trace:
[c038bf10] [c003df74] ktime_get+0x1c/0x44 (unreliable)
[c038bf40] [c004811c] tick_nohz_stop_sched_tick+0x110/0x404
[c038bf90] [c0006f00] cpu_idle+0x50/0xd8
[c038bfb0] [c000197c] rest_init+0x5c/0x70
[c038bfc0] [c033f844] start_kernel+0x224/0x2a0
[c038bff0] [c200] skpinv+0x190/0x1cc
Instruction dump:
9421ffd0 7c0802a6 bfa10024 90010034 3d20c037 8169d1b8 7c7e1b78 808b0004
5485063e 7ca62b78 54c91838 7d295a14 81090008 39290008 4814 80080014
---[ end trace 13e96cd635551e49 ]---
Kernel panic - not syncing: Attempted to kill the idle task!
Rebooting in 1 seconds..aym...@vbox:~$ 

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: help with kernel panics in task swapper on 460ex

2010-08-13 Thread Benjamin Herrenschmidt
On Fri, 2010-08-13 at 15:36 -0500, Ayman El-Khashab wrote:
 
 The exact details (though I don't think they are too useful are as follows.
 The one interesting item if I read it correctly, is that the CPU was 
 trying to get instructions from c002 address.  However, this board only
 has 512MB of memory so it seems that the address (if it is physical) isn't 
 valid.  

Actually this is a perfectly valid virtual address. The kernel maps
memory at 0xc000 (at least the first 768M of it, the rest is
dynamically mapped in/out).

 Are there any tricks we can use to analyze this problem?  Or is there any
 information we can collect to help pinpoint where this issue might lie?

Well, xmon is your friend ...

Ben.


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 08/12] ptp: Added a brand new class driver for ptp clocks.

2010-08-13 Thread Grant Likely
On Fri, Aug 13, 2010 at 3:34 AM, Richard Cochran
richardcoch...@gmail.com wrote:
 On Tue, Jun 15, 2010 at 01:11:30PM -0600, Grant Likely wrote:
 On Tue, Jun 15, 2010 at 10:09 AM, Richard Cochran
  +static DEFINE_SPINLOCK(clocks_lock); /* protects 'clocks' */

 Doesn't appear that clocks is manipulated at atomic context.  Mutex instead?
 ...
 If the spinlock is changed to a mutex that is held for the entire
 function call, then the logic here can be simpler.

 Grant,

 I am working on another go at this patch series. Stupid question:

 The caller of ptp_clock_register(), which takes the clocks_lock, is
 always a module_init() function. Is this always a safe context in
 which to call mutex_lock?

Yes, you can take mutexes in the module_init context.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[Resend][PATCHv3] Xilinx Virtex 4 FX Soft FPU support

2010-08-13 Thread Sergey Temerkhanov
This patch enables support for Xilinx Virtex 4 FX singe-float FPU.

Changelog v2-v3:
-Fixed whitespaces for SAVE_FPR/REST_FPR.
-Changed description of MSR_AP bit.
-Removed the stub for APU unavailable exception.

Changelog v1-v2:
-Added MSR_AP bit definition
-Renamed CONFIG_XILINX_FPU to CONFIG_XILINX_SOFTFPU, moved it to
 'Platform support' and made it Virtex4-FX-only.
-Changed SAVE_FPR/REST_FPR definition style.

Caveats:
- Hard-float binaries which rely on in-kernel math emulation will
give wrong results since they expect 64-bit double-precision instead of
32-bit single-precision numbers which Xilinx V4-FX Soft FPU produces.


Signed-off-by: Sergey Temerkhanovtemerkha...@cifronik.ru

diff -r 626de0d94469 arch/powerpc/include/asm/ppc_asm.h
--- a/arch/powerpc/include/asm/ppc_asm.hWed May 26 15:33:32 2010 +0400
+++ b/arch/powerpc/include/asm/ppc_asm.hWed May 26 20:30:43 2010 +0400
@@ -85,13 +85,21 @@
 #define REST_8GPRS(n, base)REST_4GPRS(n, base); REST_4GPRS(n+4, base)
 #define REST_10GPRS(n, base)   REST_8GPRS(n, base); REST_2GPRS(n+8, base)
 
+
+#ifdef CONFIG_XILINX_SOFTFPU
+#define SAVE_FPR(n, base)  stfsn,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#define REST_FPR(n, base)  lfs n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#else
 #define SAVE_FPR(n, base)  stfdn,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#define REST_FPR(n, base)  lfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#endif
+
 #define SAVE_2FPRS(n, base)SAVE_FPR(n, base); SAVE_FPR(n+1, base)
 #define SAVE_4FPRS(n, base)SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
 #define SAVE_8FPRS(n, base)SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
 #define SAVE_16FPRS(n, base)   SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
 #define SAVE_32FPRS(n, base)   SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
-#define REST_FPR(n, base)  lfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+
 #define REST_2FPRS(n, base)REST_FPR(n, base); REST_FPR(n+1, base)
 #define REST_4FPRS(n, base)REST_2FPRS(n, base); REST_2FPRS(n+2, base)
 #define REST_8FPRS(n, base)REST_4FPRS(n, base); REST_4FPRS(n+4, base)
diff -r 626de0d94469 arch/powerpc/include/asm/reg.h
--- a/arch/powerpc/include/asm/reg.hWed May 26 15:33:32 2010 +0400
+++ b/arch/powerpc/include/asm/reg.hWed May 26 20:30:43 2010 +0400
@@ -30,6 +30,7 @@
 #define MSR_ISF_LG 61  /* Interrupt 64b mode valid on 630 */
 #define MSR_HV_LG  60  /* Hypervisor state */
 #define MSR_VEC_LG 25  /* Enable AltiVec */
+#define MSR_AP_LG  25  /* Enable PPC405 APU */
 #define MSR_VSX_LG 23  /* Enable VSX */
 #define MSR_POW_LG 18  /* Enable Power Management */
 #define MSR_WE_LG  18  /* Wait State Enable */
@@ -71,6 +72,7 @@
 #define MSR_HV 0
 #endif
 
+#define MSR_AP __MASK(MSR_AP_LG)   /* Enable PPC405 APU */
 #define MSR_VEC__MASK(MSR_VEC_LG)  /* Enable AltiVec */
 #define MSR_VSX__MASK(MSR_VSX_LG)  /* Enable VSX */
 #define MSR_POW__MASK(MSR_POW_LG)  /* Enable Power 
Management */
diff -r 626de0d94469 arch/powerpc/kernel/fpu.S
--- a/arch/powerpc/kernel/fpu.S Wed May 26 15:33:32 2010 +0400
+++ b/arch/powerpc/kernel/fpu.S Wed May 26 20:30:43 2010 +0400
@@ -57,6 +57,9 @@
 _GLOBAL(load_up_fpu)
mfmsr   r5
ori r5,r5,MSR_FP
+#ifdef CONFIG_XILINX_SOFTFPU
+   orisr5,r5,msr...@h
+#endif
 #ifdef CONFIG_VSX
 BEGIN_FTR_SECTION
orisr5,r5,msr_...@h
@@ -85,6 +88,9 @@
toreal(r5)
PPC_LL  r4,_MSR-STACK_FRAME_OVERHEAD(r5)
li  r10,MSR_FP|MSR_FE0|MSR_FE1
+#ifdef CONFIG_XILINX_SOFTFPU
+   orisr10,r10,msr...@h
+#endif
andcr4,r4,r10   /* disable FP for previous task */
PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 1:
@@ -94,6 +100,9 @@
mfspr   r5,SPRN_SPRG3   /* current task's THREAD (phys) */
lwz r4,THREAD_FPEXC_MODE(r5)
ori r9,r9,MSR_FP/* enable FP for current */
+#ifdef CONFIG_XILINX_SOFTFPU
+   orisr9,r9,msr...@h
+#endif
or  r9,r9,r4
 #else
ld  r4,PACACURRENT(r13)
@@ -124,6 +133,9 @@
 _GLOBAL(giveup_fpu)
mfmsr   r5
ori r5,r5,MSR_FP
+#ifdef CONFIG_XILINX_SOFTFPU
+   orisr5,r5,msr...@h
+#endif
 #ifdef CONFIG_VSX
 BEGIN_FTR_SECTION
orisr5,r5,msr_...@h
@@ -145,6 +157,9 @@
beq 1f
PPC_LL  r4,_MSR-STACK_FRAME_OVERHEAD(r5)
li  r3,MSR_FP|MSR_FE0|MSR_FE1
+#ifdef CONFIG_XILINX_SOFTFPU
+   orisr3,r3,msr...@h
+#endif
 #ifdef CONFIG_VSX
 BEGIN_FTR_SECTION
orisr3,r3,msr_...@h
diff -r 626de0d94469 arch/powerpc/kernel/head_40x.S
--- a/arch/powerpc/kernel/head_40x.SWed May 26 15:33:32 2010 +0400
+++ b/arch/powerpc/kernel/head_40x.SWed May 26 20:30:43 2010 +0400
@@ -420,7