LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: linux-next oops in windfarm startup
From: Hugh Dickins @ 2012-05-08  1:13 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1336435741.2540.184.camel@pasglop>

On Tue, 8 May 2012, Benjamin Herrenschmidt wrote:
> On Mon, 2012-05-07 at 08:57 -0700, Hugh Dickins wrote:
> > Hi Ben,
> > 
> > 3.4.0-rc5-next-20120504 and 3.4.0-rc6-next-20120507
> > crash while booting the PowerMac G5: I have to revert
> > your commit e326b30fda9985a2e7fda6fb9212b86bf025c39
> > powerpc/pmac: Convert windfarm_smu_sat to new i2c probing
> > to get a working system.
> 
> Argh, stoopid me ... and I thought I had tested it .... just
> on the wrong machine. Oh well try this and let me know:
> 
> powerpc/windfarm: Fix crash on SMU based machine after i2c conversion
> 
> We no longer get the device node in platform_data but instead
> where it belongs in struct device, so get it from there instead
> of blowing up.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Yep, that fixes it for me: thanks a lot!

Hugh

> ---
> 
> diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
> index e2989ce..426e810 100644
> --- a/drivers/macintosh/windfarm_smu_sat.c
> +++ b/drivers/macintosh/windfarm_smu_sat.c
> @@ -204,7 +204,7 @@ static struct wf_sensor_ops wf_sat_ops = {
>  static int wf_sat_probe(struct i2c_client *client,
>  			const struct i2c_device_id *id)
>  {
> -	struct device_node *dev = client->dev.platform_data;
> +	struct device_node *dev = client->dev.of_node;
>  	struct wf_sat *sat;
>  	struct wf_sat_sensor *sens;
>  	const u32 *reg;

^ permalink raw reply

* Re: [PATCH] powerpc: use local var instead of local_paca->irq_happened directly in __check_irq_replay
From: Benjamin Herrenschmidt @ 2012-05-08  3:46 UTC (permalink / raw)
  To: Wang Sheng-Hui
  Cc: Stephen Rothwell, linux-kernel, Milton Miller, Anton Blanchard,
	linuxppc-dev
In-Reply-To: <1336090207.18712.9.camel@pasglop>

Hi Wang !

Does this patch fixes it for you ?

>From 249f8649bf95a4c3e6637284754a165c1d83c394 Mon Sep 17 00:00:00 2001
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: Tue, 8 May 2012 13:31:59 +1000
Subject: [PATCH 2/3] powerpc/irq: Fix bug with new lazy IRQ handling code

We had a case where we could turn on hard interrupts while
leaving the PACA_IRQ_HARD_DIS bit set in the PACA. This can
in turn cause a BUG_ON() to hit in __check_irq_replay() due
to interrupt state getting out of sync.

The assembly code was also way too convoluted. Instead, we
now leave it to the C code to do the right thing which ends
up being smaller and more readable.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/kernel/entry_64.S |   18 ------------------
 arch/powerpc/kernel/irq.c      |    8 +++++++-
 2 files changed, 7 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index fd46046..29f1357 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -763,16 +763,6 @@ do_work:
 	SOFT_DISABLE_INTS(r3,r4)
 1:	bl	.preempt_schedule_irq
 
-	/* Hard-disable interrupts again (and update PACA) */
-#ifdef CONFIG_PPC_BOOK3E
-	wrteei	0
-#else
-	ld	r10,PACAKMSR(r13) /* Get kernel MSR without EE */
-	mtmsrd	r10,1
-#endif /* CONFIG_PPC_BOOK3E */
-	li	r0,PACA_IRQ_HARD_DIS
-	stb	r0,PACAIRQHAPPENED(r13)
-
 	/* Re-test flags and eventually loop */
 	clrrdi	r9,r1,THREAD_SHIFT
 	ld	r4,TI_FLAGS(r9)
@@ -783,14 +773,6 @@ do_work:
 user_work:
 #endif /* CONFIG_PREEMPT */
 
-	/* Enable interrupts */
-#ifdef CONFIG_PPC_BOOK3E
-	wrteei	1
-#else
-	ori	r10,r10,MSR_EE
-	mtmsrd	r10,1
-#endif /* CONFIG_PPC_BOOK3E */
-
 	andi.	r0,r4,_TIF_NEED_RESCHED
 	beq	1f
 	bl	.restore_interrupts
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 5ec1b23..3717fb5 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -260,11 +260,17 @@ EXPORT_SYMBOL(arch_local_irq_restore);
  * if they are currently disabled. This is typically called before
  * schedule() or do_signal() when returning to userspace. We do it
  * in C to avoid the burden of dealing with lockdep etc...
+ *
+ * NOTE: This is called with interrupts hard disabled but not marked
+ * as such in paca->irq_happened, so we need to resync this.
  */
 void restore_interrupts(void)
 {
-	if (irqs_disabled())
+	if (irqs_disabled()) {
+		local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
 		local_irq_enable();
+	} else
+		__hard_irq_enable();
 }
 
 #endif /* CONFIG_PPC64 */
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH] powerpc: fix compile fail in hugetlb cmdline parsing
From: Rusty Russell @ 2012-05-08  4:23 UTC (permalink / raw)
  To: Paul Gortmaker, linuxppc-dev
  Cc: Jim Cromie, Greg Kroah-Hartman, Jason Baron, Paul Gortmaker,
	linux-next
In-Reply-To: <1336401142-18733-1-git-send-email-paul.gortmaker@windriver.com>

On Mon,  7 May 2012 10:32:22 -0400, Paul Gortmaker <paul.gortmaker@windriver.com> wrote:
> Commit 9fb48c744ba6a4bf58b666f4e6fdac3008ea1bd4
> 
>     "params: add 3rd arg to option handler callback signature"
> 
> added an extra arg to the function, but didn't catch all the use
> cases needing it, causing this compile fail in mpc85xx_defconfig:
> 
>  arch/powerpc/mm/hugetlbpage.c:316:4: error: passing argument 7 of
>  'parse_args' from incompatible pointer type [-Werror]
> 
>  include/linux/moduleparam.h:317:12: note: expected
> 	 'int (*)(char *, char *, const char *)' but argument is of type
> 	 'int (*)(char *, char *)'
> 
> This function has no need to printk out the "doing" value, so
> just add the arg as an "unused".
> 
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Cc: Jim Cromie <jim.cromie@gmail.com>
> Cc: Jason Baron <jbaron@redhat.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Becky Bruce <beckyb@kernel.crashing.org>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>

Acked-by: Rusty Russell <rusty@rustcorp.com.au>

Thanks,
Rusty.

^ permalink raw reply

* [PATCH 1/2] powerpc/watchdog: move booke watchdog param related code to prom.c
From: Shaohui Xie @ 2012-05-08  6:07 UTC (permalink / raw)
  To: linux-watchdog, linuxppc-dev; +Cc: Shaohui Xie

Currently, BOOKE watchdog code for checking "wdt" and "wdt_period" is
in setup_32.c, it cannot be used in 64-bit, so move it to a common place
prom.c, which will be shared by 32-bit and 64-bit.

Also, replace the simple_strtoul with kstrtol.

Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
---
 arch/powerpc/kernel/prom.c     |   27 +++++++++++++++++++++++++++
 arch/powerpc/kernel/setup_32.c |   24 ------------------------
 2 files changed, 27 insertions(+), 24 deletions(-)

diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index f191bf0..49e1bdf 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -84,6 +84,33 @@ static int __init early_parse_mem(char *p)
 }
 early_param("mem", early_parse_mem);
 
+#ifdef CONFIG_BOOKE_WDT
+extern u32 booke_wdt_enabled;
+extern u32 booke_wdt_period;
+
+/* Checks wdt=x and wdt_period=xx command-line option */
+notrace int __init early_parse_wdt(char *p)
+{
+	if (p && strncmp(p, "0", 1) != 0)
+		booke_wdt_enabled = 1;
+
+	return 0;
+}
+early_param("wdt", early_parse_wdt);
+
+int __init early_parse_wdt_period(char *p)
+{
+	unsigned long ret;
+	if (p) {
+		if (!kstrtol(p, 0, &ret))
+			booke_wdt_period = ret;
+	}
+
+	return 0;
+}
+early_param("wdt_period", early_parse_wdt_period);
+#endif	/* CONFIG_BOOKE_WDT */
+
 /*
  * overlaps_initrd - check for overlap with page aligned extension of
  * initrd.
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index ec8a53f..a8f54ec 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -149,30 +149,6 @@ notrace void __init machine_init(u64 dt_ptr)
 		ppc_md.progress("id mach(): done", 0x200);
 }
 
-#ifdef CONFIG_BOOKE_WDT
-extern u32 booke_wdt_enabled;
-extern u32 booke_wdt_period;
-
-/* Checks wdt=x and wdt_period=xx command-line option */
-notrace int __init early_parse_wdt(char *p)
-{
-	if (p && strncmp(p, "0", 1) != 0)
-	       booke_wdt_enabled = 1;
-
-	return 0;
-}
-early_param("wdt", early_parse_wdt);
-
-int __init early_parse_wdt_period (char *p)
-{
-	if (p)
-		booke_wdt_period = simple_strtoul(p, NULL, 0);
-
-	return 0;
-}
-early_param("wdt_period", early_parse_wdt_period);
-#endif	/* CONFIG_BOOKE_WDT */
-
 /* Checks "l2cr=xxxx" command-line option */
 int __init ppc_setup_l2cr(char *str)
 {
-- 
1.6.4

^ permalink raw reply related

* [PATCH 2/2] powerpc/watchdog: replace CONFIG_FSL_BOOKE with CONFIG_FSL_SOC_BOOKE
From: Shaohui Xie @ 2012-05-08  6:07 UTC (permalink / raw)
  To: linux-watchdog, linuxppc-dev; +Cc: Shaohui Xie

CONFIG_FSL_BOOKE is only defined in 32-bit, CONFIG_FSL_SOC_BOOKE is
defined in both 32-bit and 64-bit, so use CONFIG_FSL_SOC_BOOKE to make
diver work in 32-bit & 64-bit.

Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
---
 drivers/watchdog/Kconfig     |    8 ++++----
 drivers/watchdog/booke_wdt.c |    4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3709624..4373ca0 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1094,10 +1094,10 @@ config BOOKE_WDT
 config BOOKE_WDT_DEFAULT_TIMEOUT
 	int "PowerPC Book-E Watchdog Timer Default Timeout"
 	depends on BOOKE_WDT
-	default 38 if FSL_BOOKE
-	range 0 63 if FSL_BOOKE
-	default 3 if !FSL_BOOKE
-	range 0 3 if !FSL_BOOKE
+	default 38 if FSL_SOC_BOOKE
+	range 0 63 if FSL_SOC_BOOKE
+	default 3 if !FSL_SOC_BOOKE
+	range 0 3 if !FSL_SOC_BOOKE
 	help
 	  Select the default watchdog timer period to be used by the PowerPC
 	  Book-E watchdog driver.  A watchdog "event" occurs when the bit
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index ce0ab44..338a437 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -37,7 +37,7 @@
 u32 booke_wdt_enabled;
 u32 booke_wdt_period = CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT;
 
-#ifdef	CONFIG_FSL_BOOKE
+#ifdef	CONFIG_FSL_SOC_BOOKE
 #define WDTP(x)		((((x)&0x3)<<30)|(((x)&0x3c)<<15))
 #define WDTP_MASK	(WDTP(0x3f))
 #else
@@ -190,7 +190,7 @@ static long booke_wdt_ioctl(struct file *file,
 	case WDIOC_SETTIMEOUT:
 		if (get_user(tmp, p))
 			return -EFAULT;
-#ifdef	CONFIG_FSL_BOOKE
+#ifdef	CONFIG_FSL_SOC_BOOKE
 		/* period of 1 gives the largest possible timeout */
 		if (tmp > period_to_sec(1))
 			return -EINVAL;
-- 
1.6.4

^ permalink raw reply related

* [PATCH 1/1] powerpc: remove now unused _TIF_RUNLATCH
From: Tiejun Chen @ 2012-05-08  9:26 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev

'TIF_RUNLATCH' is already dropped from
commit fe1952fc0afb9a2e4c79f103c08aef5d13db1873

	powerpc: Rework runlatch code

So '_TIF_RUNLATCH' should be removed as well.

Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
---
 arch/powerpc/include/asm/thread_info.h |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index 4a741c7..bcebc75 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -126,7 +126,6 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_NOERROR		(1<<TIF_NOERROR)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_SYSCALL_TRACEPOINT	(1<<TIF_SYSCALL_TRACEPOINT)
-#define _TIF_RUNLATCH		(1<<TIF_RUNLATCH)
 #define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
 				 _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT)
 
-- 
1.5.6

^ permalink raw reply related

* [PATCH] edac: Change internal representation to work with layers
From: Mauro Carvalho Chehab @ 2012-05-08 13:51 UTC (permalink / raw)
  Cc: Mauro Carvalho Chehab, Jason Uhlenkott, Aristeu Rozanski,
	Hitoshi Mitake, Shaohui Xie, Mark Gross, Dmitry Eremin-Solenikov,
	Ranganathan Desikan, Egor Martovetsky, Niklas Söderlund,
	Tim Small, Arvind R., Borislav Petkov, Chris Metcalf,
	Olof Johansson, Doug Thompson, Linux Edac Mailing List,
	Michal Marek, Jiri Kosina, Linux Kernel Mailing List, Joe Perches,
	Andrew Morton, linuxppc-dev
In-Reply-To: <20120507194933.GB8627@aftab.osrc.amd.com>

Change the EDAC internal representation to work with non-csrow
based memory controllers.

There are lots of those memory controllers nowadays, and more
are coming. So, the EDAC internal representation needs to be
changed, in order to work with those memory controllers, while
preserving backward compatibility with the old ones.

The edac core was written with the idea that memory controllers
are able to directly access csrows.

This is not true for FB-DIMM and RAMBUS memory controllers.

Also, some recent advanced memory controllers don't present a per-csrows
view. Instead, they view memories as DIMMs, instead of ranks.

So, change the allocation and error report routines to allow
them to work with all types of architectures.

This will allow the removal of several hacks with FB-DIMM and RAMBUS
memory controllers.

Also, several tests were done on different platforms using different
x86 drivers.

TODO: a multi-rank DIMMs are currently represented by multiple DIMM
entries in struct dimm_info. That means that changing a label for one
rank won't change the same label for the other ranks at the same DIMM.
This bug is present since the beginning of the EDAC, so it is not a big
deal. However, on several drivers, it is possible to fix this issue, but
it should be a per-driver fix, as the csrow => DIMM arrangement may not
be equal for all. So, don't try to fix it here yet.

I tried to make this patch as short as possible, preceding it with
several other patches that simplified the logic here. Yet, as the
internal API changes, all drivers need changes. The changes are
generally bigger in the drivers for FB-DIMMs.

Cc: Aristeu Rozanski <arozansk@redhat.com>
Cc: Doug Thompson <norsk5@yahoo.com>
Cc: Borislav Petkov <borislav.petkov@amd.com>
Cc: Mark Gross <mark.gross@intel.com>
Cc: Jason Uhlenkott <juhlenko@akamai.com>
Cc: Tim Small <tim@buttersideup.com>
Cc: Ranganathan Desikan <ravi@jetztechnologies.com>
Cc: "Arvind R." <arvino55@gmail.com>
Cc: Olof Johansson <olof@lixom.net>
Cc: Egor Martovetsky <egor@pasemi.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Joe Perches <joe@perches.com>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Hitoshi Mitake <h.mitake@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: "Niklas Söderlund" <niklas.soderlund@ericsson.com>
Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
Cc: Josh Boyer <jwboyer@gmail.com>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---

v.21: As requested by Borislav, fold two patches:
  http://git.infradead.org/users/mchehab/edac.git/commitdiff/3f4610491cc58dda8c737378212559dce77adde2
  http://git.infradead.org/users/mchehab/edac.git/commitdiff/97b826eaa8fe8ceb84220a2438551c4c73e55635

 drivers/edac/edac_core.h |   99 ++++++--
 drivers/edac/edac_mc.c   |  702 +++++++++++++++++++++++++++++-----------------
 include/linux/edac.h     |   38 ++-
 3 files changed, 552 insertions(+), 287 deletions(-)

diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index e48ab31..1286c5e 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -447,8 +447,12 @@ static inline void pci_write_bits32(struct pci_dev *pdev, int offset,
 
 #endif				/* CONFIG_PCI */
 
-extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
-					  unsigned nr_chans, int edac_index);
+struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
+				   unsigned nr_chans, int edac_index);
+struct mem_ctl_info *new_edac_mc_alloc(unsigned edac_index,
+				   unsigned n_layers,
+				   struct edac_mc_layer *layers,
+				   unsigned sz_pvt);
 extern int edac_mc_add_mc(struct mem_ctl_info *mci);
 extern void edac_mc_free(struct mem_ctl_info *mci);
 extern struct mem_ctl_info *edac_mc_find(int idx);
@@ -467,24 +471,78 @@ extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
  * reporting logic and function interface - reduces conditional
  * statement clutter and extra function arguments.
  */
-extern void edac_mc_handle_ce(struct mem_ctl_info *mci,
-			      unsigned long page_frame_number,
-			      unsigned long offset_in_page,
-			      unsigned long syndrome, int row, int channel,
-			      const char *msg);
-extern void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci,
-				      const char *msg);
-extern void edac_mc_handle_ue(struct mem_ctl_info *mci,
-			      unsigned long page_frame_number,
-			      unsigned long offset_in_page, int row,
-			      const char *msg);
-extern void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci,
-				      const char *msg);
-extern void edac_mc_handle_fbd_ue(struct mem_ctl_info *mci, unsigned int csrow,
-				  unsigned int channel0, unsigned int channel1,
-				  char *msg);
-extern void edac_mc_handle_fbd_ce(struct mem_ctl_info *mci, unsigned int csrow,
-				  unsigned int channel, char *msg);
+
+void edac_mc_handle_error(const enum hw_event_mc_err_type type,
+			  struct mem_ctl_info *mci,
+			  const unsigned long page_frame_number,
+			  const unsigned long offset_in_page,
+			  const unsigned long syndrome,
+			  const int layer0,
+			  const int layer1,
+			  const int layer2,
+			  const char *msg,
+			  const char *other_detail,
+			  const void *mcelog);
+
+static inline void edac_mc_handle_ce(struct mem_ctl_info *mci,
+				     unsigned long page_frame_number,
+				     unsigned long offset_in_page,
+				     unsigned long syndrome, int row, int channel,
+				     const char *msg)
+{
+	 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
+			      page_frame_number, offset_in_page, syndrome,
+			      row, channel, -1, msg, NULL, NULL);
+}
+
+static inline void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci,
+					     const char *msg)
+{
+	 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
+			      0, 0, 0, -1, -1, -1, msg, NULL, NULL);
+}
+
+static inline void edac_mc_handle_ue(struct mem_ctl_info *mci,
+				     unsigned long page_frame_number,
+				     unsigned long offset_in_page, int row,
+				     const char *msg)
+{
+	 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
+			      page_frame_number, offset_in_page, 0,
+			      row, -1, -1, msg, NULL, NULL);
+}
+
+static inline void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci,
+					     const char *msg)
+{
+	 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
+			      0, 0, 0, -1, -1, -1, msg, NULL, NULL);
+}
+
+static inline void edac_mc_handle_fbd_ue(struct mem_ctl_info *mci,
+					 unsigned int csrow,
+					 unsigned int channel0,
+					 unsigned int channel1,
+					 char *msg)
+{
+	/*
+	 *FIXME: The error can also be at channel1 (e. g. at the second
+	 *	  channel of the same branch). The fix is to push
+	 *	  edac_mc_handle_error() call into each driver
+	 */
+	 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
+			      0, 0, 0,
+			      csrow, channel0, -1, msg, NULL, NULL);
+}
+
+static inline void edac_mc_handle_fbd_ce(struct mem_ctl_info *mci,
+					 unsigned int csrow,
+					 unsigned int channel, char *msg)
+{
+	 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
+			      0, 0, 0,
+			      csrow, channel, -1, msg, NULL, NULL);
+}
 
 /*
  * edac_device APIs
@@ -496,6 +554,7 @@ extern void edac_device_handle_ue(struct edac_device_ctl_info *edac_dev,
 extern void edac_device_handle_ce(struct edac_device_ctl_info *edac_dev,
 				int inst_nr, int block_nr, const char *msg);
 extern int edac_device_alloc_index(void);
+extern const char *edac_layer_name[];
 
 /*
  * edac_pci APIs
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 6ec967a..2614658 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -44,9 +44,25 @@ static void edac_mc_dump_channel(struct rank_info *chan)
 	debugf4("\tchannel = %p\n", chan);
 	debugf4("\tchannel->chan_idx = %d\n", chan->chan_idx);
 	debugf4("\tchannel->csrow = %p\n\n", chan->csrow);
-	debugf4("\tdimm->ce_count = %d\n", chan->dimm->ce_count);
-	debugf4("\tdimm->label = '%s'\n", chan->dimm->label);
-	debugf4("\tdimm->nr_pages = 0x%x\n", chan->dimm->nr_pages);
+	debugf4("\tchannel->dimm = %p\n", chan->dimm);
+}
+
+static void edac_mc_dump_dimm(struct dimm_info *dimm)
+{
+	int i;
+
+	debugf4("\tdimm = %p\n", dimm);
+	debugf4("\tdimm->label = '%s'\n", dimm->label);
+	debugf4("\tdimm->nr_pages = 0x%x\n", dimm->nr_pages);
+	debugf4("\tdimm location ");
+	for (i = 0; i < dimm->mci->n_layers; i++) {
+		printk(KERN_CONT "%d", dimm->location[i]);
+		if (i < dimm->mci->n_layers - 1)
+			printk(KERN_CONT ".");
+	}
+	printk(KERN_CONT "\n");
+	debugf4("\tdimm->grain = %d\n", dimm->grain);
+	debugf4("\tdimm->nr_pages = 0x%x\n", dimm->nr_pages);
 }
 
 static void edac_mc_dump_csrow(struct csrow_info *csrow)
@@ -70,6 +86,8 @@ static void edac_mc_dump_mci(struct mem_ctl_info *mci)
 	debugf4("\tmci->edac_check = %p\n", mci->edac_check);
 	debugf3("\tmci->nr_csrows = %d, csrows = %p\n",
 		mci->nr_csrows, mci->csrows);
+	debugf3("\tmci->nr_dimms = %d, dimms = %p\n",
+		mci->tot_dimms, mci->dimms);
 	debugf3("\tdev = %p\n", mci->dev);
 	debugf3("\tmod_name:ctl_name = %s:%s\n", mci->mod_name, mci->ctl_name);
 	debugf3("\tpvt_info = %p\n\n", mci->pvt_info);
@@ -157,10 +175,12 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems)
 }
 
 /**
- * edac_mc_alloc: Allocate a struct mem_ctl_info structure
- * @size_pvt:	size of private storage needed
- * @nr_csrows:	Number of CWROWS needed for this MC
- * @nr_chans:	Number of channels for the MC
+ * edac_mc_alloc: Allocate and partially fill a struct mem_ctl_info structure
+ * @mc_num:		Memory controller number
+ * @n_layers:		Number of MC hierarchy layers
+ * layers:		Describes each layer as seen by the Memory Controller
+ * @size_pvt:		size of private storage needed
+ *
  *
  * Everything is kmalloc'ed as one big chunk - more efficient.
  * Only can be used if all structures have the same lifetime - otherwise
@@ -168,22 +188,49 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems)
  *
  * Use edac_mc_free() to free mc structures allocated by this function.
  *
+ * NOTE: drivers handle multi-rank memories in different ways: in some
+ * drivers, one multi-rank memory stick is mapped as one entry, while, in
+ * others, a single multi-rank memory stick would be mapped into several
+ * entries. Currently, this function will allocate multiple struct dimm_info
+ * on such scenarios, as grouping the multiple ranks require drivers change.
+ *
  * Returns:
  *	NULL allocation failed
  *	struct mem_ctl_info pointer
  */
-struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
-				unsigned nr_chans, int edac_index)
+struct mem_ctl_info *new_edac_mc_alloc(unsigned mc_num,
+				       unsigned n_layers,
+				       struct edac_mc_layer *layers,
+				       unsigned sz_pvt)
 {
-	void *ptr = NULL;
 	struct mem_ctl_info *mci;
-	struct csrow_info *csi, *csrow;
+	struct edac_mc_layer *layer;
+	struct csrow_info *csi, *csr;
 	struct rank_info *chi, *chp, *chan;
 	struct dimm_info *dimm;
-	void *pvt;
-	unsigned size;
-	int row, chn;
-	int err;
+	u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
+	unsigned pos[EDAC_MAX_LAYERS];
+	void *pvt, *ptr = NULL;
+	unsigned size, tot_dimms = 1, count = 1;
+	unsigned tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
+	int i, j, err, row, chn;
+	bool per_rank = false;
+
+	BUG_ON(n_layers > EDAC_MAX_LAYERS || n_layers == 0);
+	/*
+	 * Calculate the total amount of dimms and csrows/cschannels while
+	 * in the old API emulation mode
+	 */
+	for (i = 0; i < n_layers; i++) {
+		tot_dimms *= layers[i].size;
+		if (layers[i].is_virt_csrow)
+			tot_csrows *= layers[i].size;
+		else
+			tot_channels *= layers[i].size;
+
+		if (layers[i].type == EDAC_MC_LAYER_CHIP_SELECT)
+			per_rank = true;
+	}
 
 	/* Figure out the offsets of the various items from the start of an mc
 	 * structure.  We want the alignment of each item to be at least as
@@ -191,12 +238,27 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
 	 * hardcode everything into a single struct.
 	 */
 	mci = edac_align_ptr(&ptr, sizeof(*mci), 1);
-	csi = edac_align_ptr(&ptr, sizeof(*csi), nr_csrows);
-	chi = edac_align_ptr(&ptr, sizeof(*chi), nr_csrows * nr_chans);
-	dimm = edac_align_ptr(&ptr, sizeof(*dimm), nr_csrows * nr_chans);
+	layer = edac_align_ptr(&ptr, sizeof(*layer), n_layers);
+	csi = edac_align_ptr(&ptr, sizeof(*csi), tot_csrows);
+	chi = edac_align_ptr(&ptr, sizeof(*chi), tot_csrows * tot_channels);
+	dimm = edac_align_ptr(&ptr, sizeof(*dimm), tot_dimms);
+	for (i = 0; i < n_layers; i++) {
+		count *= layers[i].size;
+		debugf4("%s: errcount layer %d size %d\n", __func__, i, count);
+		ce_per_layer[i] = edac_align_ptr(&ptr, sizeof(u32), count);
+		ue_per_layer[i] = edac_align_ptr(&ptr, sizeof(u32), count);
+		tot_errcount += 2 * count;
+	}
+
+	debugf4("%s: allocating %d error counters\n", __func__, tot_errcount);
 	pvt = edac_align_ptr(&ptr, sz_pvt, 1);
 	size = ((unsigned long)pvt) + sz_pvt;
 
+	debugf1("%s(): allocating %u bytes for mci data (%d %s, %d csrows/channels)\n",
+		__func__, size,
+		tot_dimms,
+		per_rank ? "ranks" : "dimms",
+		tot_csrows * tot_channels);
 	mci = kzalloc(size, GFP_KERNEL);
 	if (mci == NULL)
 		return NULL;
@@ -204,42 +266,87 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
 	/* Adjust pointers so they point within the memory we just allocated
 	 * rather than an imaginary chunk of memory located at address 0.
 	 */
+	layer = (struct edac_mc_layer *)(((char *)mci) + ((unsigned long)layer));
 	csi = (struct csrow_info *)(((char *)mci) + ((unsigned long)csi));
 	chi = (struct rank_info *)(((char *)mci) + ((unsigned long)chi));
 	dimm = (struct dimm_info *)(((char *)mci) + ((unsigned long)dimm));
+	for (i = 0; i < n_layers; i++) {
+		mci->ce_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ce_per_layer[i]));
+		mci->ue_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ue_per_layer[i]));
+	}
 	pvt = sz_pvt ? (((char *)mci) + ((unsigned long)pvt)) : NULL;
 
 	/* setup index and various internal pointers */
-	mci->mc_idx = edac_index;
+	mci->mc_idx = mc_num;
 	mci->csrows = csi;
 	mci->dimms  = dimm;
+	mci->tot_dimms = tot_dimms;
 	mci->pvt_info = pvt;
-	mci->nr_csrows = nr_csrows;
+	mci->n_layers = n_layers;
+	mci->layers = layer;
+	memcpy(mci->layers, layers, sizeof(*layer) * n_layers);
+	mci->nr_csrows = tot_csrows;
+	mci->num_cschannel = tot_channels;
+	mci->mem_is_per_rank = per_rank;
 
 	/*
-	 * For now, assumes that a per-csrow arrangement for dimms.
-	 * This will be latter changed.
+	 * Fill the csrow struct
 	 */
-	dimm = mci->dimms;
-
-	for (row = 0; row < nr_csrows; row++) {
-		csrow = &csi[row];
-		csrow->csrow_idx = row;
-		csrow->mci = mci;
-		csrow->nr_channels = nr_chans;
-		chp = &chi[row * nr_chans];
-		csrow->channels = chp;
-
-		for (chn = 0; chn < nr_chans; chn++) {
+	for (row = 0; row < tot_csrows; row++) {
+		csr = &csi[row];
+		csr->csrow_idx = row;
+		csr->mci = mci;
+		csr->nr_channels = tot_channels;
+		chp = &chi[row * tot_channels];
+		csr->channels = chp;
+
+		for (chn = 0; chn < tot_channels; chn++) {
 			chan = &chp[chn];
 			chan->chan_idx = chn;
-			chan->csrow = csrow;
+			chan->csrow = csr;
+		}
+	}
+
+	/*
+	 * Fill the dimm struct
+	 */
+	memset(&pos, 0, sizeof(pos));
+	row = 0;
+	chn = 0;
+	debugf4("%s: initializing %d %s\n", __func__, tot_dimms,
+		per_rank ? "ranks" : "dimms");
+	for (i = 0; i < tot_dimms; i++) {
+		chan = &csi[row].channels[chn];
+		dimm = EDAC_DIMM_PTR(layer, mci->dimms, n_layers,
+			       pos[0], pos[1], pos[2]);
+		dimm->mci = mci;
+
+		debugf2("%s: %d: %s%zd (%d:%d:%d): row %d, chan %d\n", __func__,
+			i, per_rank ? "rank" : "dimm", (dimm - mci->dimms),
+			pos[0], pos[1], pos[2], row, chn);
+
+		/* Copy DIMM location */
+		for (j = 0; j < n_layers; j++)
+			dimm->location[j] = pos[j];
+
+		/* Link it to the csrows old API data */
+		chan->dimm = dimm;
+		dimm->csrow = row;
+		dimm->cschannel = chn;
+
+		/* Increment csrow location */
+		row++;
+		if (row == tot_csrows) {
+			row = 0;
+			chn++;
+		}
 
-			mci->csrows[row].channels[chn].dimm = dimm;
-			dimm->csrow = row;
-			dimm->csrow_channel = chn;
-			dimm++;
-			mci->nr_dimms++;
+		/* Increment dimm location */
+		for (j = n_layers - 1; j >= 0; j--) {
+			pos[j]++;
+			if (pos[j] < layers[j].size)
+				break;
+			pos[j] = 0;
 		}
 	}
 
@@ -263,6 +370,46 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
 	 */
 	return mci;
 }
+EXPORT_SYMBOL_GPL(new_edac_mc_alloc);
+
+/**
+ * edac_mc_alloc: Allocate and partially fill a struct mem_ctl_info structure
+ * @mc_num:		Memory controller number
+ * @n_layers:		Number of layers at the MC hierarchy
+ * layers:		Describes each layer as seen by the Memory Controller
+ * @size_pvt:		Size of private storage needed
+ *
+ *
+ * FIXME: drivers handle multi-rank memories in different ways: some
+ * drivers map multi-ranked DIMMs as one DIMM while others
+ * as several DIMMs.
+ *
+ * Everything is kmalloc'ed as one big chunk - more efficient.
+ * It can only be used if all structures have the same lifetime - otherwise
+ * you have to allocate and initialize your own structures.
+ *
+ * Use edac_mc_free() to free mc structures allocated by this function.
+ *
+ * Returns:
+ *	On failure: NULL
+ *	On success: struct mem_ctl_info pointer
+ */
+
+struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
+				   unsigned nr_chans, int mc_num)
+{
+	unsigned n_layers = 2;
+	struct edac_mc_layer layers[n_layers];
+
+	layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
+	layers[0].size = nr_csrows;
+	layers[0].is_virt_csrow = true;
+	layers[1].type = EDAC_MC_LAYER_CHANNEL;
+	layers[1].size = nr_chans;
+	layers[1].is_virt_csrow = false;
+
+	return new_edac_mc_alloc(mc_num, ARRAY_SIZE(layers), layers, sz_pvt);
+}
 EXPORT_SYMBOL_GPL(edac_mc_alloc);
 
 /**
@@ -528,7 +675,6 @@ EXPORT_SYMBOL(edac_mc_find);
  * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and
  *                 create sysfs entries associated with mci structure
  * @mci: pointer to the mci structure to be added to the list
- * @mc_idx: A unique numeric identifier to be assigned to the 'mci' structure.
  *
  * Return:
  *	0	Success
@@ -555,6 +701,8 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
 				edac_mc_dump_channel(&mci->csrows[i].
 						channels[j]);
 		}
+		for (i = 0; i < mci->tot_dimms; i++)
+			edac_mc_dump_dimm(&mci->dimms[i]);
 	}
 #endif
 	mutex_lock(&mem_ctls_mutex);
@@ -712,261 +860,307 @@ int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page)
 }
 EXPORT_SYMBOL_GPL(edac_mc_find_csrow_by_page);
 
-/* FIXME - setable log (warning/emerg) levels */
-/* FIXME - integrate with evlog: http://evlog.sourceforge.net/ */
-void edac_mc_handle_ce(struct mem_ctl_info *mci,
-		unsigned long page_frame_number,
-		unsigned long offset_in_page, unsigned long syndrome,
-		int row, int channel, const char *msg)
+const char *edac_layer_name[] = {
+	[EDAC_MC_LAYER_BRANCH] = "branch",
+	[EDAC_MC_LAYER_CHANNEL] = "channel",
+	[EDAC_MC_LAYER_SLOT] = "slot",
+	[EDAC_MC_LAYER_CHIP_SELECT] = "csrow",
+};
+EXPORT_SYMBOL_GPL(edac_layer_name);
+
+static void edac_inc_ce_error(struct mem_ctl_info *mci,
+				    bool enable_per_layer_report,
+				    const int pos[EDAC_MAX_LAYERS])
 {
-	unsigned long remapped_page;
-	char *label = NULL;
-	u32 grain;
+	int i, index = 0;
 
-	debugf3("MC%d: %s()\n", mci->mc_idx, __func__);
+	mci->ce_count++;
 
-	/* FIXME - maybe make panic on INTERNAL ERROR an option */
-	if (row >= mci->nr_csrows || row < 0) {
-		/* something is wrong */
-		edac_mc_printk(mci, KERN_ERR,
-			"INTERNAL ERROR: row out of range "
-			"(%d >= %d)\n", row, mci->nr_csrows);
-		edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR");
+	if (!enable_per_layer_report) {
+		mci->ce_noinfo_count++;
 		return;
 	}
 
-	if (channel >= mci->csrows[row].nr_channels || channel < 0) {
-		/* something is wrong */
-		edac_mc_printk(mci, KERN_ERR,
-			"INTERNAL ERROR: channel out of range "
-			"(%d >= %d)\n", channel,
-			mci->csrows[row].nr_channels);
-		edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR");
+	for (i = 0; i < mci->n_layers; i++) {
+		if (pos[i] < 0)
+			break;
+		index += pos[i];
+		mci->ce_per_layer[i][index]++;
+
+		if (i < mci->n_layers - 1)
+			index *= mci->layers[i + 1].size;
+	}
+}
+
+static void edac_inc_ue_error(struct mem_ctl_info *mci,
+				    bool enable_per_layer_report,
+				    const int pos[EDAC_MAX_LAYERS])
+{
+	int i, index = 0;
+
+	mci->ue_count++;
+
+	if (!enable_per_layer_report) {
+		mci->ce_noinfo_count++;
 		return;
 	}
 
-	label = mci->csrows[row].channels[channel].dimm->label;
-	grain = mci->csrows[row].channels[channel].dimm->grain;
+	for (i = 0; i < mci->n_layers; i++) {
+		if (pos[i] < 0)
+			break;
+		index += pos[i];
+		mci->ue_per_layer[i][index]++;
 
-	if (edac_mc_get_log_ce())
-		/* FIXME - put in DIMM location */
-		edac_mc_printk(mci, KERN_WARNING,
-			"CE page 0x%lx, offset 0x%lx, grain %d, syndrome "
-			"0x%lx, row %d, channel %d, label \"%s\": %s\n",
-			page_frame_number, offset_in_page,
-			grain, syndrome, row, channel,
-			label, msg);
+		if (i < mci->n_layers - 1)
+			index *= mci->layers[i + 1].size;
+	}
+}
 
-	mci->ce_count++;
-	mci->csrows[row].ce_count++;
-	mci->csrows[row].channels[channel].dimm->ce_count++;
-	mci->csrows[row].channels[channel].ce_count++;
+static void edac_ce_error(struct mem_ctl_info *mci,
+			  const int pos[EDAC_MAX_LAYERS],
+			  const char *msg,
+			  const char *location,
+			  const char *label,
+			  const char *detail,
+			  const char *other_detail,
+			  const bool enable_per_layer_report,
+			  const unsigned long page_frame_number,
+			  const unsigned long offset_in_page,
+			  u32 grain)
+{
+	unsigned long remapped_page;
+
+	if (edac_mc_get_log_ce()) {
+		if (other_detail && *other_detail)
+			edac_mc_printk(mci, KERN_WARNING,
+				       "CE %s on %s (%s%s - %s)\n",
+				       msg, label, location,
+				       detail, other_detail);
+		else
+			edac_mc_printk(mci, KERN_WARNING,
+				       "CE %s on %s (%s%s)\n",
+				       msg, label, location,
+				       detail);
+	}
+	edac_inc_ce_error(mci, enable_per_layer_report, pos);
 
 	if (mci->scrub_mode & SCRUB_SW_SRC) {
 		/*
-		 * Some MC's can remap memory so that it is still available
-		 * at a different address when PCI devices map into memory.
-		 * MC's that can't do this lose the memory where PCI devices
-		 * are mapped.  This mapping is MC dependent and so we call
-		 * back into the MC driver for it to map the MC page to
-		 * a physical (CPU) page which can then be mapped to a virtual
-		 * page - which can then be scrubbed.
-		 */
+			* Some memory controllers (called MCs below) can remap
+			* memory so that it is still available at a different
+			* address when PCI devices map into memory.
+			* MC's that can't do this, lose the memory where PCI
+			* devices are mapped. This mapping is MC-dependent
+			* and so we call back into the MC driver for it to
+			* map the MC page to a physical (CPU) page which can
+			* then be mapped to a virtual page - which can then
+			* be scrubbed.
+			*/
 		remapped_page = mci->ctl_page_to_phys ?
 			mci->ctl_page_to_phys(mci, page_frame_number) :
 			page_frame_number;
 
-		edac_mc_scrub_block(remapped_page, offset_in_page, grain);
+		edac_mc_scrub_block(remapped_page,
+					offset_in_page, grain);
 	}
 }
-EXPORT_SYMBOL_GPL(edac_mc_handle_ce);
 
-void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, const char *msg)
+static void edac_ue_error(struct mem_ctl_info *mci,
+			  const int pos[EDAC_MAX_LAYERS],
+			  const char *msg,
+			  const char *location,
+			  const char *label,
+			  const char *detail,
+			  const char *other_detail,
+			  const bool enable_per_layer_report)
 {
-	if (edac_mc_get_log_ce())
-		edac_mc_printk(mci, KERN_WARNING,
-			"CE - no information available: %s\n", msg);
+	if (edac_mc_get_log_ue()) {
+		if (other_detail && *other_detail)
+			edac_mc_printk(mci, KERN_WARNING,
+				       "UE %s on %s (%s%s - %s)\n",
+			               msg, label, location, detail,
+				       other_detail);
+		else
+			edac_mc_printk(mci, KERN_WARNING,
+				       "UE %s on %s (%s%s)\n",
+			               msg, label, location, detail);
+	}
 
-	mci->ce_noinfo_count++;
-	mci->ce_count++;
+	if (edac_mc_get_panic_on_ue()) {
+		if (other_detail && *other_detail)
+			panic("UE %s on %s (%s%s - %s)\n",
+			      msg, label, location, detail, other_detail);
+		else
+			panic("UE %s on %s (%s%s)\n",
+			      msg, label, location, detail);
+	}
+
+	edac_inc_ue_error(mci, enable_per_layer_report, pos);
 }
-EXPORT_SYMBOL_GPL(edac_mc_handle_ce_no_info);
 
-void edac_mc_handle_ue(struct mem_ctl_info *mci,
-		unsigned long page_frame_number,
-		unsigned long offset_in_page, int row, const char *msg)
+#define OTHER_LABEL " or "
+void edac_mc_handle_error(const enum hw_event_mc_err_type type,
+			  struct mem_ctl_info *mci,
+			  const unsigned long page_frame_number,
+			  const unsigned long offset_in_page,
+			  const unsigned long syndrome,
+			  const int layer0,
+			  const int layer1,
+			  const int layer2,
+			  const char *msg,
+			  const char *other_detail,
+			  const void *mcelog)
 {
-	int len = EDAC_MC_LABEL_LEN * 4;
-	char labels[len + 1];
-	char *pos = labels;
-	int chan;
-	int chars;
-	char *label = NULL;
+	/* FIXME: too much for stack: move it to some pre-alocated area */
+	char detail[80], location[80];
+	char label[(EDAC_MC_LABEL_LEN + 1 + sizeof(OTHER_LABEL)) * mci->tot_dimms];
+	char *p;
+	int row = -1, chan = -1;
+	int pos[EDAC_MAX_LAYERS] = { layer0, layer1, layer2 };
+	int i;
 	u32 grain;
+	bool enable_per_layer_report = false;
 
 	debugf3("MC%d: %s()\n", mci->mc_idx, __func__);
 
-	/* FIXME - maybe make panic on INTERNAL ERROR an option */
-	if (row >= mci->nr_csrows || row < 0) {
-		/* something is wrong */
-		edac_mc_printk(mci, KERN_ERR,
-			"INTERNAL ERROR: row out of range "
-			"(%d >= %d)\n", row, mci->nr_csrows);
-		edac_mc_handle_ue_no_info(mci, "INTERNAL ERROR");
-		return;
-	}
-
-	grain = mci->csrows[row].channels[0].dimm->grain;
-	label = mci->csrows[row].channels[0].dimm->label;
-	chars = snprintf(pos, len + 1, "%s", label);
-	len -= chars;
-	pos += chars;
-
-	for (chan = 1; (chan < mci->csrows[row].nr_channels) && (len > 0);
-		chan++) {
-		label = mci->csrows[row].channels[chan].dimm->label;
-		chars = snprintf(pos, len + 1, ":%s", label);
-		len -= chars;
-		pos += chars;
+	/*
+	 * Check if the event report is consistent and if the memory
+	 * location is known. If it is known, enable_per_layer_report will be
+	 * true, the DIMM(s) label info will be filled and the per-layer
+	 * error counters will be incremented.
+	 */
+	for (i = 0; i < mci->n_layers; i++) {
+		if (pos[i] >= (int)mci->layers[i].size) {
+			if (type == HW_EVENT_ERR_CORRECTED)
+				p = "CE";
+			else
+				p = "UE";
+
+			edac_mc_printk(mci, KERN_ERR,
+				       "INTERNAL ERROR: %s value is out of range (%d >= %d)\n",
+				       edac_layer_name[mci->layers[i].type],
+				       pos[i], mci->layers[i].size);
+			/*
+			 * Instead of just returning it, let's use what's
+			 * known about the error. The increment routines and
+			 * the DIMM filter logic will do the right thing by
+			 * pointing the likely damaged DIMMs.
+			 */
+			pos[i] = -1;
+		}
+		if (pos[i] >= 0)
+			enable_per_layer_report = true;
 	}
 
-	if (edac_mc_get_log_ue())
-		edac_mc_printk(mci, KERN_EMERG,
-			"UE page 0x%lx, offset 0x%lx, grain %d, row %d, "
-			"labels \"%s\": %s\n", page_frame_number,
-			offset_in_page, grain, row, labels, msg);
-
-	if (edac_mc_get_panic_on_ue())
-		panic("EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, "
-			"row %d, labels \"%s\": %s\n", mci->mc_idx,
-			page_frame_number, offset_in_page,
-			grain, row, labels, msg);
-
-	mci->ue_count++;
-	mci->csrows[row].ue_count++;
-}
-EXPORT_SYMBOL_GPL(edac_mc_handle_ue);
-
-void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg)
-{
-	if (edac_mc_get_panic_on_ue())
-		panic("EDAC MC%d: Uncorrected Error", mci->mc_idx);
+	/*
+	 * Get the dimm label/grain that applies to the match criteria.
+	 * As the error algorithm may not be able to point to just one memory
+	 * stick, the logic here will get all possible labels that could
+	 * pottentially be affected by the error.
+	 * On FB-DIMM memory controllers, for uncorrected errors, it is common
+	 * to have only the MC channel and the MC dimm (also called "branch")
+	 * but the channel is not known, as the memory is arranged in pairs,
+	 * where each memory belongs to a separate channel within the same
+	 * branch.
+	 */
+	grain = 0;
+	p = label;
+	*p = '\0';
+	for (i = 0; i < mci->tot_dimms; i++) {
+		struct dimm_info *dimm = &mci->dimms[i];
 
-	if (edac_mc_get_log_ue())
-		edac_mc_printk(mci, KERN_WARNING,
-			"UE - no information available: %s\n", msg);
-	mci->ue_noinfo_count++;
-	mci->ue_count++;
-}
-EXPORT_SYMBOL_GPL(edac_mc_handle_ue_no_info);
+		if (layer0 >= 0 && layer0 != dimm->location[0])
+			continue;
+		if (layer1 >= 0 && layer1 != dimm->location[1])
+			continue;
+		if (layer2 >= 0 && layer2 != dimm->location[2])
+			continue;
 
-/*************************************************************
- * On Fully Buffered DIMM modules, this help function is
- * called to process UE events
- */
-void edac_mc_handle_fbd_ue(struct mem_ctl_info *mci,
-			unsigned int csrow,
-			unsigned int channela,
-			unsigned int channelb, char *msg)
-{
-	int len = EDAC_MC_LABEL_LEN * 4;
-	char labels[len + 1];
-	char *pos = labels;
-	int chars;
-	char *label;
-
-	if (csrow >= mci->nr_csrows) {
-		/* something is wrong */
-		edac_mc_printk(mci, KERN_ERR,
-			"INTERNAL ERROR: row out of range (%d >= %d)\n",
-			csrow, mci->nr_csrows);
-		edac_mc_handle_ue_no_info(mci, "INTERNAL ERROR");
-		return;
-	}
+		/* get the max grain, over the error match range */
+		if (dimm->grain > grain)
+			grain = dimm->grain;
 
-	if (channela >= mci->csrows[csrow].nr_channels) {
-		/* something is wrong */
-		edac_mc_printk(mci, KERN_ERR,
-			"INTERNAL ERROR: channel-a out of range "
-			"(%d >= %d)\n",
-			channela, mci->csrows[csrow].nr_channels);
-		edac_mc_handle_ue_no_info(mci, "INTERNAL ERROR");
-		return;
+		/*
+		 * If the error is memory-controller wide, there's no need to
+		 * seek for the affected DIMMs because the whole
+		 * channel/memory controller/...  may be affected.
+		 * Also, don't show errors for empty DIMM slots.
+		 */
+		if (enable_per_layer_report && dimm->nr_pages) {
+			if (p != label) {
+				strcpy(p, OTHER_LABEL);
+				p += strlen(OTHER_LABEL);
+			}
+			strcpy(p, dimm->label);
+			p += strlen(p);
+			*p = '\0';
+
+			/*
+			 * get csrow/channel of the DIMM, in order to allow
+			 * incrementing the compat API counters
+			 */
+			debugf4("%s: %s csrows map: (%d,%d)\n",
+				__func__,
+				mci->mem_is_per_rank ? "rank" : "dimm",
+				dimm->csrow, dimm->cschannel);
+
+			if (row == -1)
+				row = dimm->csrow;
+			else if (row >= 0 && row != dimm->csrow)
+				row = -2;
+
+			if (chan == -1)
+				chan = dimm->cschannel;
+			else if (chan >= 0 && chan != dimm->cschannel)
+				chan = -2;
+		}
 	}
 
-	if (channelb >= mci->csrows[csrow].nr_channels) {
-		/* something is wrong */
-		edac_mc_printk(mci, KERN_ERR,
-			"INTERNAL ERROR: channel-b out of range "
-			"(%d >= %d)\n",
-			channelb, mci->csrows[csrow].nr_channels);
-		edac_mc_handle_ue_no_info(mci, "INTERNAL ERROR");
-		return;
+	if (!enable_per_layer_report) {
+		strcpy(label, "any memory");
+	} else {
+		debugf4("%s: csrow/channel to increment: (%d,%d)\n",
+			__func__, row, chan);
+		if (p == label)
+			strcpy(label, "unknown memory");
+		if (type == HW_EVENT_ERR_CORRECTED) {
+			if (row >= 0) {
+				mci->csrows[row].ce_count++;
+				if (chan >= 0)
+					mci->csrows[row].channels[chan].ce_count++;
+			}
+		} else
+			if (row >= 0)
+				mci->csrows[row].ue_count++;
 	}
 
-	mci->ue_count++;
-	mci->csrows[csrow].ue_count++;
-
-	/* Generate the DIMM labels from the specified channels */
-	label = mci->csrows[csrow].channels[channela].dimm->label;
-	chars = snprintf(pos, len + 1, "%s", label);
-	len -= chars;
-	pos += chars;
-
-	chars = snprintf(pos, len + 1, "-%s",
-			mci->csrows[csrow].channels[channelb].dimm->label);
-
-	if (edac_mc_get_log_ue())
-		edac_mc_printk(mci, KERN_EMERG,
-			"UE row %d, channel-a= %d channel-b= %d "
-			"labels \"%s\": %s\n", csrow, channela, channelb,
-			labels, msg);
-
-	if (edac_mc_get_panic_on_ue())
-		panic("UE row %d, channel-a= %d channel-b= %d "
-			"labels \"%s\": %s\n", csrow, channela,
-			channelb, labels, msg);
-}
-EXPORT_SYMBOL(edac_mc_handle_fbd_ue);
-
-/*************************************************************
- * On Fully Buffered DIMM modules, this help function is
- * called to process CE events
- */
-void edac_mc_handle_fbd_ce(struct mem_ctl_info *mci,
-			unsigned int csrow, unsigned int channel, char *msg)
-{
-	char *label = NULL;
+	/* Fill the RAM location data */
+	p = location;
+	for (i = 0; i < mci->n_layers; i++) {
+		if (pos[i] < 0)
+			continue;
 
-	/* Ensure boundary values */
-	if (csrow >= mci->nr_csrows) {
-		/* something is wrong */
-		edac_mc_printk(mci, KERN_ERR,
-			"INTERNAL ERROR: row out of range (%d >= %d)\n",
-			csrow, mci->nr_csrows);
-		edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR");
-		return;
+		p += sprintf(p, "%s:%d ",
+			     edac_layer_name[mci->layers[i].type],
+			     pos[i]);
 	}
-	if (channel >= mci->csrows[csrow].nr_channels) {
-		/* something is wrong */
-		edac_mc_printk(mci, KERN_ERR,
-			"INTERNAL ERROR: channel out of range (%d >= %d)\n",
-			channel, mci->csrows[csrow].nr_channels);
-		edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR");
-		return;
-	}
-
-	label = mci->csrows[csrow].channels[channel].dimm->label;
 
-	if (edac_mc_get_log_ce())
-		/* FIXME - put in DIMM location */
-		edac_mc_printk(mci, KERN_WARNING,
-			"CE row %d, channel %d, label \"%s\": %s\n",
-			csrow, channel, label, msg);
+	/* Memory type dependent details about the error */
+	if (type == HW_EVENT_ERR_CORRECTED) {
+		snprintf(detail, sizeof(detail),
+			"page:0x%lx offset:0x%lx grain:%d syndrome:0x%lx",
+			page_frame_number, offset_in_page,
+			grain, syndrome);
+		edac_ce_error(mci, pos, msg, location, label, detail,
+			      other_detail, enable_per_layer_report,
+			      page_frame_number, offset_in_page, grain);
+	} else {
+		snprintf(detail, sizeof(detail),
+			"page:0x%lx offset:0x%lx grain:%d",
+			page_frame_number, offset_in_page, grain);
 
-	mci->ce_count++;
-	mci->csrows[csrow].ce_count++;
-	mci->csrows[csrow].channels[channel].dimm->ce_count++;
-	mci->csrows[csrow].channels[channel].ce_count++;
+		edac_ue_error(mci, pos, msg, location, label, detail,
+			      other_detail, enable_per_layer_report);
+	}
 }
-EXPORT_SYMBOL(edac_mc_handle_fbd_ce);
+EXPORT_SYMBOL_GPL(edac_mc_handle_error);
diff --git a/include/linux/edac.h b/include/linux/edac.h
index 3b8798d..c8f507d 100644
--- a/include/linux/edac.h
+++ b/include/linux/edac.h
@@ -412,18 +412,20 @@ struct edac_mc_layer {
 /* FIXME: add the proper per-location error counts */
 struct dimm_info {
 	char label[EDAC_MC_LABEL_LEN + 1];	/* DIMM label on motherboard */
-	unsigned memory_controller;
-	unsigned csrow;
-	unsigned csrow_channel;
+
+	/* Memory location data */
+	unsigned location[EDAC_MAX_LAYERS];
+
+	struct mem_ctl_info *mci;	/* the parent */
 
 	u32 grain;		/* granularity of reported error in bytes */
 	enum dev_type dtype;	/* memory device type */
 	enum mem_type mtype;	/* memory dimm type */
 	enum edac_type edac_mode;	/* EDAC mode for this dimm */
 
-	u32 nr_pages;			/* number of pages in csrow */
+	u32 nr_pages;			/* number of pages on this dimm */
 
-	u32 ce_count;		/* Correctable Errors for this dimm */
+	unsigned csrow, cschannel;	/* Points to the old API data */
 };
 
 /**
@@ -443,9 +445,10 @@ struct dimm_info {
  */
 struct rank_info {
 	int chan_idx;
-	u32 ce_count;
 	struct csrow_info *csrow;
 	struct dimm_info *dimm;
+
+	u32 ce_count;		/* Correctable Errors for this csrow */
 };
 
 struct csrow_info {
@@ -541,13 +544,18 @@ struct mem_ctl_info {
 	unsigned long (*ctl_page_to_phys) (struct mem_ctl_info * mci,
 					   unsigned long page);
 	int mc_idx;
-	int nr_csrows;
 	struct csrow_info *csrows;
+	unsigned nr_csrows, num_cschannel;
+
+	/* Memory Controller hierarchy */
+	unsigned n_layers;
+	struct edac_mc_layer *layers;
+	bool mem_is_per_rank;
 
 	/*
 	 * DIMM info. Will eventually remove the entire csrows_info some day
 	 */
-	unsigned nr_dimms;
+	unsigned tot_dimms;
 	struct dimm_info *dimms;
 
 	/*
@@ -562,12 +570,16 @@ struct mem_ctl_info {
 	const char *dev_name;
 	char proc_name[MC_PROC_NAME_MAX_LEN + 1];
 	void *pvt_info;
-	u32 ue_noinfo_count;	/* Uncorrectable Errors w/o info */
-	u32 ce_noinfo_count;	/* Correctable Errors w/o info */
-	u32 ue_count;		/* Total Uncorrectable Errors for this MC */
-	u32 ce_count;		/* Total Correctable Errors for this MC */
 	unsigned long start_time;	/* mci load start time (in jiffies) */
 
+	/*
+	 * drivers shouldn't access those fields directly, as the core
+	 * already handles that.
+	 */
+	u32 ce_noinfo_count, ue_noinfo_count;
+	u32 ue_count, ce_count;
+	u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
+
 	struct completion complete;
 
 	/* edac sysfs device control */
@@ -580,7 +592,7 @@ struct mem_ctl_info {
 	 * by the low level driver.
 	 *
 	 * Set by the low level driver to provide attributes at the
-	 * controller level, same level as 'ue_count' and 'ce_count' above.
+	 * controller level.
 	 * An array of structures, NULL terminated
 	 *
 	 * If attributes are desired, then set to array of attributes
-- 
1.7.8

^ permalink raw reply related

* [PATCH 1/4] powerpc/83xx: use for_each_node_by_name for km83xx.c
From: Holger Brunck @ 2012-05-08 13:57 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Heiko Schocher, Holger Brunck

Signed-off-by: Holger Brunck <holger.brunck@keymile.com>
cc: Heiko Schocher <hs@denx.de>
cc: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/platforms/83xx/km83xx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c
index a266ba8..e827c6c 100644
--- a/arch/powerpc/platforms/83xx/km83xx.c
+++ b/arch/powerpc/platforms/83xx/km83xx.c
@@ -70,7 +70,7 @@ static void __init mpc83xx_km_setup_arch(void)
 		for_each_node_by_name(np, "spi")
 			par_io_of_config(np);
 
-		for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
+		for_each_node_by_name(np, "ucc")
 			par_io_of_config(np);
 	}
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH 4/4] powerpc/82xx: add SPI support for mgcoge
From: Holger Brunck @ 2012-05-08 13:57 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Heiko Schocher, Holger Brunck
In-Reply-To: <1336485442-24190-1-git-send-email-holger.brunck@keymile.com>

Add spi support for mgcoge into the platform code and the dts
file. Additionaly SPIDEV is switched on in the defconfig and the
updates for the newer kernel version are committed. The SPI
interface is used to drive the Maxim DS3106 clock chip.

Signed-off-by: Holger Brunck <holger.brunck@keymile.com>
cc: Heiko Schocher <hs@denx.de>
cc: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/boot/dts/mgcoge.dts      |   23 +++++++++++++++++++++++
 arch/powerpc/configs/mgcoge_defconfig |   12 ++++--------
 arch/powerpc/platforms/82xx/km82xx.c  |    5 +++++
 3 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/boot/dts/mgcoge.dts b/arch/powerpc/boot/dts/mgcoge.dts
index ededaf5..d72fb5e 100644
--- a/arch/powerpc/boot/dts/mgcoge.dts
+++ b/arch/powerpc/boot/dts/mgcoge.dts
@@ -222,6 +222,29 @@
 				interrupt-parent = <&PIC>;
 				usb-clock = <5>;
 			};
+			spi@11aa0 {
+				cell-index = <0>;
+				compatible = "fsl,spi", "fsl,cpm2-spi";
+				reg = <0x11a80 0x40 0x89fc 0x2>;
+				interrupts = <2 8>;
+				interrupt-parent = <&PIC>;
+				gpios = < &cpm2_pio_d 19 0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				ds3106@1 {
+					compatible = "gen,spidev";
+					reg = <0>;
+					spi-max-frequency = <8000000>;
+				};
+			};
+
+		};
+
+		cpm2_pio_d: gpio-controller@10d60 {
+			#gpio-cells = <2>;
+			compatible = "fsl,cpm2-pario-bank";
+			reg = <0x10d60 0x14>;
+			gpio-controller;
 		};
 
 		cpm2_pio_c: gpio-controller@10d40 {
diff --git a/arch/powerpc/configs/mgcoge_defconfig b/arch/powerpc/configs/mgcoge_defconfig
index 0d36b0e..8fa84f1 100644
--- a/arch/powerpc/configs/mgcoge_defconfig
+++ b/arch/powerpc/configs/mgcoge_defconfig
@@ -2,7 +2,6 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_SPARSE_IRQ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -12,6 +11,7 @@ CONFIG_KALLSYMS_ALL=y
 # CONFIG_PCSPKR_PLATFORM is not set
 CONFIG_EMBEDDED=y
 CONFIG_SLAB=y
+CONFIG_PARTITION_ADVANCED=y
 # CONFIG_IOSCHED_CFQ is not set
 # CONFIG_PPC_PMAC is not set
 CONFIG_PPC_82xx=y
@@ -49,12 +49,9 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_NETDEVICES=y
-CONFIG_FIXED_PHY=y
-CONFIG_NET_ETHERNET=y
 CONFIG_FS_ENET=y
 CONFIG_FS_ENET_MDIO_FCC=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+CONFIG_FIXED_PHY=y
 # CONFIG_WLAN is not set
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
@@ -64,6 +61,8 @@ CONFIG_SERIAL_CPM_CONSOLE=y
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_CPM=y
+CONFIG_SPI=y
+CONFIG_SPI_FSL_SPI=y
 # CONFIG_HWMON is not set
 CONFIG_USB_GADGET=y
 CONFIG_USB_FSL_USB2=y
@@ -80,8 +79,6 @@ CONFIG_SQUASHFS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=y
 CONFIG_NLS_ISO8859_1=y
@@ -90,7 +87,6 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_DEBUG_INFO=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_BDI_SWITCH=y
 CONFIG_CRYPTO_ECB=y
 CONFIG_CRYPTO_PCBC=y
diff --git a/arch/powerpc/platforms/82xx/km82xx.c b/arch/powerpc/platforms/82xx/km82xx.c
index 3661bcd..cf964e1 100644
--- a/arch/powerpc/platforms/82xx/km82xx.c
+++ b/arch/powerpc/platforms/82xx/km82xx.c
@@ -128,6 +128,11 @@ static __initdata struct cpm_pin km82xx_pins[] = {
 	{3, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, /* TXP */
 	{3, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, /* TXN */
 	{3, 25, CPM_PIN_INPUT  | CPM_PIN_PRIMARY}, /* RXD */
+
+	/* SPI */
+	{3, 16, CPM_PIN_INPUT | CPM_PIN_SECONDARY},/* SPI_MISO PD16 */
+	{3, 17, CPM_PIN_INPUT | CPM_PIN_SECONDARY},/* SPI_MOSI PD17 */
+	{3, 18, CPM_PIN_INPUT | CPM_PIN_SECONDARY},/* SPI_CLK PD18 */
 };
 
 static void __init init_ioports(void)
-- 
1.7.1

^ permalink raw reply related

* [PATCH 2/4] powerpc/83xx: fix RGMII AC values workaround for km83xx
From: Holger Brunck @ 2012-05-08 13:57 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Christian Herzig, Holger Brunck, Heiko Schocher
In-Reply-To: <1336485442-24190-1-git-send-email-holger.brunck@keymile.com>

From: Christian Herzig <christian.herzig@keymile.com>

Fix RGMII workaround code in km83xx.c for MPC8360E and MPC8358E that it
correctly identifes all affected SoC chip models and applies the
workarounds appropriate for 2.0 and 2.1 revisions as per Freescale
MPC8360ECE Errata document Rev.5(9/2011) item QE_ENET10.

Signed-off-by: Christian Herzig <christian.herzig@keymile.com>
Signed-off-by: Holger Brunck <holger.brunck@keymile.com>
cc: Heiko Schocher <hs@denx.de>
cc: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/platforms/83xx/km83xx.c |   98 +++++++++++++++++++++++-----------
 1 files changed, 66 insertions(+), 32 deletions(-)

diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c
index e827c6c..89923d7 100644
--- a/arch/powerpc/platforms/83xx/km83xx.c
+++ b/arch/powerpc/platforms/83xx/km83xx.c
@@ -3,7 +3,7 @@
  * Author: Heiko Schocher <hs@denx.de>
  *
  * Description:
- * Keymile KMETER1 board specific routines.
+ * Keymile 83xx platform specific routines.
  *
  * 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
@@ -76,48 +76,82 @@ static void __init mpc83xx_km_setup_arch(void)
 
 	np = of_find_compatible_node(NULL, "network", "ucc_geth");
 	if (np != NULL) {
-		uint svid;
+		/*
+		 * handle mpc8360E Erratum QE_ENET10:
+		 * RGMII AC values do not meet the specification
+		 */
+		uint svid = mfspr(SPRN_SVR);
+		struct	device_node *np_par;
+		struct	resource res;
+		void	__iomem *base;
+		int	ret;
+
+		np_par = of_find_node_by_name(NULL, "par_io");
+		if (np_par == NULL) {
+			printk(KERN_WARNING "%s couldn;t find par_io node\n",
+				__func__);
+			return;
+		}
+		/* Map Parallel I/O ports registers */
+		ret = of_address_to_resource(np_par, 0, &res);
+		if (ret) {
+			printk(KERN_WARNING "%s couldn;t map par_io registers\n",
+				__func__);
+			return;
+		}
+
+		base = ioremap(res.start, res.end - res.start + 1);
+
+		/*
+		 * set output delay adjustments to default values according
+		 * table 5 in Errata Rev. 5, 9/2011:
+		 *
+		 * write 0b01 to UCC1 bits 18:19
+		 * write 0b01 to UCC2 option 1 bits 4:5
+		 * write 0b01 to UCC2 option 2 bits 16:17
+		 */
+		clrsetbits_be32((base + 0xa8), 0x0c00f000, 0x04005000);
+
+		/*
+		 * set output delay adjustments to default values according
+		 * table 3-13 in Reference Manual Rev.3 05/2010:
+		 *
+		 * write 0b01 to UCC2 option 2 bits 16:17
+		 * write 0b0101 to UCC1 bits 20:23
+		 * write 0b0101 to UCC2 option 1 bits 24:27
+		 */
+		clrsetbits_be32((base + 0xac), 0x0000cff0, 0x00004550);
 
-		/* handle mpc8360ea rev.2.1 erratum 2: RGMII Timing */
-		svid = mfspr(SPRN_SVR);
 		if (SVR_REV(svid) == 0x0021) {
-			struct	device_node *np_par;
-			struct	resource res;
-			void	__iomem *base;
-			int	ret;
-
-			np_par = of_find_node_by_name(NULL, "par_io");
-			if (np_par == NULL) {
-				printk(KERN_WARNING "%s couldn;t find par_io node\n",
-					__func__);
-				return;
-			}
-			/* Map Parallel I/O ports registers */
-			ret = of_address_to_resource(np_par, 0, &res);
-			if (ret) {
-				printk(KERN_WARNING "%s couldn;t map par_io registers\n",
-					__func__);
-				return;
-			}
-			base = ioremap(res.start, resource_size(&res));
+			/*
+			 * UCC2 option 1: write 0b1010 to bits 24:27
+			 * at address IMMRBAR+0x14AC
+			 */
+			clrsetbits_be32((base + 0xac), 0x000000f0, 0x000000a0);
+		} else if (SVR_REV(svid) == 0x0020) {
+			/*
+			 * UCC1: write 0b11 to bits 18:19
+			 * at address IMMRBAR+0x14A8
+			 */
+			setbits32((base + 0xa8), 0x00003000);
 
 			/*
-			 * IMMR + 0x14A8[4:5] = 11 (clk delay for UCC 2)
-			 * IMMR + 0x14A8[18:19] = 11 (clk delay for UCC 1)
+			 * UCC2 option 1: write 0b11 to bits 4:5
+			 * at address IMMRBAR+0x14A8
 			 */
-			setbits32((base + 0xa8), 0x0c003000);
+			setbits32((base + 0xa8), 0x0c000000);
 
 			/*
-			 * IMMR + 0x14AC[20:27] = 10101010
-			 * (data delay for both UCC's)
+			 * UCC2 option 2: write 0b11 to bits 16:17
+			 * at address IMMRBAR+0x14AC
 			 */
-			clrsetbits_be32((base + 0xac), 0xff0, 0xaa0);
-			iounmap(base);
-			of_node_put(np_par);
+			setbits32((base + 0xac), 0x0000c000);
 		}
+		iounmap(base);
+		of_node_put(np_par);
 		of_node_put(np);
 	}
-#endif				/* CONFIG_QUICC_ENGINE */
+#endif	/* CONFIG_QUICC_ENGINE */
 }
 
 machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices);
-- 
1.7.1

^ permalink raw reply related

* [PATCH 3/4] powerpc/83xx: update defconfig for kmeter1
From: Holger Brunck @ 2012-05-08 13:57 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Heiko Schocher, Holger Brunck
In-Reply-To: <1336485442-24190-1-git-send-email-holger.brunck@keymile.com>

Switch on UBIFS, HOTPLUG and TIPC and update the config to
the latest kernel version.

Signed-off-by: Holger Brunck <holger.brunck@keymile.com>
cc: Heiko Schocher <hs@denx.de>
cc: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/configs/83xx/kmeter1_defconfig |   22 ++++++++--------------
 1 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/configs/83xx/kmeter1_defconfig b/arch/powerpc/configs/83xx/kmeter1_defconfig
index 07e1bba..a0dfef1 100644
--- a/arch/powerpc/configs/83xx/kmeter1_defconfig
+++ b/arch/powerpc/configs/83xx/kmeter1_defconfig
@@ -2,14 +2,14 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_SPARSE_IRQ=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_EXPERT=y
-# CONFIG_HOTPLUG is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_MSDOS_PARTITION is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
 # CONFIG_PPC_CHRP is not set
@@ -31,11 +31,10 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_IPV6 is not set
+CONFIG_TIPC=y
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=y
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
@@ -50,17 +49,15 @@ CONFIG_MTD_UBI_DEBUG=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
-CONFIG_TUN=y
 CONFIG_MII=y
-CONFIG_MARVELL_PHY=y
-CONFIG_NET_ETHERNET=y
+CONFIG_TUN=y
 CONFIG_UCC_GETH=y
-# CONFIG_NETDEV_10000 is not set
-CONFIG_WAN=y
-CONFIG_HDLC=y
+CONFIG_MARVELL_PHY=y
 CONFIG_PPP=y
 CONFIG_PPP_MULTILINK=y
 CONFIG_PPPOE=y
+CONFIG_WAN=y
+CONFIG_HDLC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
@@ -77,10 +74,7 @@ CONFIG_UIO=y
 # CONFIG_DNOTIFY is not set
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_MSDOS_PARTITION is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-- 
1.7.1

^ permalink raw reply related

* RE: [PATCH 2/2] powerpc/watchdog: replace CONFIG_FSL_BOOKE with CONFIG_FSL_SOC_BOOKE
From: Bhushan Bharat-R65777 @ 2012-05-08 17:12 UTC (permalink / raw)
  To: Xie Shaohui-B21989, linux-watchdog@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org
  Cc: Xie Shaohui-B21989
In-Reply-To: <1336457276-32611-1-git-send-email-Shaohui.Xie@freescale.com>



> -----Original Message-----
> From: linuxppc-dev-bounces+bharat.bhushan=3Dfreescale.com@lists.ozlabs.or=
g
> [mailto:linuxppc-dev-bounces+bharat.bhushan=3Dfreescale.com@lists.ozlabs.=
org] On
> Behalf Of Shaohui Xie
> Sent: Tuesday, May 08, 2012 11:38 AM
> To: linux-watchdog@vger.kernel.org; linuxppc-dev@lists.ozlabs.org
> Cc: Xie Shaohui-B21989
> Subject: [PATCH 2/2] powerpc/watchdog: replace CONFIG_FSL_BOOKE with
> CONFIG_FSL_SOC_BOOKE

CONFIG_FSL_SOC_BOOKE looks like for SOC config option and watchdog is cpu f=
eature.

Should not we use PPC_FSL_BOOK3E?

Thanks
-Bharat

^ permalink raw reply

* RE: [PATCH 1/2] powerpc/watchdog: move booke watchdog param related code to prom.c
From: Bhushan Bharat-R65777 @ 2012-05-08 17:13 UTC (permalink / raw)
  To: Xie Shaohui-B21989, linux-watchdog@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org
  Cc: Xie Shaohui-B21989
In-Reply-To: <1336457231-32513-1-git-send-email-Shaohui.Xie@freescale.com>



> -----Original Message-----
> From: linuxppc-dev-bounces+bharat.bhushan=3Dfreescale.com@lists.ozlabs.or=
g
> [mailto:linuxppc-dev-bounces+bharat.bhushan=3Dfreescale.com@lists.ozlabs.=
org] On
> Behalf Of Shaohui Xie
> Sent: Tuesday, May 08, 2012 11:37 AM
> To: linux-watchdog@vger.kernel.org; linuxppc-dev@lists.ozlabs.org
> Cc: Xie Shaohui-B21989
> Subject: [PATCH 1/2] powerpc/watchdog: move booke watchdog param related =
code to
> prom.c
>=20
> Currently, BOOKE watchdog code for checking "wdt" and "wdt_period" is in
> setup_32.c, it cannot be used in 64-bit, so move it to a common place pro=
m.c,
> which will be shared by 32-bit and 64-bit.
>=20
> Also, replace the simple_strtoul with kstrtol.
>=20
> Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
> ---
>  arch/powerpc/kernel/prom.c     |   27 +++++++++++++++++++++++++++
>  arch/powerpc/kernel/setup_32.c |   24 ------------------------
>  2 files changed, 27 insertions(+), 24 deletions(-)

Is not setup-common.c is better place to move this?

Thanks
-Bharat

^ permalink raw reply

* Re: Build regressions/improvements in v3.4-rc6
From: Geert Uytterhoeven @ 2012-05-08 19:22 UTC (permalink / raw)
  To: linux-kernel; +Cc: Linuxppc-dev
In-Reply-To: <1336504803-1951-1-git-send-email-geert@linux-m68k.org>

On Tue, May 8, 2012 at 9:20 PM, Geert Uytterhoeven <geert@linux-m68k.org> w=
rote:
> JFYI, when comparing v3.4-rc6 to v3.4-rc5[3], the summaries are:
> =C2=A0- build errors: +2/-1

2 regressions:
  + arch/powerpc/sysdev/mpic.c: error: case label does not reduce to
an integer constant:  =3D> 890:9, 898:9, 886:9, 894:9
  + error: "set_personality_ia32" [arch/x86/ia32/ia32_aout.ko]
undefined!:  =3D> N/A

The former is from powerpc-randconfig, the latter has been fixed in
the mean time.

Gr{oetje,eeting}s,

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k=
.org

In personal conversations with technical people, I call myself a hacker. Bu=
t
when I'm talking to journalists I just say "programmer" or something like t=
hat.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0 =C2=A0=C2=A0 -- Linus Torvalds

^ permalink raw reply

* [RFC] [PATCH] usb: gadget: fix dtd dma confusion
From: Christoph Fritz @ 2012-05-09  0:02 UTC (permalink / raw)
  To: Fabio Estevam, Neil Zhang, Li Yang, Felipe Balbi,
	Greg Kroah-Hartman, linux-usb, linuxppc-dev, Hans J. Koch,
	Daniel Mack
  Cc: Oliver Neukum, Kukjin Kim, Eric Miao, Chen Peter-B29397,
	Sascha Hauer, Nicolas Ferre, Haojian Zhuang, Estevam Fabio-R49496,
	Ido Shayevitz, Ben Dooks, Thomas Dahlmann, Russell King
In-Reply-To: <CAOMZO5C729Ki0Bequ+s1nnrgt4NZWvwg3Wnjk4kHp=d9BtkeXw@mail.gmail.com>

On Wed, Apr 11, 2012 at 10:15:49AM -0300, Fabio Estevam wrote:
> On Wed, Apr 11, 2012 at 4:39 AM, Christoph Fritz
> <chf.fritz@googlemail.com> wrote:
> 
> > Can you approve this behaviour of g_ether/usbnet when using iperf?
> 
> I am not very familiar with iperf, so I will let others comment.

Hi to All,

after a while of testing and searching I can come up with a patch
that fixes g_ether <-> iperf for fsl_udc on ARM i.MX35.

The sad part is that this kind of fix is already implemented for
marvell mv_udc driver since last year but still _not_ in the ~15
other *udc.c drivers.

See here:
daec765da767e4a6a30e1298862b28f2cae9a73f
usb: gadget: mv_udc: fix dtd dma confusion

So hereby I'm CC-ing all *udc.c maintainers to point out that this
issue maybe affects you too.

And maybe someone can explain if this: 
+				if (curr_td->next_td_ptr == EP_QUEUE_HEAD_NEXT_TERMINATE) {
is necessary and why (please see below).


Thanks,
 -- Christoph

---
Subject: [PATCH] usb: gadget: fsl_udc: fix dtd dma confusion

The controller will hang when doing testings with g_ether and iperf
(tool for measuring maximum TCP and UDP bandwidth).  This patch adds a
delay to wait for controller to release dtd dma before freeing it.

Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
---
 drivers/usb/gadget/fsl_udc_core.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 55abfb6..fc86108 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -1638,6 +1638,15 @@ static int process_ep_req(struct fsl_udc *udc, int pipe,
 			status = REQ_UNCOMPLETE;
 			return status;
 		} else if (remaining_length) {
+			/* wait controller release dtd dma */
+			while ((curr_qh->curr_dtd_ptr == curr_td->td_dma)) {
+				if (curr_td->next_td_ptr ==
+						EP_QUEUE_HEAD_NEXT_TERMINATE) {
+					udelay(100);
+					break;
+				}
+				udelay(1);
+			}
 			if (direction) {
 				VDBG("Transmit dTD remaining length not zero");
 				status = -EPROTO;
-- 
1.7.2.5

^ permalink raw reply related

* [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2012-05-09  1:12 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linuxppc-dev list, Andrew Morton, Linux Kernel list

Hi Linus !

Here are a couple of last minute fixes for 3.4 for regressions
introduced by my rewrite of the lazy irq masking code.

Cheers,
Ben.

The following changes since commit 810b4de25e53459323ff48957b0162b48d6cbd57:

  tty/serial/pmac_zilog: Fix "nobody cared" IRQ message (2012-04-30 10:59:58 +1000)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git merge

for you to fetch changes up to a3512b2dd57cb653bb33645ca9c934436e547e3c:

  powerpc/irq: Make alignment & program interrupt behave the same (2012-05-09 09:42:33 +1000)

----------------------------------------------------------------
Benjamin Herrenschmidt (2):
      powerpc/irq: Fix bug with new lazy IRQ handling code
      powerpc/irq: Make alignment & program interrupt behave the same

 arch/powerpc/include/asm/exception-64s.h |    7 -------
 arch/powerpc/kernel/entry_64.S           |   18 ------------------
 arch/powerpc/kernel/exceptions-64s.S     |    2 +-
 arch/powerpc/kernel/irq.c                |    8 +++++++-
 arch/powerpc/kernel/traps.c              |   10 ++++++++--
 5 files changed, 16 insertions(+), 29 deletions(-)

^ permalink raw reply

* RE: [RFC] [PATCH] usb: gadget: fix dtd dma confusion
From: Neil Zhang @ 2012-05-09  1:50 UTC (permalink / raw)
  To: Christoph Fritz, Fabio Estevam, Li Yang, Felipe Balbi,
	Greg Kroah-Hartman, linux-usb@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org, Hans J. Koch, Daniel Mack
  Cc: Oliver Neukum, Kukjin Kim, Eric Miao, Chen Peter-B29397,
	Sascha Hauer, Nicolas Ferre, Haojian Zhuang, Estevam Fabio-R49496,
	Ido Shayevitz, Ben Dooks, Thomas Dahlmann, Russell King, Chao Xie
In-Reply-To: <20120509000221.GA19525@lovely.krouter>

SGkgQ2hyaXN0b3BoLA0KDQo+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+IEZyb206IENo
cmlzdG9waCBGcml0eiBbbWFpbHRvOmNoZi5mcml0ekBnb29nbGVtYWlsLmNvbV0NCj4gU2VudDog
MjAxMsTqNdTCOcjVIDg6MDINCj4gVG86IEZhYmlvIEVzdGV2YW07IE5laWwgWmhhbmc7IExpIFlh
bmc7IEZlbGlwZSBCYWxiaTsgR3JlZyBLcm9haC0NCj4gSGFydG1hbjsgbGludXgtdXNiQHZnZXIu
a2VybmVsLm9yZzsgbGludXhwcGMtZGV2QGxpc3RzLm96bGFicy5vcmc7IEhhbnMNCj4gSi4gS29j
aDsgRGFuaWVsIE1hY2sNCj4gQ2M6IFRob21hcyBEYWhsbWFubjsgTmljb2xhcyBGZXJyZTsgRXJp
YyBNaWFvOyBSdXNzZWxsIEtpbmc7IEhhb2ppYW4NCj4gWmh1YW5nOyBCZW4gRG9va3M7IEt1a2pp
biBLaW07IFNhc2NoYSBIYXVlcjsgT2xpdmVyIE5ldWt1bTsgQ2hlbiBQZXRlci0NCj4gQjI5Mzk3
OyBJZG8gU2hheWV2aXR6OyBFc3RldmFtIEZhYmlvLVI0OTQ5Ng0KPiBTdWJqZWN0OiBbUkZDXSBb
UEFUQ0hdIHVzYjogZ2FkZ2V0OiBmaXggZHRkIGRtYSBjb25mdXNpb24NCj4gDQo+IE9uIFdlZCwg
QXByIDExLCAyMDEyIGF0IDEwOjE1OjQ5QU0gLTAzMDAsIEZhYmlvIEVzdGV2YW0gd3JvdGU6DQo+
ID4gT24gV2VkLCBBcHIgMTEsIDIwMTIgYXQgNDozOSBBTSwgQ2hyaXN0b3BoIEZyaXR6DQo+ID4g
PGNoZi5mcml0ekBnb29nbGVtYWlsLmNvbT4gd3JvdGU6DQo+ID4NCj4gPiA+IENhbiB5b3UgYXBw
cm92ZSB0aGlzIGJlaGF2aW91ciBvZiBnX2V0aGVyL3VzYm5ldCB3aGVuIHVzaW5nIGlwZXJmPw0K
PiA+DQo+ID4gSSBhbSBub3QgdmVyeSBmYW1pbGlhciB3aXRoIGlwZXJmLCBzbyBJIHdpbGwgbGV0
IG90aGVycyBjb21tZW50Lg0KPiANCj4gSGkgdG8gQWxsLA0KPiANCj4gYWZ0ZXIgYSB3aGlsZSBv
ZiB0ZXN0aW5nIGFuZCBzZWFyY2hpbmcgSSBjYW4gY29tZSB1cCB3aXRoIGEgcGF0Y2gNCj4gdGhh
dCBmaXhlcyBnX2V0aGVyIDwtPiBpcGVyZiBmb3IgZnNsX3VkYyBvbiBBUk0gaS5NWDM1Lg0KPiAN
Cj4gVGhlIHNhZCBwYXJ0IGlzIHRoYXQgdGhpcyBraW5kIG9mIGZpeCBpcyBhbHJlYWR5IGltcGxl
bWVudGVkIGZvcg0KPiBtYXJ2ZWxsIG12X3VkYyBkcml2ZXIgc2luY2UgbGFzdCB5ZWFyIGJ1dCBz
dGlsbCBfbm90XyBpbiB0aGUgfjE1DQo+IG90aGVyICp1ZGMuYyBkcml2ZXJzLg0KPiANCj4gU2Vl
IGhlcmU6DQo+IGRhZWM3NjVkYTc2N2U0YTZhMzBlMTI5ODg2MmIyOGYyY2FlOWE3M2YNCj4gdXNi
OiBnYWRnZXQ6IG12X3VkYzogZml4IGR0ZCBkbWEgY29uZnVzaW9uDQo+IA0KPiBTbyBoZXJlYnkg
SSdtIENDLWluZyBhbGwgKnVkYy5jIG1haW50YWluZXJzIHRvIHBvaW50IG91dCB0aGF0IHRoaXMN
Cj4gaXNzdWUgbWF5YmUgYWZmZWN0cyB5b3UgdG9vLg0KPiANCj4gQW5kIG1heWJlIHNvbWVvbmUg
Y2FuIGV4cGxhaW4gaWYgdGhpczoNCj4gKwkJCQlpZiAoY3Vycl90ZC0+bmV4dF90ZF9wdHIgPT0N
Cj4gRVBfUVVFVUVfSEVBRF9ORVhUX1RFUk1JTkFURSkgew0KPiBpcyBuZWNlc3NhcnkgYW5kIHdo
eSAocGxlYXNlIHNlZSBiZWxvdykuDQo+IA0KIA0KVGhlIG91dGVyIGxvb3AgaXMgdG8gY2hlY2sg
d2hldGhlciB0aGUgY29udHJvbGxlciBzdGlsbCBwb2ludCB0byB0aGUgY3VycmVudCBkdGQuDQpJ
ZiBzbywgd2Ugc2hvdWxkIHdhaXQgaXQgdG8gbW92ZSBvbnRvIHRoZSBuZXh0IGR0ZC4NCkJ1dCB0
aGVyZSBpcyBhbiBleGNlcHRpb24sIGlmIHRoZSBjdXJyZW50IGR0ZCBpcyB0aGUgbGFzdCBkdGQg
b24gdGhpcyBlcCBxdWV1ZSwgDQp0aGVuIHRoZSBjb250cm9sbGVyIGNhbiBuZXZlciBtb3ZlIG9u
Lg0KRm9ydHVuYXRlbHksIHdlIGNhbiBjaGVjayByZWdpc3RlciBlcHN0YXR1cyAob2Zmc2V0OiAw
eDFiOCkgdG8gc2VlIHdoZXRoZXIgdGhlIGJ1ZmZlciBpcyBmcmVlIGFnYWluLg0KDQo+IFRoYW5r
cywNCj4gIC0tIENocmlzdG9waA0KPiANCj4gLS0tDQo+IFN1YmplY3Q6IFtQQVRDSF0gdXNiOiBn
YWRnZXQ6IGZzbF91ZGM6IGZpeCBkdGQgZG1hIGNvbmZ1c2lvbg0KPiANCj4gVGhlIGNvbnRyb2xs
ZXIgd2lsbCBoYW5nIHdoZW4gZG9pbmcgdGVzdGluZ3Mgd2l0aCBnX2V0aGVyIGFuZCBpcGVyZg0K
PiAodG9vbCBmb3IgbWVhc3VyaW5nIG1heGltdW0gVENQIGFuZCBVRFAgYmFuZHdpZHRoKS4gIFRo
aXMgcGF0Y2ggYWRkcyBhDQo+IGRlbGF5IHRvIHdhaXQgZm9yIGNvbnRyb2xsZXIgdG8gcmVsZWFz
ZSBkdGQgZG1hIGJlZm9yZSBmcmVlaW5nIGl0Lg0KPiANCj4gU2lnbmVkLW9mZi1ieTogQ2hyaXN0
b3BoIEZyaXR6IDxjaGYuZnJpdHpAZ29vZ2xlbWFpbC5jb20+DQo+IC0tLQ0KPiAgZHJpdmVycy91
c2IvZ2FkZ2V0L2ZzbF91ZGNfY29yZS5jIHwgICAgOSArKysrKysrKysNCj4gIDEgZmlsZXMgY2hh
bmdlZCwgOSBpbnNlcnRpb25zKCspLCAwIGRlbGV0aW9ucygtKQ0KPiANCj4gZGlmZiAtLWdpdCBh
L2RyaXZlcnMvdXNiL2dhZGdldC9mc2xfdWRjX2NvcmUuYw0KPiBiL2RyaXZlcnMvdXNiL2dhZGdl
dC9mc2xfdWRjX2NvcmUuYw0KPiBpbmRleCA1NWFiZmI2Li5mYzg2MTA4IDEwMDY0NA0KPiAtLS0g
YS9kcml2ZXJzL3VzYi9nYWRnZXQvZnNsX3VkY19jb3JlLmMNCj4gKysrIGIvZHJpdmVycy91c2Iv
Z2FkZ2V0L2ZzbF91ZGNfY29yZS5jDQo+IEBAIC0xNjM4LDYgKzE2MzgsMTUgQEAgc3RhdGljIGlu
dCBwcm9jZXNzX2VwX3JlcShzdHJ1Y3QgZnNsX3VkYyAqdWRjLA0KPiBpbnQgcGlwZSwNCj4gIAkJ
CXN0YXR1cyA9IFJFUV9VTkNPTVBMRVRFOw0KPiAgCQkJcmV0dXJuIHN0YXR1czsNCj4gIAkJfSBl
bHNlIGlmIChyZW1haW5pbmdfbGVuZ3RoKSB7DQo+ICsJCQkvKiB3YWl0IGNvbnRyb2xsZXIgcmVs
ZWFzZSBkdGQgZG1hICovDQo+ICsJCQl3aGlsZSAoKGN1cnJfcWgtPmN1cnJfZHRkX3B0ciA9PSBj
dXJyX3RkLT50ZF9kbWEpKSB7DQo+ICsJCQkJaWYgKGN1cnJfdGQtPm5leHRfdGRfcHRyID09DQo+
ICsJCQkJCQlFUF9RVUVVRV9IRUFEX05FWFRfVEVSTUlOQVRFKSB7DQo+ICsJCQkJCXVkZWxheSgx
MDApOw0KPiArCQkJCQlicmVhazsNCj4gKwkJCQl9DQo+ICsJCQkJdWRlbGF5KDEpOw0KPiArCQkJ
fQ0KPiAgCQkJaWYgKGRpcmVjdGlvbikgew0KPiAgCQkJCVZEQkcoIlRyYW5zbWl0IGRURCByZW1h
aW5pbmcgbGVuZ3RoIG5vdCB6ZXJvIik7DQo+ICAJCQkJc3RhdHVzID0gLUVQUk9UTzsNCj4gLS0N
Cj4gMS43LjIuNQ0KPiANCg0KQmVzdCBSZWdhcmRzLA0KTmVpbCBaaGFuZw0K

^ permalink raw reply

* RE: [RFC] [PATCH] usb: gadget: fix dtd dma confusion
From: Chen Peter-B29397 @ 2012-05-09  2:11 UTC (permalink / raw)
  To: Neil Zhang, Christoph Fritz, Fabio Estevam, Li Yang-R58472,
	Felipe Balbi, Greg Kroah-Hartman, linux-usb@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org, Hans J. Koch, Daniel Mack
  Cc: Oliver Neukum, Kukjin Kim, Eric Miao, Estevam Fabio-R49496,
	Sascha Hauer, Nicolas Ferre, Haojian Zhuang, Ido Shayevitz,
	Ben Dooks, Thomas Dahlmann, Russell King, Chao Xie
In-Reply-To: <175CCF5F49938B4D99B2E3EF7F558EBE1A180E49BA@SC-VEXCH4.marvell.com>


=20
> >
> > after a while of testing and searching I can come up with a patch
> > that fixes g_ether <-> iperf for fsl_udc on ARM i.MX35.
> >
> > The sad part is that this kind of fix is already implemented for
> > marvell mv_udc driver since last year but still _not_ in the ~15
> > other *udc.c drivers.
> >
=20
It is a controller limitation (bug?) for chipidea controller when using
dtd list to handle multi-dtds situation. The controller will read dtd's
next pointer after this dtd's active bit has already been cleared.

Freescale has an errata for this problem's description and solution.
http://cache.freescale.com/files/dsp/doc/errata/IMX23CE.pdf
See 2858

BR,
Peter

^ permalink raw reply

* Re: [PATCH] powerpc: fix compile fail in hugetlb cmdline parsing
From: Benjamin Herrenschmidt @ 2012-05-09  3:04 UTC (permalink / raw)
  To: Rusty Russell
  Cc: Jim Cromie, Greg Kroah-Hartman, Jason Baron, Paul Gortmaker,
	linux-next, linuxppc-dev
In-Reply-To: <878vh3cncz.fsf@rustcorp.com.au>

On Tue, 2012-05-08 at 13:53 +0930, Rusty Russell wrote:
> On Mon,  7 May 2012 10:32:22 -0400, Paul Gortmaker <paul.gortmaker@windriver.com> wrote:
> > Commit 9fb48c744ba6a4bf58b666f4e6fdac3008ea1bd4
> > 
> >     "params: add 3rd arg to option handler callback signature"
> > 
> > added an extra arg to the function, but didn't catch all the use
> > cases needing it, causing this compile fail in mpc85xx_defconfig:
> > 
> >  arch/powerpc/mm/hugetlbpage.c:316:4: error: passing argument 7 of
> >  'parse_args' from incompatible pointer type [-Werror]
> > 
> >  include/linux/moduleparam.h:317:12: note: expected
> > 	 'int (*)(char *, char *, const char *)' but argument is of type
> > 	 'int (*)(char *, char *)'
> > 
> > This function has no need to printk out the "doing" value, so
> > just add the arg as an "unused".
> > 
> > Cc: Rusty Russell <rusty@rustcorp.com.au>
> > Cc: Jim Cromie <jim.cromie@gmail.com>
> > Cc: Jason Baron <jbaron@redhat.com>
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Cc: Becky Bruce <beckyb@kernel.crashing.org>
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
> 
> Acked-by: Rusty Russell <rusty@rustcorp.com.au>

This is for -next right ? IE. I don't seem to have the faulty commit
in my tree so I can't carry the fix for now.... or am I missing
something ?

Cheers,
Ben.

^ permalink raw reply

* RE: [PATCH 1/2] powerpc/watchdog: move booke watchdog param related code to prom.c
From: Xie Shaohui-B21989 @ 2012-05-09  3:20 UTC (permalink / raw)
  To: Bhushan Bharat-R65777, linux-watchdog@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <6A3DF150A5B70D4F9B66A25E3F7C888D03CF692C@039-SN2MPN1-023.039d.mgd.msft.net>

>> -----Original Message-----
>> From:
>> linuxppc-dev-bounces+bharat.bhushan=3Dfreescale.com@lists.ozlabs.org
>> [mailto:linuxppc-dev-bounces+bharat.bhushan=3Dfreescale.com@lists.ozlabs
>> .org] On Behalf Of Shaohui Xie
>> Sent: Tuesday, May 08, 2012 11:37 AM
>> To: linux-watchdog@vger.kernel.org; linuxppc-dev@lists.ozlabs.org
>> Cc: Xie Shaohui-B21989
>> Subject: [PATCH 1/2] powerpc/watchdog: move booke watchdog param
>> related code to prom.c
>>
>> Currently, BOOKE watchdog code for checking "wdt" and "wdt_period" is
>> in setup_32.c, it cannot be used in 64-bit, so move it to a common
>> place prom.c, which will be shared by 32-bit and 64-bit.
>>
>> Also, replace the simple_strtoul with kstrtol.
>>
>> Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
>> ---
>>  arch/powerpc/kernel/prom.c     |   27 +++++++++++++++++++++++++++
>>  arch/powerpc/kernel/setup_32.c |   24 ------------------------
>>  2 files changed, 27 insertions(+), 24 deletions(-)
>
>Is not setup-common.c is better place to move this?

Move out from setup_32.c does not mean it have to go into setup-common.c, I=
 need better reason to do this.


Best Regards,=20
Shaohui Xie

^ permalink raw reply

* RE: [PATCH 1/2] powerpc/watchdog: move booke watchdog param related code to prom.c
From: Bhushan Bharat-R65777 @ 2012-05-09  3:27 UTC (permalink / raw)
  To: Xie Shaohui-B21989, linux-watchdog@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <ED492CCEAF882048BC2237DE806547C90B2EB2@039-SN2MPN1-013.039d.mgd.msft.net>



> -----Original Message-----
> From: Xie Shaohui-B21989
> Sent: Wednesday, May 09, 2012 8:50 AM
> To: Bhushan Bharat-R65777; linux-watchdog@vger.kernel.org; linuxppc-
> dev@lists.ozlabs.org
> Subject: RE: [PATCH 1/2] powerpc/watchdog: move booke watchdog param rela=
ted
> code to prom.c
>=20
> >> -----Original Message-----
> >> From:
> >> linuxppc-dev-bounces+bharat.bhushan=3Dfreescale.com@lists.ozlabs.org
> >> [mailto:linuxppc-dev-bounces+bharat.bhushan=3Dfreescale.com@lists.ozla=
b
> >> s
> >> .org] On Behalf Of Shaohui Xie
> >> Sent: Tuesday, May 08, 2012 11:37 AM
> >> To: linux-watchdog@vger.kernel.org; linuxppc-dev@lists.ozlabs.org
> >> Cc: Xie Shaohui-B21989
> >> Subject: [PATCH 1/2] powerpc/watchdog: move booke watchdog param
> >> related code to prom.c
> >>
> >> Currently, BOOKE watchdog code for checking "wdt" and "wdt_period" is
> >> in setup_32.c, it cannot be used in 64-bit, so move it to a common
> >> place prom.c, which will be shared by 32-bit and 64-bit.
> >>
> >> Also, replace the simple_strtoul with kstrtol.
> >>
> >> Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
> >> ---
> >>  arch/powerpc/kernel/prom.c     |   27 +++++++++++++++++++++++++++
> >>  arch/powerpc/kernel/setup_32.c |   24 ------------------------
> >>  2 files changed, 27 insertions(+), 24 deletions(-)
> >
> >Is not setup-common.c is better place to move this?
>=20
> Move out from setup_32.c does not mean it have to go into setup-common.c,=
 I need
> better reason to do this.
>=20

What I think that setup_32.c is for 32 bit, setup_64.c is for 64 bit and se=
tup-common.c is for both.

I am not saying that you move this to setup-common.c. I am asking why you h=
ave not used setup-common.c ? I am ok even with prom.c.


Thanks
-Bharat

^ permalink raw reply

* RE: [PATCH 1/2] powerpc/watchdog: move booke watchdog param related code to prom.c
From: Xie Shaohui-B21989 @ 2012-05-09  3:42 UTC (permalink / raw)
  To: Bhushan Bharat-R65777, linux-watchdog@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <6A3DF150A5B70D4F9B66A25E3F7C888D03CF86B7@039-SN2MPN1-023.039d.mgd.msft.net>

>> -----Original Message-----
>> From: Xie Shaohui-B21989
>> Sent: Wednesday, May 09, 2012 8:50 AM
>> To: Bhushan Bharat-R65777; linux-watchdog@vger.kernel.org; linuxppc-
>> dev@lists.ozlabs.org
>> Subject: RE: [PATCH 1/2] powerpc/watchdog: move booke watchdog param
>> related code to prom.c
>>
>> >> -----Original Message-----
>> >> From:
>> >> linuxppc-dev-bounces+bharat.bhushan=3Dfreescale.com@lists.ozlabs.org
>> >> [mailto:linuxppc-dev-bounces+bharat.bhushan=3Dfreescale.com@lists.ozl
>> >> ab
>> >> s
>> >> .org] On Behalf Of Shaohui Xie
>> >> Sent: Tuesday, May 08, 2012 11:37 AM
>> >> To: linux-watchdog@vger.kernel.org; linuxppc-dev@lists.ozlabs.org
>> >> Cc: Xie Shaohui-B21989
>> >> Subject: [PATCH 1/2] powerpc/watchdog: move booke watchdog param
>> >> related code to prom.c
>> >>
>> >> Currently, BOOKE watchdog code for checking "wdt" and "wdt_period"
>> >> is in setup_32.c, it cannot be used in 64-bit, so move it to a
>> >> common place prom.c, which will be shared by 32-bit and 64-bit.
>> >>
>> >> Also, replace the simple_strtoul with kstrtol.
>> >>
>> >> Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
>> >> ---
>> >>  arch/powerpc/kernel/prom.c     |   27 +++++++++++++++++++++++++++
>> >>  arch/powerpc/kernel/setup_32.c |   24 ------------------------
>> >>  2 files changed, 27 insertions(+), 24 deletions(-)
>> >
>> >Is not setup-common.c is better place to move this?
>>
>> Move out from setup_32.c does not mean it have to go into
>> setup-common.c, I need better reason to do this.
>>
>
>What I think that setup_32.c is for 32 bit, setup_64.c is for 64 bit and
>setup-common.c is for both.
>
>I am not saying that you move this to setup-common.c. I am asking why you
>have not used setup-common.c ? I am ok even with prom.c.
>
[Xie Shaohui] I'm not a fan of prom.c, I did this because I see same kind o=
f early parameters checking is did in this file only, so I thought maybe I =
should put them together. And seems setup-common.c is not the place to do c=
ommand line checking (I'm not sure about this).


Best Regards,=20
Shaohui Xie

^ permalink raw reply

* RE: [PATCH 1/2] powerpc/watchdog: move booke watchdog param related code to prom.c
From: Bhushan Bharat-R65777 @ 2012-05-09  3:46 UTC (permalink / raw)
  To: Xie Shaohui-B21989, linux-watchdog@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <ED492CCEAF882048BC2237DE806547C90B2EF0@039-SN2MPN1-013.039d.mgd.msft.net>

> >> >> .org] On Behalf Of Shaohui Xie
> >> >> Sent: Tuesday, May 08, 2012 11:37 AM
> >> >> To: linux-watchdog@vger.kernel.org; linuxppc-dev@lists.ozlabs.org
> >> >> Cc: Xie Shaohui-B21989
> >> >> Subject: [PATCH 1/2] powerpc/watchdog: move booke watchdog param
> >> >> related code to prom.c
> >> >>
> >> >> Currently, BOOKE watchdog code for checking "wdt" and "wdt_period"
> >> >> is in setup_32.c, it cannot be used in 64-bit, so move it to a
> >> >> common place prom.c, which will be shared by 32-bit and 64-bit.
> >> >>
> >> >> Also, replace the simple_strtoul with kstrtol.
> >> >>
> >> >> Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
> >> >> ---
> >> >>  arch/powerpc/kernel/prom.c     |   27 +++++++++++++++++++++++++++
> >> >>  arch/powerpc/kernel/setup_32.c |   24 ------------------------
> >> >>  2 files changed, 27 insertions(+), 24 deletions(-)
> >> >
> >> >Is not setup-common.c is better place to move this?
> >>
> >> Move out from setup_32.c does not mean it have to go into
> >> setup-common.c, I need better reason to do this.
> >>
> >
> >What I think that setup_32.c is for 32 bit, setup_64.c is for 64 bit
> >and setup-common.c is for both.
> >
> >I am not saying that you move this to setup-common.c. I am asking why
> >you have not used setup-common.c ? I am ok even with prom.c.
> >
> [Xie Shaohui] I'm not a fan of prom.c, I did this because I see same kind=
 of
> early parameters checking is did in this file only, so I thought maybe I =
should
> put them together. And seems setup-common.c is not the place to do comman=
d line
> checking (I'm not sure about this).
>=20

Ok, so you are also not sure.
Let us see what other guys things of this.

Thanks
-Bharat

^ permalink raw reply

* Re: [PATCH] powerpc: fix compile fail in hugetlb cmdline parsing
From: Stephen Rothwell @ 2012-05-09  4:03 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Jim Cromie, Greg Kroah-Hartman, Jason Baron, Rusty Russell,
	Paul Gortmaker, linux-next, linuxppc-dev
In-Reply-To: <1336532658.1714.15.camel@pasglop>

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

Hi Ben,

On Wed, 09 May 2012 13:04:18 +1000 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
> On Tue, 2012-05-08 at 13:53 +0930, Rusty Russell wrote:
> > On Mon,  7 May 2012 10:32:22 -0400, Paul Gortmaker <paul.gortmaker@windriver.com> wrote:
> > > Commit 9fb48c744ba6a4bf58b666f4e6fdac3008ea1bd4
> > > 
> > >     "params: add 3rd arg to option handler callback signature"
> > > 
> > > added an extra arg to the function, but didn't catch all the use
> > > cases needing it, causing this compile fail in mpc85xx_defconfig:
> > > 
> > >  arch/powerpc/mm/hugetlbpage.c:316:4: error: passing argument 7 of
> > >  'parse_args' from incompatible pointer type [-Werror]
> > > 
> > >  include/linux/moduleparam.h:317:12: note: expected
> > > 	 'int (*)(char *, char *, const char *)' but argument is of type
> > > 	 'int (*)(char *, char *)'
> > > 
> > > This function has no need to printk out the "doing" value, so
> > > just add the arg as an "unused".
> > > 
> > > Cc: Rusty Russell <rusty@rustcorp.com.au>
> > > Cc: Jim Cromie <jim.cromie@gmail.com>
> > > Cc: Jason Baron <jbaron@redhat.com>
> > > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > > Cc: Becky Bruce <beckyb@kernel.crashing.org>
> > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
> > 
> > Acked-by: Rusty Russell <rusty@rustcorp.com.au>
> 
> This is for -next right ? IE. I don't seem to have the faulty commit
> in my tree so I can't carry the fix for now.... or am I missing
> something ?

This patch has been added to the driver-core tree which contains the
faulty commit ...

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

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

^ permalink raw reply

* Re: [V2 5/5] powerpc: kernel: 16650 UART reg-shift support
From: Tanmay Inamdar @ 2012-05-09  5:27 UTC (permalink / raw)
  To: Josh Boyer; +Cc: devicetree-discuss, linuxppc-dev, linux-kernel
In-Reply-To: <CA+5PVA4sjX_Dk6ecySG4ZZoM=xhaWu2jGrQ=LtFgxGL88G=-Nw@mail.gmail.com>

On Wed, May 2, 2012 at 7:08 PM, Josh Boyer <jwboyer@gmail.com> wrote:
> On Mon, Apr 9, 2012 at 3:20 AM, Tanmay Inamdar <tinamdar@apm.com> wrote:
>> In APM8018X SOC, UART register address space has been relocated to 32-bi=
t
>> data boundaries for APB bus implementation.
>> Current legacy_serial driver ignores the reg-shift property. This patch
>> modifies legacy_serial.c and udbg_16550.c to work with above mentioned U=
ARTs.
>>
>> Signed-off-by: Tanmay Inamdar <tinamdar@apm.com>
>> ---
>> :100644 100644 8338aef... f5fc106... M =A0arch/powerpc/include/asm/udbg.=
h
>> :100644 100644 bedd12e... d523b7d... M =A0arch/powerpc/kernel/legacy_ser=
ial.c
>> :100644 100644 6837f83... e0cb7dc... M =A0arch/powerpc/kernel/udbg_16550=
.c
>> =A0arch/powerpc/include/asm/udbg.h =A0 =A0 | =A0 =A02 +-
>> =A0arch/powerpc/kernel/legacy_serial.c | =A0 16 +++++---
>> =A0arch/powerpc/kernel/udbg_16550.c =A0 =A0| =A0 64 ++++++++++++++++++++=
++------------
>> =A03 files changed, 52 insertions(+), 30 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/=
udbg.h
>> index 8338aef..f5fc106 100644
>> --- a/arch/powerpc/include/asm/udbg.h
>> +++ b/arch/powerpc/include/asm/udbg.h
>> @@ -29,7 +29,7 @@ extern void udbg_printf(const char *fmt, ...)
>> =A0extern void udbg_progress(char *s, unsigned short hex);
>>
>> =A0extern void udbg_init_uart(void __iomem *comport, unsigned int speed,
>> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0unsigned int clock)=
;
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0unsigned int clock,=
 =A0unsigned int regshift);
>> =A0extern unsigned int udbg_probe_uart_speed(void __iomem *comport,
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0unsigned int clock);
>>
>> diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/l=
egacy_serial.c
>> index bedd12e..d523b7d 100644
>> --- a/arch/powerpc/kernel/legacy_serial.c
>> +++ b/arch/powerpc/kernel/legacy_serial.c
>> @@ -33,6 +33,7 @@ static struct legacy_serial_info {
>> =A0 =A0 =A0 =A0unsigned int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0clock=
;
>> =A0 =A0 =A0 =A0int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 irq_check_parent;
>> =A0 =A0 =A0 =A0phys_addr_t =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 taddr=
;
>> + =A0 =A0 =A0 unsigned int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0regshi=
ft;
>> =A0} legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS];
>>
>> =A0static struct __initdata of_device_id legacy_serial_parents[] =3D {
>> @@ -42,6 +43,7 @@ static struct __initdata of_device_id legacy_serial_pa=
rents[] =3D {
>> =A0 =A0 =A0 =A0{.compatible =3D "ibm,opb",},
>> =A0 =A0 =A0 =A0{.compatible =3D "simple-bus",},
>> =A0 =A0 =A0 =A0{.compatible =3D "wrs,epld-localbus",},
>> + =A0 =A0 =A0 {.compatible =3D "apm,apb",},
>> =A0 =A0 =A0 =A0{},
>> =A0};
>>
>> @@ -163,11 +165,6 @@ static int __init add_legacy_soc_port(struct device=
_node *np,
>> =A0 =A0 =A0 =A0if (of_get_property(np, "clock-frequency", NULL) =3D=3D N=
ULL)
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return -1;
>>
>> - =A0 =A0 =A0 /* if reg-shift or offset, don't try to use it */
>> - =A0 =A0 =A0 if ((of_get_property(np, "reg-shift", NULL) !=3D NULL) ||
>> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 (of_get_property(np, "reg-offset", NULL) !=
=3D NULL))
>> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -1;
>> -
>
> So we explicitly didn't support reg-shift before. =A0I'm guessing there i=
s
> a reason for that, but I don't recall what. =A0Ben?
>
> Also, why do you need to use the legacy serial driver at all for this
> SOC? =A0As far as I remember, the OF serial driver should be sufficient.
>

You are right. There is no need to use legacy serial driver. However I
realized that when 40x is selected, 'PPC_UDBG_16550' is by default
selected. This enables legacy serial driver.

Is it now required to enable 'PPC_UDBG_16550' by default for every SOC
that uses 40x processor?

>> +static unsigned int reg_shift;
>> +#define ns16550_offset(addr) (addr - (unsigned char *)udbg_comport)
>> +
>> =A0static struct NS16550 __iomem *udbg_comport;
>>
>> +static inline u8 serial_read(unsigned char *addr)
>> +{
>> + =A0 =A0 =A0 u32 offset =3D ns16550_offset(addr) << reg_shift;
>> + =A0 =A0 =A0 return readb(udbg_comport + offset);
>> +}
>> +
>> +static inline void serial_write(unsigned char *addr, char val)
>> +{
>> + =A0 =A0 =A0 u32 offset =3D ns16550_offset(addr) << reg_shift;
>> + =A0 =A0 =A0 writeb(val, udbg_comport + offset);
>> +}
>> +
>
> I don't think readb/writeb are correct here. =A0Why did you switch to
> using those instead of sticking with in_8/out_8?
>
> josh

Thanks,
Tanmay
CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, =

is for the sole use of the intended recipient(s) and contains information=
=A0
that is confidential and proprietary to AppliedMicro Corporation or its s=
ubsidiaries. =

It is to be used solely for the purpose of furthering the parties' busine=
ss relationship. =

All unauthorized review, use, disclosure or distribution is prohibited. =

If you are not the intended recipient, please contact the sender by reply=
 e-mail =

and destroy all copies of the original message.
=0D

^ 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