LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: how can I write a Device Tree Source for PCI-PCI Bridge?
From: Benjamin Herrenschmidt @ 2010-03-18  8:58 UTC (permalink / raw)
  To: Jianbin Hu; +Cc: linuxppc-dev
In-Reply-To: <72714651003171005i5b7d7f7ai25e6b9876deb3d4@mail.gmail.com>

On Thu, 2010-03-18 at 01:05 +0800, Jianbin Hu wrote:
> My board have a PCIe switch(PLX PEX8608), which have a AMCC 460EX
> processor. I have parted the dts source file from canyonlands.dts. But
> I have no idea for the PCI bridge device node. Is anyone have a
> suggestion ? 

Hi !

First, you don't always need one. The kernel will be happy without a
device node, unless you want to also represent some devices below that
bridge for some reason (such as providing the driver with specific
properties from the FW), or your interrupt routing for devices below the
bridge doesn't follow the standard PCI swizzling.

If you really want to represent it, let me know, I'll try to cook up an
example for you tomorrow. You may want to read the Open Firmware PCI
binding too which contains all the explanation but it can be a tedious
read :-)

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH] powerpc/fsl-booke: Get coherent bit from PTE
From: Micha Nelissen @ 2010-03-18  7:02 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <1268800916-14247-1-git-send-email-galak@kernel.crashing.org>

Kumar Gala wrote:
> We shouldn't be always setting 'M' in the TLB entry since its reasonable
> for somethings to be mapped non-coherent.  The PTE should have 'M' set
> properly.

properly = not at all? AFAICS the patch only removes the setting of the 
bit; so where is that 'M' bit set then?

Micha

^ permalink raw reply

* Re: [PATCH] powerpc/fsl-booke: Get coherent bit from PTE
From: Kumar Gala @ 2010-03-18  7:08 UTC (permalink / raw)
  To: Micha Nelissen; +Cc: linuxppc-dev
In-Reply-To: <4BA1D00F.1090809@neli.hopto.org>


On Mar 18, 2010, at 2:02 AM, Micha Nelissen wrote:

> Kumar Gala wrote:
>> We shouldn't be always setting 'M' in the TLB entry since its =
reasonable
>> for somethings to be mapped non-coherent.  The PTE should have 'M' =
set
>> properly.
>=20
> properly =3D not at all? AFAICS the patch only removes the setting of =
the bit; so where is that 'M' bit set then?
>=20
> Micha

Its set via things like the _PAGE_BASE define in =
arch/powerpc/include/asm/pte-common.h

- k=

^ permalink raw reply

* [PATCH v2 5/7] drivers/net: Remove local #define IW_IOCTL, use STD_IW_HANDLER
From: Joe Perches @ 2010-03-18  6:21 UTC (permalink / raw)
  To: linux-kernel
  Cc: Zhu Yi, Reinette Chatre, netdev, linux-wireless,
	Intel Linux Wireless, linuxppc-dev, Johannes Berg,
	Richard Kennedy, cbe-oss-dev
In-Reply-To: <cover.1268892663.git.joe@perches.com>

Use #define STD_IW_HANDLER from wireless.h instead

Signed-off-by: Joe Perches <joe@perches.com>
---
 drivers/net/ps3_gelic_wireless.c       |   35 +++++++-------
 drivers/net/wireless/ipw2x00/ipw2200.c |   83 ++++++++++++++++----------------
 2 files changed, 58 insertions(+), 60 deletions(-)

diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index 2663b2f..2bc8935 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -2279,26 +2279,25 @@ void gelic_wl_interrupt(struct net_device *netdev, u64 status)
 /*
  * driver helpers
  */
-#define IW_IOCTL(n) [(n) - SIOCSIWCOMMIT]
 static const iw_handler gelic_wl_wext_handler[] =
 {
-	IW_IOCTL(SIOCGIWNAME)		= gelic_wl_get_name,
-	IW_IOCTL(SIOCGIWRANGE)		= gelic_wl_get_range,
-	IW_IOCTL(SIOCSIWSCAN)		= gelic_wl_set_scan,
-	IW_IOCTL(SIOCGIWSCAN)		= gelic_wl_get_scan,
-	IW_IOCTL(SIOCSIWAUTH)		= gelic_wl_set_auth,
-	IW_IOCTL(SIOCGIWAUTH)		= gelic_wl_get_auth,
-	IW_IOCTL(SIOCSIWESSID)		= gelic_wl_set_essid,
-	IW_IOCTL(SIOCGIWESSID)		= gelic_wl_get_essid,
-	IW_IOCTL(SIOCSIWENCODE)		= gelic_wl_set_encode,
-	IW_IOCTL(SIOCGIWENCODE)		= gelic_wl_get_encode,
-	IW_IOCTL(SIOCSIWAP)		= gelic_wl_set_ap,
-	IW_IOCTL(SIOCGIWAP)		= gelic_wl_get_ap,
-	IW_IOCTL(SIOCSIWENCODEEXT)	= gelic_wl_set_encodeext,
-	IW_IOCTL(SIOCGIWENCODEEXT)	= gelic_wl_get_encodeext,
-	IW_IOCTL(SIOCSIWMODE)		= gelic_wl_set_mode,
-	IW_IOCTL(SIOCGIWMODE)		= gelic_wl_get_mode,
-	IW_IOCTL(SIOCGIWNICKN)		= gelic_wl_get_nick,
+	STD_IW_HANDLER(SIOCGIWNAME, gelic_wl_get_name),
+	STD_IW_HANDLER(SIOCGIWRANGE, gelic_wl_get_range),
+	STD_IW_HANDLER(SIOCSIWSCAN, gelic_wl_set_scan),
+	STD_IW_HANDLER(SIOCGIWSCAN, gelic_wl_get_scan),
+	STD_IW_HANDLER(SIOCSIWAUTH, gelic_wl_set_auth),
+	STD_IW_HANDLER(SIOCGIWAUTH, gelic_wl_get_auth),
+	STD_IW_HANDLER(SIOCSIWESSID, gelic_wl_set_essid),
+	STD_IW_HANDLER(SIOCGIWESSID, gelic_wl_get_essid),
+	STD_IW_HANDLER(SIOCSIWENCODE, gelic_wl_set_encode),
+	STD_IW_HANDLER(SIOCGIWENCODE, gelic_wl_get_encode),
+	STD_IW_HANDLER(SIOCSIWAP, gelic_wl_set_ap),
+	STD_IW_HANDLER(SIOCGIWAP, gelic_wl_get_ap),
+	STD_IW_HANDLER(SIOCSIWENCODEEXT, gelic_wl_set_encodeext),
+	STD_IW_HANDLER(SIOCGIWENCODEEXT, gelic_wl_get_encodeext),
+	STD_IW_HANDLER(SIOCSIWMODE, gelic_wl_set_mode),
+	STD_IW_HANDLER(SIOCGIWMODE, gelic_wl_get_mode),
+	STD_IW_HANDLER(SIOCGIWNICKN, gelic_wl_get_nick),
 };
 
 static const struct iw_handler_def gelic_wl_wext_handler_def = {
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 5c7aa1b..1e84888 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -9995,49 +9995,48 @@ static int ipw_wx_sw_reset(struct net_device *dev,
 }
 
 /* Rebase the WE IOCTLs to zero for the handler array */
-#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
 static iw_handler ipw_wx_handlers[] = {
-	IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname,
-	IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
-	IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
-	IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
-	IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
-	IW_IOCTL(SIOCSIWSENS) = ipw_wx_set_sens,
-	IW_IOCTL(SIOCGIWSENS) = ipw_wx_get_sens,
-	IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
-	IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
-	IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
-	IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan,
-	IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan,
-	IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid,
-	IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid,
-	IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick,
-	IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick,
-	IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate,
-	IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate,
-	IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts,
-	IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts,
-	IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag,
-	IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag,
-	IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow,
-	IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow,
-	IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry,
-	IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry,
-	IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode,
-	IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
-	IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
-	IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
-	IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy,
-	IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
-	IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
-	IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
-	IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie,
-	IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie,
-	IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme,
-	IW_IOCTL(SIOCSIWAUTH) = ipw_wx_set_auth,
-	IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth,
-	IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext,
-	IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext,
+	STD_IW_HANDLER(SIOCGIWNAME, cfg80211_wext_giwname),
+	STD_IW_HANDLER(SIOCSIWFREQ, ipw_wx_set_freq),
+	STD_IW_HANDLER(SIOCGIWFREQ, ipw_wx_get_freq),
+	STD_IW_HANDLER(SIOCSIWMODE, ipw_wx_set_mode),
+	STD_IW_HANDLER(SIOCGIWMODE, ipw_wx_get_mode),
+	STD_IW_HANDLER(SIOCSIWSENS, ipw_wx_set_sens),
+	STD_IW_HANDLER(SIOCGIWSENS, ipw_wx_get_sens),
+	STD_IW_HANDLER(SIOCGIWRANGE, ipw_wx_get_range),
+	STD_IW_HANDLER(SIOCSIWAP, ipw_wx_set_wap),
+	STD_IW_HANDLER(SIOCGIWAP, ipw_wx_get_wap),
+	STD_IW_HANDLER(SIOCSIWSCAN, ipw_wx_set_scan),
+	STD_IW_HANDLER(SIOCGIWSCAN, ipw_wx_get_scan),
+	STD_IW_HANDLER(SIOCSIWESSID, ipw_wx_set_essid),
+	STD_IW_HANDLER(SIOCGIWESSID, ipw_wx_get_essid),
+	STD_IW_HANDLER(SIOCSIWNICKN, ipw_wx_set_nick),
+	STD_IW_HANDLER(SIOCGIWNICKN, ipw_wx_get_nick),
+	STD_IW_HANDLER(SIOCSIWRATE, ipw_wx_set_rate),
+	STD_IW_HANDLER(SIOCGIWRATE, ipw_wx_get_rate),
+	STD_IW_HANDLER(SIOCSIWRTS, ipw_wx_set_rts),
+	STD_IW_HANDLER(SIOCGIWRTS, ipw_wx_get_rts),
+	STD_IW_HANDLER(SIOCSIWFRAG, ipw_wx_set_frag),
+	STD_IW_HANDLER(SIOCGIWFRAG, ipw_wx_get_frag),
+	STD_IW_HANDLER(SIOCSIWTXPOW, ipw_wx_set_txpow),
+	STD_IW_HANDLER(SIOCGIWTXPOW, ipw_wx_get_txpow),
+	STD_IW_HANDLER(SIOCSIWRETRY, ipw_wx_set_retry),
+	STD_IW_HANDLER(SIOCGIWRETRY, ipw_wx_get_retry),
+	STD_IW_HANDLER(SIOCSIWENCODE, ipw_wx_set_encode),
+	STD_IW_HANDLER(SIOCGIWENCODE, ipw_wx_get_encode),
+	STD_IW_HANDLER(SIOCSIWPOWER, ipw_wx_set_power),
+	STD_IW_HANDLER(SIOCGIWPOWER, ipw_wx_get_power),
+	STD_IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
+	STD_IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
+	STD_IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
+	STD_IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
+	STD_IW_HANDLER(SIOCSIWGENIE, ipw_wx_set_genie),
+	STD_IW_HANDLER(SIOCGIWGENIE, ipw_wx_get_genie),
+	STD_IW_HANDLER(SIOCSIWMLME, ipw_wx_set_mlme),
+	STD_IW_HANDLER(SIOCSIWAUTH, ipw_wx_set_auth),
+	STD_IW_HANDLER(SIOCGIWAUTH, ipw_wx_get_auth),
+	STD_IW_HANDLER(SIOCSIWENCODEEXT, ipw_wx_set_encodeext),
+	STD_IW_HANDLER(SIOCGIWENCODEEXT, ipw_wx_get_encodeext),
 };
 
 enum {
-- 
1.7.0.14.g7e948

^ permalink raw reply related

* [PATCH v2 0/7] wireless: Use macros from wireless.h
From: Joe Perches @ 2010-03-18  6:21 UTC (permalink / raw)
  To: linux-kernel
  Cc: orinoco-users, Zhu Yi, Reinette Chatre, Corey Thomas,
	David Gibson, netdev, orinoco-devel, linux-wireless, cbe-oss-dev,
	Intel Linux Wireless, linuxppc-dev, Arnaldo Carvalho de Melo,
	Johannes Berg, Richard Kennedy, David S. Miller, Pavel Roskin

Move the STD_IW_HANDLER macro from orinoco to wireless.h
Use the wireless.h macros in various wireless files
Remove local #defines of IW_IOCTL

Joe Perches (7):
  wireless.h: Add STD_IW_HANDLER macro
  net/wireless/wext_core.c: Use IW_IOCTL_IDX macro
  net/wireless/wext-core.c: Use IW_EVENT_IDX macro
  drivers/net/wireless: Use STD_IW_HANDLER macro
  drivers/net: Remove local #define IW_IOCTL, use STD_IW_HANDLER
  orinoco/wext.c: Remove local #define STD_IW_HANDLER
  wireless.h: Use SIOCIWFIRST not SIOCSIWCOMMIT for range check

 drivers/net/ps3_gelic_wireless.c       |   35 ++++----
 drivers/net/wireless/ipw2x00/ipw2200.c |   83 ++++++++++----------
 drivers/net/wireless/orinoco/wext.c    |    2 -
 drivers/net/wireless/ray_cs.c          |   40 +++++-----
 drivers/net/wireless/wl3501_cs.c       |   52 ++++++------
 include/linux/wireless.h               |    4 +-
 net/wireless/wext-core.c               |  134 ++++++++++++++++----------------
 7 files changed, 174 insertions(+), 176 deletions(-)

^ permalink raw reply

* [PATCH v2] powerpc/perf_events: Implement perf_arch_fetch_caller_regs
From: Paul Mackerras @ 2010-03-18  5:05 UTC (permalink / raw)
  To: Ingo Molnar, Peter Zijlstra, Frederic Weisbecker, benh
  Cc: linuxppc-dev, linux-kernel, anton

This implements a powerpc version of perf_arch_fetch_caller_regs.
It's implemented in assembly because that way we can be sure there
isn't a stack frame for perf_arch_fetch_caller_regs.  If it was in
C, gcc might or might not create a stack frame for it, which would
affect the number of levels we have to skip.

With this, we see results from perf record -e lock:lock_acquire like
this:

# Samples: 24878
#
# Overhead         Command      Shared Object  Symbol
# ........  ..............  .................  ......
#
    14.99%            perf  [kernel.kallsyms]  [k] ._raw_spin_lock
                      |
                      --- ._raw_spin_lock
                         |
                         |--25.00%-- .alloc_fd
                         |          (nil)
                         |          |
                         |          |--50.00%-- .anon_inode_getfd
                         |          |          .sys_perf_event_open
                         |          |          syscall_exit
                         |          |          syscall
                         |          |          create_counter
                         |          |          __cmd_record
                         |          |          run_builtin
                         |          |          main
                         |          |          0xfd2e704
                         |          |          0xfd2e8c0
                         |          |          (nil)

... etc.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/include/asm/asm-compat.h |    2 ++
 arch/powerpc/kernel/misc.S            |   28 ++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h
index c1b475a..a9b91ed 100644
--- a/arch/powerpc/include/asm/asm-compat.h
+++ b/arch/powerpc/include/asm/asm-compat.h
@@ -28,6 +28,7 @@
 #define PPC_LLARX(t, a, b, eh)	PPC_LDARX(t, a, b, eh)
 #define PPC_STLCX	stringify_in_c(stdcx.)
 #define PPC_CNTLZL	stringify_in_c(cntlzd)
+#define PPC_LR_STKOFF	16
 
 /* Move to CR, single-entry optimized version. Only available
  * on POWER4 and later.
@@ -51,6 +52,7 @@
 #define PPC_STLCX	stringify_in_c(stwcx.)
 #define PPC_CNTLZL	stringify_in_c(cntlzw)
 #define PPC_MTOCRF	stringify_in_c(mtcrf)
+#define PPC_LR_STKOFF	4
 
 #endif
 
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index 2d29752..b485a87 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -127,3 +127,31 @@ _GLOBAL(__setup_cpu_power7)
 _GLOBAL(__restore_cpu_power7)
 	/* place holder */
 	blr
+
+#ifdef CONFIG_EVENT_TRACING
+/*
+ * Get a minimal set of registers for our caller's nth caller.
+ * r3 = regs pointer, r5 = n.
+ *
+ * We only get R1 (stack pointer), NIP (next instruction pointer)
+ * and LR (link register).  These are all we can get in the
+ * general case without doing complicated stack unwinding, but
+ * fortunately they are enough to do a stack backtrace, which
+ * is all we need them for.
+ */
+_GLOBAL(perf_arch_fetch_caller_regs)
+	mr	r6,r1
+	cmpwi	r5,0
+	mflr	r4
+	ble	2f
+	mtctr	r5
+1:	PPC_LL	r6,0(r6)
+	bdnz	1b
+	PPC_LL	r4,PPC_LR_STKOFF(r6)
+2:	PPC_LL	r7,0(r6)
+	PPC_LL	r7,PPC_LR_STKOFF(r7)
+	PPC_STL	r6,GPR1-STACK_FRAME_OVERHEAD(r3)
+	PPC_STL	r4,_NIP-STACK_FRAME_OVERHEAD(r3)
+	PPC_STL	r7,_LINK-STACK_FRAME_OVERHEAD(r3)
+	blr
+#endif /* CONFIG_EVENT_TRACING */

^ permalink raw reply related

* Re: [PATCH] [V2] Add non-Virtex5 support for LL TEMAC driver
From: Edgar E. Iglesias @ 2010-03-18  0:46 UTC (permalink / raw)
  To: Michal Simek; +Cc: netdev, John Tyner, linuxppc-dev, John Linn, john.williams
In-Reply-To: <4B9E46B5.1060508@petalogix.com>

On Mon, Mar 15, 2010 at 03:39:49PM +0100, Michal Simek wrote:
> John Linn wrote:
> >> -----Original Message-----
> >> From: Michal Simek [mailto:michal.simek@petalogix.com]
> >> Sent: Monday, March 15, 2010 2:40 AM
> >> To: John Linn
> >> Cc: netdev@vger.kernel.org; linuxppc-dev@ozlabs.org;
> > grant.likely@secretlab.ca;
> >> jwboyer@linux.vnet.ibm.com; john.williams@petalogix.com; John Tyner
> >> Subject: Re: [PATCH] [V2] Add non-Virtex5 support for LL TEMAC driver
> >>
> >> John Linn wrote:
> >>> This patch adds support for using the LL TEMAC Ethernet driver on
> >>> non-Virtex 5 platforms by adding support for accessing the Soft DMA
> >>> registers as if they were memory mapped instead of solely through
> > the
> >>> DCR's (available on the Virtex 5).
> >>>
> >>> The patch also updates the driver so that it runs on the MicroBlaze.
> >>> The changes were tested on the PowerPC 440, PowerPC 405, and the
> >>> MicroBlaze platforms.
> >> Which git-tree have you tested on? (Of course microblaze)
> > 
> > It was tested on the Xilinx tree for MicroBlaze which is based on the
> > mainline and the Petalogix tree as DMA was needed. I tried to build
> > against the mainline head but got errors with the DMA routines. I guess
> > it's possible that it was a configuration issue there as I didn't dig
> > real deep.
> 
> New dma api is in for-linus branch.
> I tested it on that version and I am seeing some weird things. :-(
> Access to bad area. I will try your tree.
> 
> The second thing which I see is in ll_temac_recv function.
> On the following line is read a packet length which could be 0-16k.
> 		length = cur_p->app4 & 0x3FFF;
> 
> But allocated skb has max size XTE_MAX_JUMBO_FRAME_SIZE + XTE_ALIGN.
> 
> What happen if driver get packet greater than 9kB?
> I got it (I don't know how) but skb_put has one checking mechanism which 
> will cal skb_over_panic which caused panic.
> That's why I think that will be good always to check that length is less 
> than XTE_MAX_JUMBO_FRAME_SIZE + XTE_ALIGN.
> 
> What do you think?

I agree. IIRC the LLTEMAC when configured to accept jumboframes will
accepts packets up to 16K and the driver should handle that without
raising panics.

I remeber beeing a bit surprised about that when hacking the QEMU model.
Not sure if I remember correctly though.

Cheers

^ permalink raw reply

* Re: [PATCH] powerpc/of: Fix comparison of "compatible" properties
From: Grant Likely @ 2010-03-18  0:35 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Michal Simek
  Cc: microblaze-uclinux, devicetree-discuss, linuxppc-dev,
	David Miller
In-Reply-To: <1268870941.2335.214.camel@pasglop>

On Wed, Mar 17, 2010 at 6:09 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> Commit 7c7b60cb87547b1664a4385c187f029bf514a737
> "of: put default string compare and #a/s-cell values into common header"
>
> Breaks various things on powerpc due to using strncasecmp instead of
> strcasecmp for comparing against "compatible" strings.
>
> This causes things like the 4xx PCI code to fail miserably due to the
> partial matches in code like this:
>
> =A0 =A0 =A0 =A0for_each_compatible_node(np, NULL, "ibm,plb-pcix")
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ppc4xx_probe_pcix_bridge(np);
> =A0 =A0 =A0 =A0for_each_compatible_node(np, NULL, "ibm,plb-pci")
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ppc4xx_probe_pci_bridge(np);
>
> This reverts us to use strcasecmp. I do wonder why microblase and sparc
> want the partial matches though. For sparc it could be historical, but
> microblaze might want to change.
>
> It's not quite right to do partial name match. Entries in a compatible
> list are meant to be matched whole. If a device is compatible with both
> "foo" and "foo1", then the device should have both strings in its
> "compatible" property.

Hmmm.  That's a mistake I made then in commit 7c7b60cb.  I had meant
to use strcasecmp(), and had missed that microblaze was doing it
differently.  I certainly don't want to carry over partial name match
when other architectures pick up device tree support.  If anything,
microblaze should have the exception and the common code fixed.

Michal, why does microblaze differ from powerpc on this point?

Cheers,
g.

>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> =A0arch/powerpc/include/asm/prom.h | =A0 =A08 ++++++++
> =A01 files changed, 8 insertions(+), 0 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/p=
rom.h
> index ddd408a..47ce796 100644
> --- a/arch/powerpc/include/asm/prom.h
> +++ b/arch/powerpc/include/asm/prom.h
> @@ -23,6 +23,14 @@
> =A0#include <asm/irq.h>
> =A0#include <asm/atomic.h>
>
> +/* We do -not- want the generic "strncasecmp" here for of_compat_cmp.
> + * We have cases where we could otherwise mismatch "pcix" and "pci"
> + * and similar.
> + */
> +#define of_compat_cmp(s1, s2, l) =A0 =A0 =A0 strcasecmp((s1), (s2))
> +#define of_prop_cmp(s1, s2) =A0 =A0 =A0 =A0 =A0 =A0strcmp((s1), (s2))
> +#define of_node_cmp(s1, s2) =A0 =A0 =A0 =A0 =A0 =A0strcasecmp((s1), (s2)=
)
> +
> =A0#define HAVE_ARCH_DEVTREE_FIXUPS
>
> =A0#ifdef CONFIG_PPC32
>
>
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* Re: Problem with PCI bus rescan on 460EX
From: Benjamin Herrenschmidt @ 2010-03-18  0:09 UTC (permalink / raw)
  To: Felix Radensky
  Cc: linuxppc-dev@ozlabs.org, linux-pci, yinghai, Alex Chiang,
	Kenji Kaneshige
In-Reply-To: <4BA08B61.5000406@embedded-sol.com>


> > This is Jesse tree with the default Canyonlands defconfig ? Hrm... I'll
> > have to take a look, somebody mucking with PCI resource allocation is
> > very likely to break something :-)
> >
> >
> >   
> 
> Yep, default Canyonlands defconfig and default DTS.

Ok so Jesse is innocent :-)

See the patch I just posted:

http://patchwork.ozlabs.org/patch/47976/

That fixes it here.

Cheers,
Ben.

^ permalink raw reply

* [PATCH] powerpc/of: Fix comparison of "compatible" properties
From: Benjamin Herrenschmidt @ 2010-03-18  0:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: microblaze-uclinux, devicetree-discuss, David Miller

Commit 7c7b60cb87547b1664a4385c187f029bf514a737
"of: put default string compare and #a/s-cell values into common header"

Breaks various things on powerpc due to using strncasecmp instead of
strcasecmp for comparing against "compatible" strings.

This causes things like the 4xx PCI code to fail miserably due to the
partial matches in code like this:

	for_each_compatible_node(np, NULL, "ibm,plb-pcix")
		ppc4xx_probe_pcix_bridge(np);
	for_each_compatible_node(np, NULL, "ibm,plb-pci")
		ppc4xx_probe_pci_bridge(np);

This reverts us to use strcasecmp. I do wonder why microblase and sparc
want the partial matches though. For sparc it could be historical, but
microblaze might want to change.

It's not quite right to do partial name match. Entries in a compatible
list are meant to be matched whole. If a device is compatible with both
"foo" and "foo1", then the device should have both strings in its
"compatible" property.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/include/asm/prom.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index ddd408a..47ce796 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -23,6 +23,14 @@
 #include <asm/irq.h>
 #include <asm/atomic.h>
 
+/* We do -not- want the generic "strncasecmp" here for of_compat_cmp.
+ * We have cases where we could otherwise mismatch "pcix" and "pci"
+ * and similar.
+ */
+#define of_compat_cmp(s1, s2, l)	strcasecmp((s1), (s2))
+#define of_prop_cmp(s1, s2)		strcmp((s1), (s2))
+#define of_node_cmp(s1, s2)		strcasecmp((s1), (s2))
+
 #define HAVE_ARCH_DEVTREE_FIXUPS
 
 #ifdef CONFIG_PPC32

^ permalink raw reply related

* Re: Problem with PCI bus rescan on 460EX
From: Benjamin Herrenschmidt @ 2010-03-17 23:04 UTC (permalink / raw)
  To: Felix Radensky
  Cc: linuxppc-dev@ozlabs.org, linux-pci, yinghai, Alex Chiang,
	Kenji Kaneshige
In-Reply-To: <4BA08B61.5000406@embedded-sol.com>


> > This is Jesse tree with the default Canyonlands defconfig ? Hrm... I'll
> > have to take a look, somebody mucking with PCI resource allocation is
> > very likely to break something :-)
> >
> >
> >   
> 
> Yep, default Canyonlands defconfig and default DTS.

Which branch of Jesse tree btw ? "master" ?

Cheers,
Ben.

^ permalink raw reply

* [PATCH RESEND] powerpc: fix handling of strnlen with zero len
From: Jeff Mahoney @ 2010-03-17 20:55 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Rostedt, Christian_Sellars

 Commit 0119536c, which added the assembly version of strncmp to
 powerpc, mentions that it adds two instructions to the version from
 boot/string.S to allow it to handle len=0. Unfortunately, it doesn't
 always return 0 when that is the case. The length is passed in r5, but
 the return value is passed back in r3. In certain cases, this will
 happen to work. Otherwise it will pass back the address of the first
 string as the return value.

 This patch lifts the len <= 0 handling code from memcpy to handle that
 case.

Reported by: Christian_Sellars@symantec.com
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
 arch/powerpc/lib/string.S |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

--- a/arch/powerpc/lib/string.S
+++ b/arch/powerpc/lib/string.S
@@ -71,7 +71,7 @@ _GLOBAL(strcmp)
  _GLOBAL(strncmp)
 	PPC_LCMPI r5,0
-	beqlr
+	ble-	2f
 	mtctr	r5
 	addi	r5,r3,-1
 	addi	r4,r4,-1
@@ -82,6 +82,8 @@ _GLOBAL(strncmp)
 	beqlr	1
 	bdnzt	eq,1b
 	blr
+2:	li	r3,0
+	blr
  _GLOBAL(strlen)
 	addi	r4,r3,-1
-- 
Jeff Mahoney
SUSE Labs

^ permalink raw reply

* Re: [PATCH] 460EX on-chip SATA driver<kernel 2.6.33> < resubmission : 01>
From: Jeff Garzik @ 2010-03-17 20:15 UTC (permalink / raw)
  To: Stefan Roese, Rupjyoti Sarmah
  Cc: Rupjyoti Sarmah, linuxppc-dev, linux-kernel, linux-ide,
	Rupjyoti Sarmah, linuxppc-dev
In-Reply-To: <201003171303.06258.sr@denx.de>

On 03/17/2010 08:03 AM, Stefan Roese wrote:
> Hi Rup,
>
> On Wednesday 17 March 2010 05:23:16 Rupjyoti Sarmah wrote:
>> This patch enables the on-chip DWC SATA controller of the AppliedMicro
>> processor 460EX.
>
> Apart from the other comments, did you take a look at the latest version of
> this driver in our linux-2.6-denx repository? We did some work on this driver
> for a new Canyonlands release last year. It's hard to check this for me now,
> with this line wrapped patch (the drivers diverged somewhat). So either check
> for yourself, or send a new, not line-wrapped, patch version so that I can
> better check myself.
>
> BTW: It would be nice if you would add me to Cc on DWC-SATA related patches,
> since I've been involved in the development at some time.

I will wait for Rupjyoti to check the linux-2.6-denx repo, and resend 
the patches without word wrapping.

	Jeff

^ permalink raw reply

* Re: [PATCH] [V2] Add non-Virtex5 support for LL TEMAC driver
From: Grant Likely @ 2010-03-17 20:02 UTC (permalink / raw)
  To: John Linn
  Cc: linuxppc-dev, netdev, John Tyner, michal.simek, David Miller,
	john.williams
In-Reply-To: <bda26c8d-00b2-411d-b4b7-ad6954b9049e@SG2EHSMHS005.ehs.local>

On Fri, Mar 12, 2010 at 7:05 PM, John Linn <john.linn@xilinx.com> wrote:
> This patch adds support for using the LL TEMAC Ethernet driver on
> non-Virtex 5 platforms by adding support for accessing the Soft DMA
> registers as if they were memory mapped instead of solely through the
> DCR's (available on the Virtex 5).
>
> The patch also updates the driver so that it runs on the MicroBlaze.
> The changes were tested on the PowerPC 440, PowerPC 405, and the
> MicroBlaze platforms.
>
> Signed-off-by: John Tyner <jtyner@cs.ucr.edu>
> Signed-off-by: John Linn <john.linn@xilinx.com>
> ---

I've not booted this, but it looks right, and it compiles fine.  The
issues that Michal raised need to be delt with too, but they are
preexisting bugs unrelated to this change which you should fix up in a
separate patch.

Acked-by: Grant Likely <grant.likely@secretlab.ca>

>
> V2 - Incorporated comments from Grant and added more logic to allow the d=
river
> to work on MicroBlaze.
>
> =A0drivers/net/Kconfig =A0 =A0 =A0 =A0 | =A0 =A01 -
> =A0drivers/net/ll_temac.h =A0 =A0 =A0| =A0 17 +++++-
> =A0drivers/net/ll_temac_main.c | =A0124 +++++++++++++++++++++++++++++++++=
+---------
> =A03 files changed, 113 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 9b6efe1..5402105 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -2443,7 +2443,6 @@ config MV643XX_ETH
> =A0config XILINX_LL_TEMAC
> =A0 =A0 =A0 =A0tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC=
) driver"
> =A0 =A0 =A0 =A0select PHYLIB
> - =A0 =A0 =A0 depends on PPC_DCR_NATIVE
> =A0 =A0 =A0 =A0help
> =A0 =A0 =A0 =A0 =A0This driver supports the Xilinx 10/100/1000 LocalLink =
TEMAC
> =A0 =A0 =A0 =A0 =A0core used in Xilinx Spartan and Virtex FPGAs
> diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h
> index 1af66a1..915aa34 100644
> --- a/drivers/net/ll_temac.h
> +++ b/drivers/net/ll_temac.h
> @@ -5,8 +5,11 @@
> =A0#include <linux/netdevice.h>
> =A0#include <linux/of.h>
> =A0#include <linux/spinlock.h>
> +
> +#ifdef CONFIG_PPC_DCR
> =A0#include <asm/dcr.h>
> =A0#include <asm/dcr-regs.h>
> +#endif
>
> =A0/* packet size info */
> =A0#define XTE_HDR_SIZE =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 14 =A0 =A0 =
=A0/* size of Ethernet header */
> @@ -290,8 +293,12 @@ This option defaults to enabled (set) */
>
> =A0#define TX_CONTROL_CALC_CSUM_MASK =A0 1
>
> +/* Align the IP data in the packet on word boundaries as MicroBlaze
> + * needs it.
> + */
> +
> =A0#define XTE_ALIGN =A0 =A0 =A0 32
> -#define BUFFER_ALIGN(adr) ((XTE_ALIGN - ((u32) adr)) % XTE_ALIGN)
> +#define BUFFER_ALIGN(adr) ((34 - ((u32) adr)) % XTE_ALIGN)
>
> =A0#define MULTICAST_CAM_TABLE_NUM 4
>
> @@ -335,9 +342,15 @@ struct temac_local {
> =A0 =A0 =A0 =A0struct mii_bus *mii_bus; =A0 =A0 =A0 =A0/* MII bus referen=
ce */
> =A0 =A0 =A0 =A0int mdio_irqs[PHY_MAX_ADDR]; =A0 =A0/* IRQs table for MDIO=
 bus */
>
> - =A0 =A0 =A0 /* IO registers and IRQs */
> + =A0 =A0 =A0 /* IO registers, dma functions and IRQs */
> =A0 =A0 =A0 =A0void __iomem *regs;
> + =A0 =A0 =A0 void __iomem *sdma_regs;
> +#ifdef CONFIG_PPC_DCR
> =A0 =A0 =A0 =A0dcr_host_t sdma_dcrs;
> +#endif
> + =A0 =A0 =A0 u32 (*dma_in)(struct temac_local *, int);
> + =A0 =A0 =A0 void (*dma_out)(struct temac_local *, int, u32);
> +
> =A0 =A0 =A0 =A0int tx_irq;
> =A0 =A0 =A0 =A0int rx_irq;
> =A0 =A0 =A0 =A0int emac_num;
> diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
> index a18e348..9aedf9b 100644
> --- a/drivers/net/ll_temac_main.c
> +++ b/drivers/net/ll_temac_main.c
> @@ -20,9 +20,6 @@
> =A0* =A0 or rx, so this should be okay.
> =A0*
> =A0* TODO:
> - * - Fix driver to work on more than just Virtex5. =A0Right now the driv=
er
> - * =A0 assumes that the locallink DMA registers are accessed via DCR
> - * =A0 instructions.
> =A0* - Factor out locallink DMA code into separate driver
> =A0* - Fix multicast assignment.
> =A0* - Fix support for hardware checksumming.
> @@ -115,17 +112,86 @@ void temac_indirect_out32(struct temac_local *lp, i=
nt reg, u32 value)
> =A0 =A0 =A0 =A0temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK |=
 reg);
> =A0}
>
> +/**
> + * temac_dma_in32 - Memory mapped DMA read, this function expects a
> + * register input that is based on DCR word addresses which
> + * are then converted to memory mapped byte addresses
> + */
> =A0static u32 temac_dma_in32(struct temac_local *lp, int reg)
> =A0{
> - =A0 =A0 =A0 return dcr_read(lp->sdma_dcrs, reg);
> + =A0 =A0 =A0 return in_be32((u32 *)(lp->sdma_regs + (reg << 2)));
> =A0}
>
> +/**
> + * temac_dma_out32 - Memory mapped DMA read, this function expects a
> + * register input that is based on DCR word addresses which
> + * are then converted to memory mapped byte addresses
> + */
> =A0static void temac_dma_out32(struct temac_local *lp, int reg, u32 value=
)
> =A0{
> + =A0 =A0 =A0 out_be32((u32 *)(lp->sdma_regs + (reg << 2)), value);
> +}
> +
> +/* DMA register access functions can be DCR based or memory mapped.
> + * The PowerPC 440 is DCR based, the PowerPC 405 and MicroBlaze are both
> + * memory mapped.
> + */
> +#ifdef CONFIG_PPC_DCR
> +
> +/**
> + * temac_dma_dcr_in32 - DCR based DMA read
> + */
> +static u32 temac_dma_dcr_in(struct temac_local *lp, int reg)
> +{
> + =A0 =A0 =A0 return dcr_read(lp->sdma_dcrs, reg);
> +}
> +
> +/**
> + * temac_dma_dcr_out32 - DCR based DMA write
> + */
> +static void temac_dma_dcr_out(struct temac_local *lp, int reg, u32 value=
)
> +{
> =A0 =A0 =A0 =A0dcr_write(lp->sdma_dcrs, reg, value);
> =A0}
>
> =A0/**
> + * temac_dcr_setup - If the DMA is DCR based, then setup the address and
> + * I/O =A0functions
> + */
> +static int temac_dcr_setup(struct temac_local *lp, struct of_device *op,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct devi=
ce_node *np)
> +{
> + =A0 =A0 =A0 unsigned int dcrs;
> +
> + =A0 =A0 =A0 /* setup the dcr address mapping if it's in the device tree=
 */
> +
> + =A0 =A0 =A0 dcrs =3D dcr_resource_start(np, 0);
> + =A0 =A0 =A0 if (dcrs !=3D 0) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 lp->sdma_dcrs =3D dcr_map(np, dcrs, dcr_res=
ource_len(np, 0));
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 lp->dma_in =3D temac_dma_dcr_in;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 lp->dma_out =3D temac_dma_dcr_out;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_dbg(&op->dev, "DCR base: %x\n", dcrs);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return 0;
> + =A0 =A0 =A0 }
> + =A0 =A0 =A0 /* no DCR in the device tree, indicate a failure */
> + =A0 =A0 =A0 return -1;
> +}
> +
> +#else
> +
> +/*
> + * temac_dcr_setup - This is a stub for when DCR is not supported,
> + * such as with MicroBlaze
> + */
> +static int temac_dcr_setup(struct temac_local *lp, struct of_device *op,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct devi=
ce_node *np)
> +{
> + =A0 =A0 =A0 return -1;
> +}
> +
> +#endif
> +
> +/**
> =A0* temac_dma_bd_init - Setup buffer descriptor rings
> =A0*/
> =A0static int temac_dma_bd_init(struct net_device *ndev)
> @@ -172,23 +238,23 @@ static int temac_dma_bd_init(struct net_device *nde=
v)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0lp->rx_bd_v[i].app0 =3D STS_CTRL_APP0_IRQO=
NEND;
> =A0 =A0 =A0 =A0}
>
> - =A0 =A0 =A0 temac_dma_out32(lp, TX_CHNL_CTRL, 0x10220400 |
> + =A0 =A0 =A0 lp->dma_out(lp, TX_CHNL_CTRL, 0x10220400 |
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0CHNL_CTRL_IRQ_EN |
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0CHNL_CTRL_IRQ_DLY_EN |
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0CHNL_CTRL_IRQ_COAL_EN);
> =A0 =A0 =A0 =A0/* 0x10220483 */
> =A0 =A0 =A0 =A0/* 0x00100483 */
> - =A0 =A0 =A0 temac_dma_out32(lp, RX_CHNL_CTRL, 0xff010000 |
> + =A0 =A0 =A0 lp->dma_out(lp, RX_CHNL_CTRL, 0xff010000 |
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0CHNL_CTRL_IRQ_EN |
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0CHNL_CTRL_IRQ_DLY_EN |
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0CHNL_CTRL_IRQ_COAL_EN |
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0CHNL_CTRL_IRQ_IOE);
> =A0 =A0 =A0 =A0/* 0xff010283 */
>
> - =A0 =A0 =A0 temac_dma_out32(lp, RX_CURDESC_PTR, =A0lp->rx_bd_p);
> - =A0 =A0 =A0 temac_dma_out32(lp, RX_TAILDESC_PTR,
> + =A0 =A0 =A0 lp->dma_out(lp, RX_CURDESC_PTR, =A0lp->rx_bd_p);
> + =A0 =A0 =A0 lp->dma_out(lp, RX_TAILDESC_PTR,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lp->rx_bd_p + (sizeof(*lp->rx=
_bd_v) * (RX_BD_NUM - 1)));
> - =A0 =A0 =A0 temac_dma_out32(lp, TX_CURDESC_PTR, lp->tx_bd_p);
> + =A0 =A0 =A0 lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p);
>
> =A0 =A0 =A0 =A0return 0;
> =A0}
> @@ -426,9 +492,9 @@ static void temac_device_reset(struct net_device *nde=
v)
> =A0 =A0 =A0 =A0temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_=
RXEN_MASK);
>
> =A0 =A0 =A0 =A0/* Reset Local Link (DMA) */
> - =A0 =A0 =A0 temac_dma_out32(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
> + =A0 =A0 =A0 lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
> =A0 =A0 =A0 =A0timeout =3D 1000;
> - =A0 =A0 =A0 while (temac_dma_in32(lp, DMA_CONTROL_REG) & DMA_CONTROL_RS=
T) {
> + =A0 =A0 =A0 while (lp->dma_in(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0udelay(1);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (--timeout =3D=3D 0) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0dev_err(&ndev->dev,
> @@ -436,7 +502,7 @@ static void temac_device_reset(struct net_device *nde=
v)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
> =A0 =A0 =A0 =A0}
> - =A0 =A0 =A0 temac_dma_out32(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE);
> + =A0 =A0 =A0 lp->dma_out(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE);
>
> =A0 =A0 =A0 =A0temac_dma_bd_init(ndev);
>
> @@ -597,7 +663,7 @@ static int temac_start_xmit(struct sk_buff *skb, stru=
ct net_device *ndev)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0lp->tx_bd_tail =3D 0;
>
> =A0 =A0 =A0 =A0/* Kick off the transfer */
> - =A0 =A0 =A0 temac_dma_out32(lp, TX_TAILDESC_PTR, tail_p); /* DMA start =
*/
> + =A0 =A0 =A0 lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */
>
> =A0 =A0 =A0 =A0return NETDEV_TX_OK;
> =A0}
> @@ -663,7 +729,7 @@ static void ll_temac_recv(struct net_device *ndev)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0cur_p =3D &lp->rx_bd_v[lp->rx_bd_ci];
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0bdstat =3D cur_p->app0;
> =A0 =A0 =A0 =A0}
> - =A0 =A0 =A0 temac_dma_out32(lp, RX_TAILDESC_PTR, tail_p);
> + =A0 =A0 =A0 lp->dma_out(lp, RX_TAILDESC_PTR, tail_p);
>
> =A0 =A0 =A0 =A0spin_unlock_irqrestore(&lp->rx_lock, flags);
> =A0}
> @@ -674,8 +740,8 @@ static irqreturn_t ll_temac_tx_irq(int irq, void *_nd=
ev)
> =A0 =A0 =A0 =A0struct temac_local *lp =3D netdev_priv(ndev);
> =A0 =A0 =A0 =A0unsigned int status;
>
> - =A0 =A0 =A0 status =3D temac_dma_in32(lp, TX_IRQ_REG);
> - =A0 =A0 =A0 temac_dma_out32(lp, TX_IRQ_REG, status);
> + =A0 =A0 =A0 status =3D lp->dma_in(lp, TX_IRQ_REG);
> + =A0 =A0 =A0 lp->dma_out(lp, TX_IRQ_REG, status);
>
> =A0 =A0 =A0 =A0if (status & (IRQ_COAL | IRQ_DLY))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0temac_start_xmit_done(lp->ndev);
> @@ -692,8 +758,8 @@ static irqreturn_t ll_temac_rx_irq(int irq, void *_nd=
ev)
> =A0 =A0 =A0 =A0unsigned int status;
>
> =A0 =A0 =A0 =A0/* Read and clear the status registers */
> - =A0 =A0 =A0 status =3D temac_dma_in32(lp, RX_IRQ_REG);
> - =A0 =A0 =A0 temac_dma_out32(lp, RX_IRQ_REG, status);
> + =A0 =A0 =A0 status =3D lp->dma_in(lp, RX_IRQ_REG);
> + =A0 =A0 =A0 lp->dma_out(lp, RX_IRQ_REG, status);
>
> =A0 =A0 =A0 =A0if (status & (IRQ_COAL | IRQ_DLY))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ll_temac_recv(lp->ndev);
> @@ -794,7 +860,7 @@ static ssize_t temac_show_llink_regs(struct device *d=
ev,
> =A0 =A0 =A0 =A0int i, len =3D 0;
>
> =A0 =A0 =A0 =A0for (i =3D 0; i < 0x11; i++)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 len +=3D sprintf(buf + len, "%.8x%s", temac=
_dma_in32(lp, i),
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 len +=3D sprintf(buf + len, "%.8x%s", lp->d=
ma_in(lp, i),
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (i % 8) =3D=
=3D 7 ? "\n" : " ");
> =A0 =A0 =A0 =A0len +=3D sprintf(buf + len, "\n");
>
> @@ -820,7 +886,6 @@ temac_of_probe(struct of_device *op, const struct of_=
device_id *match)
> =A0 =A0 =A0 =A0struct net_device *ndev;
> =A0 =A0 =A0 =A0const void *addr;
> =A0 =A0 =A0 =A0int size, rc =3D 0;
> - =A0 =A0 =A0 unsigned int dcrs;
>
> =A0 =A0 =A0 =A0/* Init network device structure */
> =A0 =A0 =A0 =A0ndev =3D alloc_etherdev(sizeof(*lp));
> @@ -870,13 +935,20 @@ temac_of_probe(struct of_device *op, const struct o=
f_device_id *match)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto nodev;
> =A0 =A0 =A0 =A0}
>
> - =A0 =A0 =A0 dcrs =3D dcr_resource_start(np, 0);
> - =A0 =A0 =A0 if (dcrs =3D=3D 0) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&op->dev, "could not get DMA regist=
er address\n");
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto nodev;
> + =A0 =A0 =A0 /* Setup the DMA register accesses, could be DCR or memory =
mapped */
> + =A0 =A0 =A0 if (temac_dcr_setup(lp, op, np)) {
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* no DCR in the device tree, try non-DCR *=
/
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 lp->sdma_regs =3D of_iomap(np, 0);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (lp->sdma_regs) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lp->dma_in =3D temac_dma_in=
32;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lp->dma_out =3D temac_dma_o=
ut32;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_dbg(&op->dev, "MEM base=
: %p\n", lp->sdma_regs);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 } else {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&op->dev, "unable t=
o map DMA registers\n");
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto nodev;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0}
> - =A0 =A0 =A0 lp->sdma_dcrs =3D dcr_map(np, dcrs, dcr_resource_len(np, 0)=
);
> - =A0 =A0 =A0 dev_dbg(&op->dev, "DCR base: %x\n", dcrs);
>
> =A0 =A0 =A0 =A0lp->rx_irq =3D irq_of_parse_and_map(np, 0);
> =A0 =A0 =A0 =A0lp->tx_irq =3D irq_of_parse_and_map(np, 1);
> --
> 1.6.2.1
>
>
>
> This email and any attachments are intended for the sole use of the named=
 recipient(s) and contain(s) confidential information that may be proprieta=
ry, privileged or copyrighted under applicable law. If you are not the inte=
nded recipient, do not read, copy, or forward this email message or any att=
achments. Delete this email message and any attachments immediately.
>
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* Re: Freescale MPC5554 device tree (was: cross-compiling Linux for PowerPC e200 core?)
From: Grant Likely @ 2010-03-17 19:02 UTC (permalink / raw)
  To: Németh Márton; +Cc: linuxppc-dev Development, David Gibson
In-Reply-To: <4B9B7E0A.8090703@freemail.hu>

MjAxMC8zLzEzIE7pbWV0aCBN4XJ0b24gPG5tMTI3QGZyZWVtYWlsLmh1PjoKPiBIaSwKPgo+IGhl
cmUgaXMgYSB2ZXJzaW9uIHdpdGggbW9kaWZpZWQgY3B1IG5vZGUsIHhiYXIgcmFuZ2VzIGFuZCBh
ZGRlZCBpbnRlcnJ1cHQgc291cmNlcy4KPiBQbGVhc2Ugc2VuZCBjb21tZW50cy4KCkhpIE3hcnRv
bi4gIEEgZmV3IGNvbW1lbnRzIGJlbG93LgoKPiAtLS0KPiBGcm9tOiBN4XJ0b24gTultZXRoIDxu
bTEyN0BmcmVlbWFpbC5odT4KPgo+IEFkZCBkZXZpY2UgdHJlZSBmb3IgRnJlZXNjYWxlIE1QQzU1
NTQuCj4KPiBTaWduZWQtb2ZmLWJ5OiBN4XJ0b24gTultZXRoIDxubTEyN0BmcmVlbWFpbC5odT4K
PiAtLS0KPiBkaWZmIC11cHJOIGxpbnV4LTIuNi4zMy5vcmlnL2FyY2gvcG93ZXJwYy9ib290L2R0
cy9tcGM1NTU0LmR0cyBsaW51eC9hcmNoL3Bvd2VycGMvYm9vdC9kdHMvbXBjNTU1NC5kdHMKPiAt
LS0gbGludXgtMi42LjMzLm9yaWcvYXJjaC9wb3dlcnBjL2Jvb3QvZHRzL21wYzU1NTQuZHRzIDE5
NzAtMDEtMDEgMDE6MDA6MDAuMDAwMDAwMDAwICswMTAwCj4gKysrIGxpbnV4L2FyY2gvcG93ZXJw
Yy9ib290L2R0cy9tcGM1NTU0LmR0cyCgIKAgMjAxMC0wMy0xMyAxMjo1MjozMi4wMDAwMDAwMDAg
KzAxMDAKPiBAQCAtMCwwICsxLDQ3MyBAQAo+ICsvKgo+ICsgKiBGcmVlc2NhbGUgTVBDNTU1NCBE
ZXZpY2UgVHJlZSBTb3VyY2UKPiArICoKPiArICogQmFzZWQgb24gTVBDNTU1My81NTU0IE1pY3Jv
Y29udHJvbGxlciBSZWZlcmVuY2UgTWFudWFsLCBSZXYuIDQuMCwgMDQvMjAwNwo+ICsgKiBodHRw
Oi8vd3d3LmZyZWVzY2FsZS5jb20vZmlsZXMvMzJiaXQvZG9jL3JlZl9tYW51YWwvTVBDNTU1M19N
UEM1NTU0X1JNLnBkZgo+ICsgKiCgLSBCbG9jayBEaWFncmFtOiBwYWdlIDEtMywgRmlndXJlIDEt
MQo+ICsgKiCgLSBNZW1vcnkgTWFwOiBwYWdlIDEtMjEsIFRhYmxlIDEtMgo+ICsgKiCgLSBJbnRl
cnJ1cHQgUmVxdWVzdCBTb3VyY2VzOiBwYWdlIDEwLTE2LCBUYWJsZSAxMC05Cj4gKyAqCj4gKyAq
IENvcHlyaWdodCAyMDEwIE3hcnRvbiBO6W1ldGgKPiArICogTeFydG9uIE7pbWV0aCA8bm0xMjdA
ZnJlZW1haWwuaHU+Cj4gKyAqCj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5
b3UgY2FuIHJlZGlzdHJpYnV0ZSCgaXQgYW5kL29yIG1vZGlmeSBpdAo+ICsgKiB1bmRlciCgdGhl
IHRlcm1zIG9mIKB0aGUgR05VIEdlbmVyYWwgoFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBi
eSB0aGUKPiArICogRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyCgZWl0aGVyIHZlcnNpb24gMiBv
ZiB0aGUgoExpY2Vuc2UsIG9yIChhdCB5b3VyCj4gKyAqIG9wdGlvbikgYW55IGxhdGVyIHZlcnNp
b24uCj4gKyAqLwo+ICsKPiArL2R0cy12MS87Cj4gKwo+ICsvIHsKPiArIKAgoCCgIG1vZGVsID0g
Ik1QQzU1NTQiOwo+ICsgoCCgIKAgY29tcGF0aWJsZSA9ICJmc2wsTVBDNTU1NEVWQiI7IKAgoCCg
IKAgoC8vIEZyZWVzY2FsZSBNUEM1NTU0IEV2YWx1YXRpb24gQm9hcmQKPiArIKAgoCCgICNhZGRy
ZXNzLWNlbGxzID0gPDE+Owo+ICsgoCCgIKAgI3NpemUtY2VsbHMgPSA8MT47Cj4gKyCgIKAgoCBp
bnRlcnJ1cHQtcGFyZW50ID0gPCZpbnRjPjsKPiArCj4gKyCgIKAgoCBjcHVzIHsKPiArIKAgoCCg
IKAgoCCgIKAgI2FkZHJlc3MtY2VsbHMgPSA8MT47Cj4gKyCgIKAgoCCgIKAgoCCgICNzaXplLWNl
bGxzID0gPDA+Owo+ICsKPiArIKAgoCCgIKAgoCCgIKAgY3B1QDAgewo+ICsgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIGRldmljZV90eXBlID0gImNwdSI7Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
Y29tcGF0aWJsZSA9ICJQb3dlclBDLDU1NTQiLCAiZnNsLG1wYzU1NTQtZTIwMHo2IiwgImZzbCxw
b3dlcnBjLWUyMDB6NiI7Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgcmVnID0gPDA+Owo+ICsg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIGQtY2FjaGUtbGluZS1zaXplID0gPDMyPjsKPiArIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCBpLWNhY2hlLWxpbmUtc2l6ZSA9IDwzMj47Cj4gKyCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgZC1jYWNoZS1zaXplID0gPDB4ODAwMD47IKAgoCCgIKAvLyBMMSwgMzJLaUIK
PiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCBpLWNhY2hlLXNpemUgPSA8MHg4MDAwPjsgoCCgIKAg
oC8vIEwxLCAzMktpQgo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIHRpbWViYXNlLWZyZXF1ZW5j
eSA9IDwwPjsgoCCgIKAgLy8gZnJvbSBib290bG9hZGVyCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgYnVzLWZyZXF1ZW5jeSA9IDwwPjsgoCCgIKAgoCCgIKAvLyBmcm9tIGJvb3Rsb2FkZXIKPiAr
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCBjbG9jay1mcmVxdWVuY3kgPSA8MD47IKAgoCCgIKAgoC8v
IGZyb20gYm9vdGxvYWRlcgo+ICsgoCCgIKAgoCCgIKAgoCB9Owo+ICsgoCCgIKAgfTsKPiArCj4g
KyCgIKAgoCBtZW1vcnlANDAwMDAwMDAgewo+ICsgoCCgIKAgoCCgIKAgoCBkZXZpY2VfdHlwZSA9
ICJtZW1vcnkiOwo+ICsgoCCgIKAgoCCgIKAgoCByZWcgPSA8MHg0MDAwMDAwMCAweDEwMDAwPjsg
oCCgIC8vIDMyS2lCIGludGVybmFsIFNSQU0KPiArIKAgoCCgIH07CgpPaC4uLi4gdGhpcyBpcyB0
aGUgc21hbGwgU1JBTS4gIHllYWgsIHlvdSBzaG91bGQgbW92ZSB0aGlzIHVuZGVyIHRoZQphcHBy
b3ByaWF0ZSBicmlkZ2Ugbm9kZSwgcmVtb3ZlIHRoZSBkZXZpY2VfdHlwZSBwcm9wZXJ0eSwgYW5k
IGFkZCBhCmNvbXBhdGlibGUgcHJvcGVydHkuICBNZW1vcnkgbm9kZXMgYXQgdGhlIHJvb3QgbGlr
ZSB0aGlzIGFyZSB1c2VkIHRvCmRlc2NyaWJlIHdoYXQgaXMgYmFzaWNhbGx5IG1haW4gbWVtb3J5
ICh3aGF0IExpbnV4IHdpbGwgZXhlY3V0ZSBvdXQKb2YpLiAgWW91J2xsIHdhbnQgYSBuZXcgbWVt
b3J5IG5vZGUgZm9yIHRoZSBleHRlcm5hbCByYW0gaG9va2VkIHVwIHRvCnRoZSA1NTU0LgoKPiAr
Cj4gKyCgIKAgoCB4YmFyQGZmZjA0MDAwIHsgoCCgIKAgoCAvLyBTeXN0ZW0gQnVzIENyb3NzYmFy
IFN3aXRjaCAoWEJBUikKPiArIKAgoCCgIKAgoCCgIKAgY29tcGF0aWJsZSA9ICJmc2wsbXBjNTU1
NC14YmFyIjsKPiArIKAgoCCgIKAgoCCgIKAgI2FkZHJlc3MtY2VsbHMgPSA8MT47Cj4gKyCgIKAg
oCCgIKAgoCCgICNzaXplLWNlbGxzID0gPDE+Owo+ICsgoCCgIKAgoCCgIKAgoCAvLyBUaGUgZnVs
bCBtZW1vcnkgcmFuZ2UgaXMgY292ZXJlZCBieSBYQkFSCj4gKyCgIKAgoCCgIKAgoCCgIHJhbmdl
czsKPiArIKAgoCCgIKAgoCCgIKAgcmVnID0gPDB4ZmZmMDQwMDAgMHg0MDAwPjsKPiArCj4gKyCg
IKAgoCCgIKAgoCCgIGZsYXNoQDAgeyCgIKAgoCAvLyByZWFkLW9ubHkgRkxBU0gKPiArIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCBjb21wYXRpYmxlID0gImZzbCxtcGM1NTU0LWZsYXNoIjsKPiArIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCByZWcgPSA8MHgwMDAwMDAwMCAweDIwMDAwMD47IKAgoC8vIDJN
aUIgaW50ZXJuYWwgRkxBU0gKPiArIKAgoCCgIKAgoCCgIKAgfTsKPiArCj4gKyCgIKAgoCCgIKAg
oCCgIGJyaWRnZUBjM2YwMDAwMCB7Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgY29tcGF0aWJs
ZSA9ICJmc2wsbXBjNTU1NC1wYnJpZGdlLWEiOwo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgICNh
ZGRyZXNzLWNlbGxzID0gPDE+Owo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgICNzaXplLWNlbGxz
ID0gPDE+Owo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIHJhbmdlcyA9IDwwIDB4YzAwMDAwMDAg
MHgyMDAwMDAwMD47Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgcmVnID0gPDB4YzNmMDAwMDAg
MHg0MDAwPjsKPiArCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgZm1wbGxAM2Y4MDAwMCB7IKAg
oCCgIKAgLy8gRnJlcXVlbmN5IE1vZHVsYXRlZCBQTEwKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIGNvbXBhdGlibGUgPSAiZnNsLG1wYzU1NTQtZm1wbGwiOwo+ICsgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgcmVnID0gPDB4MDNmODAwMDAgMHg0MDAwPjsKPiArIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIGludGVycnVwdHMgPSA8NDMgMSCgIKAgoC8vIExvc3Mg
b2YgQ2xvY2sKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
NDQgMT47IKAgoC8vIExvc3Mgb2YgTG9jawo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIH07Cj4g
Kwo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIGZsYXNoY29uZmlnQDNmODgwMDAgeyCgIC8vIEZs
YXNoIENvbmZpZ3VyYXRpb24KPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIGNvbXBh
dGlibGUgPSAiZnNsLG1wYzU1NTQtZmxhc2hjb25maWciOwo+ICsgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgcmVnID0gPDB4MDNmODgwMDAgMHg0MDAwPjsKPiArIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCB9Owo+ICsKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCBzaXVAM2Y4OTAwMCB7IKAg
oCCgIKAgoCAvLyBTeXN0ZW0gSW50ZWdyYXRpb24gVW5pdAo+ICsgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgY29tcGF0aWJsZSA9ICJmc2wsbXBjNTU1NC1zaXUiOwo+ICsgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgcmVnID0gPDB4MDNmOTAwMDAgMHg0MDAwPjsKPiArIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIGludGVycnVwdHMgPSA8NDUgMSCgIKAgoC8vIEV4dGVy
bmFsIEludGVycnVwdCBPdmVycnVuIDAtMTUKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgNDYgMSCgIKAgoC8vIEV4dGVybmFsIEludGVycnVwdCAwCj4gKyCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDQ3IDEgoCCgIKAvLyBF
eHRlcm5hbCBJbnRlcnJ1cHQgMQo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCA0OCAxIKAgoCCgLy8gRXh0ZXJuYWwgSW50ZXJydXB0IDIKPiArIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgNDkgMSCgIKAgoC8vIEV4dGVybmFs
IEludGVycnVwdCAzCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIDUwIDE+OyCgIKAvLyBFeHRlcm5hbCBJbnRlcnJ1cHQgNC0xNQo+ICsgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIH07CgpUaGlzIGRvZXNuJ3QgbG9vayBxdWl0ZSByaWdodC4uLi4gL21lIGdvZXMg
dG8gbG9vayBhdCB0aGUgNTU1NApyZWZlcmVuY2UgbWFudWFsLi4uLgoKT2theSwgc28gYWxsIHRo
ZSBleHRlcm5hbCBJUlFzIGdvIHRocm91Z2ggdGhlIFNJVSB0aGVuLCBldmVuIHRob3VnaAp0aGUg
Zmlyc3QgNCBnZXQgcGFzc2VkIHN0cmFpZ2h0IHRocm91Z2ggdG8gdGhlIGludGM/ICBBbmQgSSBz
ZWUgdGhhdAphbGwgdGhlIGxldmVsL2VkZ2Ugc2Vuc2luZyBhbmQgbWFza2luZy9hY2tub3dsZWRn
aW5nIGlzIGRvbmUgYXQgdGhlClNJVSBsZXZlbCwgbm90IHRoZSBpbnRjIGxldmVsLCBjb3JyZWN0
PyAgU28sIHdoYXQgeW91IGVmZmVjdGl2ZWx5IGhhdmUKaXMgdGhlIFNJVSBpcyAqYW5vdGhlciog
aW50ZXJydXB0IGNvbnRyb2xsZXIgdGhhdCBpcyBjYXNjYWRlZCB0byB0aGUKaW50Yy4gIFRoZXJl
Zm9yZSB5b3UgbmVlZCB0byBhZGQgdGhlIGZvbGxvd2luZyB0byB0aGlzIG5vZGU6CgojaW50ZXJy
dXB0LWNlbGxzID0gPDI+OyAgIC8vIGNlbGwxOmV4dGlycSMsIGNlbGwyOmxldmVsL2VkZ2UgZmxh
Z3MKaW50ZXJydXB0LWNvbnRyb2xsZXI7CgpBbHNvIGdpdmUgdGhlIG5vZGUgYSBsYWJlbCBzbyB0
aGF0IG5vZGVzIGZvciBleHRlcm5hbCBkZXZpY2VzIGNhbgpyZWZlcmVuY2UgaXQgZm9yIGhvb2tp
bmcgdXAgZXh0ZXJuYWwgaXJxcyBieSBvdmVycmlkaW5nIHRoZSB0b3AtbGV2ZWwKaW50ZXJydXB0
LXBhcmVudCBwcm9wZXJ0eS4KCkFsc28sIGl0IHdvdWxkIGFwcGVhciB0aGF0IGludGMgaW50ZXJy
dXB0cyBkb24ndCBoYXZlIGFueSBsZXZlbC9lZGdlCmNvbmZpZ3VyYXRpb24gYXNzb2NpYXRlZCB3
aXRoIHRoZW0uICBUaGV5IGFyZSBlaXRoZXIgYXNzZXJ0ZWQsIG9yIHRoZXkKYXJlIG5vdCwgY29y
cmVjdD8gIEF0IHRoZSBtb21lbnQgeW91J3JlIHNwZWNpZnlpbmcgZXZlcnkgaW50YwppbnRlcnJ1
cHQgd2l0aCAyIGNlbGxzLCBhbmQgdGhlIDJuZCBjZWxsIGlzIGFsd2F5cyAnMScuICBJIHRoaW5r
IHlvdQpjYW4gY2hhbmdlICNpbnRlcnJ1cHQtY2VsbHMgdG8gPDE+IGluIHRoZSBpbnRjIG5vZGUg
YW5kIGRyb3AgdGhlICcxJwpldmVyeXdoZXJlLgoKV2hlbiB5b3Ugd3JpdGUgeW91ciBpbnRjIGRy
aXZlciwgeW91J2xsIGFsc28gbmVlZCB0byB3cml0ZSB0aGUKY2FzY2FkZWQgZHJpdmVyIGZvciB0
aGUgZXh0ZXJuYWwgSVJRcy4KCj4gKwo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIGVtaW9zQDNm
YTAwMDAgeyCgIKAgoCCgIC8vIE1vZHVsYXIgVGltZXIgU3lzdGVtCj4gKyCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCBjb21wYXRpYmxlID0gImZzbCxtcGM1NTU0LWVtaW9zIjsKPiArIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIHJlZyA9IDwweDAzZmEwMDAwIDB4NDAwMD47Cj4g
KyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCBpbnRlcnJ1cHRzID0gPDUxIDEgoCCgIKAv
LyBDaGFubmVsIDAKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgNTIgMSCgIKAgoC8vIENoYW5uZWwgMQo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCA1MyAxIKAgoCCgLy8gQ2hhbm5lbCAyCj4gKyCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDU0IDEgoCCgIKAvLyBDaGFubmVsIDMKPiAr
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgNTUgMSCgIKAgoC8v
IENoYW5uZWwgNAo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCA1NiAxIKAgoCCgLy8gQ2hhbm5lbCA1Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIDU3IDEgoCCgIKAvLyBDaGFubmVsIDYKPiArIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgNTggMSCgIKAgoC8vIENoYW5uZWwgNwo+ICsg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCA1OSAxIKAgoCCgLy8g
Q2hhbm5lbCA4Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IDYwIDEgoCCgIKAvLyBDaGFubmVsIDkKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgNjEgMSCgIKAgoC8vIENoYW5uZWwgMTAKPiArIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgNjIgMSCgIKAgoC8vIENoYW5uZWwgMTEKPiAr
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgNjMgMSCgIKAgoC8v
IENoYW5uZWwgMTIKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgNjQgMSCgIKAgoC8vIENoYW5uZWwgMTMKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgNjUgMSCgIKAgoC8vIENoYW5uZWwgMTQKPiArIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgNjYgMSCgIKAgoC8vIENoYW5uZWwgMTUK
PiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgMjAyIDEgoCCg
IC8vIENoYW5uZWwgMTYKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgMjAzIDEgoCCgIC8vIENoYW5uZWwgMTcKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgMjA0IDEgoCCgIC8vIENoYW5uZWwgMTgKPiArIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgMjA1IDEgoCCgIC8vIENoYW5uZWwg
MTkKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgMjA2IDEg
oCCgIC8vIENoYW5uZWwgMjAKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgMjA3IDEgoCCgIC8vIENoYW5uZWwgMjEKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgMjA4IDEgoCCgIC8vIENoYW5uZWwgMjIKPiArIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgMjA5IDE+OyCgIC8vIENoYW5u
ZWwgMjMKClRoZXNlIGxvbmcgbGlzdHMgYm90aGVyIG1lLCBidXQgbG9va2luZyBhdCB0aGUgbWFu
dWFsIHRoZXkgc2VlbSB0bwpkZXNjcmliZSB0aGUgYWN0dWFsIGhhcmR3YXJlIGFyY2hpdGVjdHVy
ZSwgc28gSSB0aGluayB0aGV5IGFyZQpwcm9iYWJseSBmaW5lLiAgQnV0IHlvdSBtYXkgd2FudCB0
byBjb21wYWN0IHlvdXIgZm9ybWF0dGluZyBzb21ld2hhdC4KWW91IGNhbiBwcm9iYWJseSBsaXN0
IG1vcmUgdGhhbiBvbmUgY2hhbm5lbCBwZXIKc291cmNlIGxpbmUgaW4gdGhlIGZpbGUuCgpEaXR0
byB0aHJvdWdoIHRoZSByZXN0IG9mIHRoZSBmaWxlLgoKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCB9Owo+ICsKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCBldHB1QDNmYzAwMDAgeyCgIKAgoCCg
IKAvLyBFbmhhbmNlZCBUaW1lIFByb2Nlc3NpbmcgVW5pdAo+ICsgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgY29tcGF0aWJsZSA9ICJmc2wsbXBjNTU1NC1ldHB1IjsKPiArIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIHJlZyA9IDwweDAzZmMwMDAwIDB4NDAwMD47Cj4gKyCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCBpbnRlcnJ1cHRzID0gPDY3IDEgoCCgIKAvLyBHbG9i
YWwgRXhjZXB0aW9uCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIDY4IDEgoCCgIKAvLyBBIENoYW5uZWwgMAo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCA2OSAxIKAgoCCgLy8gQSBDaGFubmVsIDEKPiArIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgNzAgMSCgIKAgoC8vIEEgQ2hhbm5l
bCAyCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDcxIDEg
oCCgIKAvLyBBIENoYW5uZWwgMwo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCA3MiAxIKAgoCCgLy8gQSBDaGFubmVsIDQKPiArIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgNzMgMSCgIKAgoC8vIEEgQ2hhbm5lbCA1Cj4gKyCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDc0IDEgoCCgIKAvLyBB
IENoYW5uZWwgNgo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCA3NSAxIKAgoCCgLy8gQSBDaGFubmVsIDcKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgNzYgMSCgIKAgoC8vIEEgQ2hhbm5lbCA4Cj4gKyCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDc3IDEgoCCgIKAvLyBBIENoYW5uZWwg
OQo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCA3OCAxIKAg
oCCgLy8gQSBDaGFubmVsIDEwCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIDc5IDEgoCCgIKAvLyBBIENoYW5uZWwgMTEKPiArIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgODAgMSCgIKAgoC8vIEEgQ2hhbm5lbCAxMgo+ICsg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCA4MSAxIKAgoCCgLy8g
QSBDaGFubmVsIDEzCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIDgyIDEgoCCgIKAvLyBBIENoYW5uZWwgMTQKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgODMgMSCgIKAgoC8vIEEgQ2hhbm5lbCAxNQo+ICsgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCA4NCAxIKAgoCCgLy8gQSBDaGFu
bmVsIDE2Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDg1
IDEgoCCgIKAvLyBBIENoYW5uZWwgMTcKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgODYgMSCgIKAgoC8vIEEgQ2hhbm5lbCAxOAo+ICsgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCA4NyAxIKAgoCCgLy8gQSBDaGFubmVsIDE5
Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDg4IDEgoCCg
IKAvLyBBIENoYW5uZWwgMjAKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgODkgMSCgIKAgoC8vIEEgQ2hhbm5lbCAyMQo+ICsgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCA5MCAxIKAgoCCgLy8gQSBDaGFubmVsIDIyCj4gKyCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDkxIDEgoCCgIKAvLyBB
IENoYW5uZWwgMjMKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgOTIgMSCgIKAgoC8vIEEgQ2hhbm5lbCAyNAo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCA5MyAxIKAgoCCgLy8gQSBDaGFubmVsIDI1Cj4gKyCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDk0IDEgoCCgIKAvLyBBIENoYW5u
ZWwgMjYKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgOTUg
MSCgIKAgoC8vIEEgQ2hhbm5lbCAyNwo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCA5NiAxIKAgoCCgLy8gQSBDaGFubmVsIDI4Cj4gKyCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDk3IDEgoCCgIKAvLyBBIENoYW5uZWwgMjkK
PiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgOTggMSCgIKAg
oC8vIEEgQ2hhbm5lbCAzMAo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCA5OSAxIKAgoCCgLy8gQSBDaGFubmVsIDMxCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDI0MyAxIKAgoCAvLyBCIENoYW5uZWwgMAo+ICsgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCAyNDQgMSCgIKAgLy8gQiBD
aGFubmVsIDEKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
MjQ1IDEgoCCgIC8vIEIgQ2hhbm5lbCAyCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIDI0NiAxIKAgoCAvLyBCIENoYW5uZWwgMwo+ICsgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCAyNDcgMSCgIKAgLy8gQiBDaGFubmVsIDQK
PiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgMjQ4IDEgoCCg
IC8vIEIgQ2hhbm5lbCA1Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIDI0OSAxIKAgoCAvLyBCIENoYW5uZWwgNgo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCAyNTAgMSCgIKAgLy8gQiBDaGFubmVsIDcKPiArIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgMjUxIDEgoCCgIC8vIEIgQ2hh
bm5lbCA4Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDI1
MiAxIKAgoCAvLyBCIENoYW5uZWwgOQo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCAyNTMgMSCgIKAgLy8gQiBDaGFubmVsIDEwCj4gKyCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDI1NCAxIKAgoCAvLyBCIENoYW5uZWwgMTEK
PiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgMjU1IDEgoCCg
IC8vIEIgQ2hhbm5lbCAxMgo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCAyNTYgMSCgIKAgLy8gQiBDaGFubmVsIDEzCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDI1NyAxIKAgoCAvLyBCIENoYW5uZWwgMTQKPiArIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgMjU4IDEgoCCgIC8vIEIg
Q2hhbm5lbCAxNQo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCAyNTkgMSCgIKAgLy8gQiBDaGFubmVsIDE2Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIDI2MCAxIKAgoCAvLyBCIENoYW5uZWwgMTcKPiArIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgMjYxIDEgoCCgIC8vIEIgQ2hhbm5l
bCAxOAo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCAyNjIg
MSCgIKAgLy8gQiBDaGFubmVsIDE5Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIDI2MyAxIKAgoCAvLyBCIENoYW5uZWwgMjAKPiArIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgMjY0IDEgoCCgIC8vIEIgQ2hhbm5lbCAyMQo+
ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCAyNjUgMSCgIKAg
Ly8gQiBDaGFubmVsIDIyCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIDI2NiAxIKAgoCAvLyBCIENoYW5uZWwgMjMKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgMjY3IDEgoCCgIC8vIEIgQ2hhbm5lbCAyNAo+ICsgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCAyNjggMSCgIKAgLy8gQiBD
aGFubmVsIDI1Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IDI2OSAxIKAgoCAvLyBCIENoYW5uZWwgMjYKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgMjcwIDEgoCCgIC8vIEIgQ2hhbm5lbCAyNwo+ICsgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCAyNzEgMSCgIKAgLy8gQiBDaGFubmVs
IDI4Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIDI3MiAx
IKAgoCAvLyBCIENoYW5uZWwgMjkKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIKAgMjczIDEgoCCgIC8vIEIgQ2hhbm5lbCAzMAo+ICsgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCAyNzQgMT47IKAgLy8gQiBDaGFubmVsIDMxCgpB
cmUgQSBhbmQgQiB0d28gaW5zdGFuY2VzIG9mIHRoZSBzYW1lIGhhcmR3YXJlIGJsb2NrPyAgQ29u
c2lkZXIgaGF2aW5nCmEgc3Vibm9kZSBmb3IgZWFjaCBpbnN0YW5jZSB0byBnaXZlIHNvbWUgbG9n
aWNhbCBzZXBhcmF0aW9uIHRvIHRoaXMKbGlzdCBhbmQgYXNzb2NpYXRlIHJlZ2lzdGVyIHJhbmdl
cyB3aXRoIGluc3RhbmNlcy4gIERvaW5nIGl0IHRoYXQgd2F5CmFsc28gbWFrZXMgaXQgZWFzaWVy
IGZvciBleHRlcm5hbCBkZXZpY2Ugbm9kZXMgdG8gZGVzY3JpYmUgYW4KYXR0YWNobWVudCB0byBh
IHBhcnRpY3VsYXIgY2hhbm5lbC4KCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgfTsKPiArCj4g
KyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgZXRwdWRhdGFAM2ZjODAwMCB7IKAgoCCgLy8gZVRQVSBT
aGFyZWQgRGF0YSBNZW1vcnkgKFBhcmFtZXRlciBSQU0pCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCCgIKAgoCBjb21wYXRpYmxlID0gImZzbCxtcGM1NTU0LWV0cHVkYXRhIjsKPiArIKAgoCCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIHJlZyA9IDwweDAzZmM4MDAwIDB4NDAwMD47Cj4gKyCg
IKAgoCCgIKAgoCCgIKAgoCCgIKAgfTsKPiArCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgZXRw
dWRhdGFAM2ZjYzAwMCB7IKAgoCCgLy8gZVRQVSBTaGFyZWQgRGF0YSBNZW1vcnkgKFBhcmFtZXRl
ciBSQU0pIG1pcnJvcgo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgY29tcGF0aWJs
ZSA9ICJmc2wsbXBjNTU1NC1ldHB1ZGF0YSI7Cj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IKAgoCByZWcgPSA8MHgwM2ZjYzAwMCAweDQwMDA+Owo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCg
IH07Cj4gKwo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIGV0cHVjb2RlQDNmZDAwMDAgeyCgIKAg
oCCgIKAgoCCgLy8gZVRQVSBTaGFyZWQgQ29kZSBSQU0KPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAg
oCCgIKAgoCCgIGNvbXBhdGlibGUgPSAiZnNsLG1wYzU1NTQtZXRwdWNvZGUiOwo+ICsgoCCgIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgcmVnID0gPDB4MDNmZDAwMDAgMHg0MDAwPjsKPiArIKAg
oCCgIKAgoCCgIKAgoCCgIKAgoCB9OwoKU2hvdWxkIGFsbCB0aGlzIGV0cHUgc3R1ZmYgYmUgcGFy
dCBvZiB0aGUgZXRwdSBub2RlPwoKVGhpcyBsb29rcyBsaWtlIGl0IGlzIGdldHRpbmcgY2xvc2Uu
ICBPbmNlIHlvdSd2ZSBnb3QgYSB2ZXJzaW9uIHRoYXQKbG9va3MgZ29vZCB0byBldmVyeW9uZSwg
eW91IGFsc28gbmVlZCB0byBkb2N1bWVudCB3aGF0IHRoZSBuZXcKYmluZGluZ3MgbWVhbi4gIEVz
c2VudGlhbGx5IHRoaXMgdGFzayBpbnZvbHZlcyB3cml0aW5nIGRvd24gYWxsIHRoZQpuZXcgY29t
cGF0aWJsZSBwcm9wZXJ0eSB2YWx1ZXMgdGhhdCB5b3UndmUgZGVmaW5lZCwgd2hhdCBkZXZpY2Ug
ZWFjaApvbmUgZGVzY3JpYmVzLCBhbmQgd2hhdCBwcm9wZXJ0aWVzL3N1Ym5vZGVzIGFyZSBleHBl
Y3RlZCBmb3IgZWFjaCBuZXcKY29tcGF0aWJsZSB2YWx1ZS4gIERvY3VtZW50YXRpb24gY3VycmVu
dGx5IGdvZXMgaW4gdGhlCkRvY3VtZW50YXRpb24vcG93ZXJwYy9kdHMtYmluZGluZ3MgZGlyZWN0
b3J5LCBhbmQgeW91IGNhbiBzZWUgbG90cyBvZgpleGFtcGxlcyB0aGVyZS4gIChIb3dldmVyLCBJ
J20gaG9waW5nIHRvIG1vdmluZyBpdCB0bwpodHRwOi8vZGV2aWNldHJlZS5vcmcgaW4gdGhlIG5l
YXIgZnV0dXJlIHNvIGl0IGNhbiBiZSBzaGFyZWQgYnkgb3RoZXIKT1Nlcy4gIEkndmUgY3VycmVu
dGx5IGdvdCBhIHRlc3Qgc2l0ZSB1cCBhdCBodHRwOi8vZmR0LnNlY3JldGxhYi5jYSkuCgpUaGUg
cnVsZSBpcyB0aGF0IHdlIHdpbGwgbm90IG1lcmdlIGRyaXZlcnMgdXNpbmcgbmV3IE9GIGJpbmRp
bmdzIHVudGlsCnRob3NlIGJpbmRpbmdzIGhhdmUgYmVlbiBkb2N1bWVudGVkIGFuZCByZXZpZXdl
ZC4KCkNoZWVycywKZy4K

^ permalink raw reply

* [PATCH] [RFC] Xilinx MPMC SDMA subsystem
From: Sergey Temerkhanov @ 2010-03-17 18:18 UTC (permalink / raw)
  To: linuxppc-dev

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

This patch adds generic support for Xilinx MPMC SoftDMA channels which are 
used by, e.g., LLTEMAC and other IP cores (including custom cores). So, the 
implemented functions include only SDMA channels enumeration and control 
(finding device by phandle property, channel reset, initialization of RX/TX 
links, enabling/disabling IRQs,  IRQ coalescing control and submission of 
descriptors (struct sdma_desc).

The users of this subsystem are supposed to get the pointer to the struct 
sdma_device by phandle (using sdma_find_device() function), fill the struct 
sdma_client with pointers to the callback functions which are called on rx/tx 
completion, on error, and when sdma_reset is called by any client and then 
register the client with add_client() (sdma_del_client can be used to 
unregister the struct sdma_client)

Also, some auxiliary functions are provided to check the status of descriptors 
(busy, done, start of packet, end of packet).

The user is also responsible for maintenance of linked descriptors queue, 
proper initialization of their fields, and submission of the descriptors list 
to SDMA channel. IRQ acknowledge must be performed by user too (calling 
sdma_[rx|tx]_irq_ack respectively in [rx|tx]_complete callbacks). Also on RX 
side user must check the __be32 user[4] fields of descriptors to get the 
information supplied by SDMA channel.

This code uses SDMA channels in "Tail pointer fashion", i.e. the call to 
sdma_[rx|tx]_init is performed only once after reset and then only sdma_[rx|
tx]_submit calls are used to update the pointer to the last descriptor in SDMA 
channel.

Simple bus driver for MPMC is also added by this patch.

This code is in production use with our internal LLTEMAC driver implementation 
since 2008 and with a few custom cores drivers since 2009.

This code currently supports only soft MPMCs, i.e., only SDMA channels with 
memory-mapped registers. In order to support channels with DCR, a few 
modifications are needed.

Any comments and suggestions are appreciated.

Regards, Sergey Temerkhanov, Cifronic ZAO

[-- Attachment #2: sdma.patch --]
[-- Type: text/x-patch, Size: 25641 bytes --]

* * *
* * *

diff --git a/arch/powerpc/include/asm/sdma.h b/arch/powerpc/include/asm/sdma.h
new file mode 100644
--- /dev/null
+++ b/arch/powerpc/include/asm/sdma.h
@@ -0,0 +1,173 @@
+#ifndef __SDMA_H__
+#define __SDMA_H__
+
+/*
+ * SDMA subsystem support for Xilinx MPMC.
+ *
+ * Author: Sergey Temerkhanov
+ *
+ * Copyright (c) 2008-2010 Cifronic ZAO
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <asm/dcr.h>
+
+#define SDMA_ALIGNMENT	0x40
+
+struct sdma_desc {
+	__be32 next;
+	__be32 address;
+	__be32 length;
+	__be32 stat_ctl;
+	__be32 user[4];
+	void *virt;
+	u32 flags;
+} __attribute__((aligned(SDMA_ALIGNMENT)));
+
+
+enum {
+	SDMA_STSCTL_ERROR	= (1 << 31), /* DMA error */
+	SDMA_STSCTL_IOE		= (1 << 30), /* Interrupt on end */
+	SDMA_STSCTL_SOE		= (1 << 29), /* Stop on end */
+	SDMA_STSCTL_DONE	= (1 << 28), /* DMA completed */
+	SDMA_STSCTL_SOP		= (1 << 27), /* Start of packet */
+	SDMA_STSCTL_EOP		= (1 << 26), /* End of packet */
+	SDMA_STSCTL_BUSY	= (1 << 25), /* DMA busy */
+	SDMA_STSCTL_CSUM	= (1 << 0),  /* Checksum enable */
+
+	SDMA_STSCTL_MSK		= (0xFF << 24), /*Status/control field */
+};
+
+/* SDMA client operations */
+struct sdma_client {
+	void *data;
+	void (*tx_complete) (void *data);
+	void (*rx_complete) (void *data);
+	void (*error) (void *data);
+	void (*reset) (void *data);
+	struct list_head item;
+};
+
+struct sdma_coalesce {
+	int tx_threshold;
+	int tx_timeout;
+
+	int rx_threshold;
+	int rx_timeout;
+};
+
+#define DEFINE_SDMA_COALESCE(x) struct sdma_coalesce x = { \
+	.tx_timeout	= 0, \
+	.tx_threshold	= 1, \
+	.rx_timeout	= 0, \
+	.rx_threshold	= 1, };
+
+struct mpmc_device {
+	void __iomem		*ioaddr;
+
+	struct resource		memregion;
+	int			irq;
+
+	int			registered;
+	struct list_head	item;
+
+	struct mutex		devs_lock;
+	struct list_head	sdma_devs;
+};
+
+struct sdma_device {
+	void __iomem		*ioaddr;
+	wait_queue_head_t 	wait;
+
+	spinlock_t		lock;
+
+	dcr_host_t		dcr_host;
+
+	struct resource		memregion;
+	int			rx_irq;
+	int			tx_irq;
+	int			rx_ack;
+	int			tx_ack;
+	int			phandle;
+
+	int			registered;
+	struct mpmc_device	*parent;
+
+	struct sdma_coalesce	coal;
+	struct list_head	item;
+
+	struct mutex		clients_lock;
+	struct list_head	clients;
+};
+
+static inline void sdma_add_client(struct sdma_device *sdma, struct sdma_client *client)
+{
+	mutex_lock(&sdma->clients_lock);
+	list_add(&client->item, &sdma->clients);
+	mutex_unlock(&sdma->clients_lock);
+}
+
+static inline void sdma_del_client(struct sdma_device *sdma, struct sdma_client *client)
+{
+	mutex_lock(&sdma->clients_lock);
+	list_del(&client->item);
+	mutex_unlock(&sdma->clients_lock);
+}
+
+struct sdma_device *sdma_find_device(int phandle);
+void sdma_pause(struct sdma_device *sdma);
+void sdma_resume(struct sdma_device *sdma);
+void sdma_reset(struct sdma_device *sdma);
+void sdma_rx_init(struct sdma_device *sdma, dma_addr_t desc);
+void sdma_tx_init(struct sdma_device *sdma, dma_addr_t desc);
+
+int sdma_tx_submit(struct sdma_device *sdma, dma_addr_t desc);
+int sdma_rx_submit(struct sdma_device *sdma, dma_addr_t desc);
+
+void sdma_tx_irq_enable(struct sdma_device *sdma);
+void sdma_rx_irq_enable(struct sdma_device *sdma);
+void sdma_tx_irq_disable(struct sdma_device *sdma);
+void sdma_rx_irq_disable(struct sdma_device *sdma);
+void sdma_tx_irq_ack(struct sdma_device *sdma);
+void sdma_rx_irq_ack(struct sdma_device *sdma);
+
+int sdma_set_coalesce(struct sdma_device *sdma, struct sdma_coalesce *coal);
+int sdma_get_coalesce(struct sdma_device *sdma, struct sdma_coalesce *coal);
+
+static inline int sdma_desc_busy(struct sdma_desc *desc)
+{
+	return (be32_to_cpu(desc->stat_ctl) & SDMA_STSCTL_BUSY);
+}
+
+static inline int sdma_desc_done(struct sdma_desc *desc)
+{
+	return (be32_to_cpu(desc->stat_ctl) & SDMA_STSCTL_DONE);
+}
+
+static inline int sdma_desc_sop(struct sdma_desc *desc)
+{
+	return (be32_to_cpu(desc->stat_ctl) & SDMA_STSCTL_SOP);
+}
+
+static inline int sdma_desc_eop(struct sdma_desc *desc)
+{
+	return (be32_to_cpu(desc->stat_ctl) & SDMA_STSCTL_EOP);
+}
+
+static inline void sdma_set_ack(struct sdma_device *sdma, int rx_ack, int tx_ack)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&sdma->lock, flags);
+	sdma->rx_ack = rx_ack;
+	sdma->tx_ack = tx_ack;
+	spin_unlock_irqrestore(&sdma->lock, flags);
+}
+
+#endif
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -35,7 +35,7 @@
 obj-$(CONFIG_IPIC)		+= ipic.o
 obj-$(CONFIG_4xx)		+= uic.o
 obj-$(CONFIG_4xx_SOC)		+= ppc4xx_soc.o
-obj-$(CONFIG_XILINX_VIRTEX)	+= xilinx_intc.o
+obj-$(CONFIG_XILINX_VIRTEX)	+= xilinx_intc.o sdma.o
 obj-$(CONFIG_XILINX_PCI)	+= xilinx_pci.o
 obj-$(CONFIG_OF_RTC)		+= of_rtc.o
 ifeq ($(CONFIG_PCI),y)
diff --git a/arch/powerpc/sysdev/sdma.c b/arch/powerpc/sysdev/sdma.c
new file mode 100644
--- /dev/null
+++ b/arch/powerpc/sysdev/sdma.c
@@ -0,0 +1,751 @@
+/*
+ * SDMA subsystem support for Xilinx MPMC.
+ *
+ * Author: Sergey Temerkhanov
+ *
+ * Copyright (c) 2008-2010 Cifronic ZAO
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <asm/io.h>
+#include <asm/sdma.h>
+
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+
+#define DRV_VERSION "0.0.3"
+#define DRV_NAME "sdma"
+
+MODULE_AUTHOR ("Sergey Temerkhanov <temerkhanov@cifronik.ru>");
+MODULE_DESCRIPTION ("Xilinx SDMA driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+LIST_HEAD(mpmc_devs);
+DEFINE_MUTEX(mpmc_devs_lock);
+
+enum {
+	SDMA_TX_REGS	= 0x00,	/* TX channel registers beginning */
+	SDMA_RX_REGS	= 0x20,	/* RX channel registers beginning */
+	SDMA_DMACR	= 0x40,	/* DMA control register */
+
+	SDMA_NDESCR	= 0x00,	/* Next descriptor address */
+	SDMA_BUFA	= 0x04,	/* Current buffer address */
+	SDMA_BUFL	= 0x08,	/* Current buffer length */
+	SDMA_CDESCR	= 0x0C,	/* Current descriptor address */
+	SDMA_TDESCR	= 0x10,	/* Tail descriptor address */
+	SDMA_CR		= 0x14,	/* Channel control */
+	SDMA_IRQ	= 0x18,	/* Interrupt register */
+	SDMA_SR		= 0x1C,	/* Status */
+};
+
+enum {
+	SDMA_CR_IRQ_TIMEOUT_MSK	  = (0xFF << 24),	/* Interrupt coalesce timeout */
+	SDMA_CR_IRQ_THRESHOLD_MSK = (0xFF << 16),	/* Interrupt coalesce count */
+	SDMA_CR_MSB_ADDR_MSK	  = (0xF << 12),	/* MSB for 36 bit addressing */
+	SDMA_CR_APP_EN		  = (1 << 11),	/* Application data mask enable */
+	SDMA_CR_1_BIT_CNT	  = (1 << 10),	/* All interrupt counters are 1-bit */
+	SDMA_CR_INT_ON_END	  = (1 << 9),	/* Interrupt-on-end */
+	SDMA_CR_LD_IRQ_CNT	  = (1 << 8),	/* Load IRQ_COUNT */
+	SDMA_CR_IRQ_EN		  = (1 << 7),	/* Master interrupt enable */
+	SDMA_CR_IRQ_ERROR	  = (1 << 2),	/* Error interrupt enable */
+	SDMA_CR_IRQ_TIMEOUT	  = (1 << 1),	/* Coalesce timeout interrupt enable */
+	SDMA_CR_IRQ_THRESHOLD	  = (1 << 0),	/* Coalesce threshold interrupt enable */
+
+	SDMA_CR_IRQ_ALL		  = SDMA_CR_IRQ_EN | SDMA_CR_IRQ_ERROR |
+					SDMA_CR_IRQ_TIMEOUT | SDMA_CR_IRQ_THRESHOLD,
+
+	SDMA_CR_IRQ_TIMEOUT_SH	 = 24,
+	SDMA_CR_IRQ_THRESHOLD_SH = 16,
+	SDMA_CR_MSB_ADDR_SH	 = 12,
+
+	SDMA_IRQ_WRQ_EMPTY	= (1 << 14),	/* Write Command Queue Empty (rx) */
+	SDMA_IRQ_PLB_RD_ERROR	= (1 << 4),	/* PLB Read Error IRQ */
+	SDMA_IRQ_PLB_WR_ERROR	= (1 << 3),	/* PLB Write Error IRQ */
+	SDMA_IRQ_ERROR		= (1 << 2),	/* Error IRQ */
+	SDMA_IRQ_TIMEOUT	= (1 << 1),	/* Coalesce timeout IRQ */
+	SDMA_IRQ_THRESHOLD	= (1 << 0),	/* Coalesce threshold IRQ */
+
+	SDMA_IRQ_ALL_ERR	= 0x1C,		/* All error interrupt */
+	SDMA_IRQ_ALL		= 0x1F,		/* All interrupt bits */
+	SDMA_IRQ_ALL_DONE	= 0x3,		/* All work complete interrupt bits */
+
+
+#define SDMA_IRQ_COALESCE_COUNT(x)	((x >> 10) & 0xF)
+#define SDMA_IRQ_DELAY_COUNT(x)		((x >> 8) & 0x3)
+
+	SDMA_SR_ERR_TDESCR	= (1 << 21),	/* Tail descriptor pointer is invalid */
+	SDMA_SR_ERR_CMPL	= (1 << 20),	/* Complete bit is set */
+	SDMA_SR_ERR_BUFA	= (1 << 19),	/* Buffer address is invalid */
+	SDMA_SR_ERR_NDESCR	= (1 << 18),	/* Next descriptor pointer is invalid */
+	SDMA_SR_ERR_CDESCR	= (1 << 17),	/* Current descriptor pointer is invalid */
+	SDMA_SR_ERR_BUSYWR	= (1 << 16),	/* Current descriptor modified */
+	SDMA_SR_ERROR		= (1 << 7),	/* Error IRQ has occurred */
+	SDMA_SR_IRQ_ON_END	= (1 << 6),	/* On-end IRQ has occurred */
+	SDMA_SR_STOP_ON_END	= (1 << 5), 	/* Stop on end has occurred */
+	SDMA_SR_COMPLETED	= (1 << 4),	/* BD completed */
+	SDMA_SR_SOP		= (1 << 3),	/* Current BD has SOP set */
+	SDMA_SR_EOP		= (1 << 2),	/* Current BD has EOP set */
+	SDMA_SR_ENGINE_BUSY	= (1 << 1),	/* Channel is busy */
+	
+
+	SDMA_DMACR_TX_PAUSE	= (1 << 29),	/* Pause TX channel */
+	SDMA_DMACR_RX_PAUSE	= (1 << 28),	/* Pause RX channel */
+	SDMA_DMACR_PLB_ERR_DIS	= (1 << 5),	/* Disable PLB error detection */
+	SDMA_DMACR_RX_OVF_DIS	= (1 << 4),	/* Disable error on RX coalesce counter overflows */
+	SDMA_DMACR_TX_OVF_DIS	= (1 << 3),	/* Disable error on TX coalesce counter overflows */
+	SDMA_DMACR_TAIL_PTR_EN	= (1 << 2),	/* Enable use of tail pointer register */
+	SDMA_DMACR_EN_ARB_HOLD	= (1 << 1),	/* Enable arbitration hold */
+	SDMA_DMACR_RESET	= (1 << 0),	/* Reset both channels */
+};
+
+#if 1
+#  define debug(x...)	printk(KERN_DEBUG x)
+#else
+#  define debug(x...)
+#endif
+
+static inline void sdma_write_cr(struct sdma_device *sdma, u32 value)
+{
+	out_be32(sdma->ioaddr + SDMA_DMACR, value);
+}
+
+static inline u32 sdma_read_cr(struct sdma_device *sdma)
+{
+	return in_be32(sdma->ioaddr + SDMA_DMACR);
+}
+
+static inline void sdma_tx_out32(struct sdma_device *sdma, int reg, u32 value)
+{
+	out_be32(sdma->ioaddr + reg + SDMA_TX_REGS, value);
+}
+
+static inline u32 sdma_tx_in32(struct sdma_device *sdma, int reg)
+{
+	return in_be32(sdma->ioaddr + reg + SDMA_TX_REGS);
+}
+
+static inline void sdma_rx_out32(struct sdma_device *sdma, int reg, u32 value)
+{
+	out_be32(sdma->ioaddr + reg + SDMA_RX_REGS, value);
+}
+
+static inline u32 sdma_rx_in32(struct sdma_device *sdma, int reg)
+{
+	return in_be32(sdma->ioaddr + reg + SDMA_RX_REGS);
+}
+
+void sdma_reset(struct sdma_device *sdma)
+{
+	u32 rx_cr, tx_cr, rx_irq, tx_irq;
+
+	dma_addr_t curr_desc_rx;
+	dma_addr_t curr_desc_tx;
+	unsigned long flags;
+	struct sdma_client *client, *tmp;
+
+	DEFINE_SDMA_COALESCE(coal);
+	spin_lock_irqsave(&sdma->lock, flags);
+
+ 	curr_desc_rx= sdma_rx_in32(sdma, SDMA_CDESCR);
+	curr_desc_tx = sdma_tx_in32(sdma, SDMA_CDESCR);
+
+	sdma_write_cr(sdma, SDMA_DMACR_RESET);
+
+	while (sdma_read_cr(sdma) & SDMA_DMACR_RESET)
+		udelay(100);
+
+	rx_cr = sdma_rx_in32(sdma, SDMA_CR);
+	tx_cr = sdma_tx_in32(sdma, SDMA_CR);
+
+	sdma_rx_out32(sdma, SDMA_CR, rx_cr & ~SDMA_CR_IRQ_ALL);
+	sdma_tx_out32(sdma, SDMA_CR, tx_cr & ~SDMA_CR_IRQ_ALL);
+
+	rx_irq = sdma_rx_in32(sdma, SDMA_IRQ);
+	tx_irq = sdma_tx_in32(sdma, SDMA_IRQ);
+
+	sdma_rx_out32(sdma, SDMA_IRQ, rx_irq);
+	sdma_tx_out32(sdma, SDMA_IRQ, tx_irq);
+
+	sdma_write_cr(sdma, SDMA_DMACR_TAIL_PTR_EN |
+		SDMA_DMACR_RX_OVF_DIS | SDMA_DMACR_TX_OVF_DIS);
+
+	sdma_rx_out32(sdma, SDMA_CR, rx_cr | (SDMA_CR_IRQ_ALL & ~SDMA_CR_IRQ_EN));
+	sdma_tx_out32(sdma, SDMA_CR, tx_cr | (SDMA_CR_IRQ_ALL & ~SDMA_CR_IRQ_EN));
+
+	rx_cr = sdma_rx_in32(sdma, SDMA_CR);
+	sdma_rx_out32(sdma, SDMA_CR, rx_cr | SDMA_CR_IRQ_EN);
+	tx_cr = sdma_tx_in32(sdma, SDMA_CR);
+	sdma_tx_out32(sdma, SDMA_CR, tx_cr | SDMA_CR_IRQ_EN);
+
+	spin_unlock_irqrestore(&sdma->lock, flags);
+
+	list_for_each_entry_safe(client, tmp, &sdma->clients, item)
+		if (likely(client->reset))
+			client->reset(client->data);
+
+	sdma_set_coalesce(sdma, &coal);
+}
+
+void sdma_tx_irq_enable(struct sdma_device *sdma)
+{
+	u32 tx_cr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdma->lock, flags);
+	tx_cr = sdma_tx_in32(sdma, SDMA_CR);
+	sdma_tx_out32(sdma, SDMA_CR, tx_cr | SDMA_CR_IRQ_EN);
+	spin_unlock_irqrestore(&sdma->lock, flags);
+}
+
+void sdma_rx_irq_enable(struct sdma_device *sdma)
+{
+	u32 rx_cr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdma->lock, flags);
+	rx_cr = sdma_rx_in32(sdma, SDMA_CR);
+	sdma_rx_out32(sdma, SDMA_CR, rx_cr | SDMA_CR_IRQ_EN);
+	spin_unlock_irqrestore(&sdma->lock, flags);
+}
+
+void sdma_tx_irq_disable(struct sdma_device *sdma)
+{
+	u32 tx_cr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdma->lock, flags);
+	tx_cr = sdma_tx_in32(sdma, SDMA_CR);
+	sdma_tx_out32(sdma, SDMA_CR, tx_cr & ~SDMA_CR_IRQ_EN);
+	spin_unlock_irqrestore(&sdma->lock, flags);
+}
+
+void sdma_rx_irq_disable(struct sdma_device *sdma)
+{
+	u32 rx_cr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdma->lock, flags);
+	rx_cr = sdma_rx_in32(sdma, SDMA_CR);
+	sdma_rx_out32(sdma, SDMA_CR, rx_cr & ~SDMA_CR_IRQ_EN);
+	spin_unlock_irqrestore(&sdma->lock, flags);
+}
+
+void sdma_tx_irq_ack(struct sdma_device *sdma)
+{
+	u32 irq_stat;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdma->lock, flags);
+	irq_stat = sdma_tx_in32(sdma, SDMA_IRQ);
+	sdma_tx_out32(sdma, SDMA_IRQ, irq_stat & SDMA_IRQ_ALL_DONE);
+	spin_unlock_irqrestore(&sdma->lock, flags);
+}
+
+void sdma_rx_irq_ack(struct sdma_device *sdma)
+{
+	u32 irq_stat;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdma->lock, flags);
+	irq_stat = sdma_rx_in32(sdma, SDMA_IRQ);
+	sdma_rx_out32(sdma, SDMA_IRQ, irq_stat & SDMA_IRQ_ALL_DONE);
+	spin_unlock_irqrestore(&sdma->lock, flags);
+}
+
+void sdma_pause(struct sdma_device *sdma)
+{
+	u32 dmacr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdma->lock, flags);
+	dmacr = sdma_read_cr(sdma);
+	dmacr |= SDMA_DMACR_TX_PAUSE | SDMA_DMACR_RX_PAUSE;
+	sdma_write_cr(sdma, dmacr);
+	spin_unlock_irqrestore(&sdma->lock, flags);
+}
+
+void sdma_resume(struct sdma_device *sdma)
+{
+	u32 dmacr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdma->lock, flags);
+	dmacr = sdma_read_cr(sdma);
+	dmacr &= ~(SDMA_DMACR_TX_PAUSE | SDMA_DMACR_RX_PAUSE);
+	sdma_write_cr(sdma, dmacr);
+	spin_unlock_irqrestore(&sdma->lock, flags);
+}
+
+int sdma_set_coalesce(struct sdma_device *sdma, struct sdma_coalesce *coal)
+{
+	u32 tx_cr, rx_cr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdma->lock, flags);
+
+	tx_cr = sdma_tx_in32(sdma, SDMA_CR);
+	rx_cr = sdma_rx_in32(sdma, SDMA_CR);
+
+	if (coal->tx_timeout > 255 ||
+	    coal->rx_timeout > 255 ||
+	    coal->tx_threshold > 255 ||
+	    coal->rx_threshold > 255)
+		return -EINVAL;
+
+	if (coal->tx_timeout == 0) {
+		coal->tx_timeout = 1;
+		tx_cr &= ~SDMA_CR_IRQ_TIMEOUT;
+	} else {
+		tx_cr |= SDMA_CR_IRQ_TIMEOUT;
+	}
+
+	if (coal->rx_timeout == 0) {
+		coal->rx_timeout = 1;
+		rx_cr &= ~SDMA_CR_IRQ_TIMEOUT;
+	} else {
+		rx_cr |= SDMA_CR_IRQ_TIMEOUT;
+	}
+
+	tx_cr &= ~(SDMA_CR_IRQ_THRESHOLD_MSK | SDMA_CR_IRQ_TIMEOUT_SH);
+	tx_cr |= (coal->tx_threshold << SDMA_CR_IRQ_THRESHOLD_SH) & SDMA_CR_IRQ_THRESHOLD_MSK;
+	tx_cr |= (coal->tx_timeout << SDMA_CR_IRQ_TIMEOUT_SH) & SDMA_CR_IRQ_TIMEOUT_MSK;
+	tx_cr |= SDMA_CR_LD_IRQ_CNT;
+
+
+	rx_cr &= ~(SDMA_CR_IRQ_THRESHOLD_MSK | SDMA_CR_IRQ_TIMEOUT_SH);
+	rx_cr |= (coal->rx_threshold << SDMA_CR_IRQ_THRESHOLD_SH) & SDMA_CR_IRQ_THRESHOLD_MSK;
+	rx_cr |= (coal->rx_timeout << SDMA_CR_IRQ_TIMEOUT_SH) & SDMA_CR_IRQ_TIMEOUT_MSK;
+	rx_cr |= SDMA_CR_LD_IRQ_CNT;
+
+	sdma_tx_out32(sdma, SDMA_CR, tx_cr);
+	sdma_rx_out32(sdma, SDMA_CR, rx_cr);
+
+	spin_unlock_irqrestore(&sdma->lock, flags);
+
+	return 0;
+}
+
+int sdma_get_coalesce(struct sdma_device *sdma, struct sdma_coalesce *coal)
+{
+	u32 tx_cr, rx_cr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdma->lock, flags);
+
+	tx_cr = sdma_tx_in32(sdma, SDMA_CR);
+	rx_cr = sdma_rx_in32(sdma, SDMA_CR);
+
+	coal->tx_threshold = (tx_cr & SDMA_CR_IRQ_THRESHOLD_MSK) >> SDMA_CR_IRQ_THRESHOLD_SH;
+	coal->tx_timeout = (tx_cr & SDMA_CR_IRQ_TIMEOUT_MSK) >> SDMA_CR_IRQ_TIMEOUT_SH;
+
+	coal->rx_threshold = (rx_cr & SDMA_CR_IRQ_THRESHOLD_MSK) >> SDMA_CR_IRQ_THRESHOLD_SH;
+	coal->rx_timeout = (rx_cr & SDMA_CR_IRQ_TIMEOUT_MSK) >> SDMA_CR_IRQ_TIMEOUT_SH;
+
+	if (!(tx_cr & SDMA_CR_IRQ_TIMEOUT))
+		coal->tx_timeout = 0;
+
+	if (!(rx_cr & SDMA_CR_IRQ_TIMEOUT))
+		coal->rx_timeout = 0;
+
+	spin_unlock_irqrestore(&sdma->lock, flags);
+
+	return 0;
+}
+
+int sdma_tx_submit(struct sdma_device *sdma, dma_addr_t desc)
+{
+	sdma_tx_out32(sdma, SDMA_TDESCR, desc);
+	return 0;
+}
+
+int sdma_rx_submit(struct sdma_device *sdma, dma_addr_t desc)
+{
+	sdma_rx_out32(sdma, SDMA_TDESCR, desc);
+	return 0;
+}
+
+void sdma_tx_init(struct sdma_device *sdma, dma_addr_t desc)
+{
+	sdma_tx_out32(sdma, SDMA_CDESCR, desc);
+	sdma_tx_out32(sdma, SDMA_TDESCR, desc);
+}
+
+void sdma_rx_init(struct sdma_device *sdma, dma_addr_t desc)
+{
+	sdma_rx_out32(sdma, SDMA_CDESCR, desc);
+	sdma_rx_out32(sdma, SDMA_TDESCR, desc);
+}
+
+
+struct sdma_device *sdma_find_device(int phandle)
+{
+	struct mpmc_device *mpmc;
+	struct sdma_device *sdma = NULL;
+	int found = 0;
+	mutex_lock(&mpmc_devs_lock);
+	list_for_each_entry(mpmc, &mpmc_devs, item) {
+		mutex_lock(&mpmc->devs_lock);
+		list_for_each_entry(sdma, &mpmc->sdma_devs, item) {
+			if (sdma->phandle == phandle) {
+				found = 1;
+				break;
+			}
+		}
+		mutex_unlock(&mpmc->devs_lock);
+		if (found)
+			break;
+		else
+			sdma = NULL;
+	}
+	mutex_unlock(&mpmc_devs_lock);
+	return sdma;
+}
+
+EXPORT_SYMBOL_GPL(sdma_find_device);
+EXPORT_SYMBOL_GPL(sdma_tx_submit);
+EXPORT_SYMBOL_GPL(sdma_rx_submit);
+EXPORT_SYMBOL_GPL(sdma_set_coalesce);
+EXPORT_SYMBOL_GPL(sdma_get_coalesce);
+EXPORT_SYMBOL_GPL(sdma_pause);
+EXPORT_SYMBOL_GPL(sdma_resume);
+EXPORT_SYMBOL_GPL(sdma_reset);
+EXPORT_SYMBOL_GPL(sdma_rx_init);
+EXPORT_SYMBOL_GPL(sdma_tx_init);
+EXPORT_SYMBOL_GPL(sdma_rx_irq_disable);
+EXPORT_SYMBOL_GPL(sdma_tx_irq_disable);
+EXPORT_SYMBOL_GPL(sdma_rx_irq_enable);
+EXPORT_SYMBOL_GPL(sdma_tx_irq_enable);
+EXPORT_SYMBOL_GPL(sdma_rx_irq_ack);
+EXPORT_SYMBOL_GPL(sdma_tx_irq_ack);
+
+static irqreturn_t sdma_rx_intr(int irq, void *dev_id)
+{
+	u32 irq_ack, status;
+	struct sdma_device *sdma = dev_id;
+	struct sdma_client *client, *tmp;
+
+	/* Read pending interrupts */
+	status = sdma_rx_in32(sdma, SDMA_IRQ);
+	irq_ack = status;
+	irq_ack &= sdma->rx_ack ? SDMA_IRQ_ALL : SDMA_IRQ_ALL_ERR;
+	sdma_rx_out32(sdma, SDMA_IRQ, irq_ack);
+
+	if (unlikely(status & SDMA_IRQ_ALL_ERR)) {
+		printk("%s: error status: %08x\n", __func__, status);
+		sdma_reset(sdma);
+		list_for_each_entry_safe(client, tmp, &sdma->clients, item)
+			if (likely(client->error))
+				client->error(client->data);
+		return IRQ_HANDLED;
+	}
+
+	if (likely(status & SDMA_IRQ_ALL_DONE)) {
+		list_for_each_entry_safe(client, tmp, &sdma->clients, item)
+			if (likely(client->rx_complete))
+				client->rx_complete(client->data);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t sdma_tx_intr(int irq, void *dev_id)
+{
+	u32 irq_ack, status;
+	struct sdma_device *sdma = dev_id;
+	struct sdma_client *client, *tmp;
+
+	/* Read pending interrupts */
+	status = sdma_tx_in32(sdma, SDMA_IRQ);
+	irq_ack = status;
+	irq_ack &= sdma->tx_ack ? SDMA_IRQ_ALL : SDMA_IRQ_ALL_ERR;
+	sdma_tx_out32(sdma, SDMA_IRQ, irq_ack);
+
+	if (unlikely(status & SDMA_IRQ_ALL_ERR)) {
+		printk("%s: error status: %08x\n", __func__, status);
+		sdma_reset(sdma);
+		list_for_each_entry_safe(client, tmp, &sdma->clients, item)
+			if (likely(client->error))
+				client->error(client->data);
+		return IRQ_HANDLED;
+	}
+
+	if (likely(status & SDMA_IRQ_ALL_DONE)) {
+		list_for_each_entry_safe(client, tmp, &sdma->clients, item)
+			if (likely(client->tx_complete))
+				client->tx_complete(client->data);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void sdma_dev_register(struct mpmc_device *mpmc, struct sdma_device *sdma)
+{
+	mutex_lock(&mpmc->devs_lock);
+	list_add(&sdma->item, &mpmc->sdma_devs);
+	mutex_unlock(&mpmc->devs_lock);
+}
+
+static void sdma_dev_unregister(struct sdma_device *sdma)
+{
+	struct mpmc_device *mpmc = sdma->parent;
+
+	mutex_lock(&mpmc->devs_lock);
+	list_del(&sdma->item);
+	mutex_unlock(&mpmc->devs_lock);
+}
+
+static int sdma_of_remove(struct of_device* op)
+{
+	struct sdma_device *sdma = dev_get_drvdata(&op->dev);
+
+	if (sdma->tx_irq)
+		free_irq(sdma->tx_irq, sdma);
+
+	if (sdma->rx_irq)
+		free_irq(sdma->rx_irq, sdma);
+
+	if (sdma->memregion.start)
+		release_mem_region(sdma->memregion.start,
+			sdma->memregion.end - sdma->memregion.start + 1);
+
+	if (sdma->ioaddr)
+		iounmap(sdma->ioaddr);
+
+	sdma_dev_unregister(sdma);
+
+	kfree(sdma);
+
+	dev_set_drvdata(&op->dev, NULL);
+
+	return 0;
+}
+
+/* Match table for of_platform binding */
+static struct of_device_id sdma_of_match[] = {
+	{ .compatible = "xlnx,ll-dma-1.00.a" },
+	{},
+};
+
+static int __devinit sdma_of_probe(struct of_device *op, const struct of_device_id *match)
+{
+	struct sdma_device *sdma;
+	struct mpmc_device *mpmc;
+
+	const int *prop;
+	struct resource rx_irq, tx_irq, mem;
+	int res;
+
+	mpmc = dev_get_drvdata(op->dev.parent);
+
+	sdma = kzalloc(sizeof(struct sdma_device), GFP_KERNEL);
+
+	dev_set_drvdata(&op->dev, sdma);
+
+	spin_lock_init(&sdma->lock);
+
+	if (!sdma) {
+		dev_err(&op->dev, "Cannot allocate SDMA device\n");
+		return -ENOMEM;
+	}
+
+	res = of_address_to_resource(op->node, 0, &mem);
+	if(res) {
+		dev_err(&op->dev, "invalid address\n");
+		return res;
+	}
+
+	INIT_LIST_HEAD(&sdma->clients);
+	mutex_init(&sdma->clients_lock);
+	sdma->parent = mpmc;
+	/* IRQ */
+	res = of_irq_to_resource(op->node, 0, &rx_irq);
+	if(res == NO_IRQ) {
+		dev_err(&op->dev, "no RX IRQ assigned.\n");
+		return res;
+	}
+
+	res = of_irq_to_resource(op->node, 1, &tx_irq);
+	if(res == NO_IRQ) {
+		dev_err(&op->dev, "no TX IRQ assigned.\n");
+		return res;
+	}
+
+	prop = of_get_property(op->node, "linux,phandle", NULL);
+	sdma->phandle = (prop) ? *prop : -1;
+
+	if(!request_mem_region(mem.start, mem.end - mem.start + 1, DRV_NAME)) {
+		dev_err(&op->dev, "I/O memory region at %p is busy\n", (void *)mem.start);
+		sdma_of_remove(op);
+		return -EBUSY;
+	}
+
+	sdma->memregion = mem;
+	sdma->ioaddr = ioremap(mem.start, mem.end - mem.start + 1);
+
+	if (!sdma->ioaddr) {
+		dev_err(&op->dev, "Cannot ioremap() I/O memory %p\n", (void*)mem.start);
+		sdma_of_remove(op);
+		return -ENOMEM;
+	}
+
+	sdma_reset(sdma);
+
+	res = request_irq(rx_irq.start, sdma_rx_intr,
+			IRQF_SHARED, "SDMA RX", sdma);
+	if (res) {
+		dev_err(&op->dev, "Could not allocate RX interrupt %d.\n", rx_irq.start);
+		sdma_of_remove(op);
+		return res;
+	}
+
+	sdma->rx_irq = rx_irq.start;
+
+	res = request_irq(tx_irq.start, sdma_tx_intr,
+			IRQF_SHARED, "SDMA TX", sdma);
+	if (res) {
+		dev_err(&op->dev, "Could not allocate TX interrupt %d.\n", tx_irq.start);
+		sdma_of_remove(op);
+		return res;
+	}
+
+	sdma->tx_irq = tx_irq.start;
+
+	sdma->rx_ack = 1;
+	sdma->tx_ack = 1;
+	sdma_dev_register(mpmc, sdma);
+
+	return 0;
+}
+
+static struct of_platform_driver sdma_of_driver = {
+	.name		= "xilinx-sdma",
+	.match_table	= sdma_of_match,
+	.probe		= sdma_of_probe,
+	.remove		= sdma_of_remove,
+};
+
+int __init sdma_of_init(void)
+{
+	int ret;
+
+	ret = of_register_platform_driver(&sdma_of_driver);
+	if (ret) {
+		of_unregister_platform_driver(&sdma_of_driver);
+		printk(KERN_ERR "registering driver failed: err=%i", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+void sdma_of_exit(void)
+{
+	of_unregister_platform_driver(&sdma_of_driver);
+}
+
+
+static void mpmc_dev_register(struct mpmc_device *mpmc)
+{
+	mutex_lock(&mpmc_devs_lock);
+	list_add_tail(&mpmc->item, &mpmc_devs);
+	mutex_unlock(&mpmc_devs_lock);
+}
+
+static void mpmc_dev_unregister(struct mpmc_device *mpmc)
+{
+	mutex_lock(&mpmc_devs_lock);
+	list_del(&mpmc->item);
+	mutex_unlock(&mpmc_devs_lock);
+}
+
+static int mpmc_of_remove(struct of_device *op)
+{
+	struct mpmc_device *mpmc = dev_get_drvdata(&op->dev);
+	struct device_node *node;
+	struct of_device *ofdev;
+	
+	for_each_child_of_node(op->node, node) {
+		ofdev = of_find_device_by_node(node);
+		of_device_unregister(ofdev);
+		of_device_free(ofdev);
+	}
+
+	if (mpmc->registered)
+		mpmc_dev_unregister(mpmc);
+
+	kfree(mpmc);
+	dev_set_drvdata(&op->dev, NULL);
+	return 0;
+}
+
+static int __devinit mpmc_of_probe(struct of_device *op,
+			const struct of_device_id *match)
+{
+	struct mpmc_device *mpmc;
+
+	mpmc = kzalloc(sizeof(struct mpmc_device), GFP_KERNEL);
+
+	if (!mpmc) {
+		dev_err(&op->dev, "Cannot allocate MPMC device\n");
+		return -ENOMEM;
+	}
+
+	dev_set_drvdata(&op->dev, mpmc);
+
+	INIT_LIST_HEAD(&mpmc->sdma_devs);
+	mutex_init(&mpmc->devs_lock);
+
+	mpmc_dev_register(mpmc);
+
+	mpmc->registered = 1;
+
+	of_platform_bus_probe(op->node, sdma_of_match, &op->dev);
+
+	return 0;
+}
+
+static struct of_device_id  __devinitdata mpmc_of_match[] = {
+	{ .compatible = "xlnx,mpmc-4.01.a" },
+	{ .compatible = "xlnx,mpmc-4.03.a" },
+	{},
+};
+
+static struct of_platform_driver mpmc_of_driver = {
+	.name = "xilinx-mpmc",
+	.match_table = mpmc_of_match,
+	.probe = mpmc_of_probe,
+	.remove	= mpmc_of_remove,
+};
+
+int __init mpmc_of_init(void)
+{
+	return of_register_platform_driver(&mpmc_of_driver);
+}
+
+void mpmc_cleanup(void)
+{
+}
+
+void mpmc_of_exit(void)
+{
+	mpmc_cleanup();
+	of_unregister_platform_driver(&mpmc_of_driver);
+}
+
+subsys_initcall(mpmc_of_init);
+subsys_initcall(sdma_of_init);

^ permalink raw reply

* Re: Freescale MPC5554 device tree (was: cross-compiling Linux for PowerPC e200 core?)
From: Németh Márton @ 2010-03-17 18:12 UTC (permalink / raw)
  To: Grant Likely, David Gibson, Segher Boessenkool; +Cc: linuxppc-dev Development
In-Reply-To: <4B9B7E0A.8090703@freemail.hu>

Hi Grant, David and Segher,

is there any comments or suggestions about this MPC5554 device tree?

Regards,

	Márton Németh

Németh Márton wrote:
> Hi,
> 
> here is a version with modified cpu node, xbar ranges and added interrupt sources.
> Please send comments.
> 
> Regards,
> 
> 	Márton Németh
> 
> ---
> From: Márton Németh <nm127@freemail.hu>
> 
> Add device tree for Freescale MPC5554.
> 
> Signed-off-by: Márton Németh <nm127@freemail.hu>
> ---
> diff -uprN linux-2.6.33.orig/arch/powerpc/boot/dts/mpc5554.dts linux/arch/powerpc/boot/dts/mpc5554.dts
> --- linux-2.6.33.orig/arch/powerpc/boot/dts/mpc5554.dts	1970-01-01 01:00:00.000000000 +0100
> +++ linux/arch/powerpc/boot/dts/mpc5554.dts	2010-03-13 12:52:32.000000000 +0100
> @@ -0,0 +1,473 @@
> +/*
> + * Freescale MPC5554 Device Tree Source
> + *
> + * Based on MPC5553/5554 Microcontroller Reference Manual, Rev. 4.0, 04/2007
> + * http://www.freescale.com/files/32bit/doc/ref_manual/MPC5553_MPC5554_RM.pdf
> + *  - Block Diagram: page 1-3, Figure 1-1
> + *  - Memory Map: page 1-21, Table 1-2
> + *  - Interrupt Request Sources: page 10-16, Table 10-9
> + *
> + * Copyright 2010 Márton Németh
> + * Márton Németh <nm127@freemail.hu>
> + *
> + * This program is free software; you can redistribute  it and/or modify it
> + * under  the terms of  the GNU General  Public License as published by the
> + * Free Software Foundation;  either version 2 of the  License, or (at your
> + * option) any later version.
> + */
> +
> +/dts-v1/;
> +
> +/ {
> +	model = "MPC5554";
> +	compatible = "fsl,MPC5554EVB";		// Freescale MPC5554 Evaluation Board
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	interrupt-parent = <&intc>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu@0 {
> +			device_type = "cpu";
> +			compatible = "PowerPC,5554", "fsl,mpc5554-e200z6", "fsl,powerpc-e200z6";
> +			reg = <0>;
> +			d-cache-line-size = <32>;
> +			i-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;	// L1, 32KiB
> +			i-cache-size = <0x8000>;	// L1, 32KiB
> +			timebase-frequency = <0>;	// from bootloader
> +			bus-frequency = <0>;		// from bootloader
> +			clock-frequency = <0>;		// from bootloader
> +		};
> +	};
> +
> +	memory@40000000 {
> +		device_type = "memory";
> +		reg = <0x40000000 0x10000>;	// 32KiB internal SRAM
> +	};
> +
> +	xbar@fff04000 {		// System Bus Crossbar Switch (XBAR)
> +		compatible = "fsl,mpc5554-xbar";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		// The full memory range is covered by XBAR
> +		ranges;
> +		reg = <0xfff04000 0x4000>;
> +
> +		flash@0 {	// read-only FLASH
> +			compatible = "fsl,mpc5554-flash";
> +			reg = <0x00000000 0x200000>;	// 2MiB internal FLASH
> +		};
> +
> +		bridge@c3f00000 {
> +			compatible = "fsl,mpc5554-pbridge-a";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0 0xc0000000 0x20000000>;
> +			reg = <0xc3f00000 0x4000>;
> +
> +			fmpll@3f80000 {		// Frequency Modulated PLL
> +				compatible = "fsl,mpc5554-fmpll";
> +				reg = <0x03f80000 0x4000>;
> +				interrupts = <43 1	// Loss of Clock
> +					      44 1>;	// Loss of Lock
> +			};
> +
> +			flashconfig@3f88000 {	// Flash Configuration
> +				compatible = "fsl,mpc5554-flashconfig";
> +				reg = <0x03f88000 0x4000>;
> +			};
> +
> +			siu@3f89000 {		// System Integration Unit
> +				compatible = "fsl,mpc5554-siu";
> +				reg = <0x03f90000 0x4000>;
> +				interrupts = <45 1	// External Interrupt Overrun 0-15
> +					      46 1	// External Interrupt 0
> +					      47 1	// External Interrupt 1
> +					      48 1	// External Interrupt 2
> +					      49 1	// External Interrupt 3
> +					      50 1>;	// External Interrupt 4-15
> +			};
> +
> +			emios@3fa0000 {		// Modular Timer System
> +				compatible = "fsl,mpc5554-emios";
> +				reg = <0x03fa0000 0x4000>;
> +				interrupts = <51 1	// Channel 0
> +					      52 1	// Channel 1
> +					      53 1	// Channel 2
> +					      54 1	// Channel 3
> +					      55 1	// Channel 4
> +					      56 1	// Channel 5
> +					      57 1	// Channel 6
> +					      58 1	// Channel 7
> +					      59 1	// Channel 8
> +					      60 1	// Channel 9
> +					      61 1	// Channel 10
> +					      62 1	// Channel 11
> +					      63 1	// Channel 12
> +					      64 1	// Channel 13
> +					      65 1	// Channel 14
> +					      66 1	// Channel 15
> +					      202 1	// Channel 16
> +					      203 1	// Channel 17
> +					      204 1	// Channel 18
> +					      205 1	// Channel 19
> +					      206 1	// Channel 20
> +					      207 1	// Channel 21
> +					      208 1	// Channel 22
> +					      209 1>;	// Channel 23
> +			};
> +
> +			etpu@3fc0000 {		// Enhanced Time Processing Unit
> +				compatible = "fsl,mpc5554-etpu";
> +				reg = <0x03fc0000 0x4000>;
> +				interrupts = <67 1	// Global Exception
> +					      68 1	// A Channel 0
> +					      69 1	// A Channel 1
> +					      70 1	// A Channel 2
> +					      71 1	// A Channel 3
> +					      72 1	// A Channel 4
> +					      73 1	// A Channel 5
> +					      74 1	// A Channel 6
> +					      75 1	// A Channel 7
> +					      76 1	// A Channel 8
> +					      77 1	// A Channel 9
> +					      78 1	// A Channel 10
> +					      79 1	// A Channel 11
> +					      80 1	// A Channel 12
> +					      81 1	// A Channel 13
> +					      82 1	// A Channel 14
> +					      83 1	// A Channel 15
> +					      84 1	// A Channel 16
> +					      85 1	// A Channel 17
> +					      86 1	// A Channel 18
> +					      87 1	// A Channel 19
> +					      88 1	// A Channel 20
> +					      89 1	// A Channel 21
> +					      90 1	// A Channel 22
> +					      91 1	// A Channel 23
> +					      92 1	// A Channel 24
> +					      93 1	// A Channel 25
> +					      94 1	// A Channel 26
> +					      95 1	// A Channel 27
> +					      96 1	// A Channel 28
> +					      97 1	// A Channel 29
> +					      98 1	// A Channel 30
> +					      99 1	// A Channel 31
> +					      243 1	// B Channel 0
> +					      244 1	// B Channel 1
> +					      245 1	// B Channel 2
> +					      246 1	// B Channel 3
> +					      247 1	// B Channel 4
> +					      248 1	// B Channel 5
> +					      249 1	// B Channel 6
> +					      250 1	// B Channel 7
> +					      251 1	// B Channel 8
> +					      252 1	// B Channel 9
> +					      253 1	// B Channel 10
> +					      254 1	// B Channel 11
> +					      255 1	// B Channel 12
> +					      256 1	// B Channel 13
> +					      257 1	// B Channel 14
> +					      258 1	// B Channel 15
> +					      259 1	// B Channel 16
> +					      260 1	// B Channel 17
> +					      261 1	// B Channel 18
> +					      262 1	// B Channel 19
> +					      263 1	// B Channel 20
> +					      264 1	// B Channel 21
> +					      265 1	// B Channel 22
> +					      266 1	// B Channel 23
> +					      267 1	// B Channel 24
> +					      268 1	// B Channel 25
> +					      269 1	// B Channel 26
> +					      270 1	// B Channel 27
> +					      271 1	// B Channel 28
> +					      272 1	// B Channel 29
> +					      273 1	// B Channel 30
> +					      274 1>;	// B Channel 31
> +			};
> +
> +			etpudata@3fc8000 {	// eTPU Shared Data Memory (Parameter RAM)
> +				compatible = "fsl,mpc5554-etpudata";
> +				reg = <0x03fc8000 0x4000>;
> +			};
> +
> +			etpudata@3fcc000 {	// eTPU Shared Data Memory (Parameter RAM) mirror
> +				compatible = "fsl,mpc5554-etpudata";
> +				reg = <0x03fcc000 0x4000>;
> +			};
> +
> +			etpucode@3fd0000 {		// eTPU Shared Code RAM
> +				compatible = "fsl,mpc5554-etpucode";
> +				reg = <0x03fd0000 0x4000>;
> +			};
> +		};
> +
> +		bridge@fff00000 {
> +			compatible = "fsl,mpc5554-pbridge-b";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0 0xe0000000 0x20000000>;
> +			reg = <0xfff00000 0x4000>;
> +
> +			ecsm@fff40000 {		// Error Correction Status Module (ECSM)
> +				compatible = "fsl,mpc5554-ecsm";
> +				reg = <0xfff40000 0x4000>;
> +				interrupts = <8 1	// Software Watchdog Interrupt
> +					      9 1>;	// Combined: Internal SRAM Non-Correctable Error, Flash Non-Correctable Error
> +			};
> +
> +			edma@fff44000 {		// Enhanced DMA Controller (eDMA)
> +				compatible = "fsl,mpc5554-edma";
> +				reg = <0xfff44000 0x4000>;
> +				interrupts = <10 1	// Channel Error 0-31
> +					      11 1	// Channel 0
> +					      12 1	// Channel 1
> +					      13 1	// Channel 2
> +					      14 1	// Channel 3
> +					      15 1	// Channel 4
> +					      16 1	// Channel 5
> +					      17 1	// Channel 6
> +					      18 1	// Channel 7
> +					      19 1	// Channel 8
> +					      20 1	// Channel 9
> +					      21 1	// Channel 10
> +					      22 1	// Channel 11
> +					      23 1	// Channel 12
> +					      24 1	// Channel 13
> +					      25 1	// Channel 14
> +					      26 1	// Channel 15
> +					      27 1	// Channel 16
> +					      28 1	// Channel 17
> +					      29 1	// Channel 18
> +					      30 1	// Channel 19
> +					      31 1	// Channel 20
> +					      32 1	// Channel 21
> +					      33 1	// Channel 22
> +					      34 1	// Channel 23
> +					      35 1	// Channel 24
> +					      36 1	// Channel 25
> +					      37 1	// Channel 26
> +					      38 1	// Channel 27
> +					      39 1	// Channel 28
> +					      40 1	// Channel 29
> +					      41 1	// Channel 30
> +					      42 1	// Channel 31
> +					      210 1	// Channel Error 32-63
> +					      211 1	// Channel 32
> +					      212 1	// Channel 33
> +					      213 1	// Channel 34
> +					      214 1	// Channel 35
> +					      215 1	// Channel 36
> +					      216 1	// Channel 37
> +					      217 1	// Channel 38
> +					      218 1	// Channel 39
> +					      219 1	// Channel 40
> +					      220 1	// Channel 41
> +					      221 1	// Channel 42
> +					      222 1	// Channel 43
> +					      223 1	// Channel 44
> +					      224 1	// Channel 45
> +					      225 1	// Channel 46
> +					      226 1	// Channel 47
> +					      227 1	// Channel 48
> +					      228 1	// Channel 49
> +					      229 1	// Channel 50
> +					      230 1	// Channel 51
> +					      231 1	// Channel 52
> +					      232 1	// Channel 53
> +					      233 1	// Channel 54
> +					      234 1	// Channel 55
> +					      235 1	// Channel 56
> +					      236 1	// Channel 57
> +					      237 1	// Channel 58
> +					      238 1	// Channel 59
> +					      239 1	// Channel 60
> +					      240 1	// Channel 61
> +					      241 1	// Channel 62
> +					      242 1>;	// Channel 63
> +			};
> +
> +			intc: intc@fff48000 {		// Interrupt Controller (INTC)
> +				compatible = "fsl,mpc5554-intc";
> +				interrupt-controller;
> +				#interrupt-cells = <2>;
> +				reg = <0xfff48000 0x4000>;
> +			};
> +
> +			eqadc@fff80000 {	// Enhanced Queued Analog-to-Digital Converter (eQADC)
> +				compatible = "fsl,mpc5554-eqacd";
> +				reg = <0xfff80000 0x4000>;
> +				interrupts = <100 1	// Combined: Trigger Overrun, Receive FIFO Overflow, Command FIFO Underflow
> +					      101 1	// Command FIFO 0 Non-Coherency
> +					      102 1	// Command FIFO 0 Pause
> +					      103 1	// Command FIFO 0 End of Queue
> +					      104 1	// Command FIFO 0 Fill
> +					      105 1	// Command FIFO 0 Drain
> +					      106 1	// Command FIFO 1 Non-Coherency
> +					      107 1	// Command FIFO 1 Pause
> +					      108 1	// Command FIFO 1 End of Queue
> +					      109 1	// Command FIFO 1 Fill
> +					      111 1	// Command FIFO 1 Drain
> +					      111 1	// Command FIFO 2 Non-Coherency
> +					      112 1	// Command FIFO 2 Pause
> +					      113 1	// Command FIFO 2 End of Queue
> +					      114 1	// Command FIFO 2 Fill
> +					      115 1	// Command FIFO 2 Drain
> +					      116 1	// Command FIFO 3 Non-Coherency
> +					      117 1	// Command FIFO 3 Pause
> +					      118 1	// Command FIFO 3 End of Queue
> +					      119 1	// Command FIFO 3 Fill
> +					      120 1	// Command FIFO 3 Drain
> +					      121 1	// Command FIFO 4 Non-Coherency
> +					      122 1	// Command FIFO 4 Pause
> +					      123 1	// Command FIFO 4 End of Queue
> +					      124 1	// Command FIFO 4 Fill
> +					      125 1	// Command FIFO 4 Drain
> +					      126 1	// Command FIFO 5 Non-Coherency
> +					      127 1	// Command FIFO 5 Pause
> +					      128 1	// Command FIFO 5 End of Queue
> +					      129 1	// Command FIFO 5 Fill
> +					      130 1>;	// Command FIFO 5 Drain
> +			};
> +
> +			dspi@fff90000 {		// Deserial Serial Peripheral Interface (DSPI_A)
> +				compatible = "fsl,mpc5554-dspi";
> +				reg = <0xfff90000 0x4000>;
> +				interrupts = <275 1	// Combined: Transmit FIFO Underflow, Receive FIFO Overflow
> +					      276 1	// Transmit FIFO End of Queue
> +					      277 1	// Transmit FIFO Fill Flag
> +					      278 1	// Transfer Complete
> +					      279 1>;	// Receive FIFO Drain
> +			};
> +
> +			dspi@fff94000 {		// Deserial Serial Peripheral Interface (DSPI_B)
> +				compatible = "fsl,mpc5554-dspi";
> +				reg = <0xfff94000 0x4000>;
> +				interrupts = <131 1	// Combined: Transmit FIFO Underflow, Receive FIFO Overflow
> +					      132 1	// Transmit FIFO End of Queue
> +					      133 1	// Transmit FIFO Fill Flag
> +					      134 1	// Transfer Complete
> +					      135 1>;	// Receive FIFO Drain
> +			};
> +
> +			dspi@fff98000 {		// Deserial Serial Peripheral Interface (DSPI_C)
> +				compatible = "fsl,mpc5554-dspi";
> +				reg = <0xfff98000 0x4000>;
> +				interrupts = <136 1	// Combined: Transmit FIFO Underflow, Receive FIFO Overflow
> +					      137 1	// Transmit FIFO End of Queue
> +					      138 1	// Transmit FIFO Fill Flag
> +					      139 1	// Transfer Complete
> +					      140 1>;	// Receive FIFO Drain
> +			};
> +
> +			dspi@fff9c000 {		// Deserial Serial Peripheral Interface (DSPI_D)
> +				compatible = "fsl,mpc5554-dspi";
> +				reg = <0xfff9c000 0x4000>;
> +				interrupts = <141 1	// Combined: Transmit FIFO Underflow, Receive FIFO Overflow
> +					      142 1	// Transmit FIFO End of Queue
> +					      143 1	// Transmit FIFO Fill Flag
> +					      144 1	// Transfer Complete
> +					      145 1>;	// Receive FIFO Drain
> +			};
> +
> +			esci@fffb0000 {		// Serial Communications Interface (SCI_A)
> +				compatible = "fsl,mpc5554-esci";
> +				reg = <0xfffb0000 0x4000>;
> +				interrupts = <146 1>;	// Combined request for all SCI_A interrupts
> +			};
> +
> +			esci@fffb4000 {		// Serial Communications Interface (SCI_B)
> +				compatible = "fsl,mpc5554-esci";
> +				reg = <0xfffb4000 0x4000>;
> +				interrupts = <149 1>;	// Combined request for all SCI_A interrupts
> +			};
> +
> +			can@fffc0000 {		// Controller Area Network (FlexCAN_A)
> +				compatible = "fsl,mpc5554-flexcan";
> +				reg = <0xfffc0000 0x4000>;
> +				interrupts = <152 1	// Bus off
> +					      153 1	// Error
> +					      155 1	// Buffer 0
> +					      156 1	// Buffer 1
> +					      157 1	// Buffer 2
> +					      158 1	// Buffer 3
> +					      159 1	// Buffer 4
> +					      160 1	// Buffer 5
> +					      161 1	// Buffer 6
> +					      162 1	// Buffer 7
> +					      163 1	// Buffer 8
> +					      164 1	// Buffer 9
> +					      165 1	// Buffer 10
> +					      166 1	// Buffer 11
> +					      167 1	// Buffer 12
> +					      168 1	// Buffer 13
> +					      169 1	// Buffer 14
> +					      170 1	// Buffer 15
> +					      171 1	// Buffers 16-31
> +					      172 1>;	// Buffers 32-63
> +			};
> +
> +			can@fffc4000 {		// Controller Area Network (FlexCAN_B)
> +				compatible = "fsl,mpc5554-flexcan";
> +				reg = <0xfffc4000 0x4000>;
> +				interrupts = <280 1	// Bus off
> +					      281 1	// Error
> +					      283 1	// Buffer 0
> +					      284 1	// Buffer 1
> +					      285 1	// Buffer 2
> +					      286 1	// Buffer 3
> +					      287 1	// Buffer 4
> +					      288 1	// Buffer 5
> +					      289 1	// Buffer 6
> +					      290 1	// Buffer 7
> +					      291 1	// Buffer 8
> +					      292 1	// Buffer 9
> +					      293 1	// Buffer 10
> +					      294 1	// Buffer 11
> +					      295 1	// Buffer 12
> +					      296 1	// Buffer 13
> +					      297 1	// Buffer 14
> +					      298 1	// Buffer 15
> +					      299 1	// Buffers 16-31
> +					      300 1>;	// Buffers 32-63
> +			};
> +
> +			can@fffc8000 {		// Controller Area Network (FlexCAN_C)
> +				compatible = "fsl,mpc5554-flexcan";
> +				reg = <0xfffc8000 0x4000>;
> +				interrupts = <173 1	// Bus off
> +					      174 1	// Error
> +					      176 1	// Buffer 0
> +					      177 1	// Buffer 1
> +					      178 1	// Buffer 2
> +					      179 1	// Buffer 3
> +					      180 1	// Buffer 4
> +					      181 1	// Buffer 5
> +					      182 1	// Buffer 6
> +					      183 1	// Buffer 7
> +					      184 1	// Buffer 8
> +					      185 1	// Buffer 9
> +					      186 1	// Buffer 10
> +					      187 1	// Buffer 11
> +					      188 1	// Buffer 12
> +					      189 1	// Buffer 13
> +					      190 1	// Buffer 14
> +					      191 1	// Buffer 15
> +					      192 1	// Buffers 16-31
> +					      193 1>;	// Buffers 32-63
> +			};
> +
> +			bam@ffffc000 {		// Boot Assist Module (BAM)
> +				compatible = "fsl,mpc5554-bam";
> +				reg = <0xffffc000 0x4000>;
> +			};
> +
> +		};
> +
> +	};
> +
> +};
> 

^ permalink raw reply

* how can I write a Device Tree Source for PCI-PCI Bridge?
From: Jianbin Hu @ 2010-03-17 17:05 UTC (permalink / raw)
  To: linuxppc-dev

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

Hi, all
My board have a PCIe switch(PLX PEX8608), which have a AMCC 460EX processor.
I have parted the dts source file from canyonlands.dts.
But I have no idea for the PCI bridge device node. Is anyone have a
suggestion ?

Best Regards.

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

^ permalink raw reply

* Re: MPC5121e - using both USB modules
From: Wolfram Sang @ 2010-03-17 14:24 UTC (permalink / raw)
  To: LD; +Cc: Linux ppc mailing list
In-Reply-To: <4BA0DF86.8000209@tin.it>

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

On Wed, Mar 17, 2010 at 02:56:22PM +0100, LD wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Hi all,
> I am working on a custom MPC5121e board, adapting 2.6.24 kernel.

This is probably the Freescale-provided kernel, so you should ask them.

Or, even better, use the current mainline kernel and check the newly
merged MPC5121-patches :)

Regards,

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

^ permalink raw reply

* MPC5121e - using both USB modules
From: LD @ 2010-03-17 13:56 UTC (permalink / raw)
  To: Linux ppc mailing list

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi all,
I am working on a custom MPC5121e board, adapting 2.6.24 kernel.
The board has two USB ports:
- - cell-index 0 uses internal phy
- - cell-index 1 uses external phy

For mechanical/commercial reasons I cannot use Mini-A / Mini-B connectors, so I
have two "host" connectors, but the board should be capable of doing host or
device by dip-switch selection and using an external M/M connector adapter.

First I enabled cell-index 0 only in dts file, dr_mode = "otg", used OTG kernel
modules ; I succeeded in switching from host to device mode : port 0 is working.

Cell-index 1: disabled cell 0 and wrote some tweaks in drivers to enable correct
USB clocks (I saw some recent patches about this), then realized that the
hardware people have chosen a wrong ULPI phy (CY7C68003), which is capable of
doing only device, not host (arrrggghh !!) ; next boards will have a different
phy (capable of OTG).
I have some preliminary boards with this Cypress phy and tried enabling this
cell in otg mode to try and see if I can work in device mode, but strange things
- - ehci_hub_control complains. I suppose the phy is not ok to work this way.

Now I am trying to arrive to something like:
cell-0 : dr_mode = otg
cell-1 : dr_mode = peripheral

This way I could save the preliminary boards, with cell-1 working only as a usb
device. I am having problems with processor reset in inserting modules, still
not clear what is happening.

Anyway, final target will be (new boards):
cell-0 : dr_mode = otg
cell-1 : dr_mode = otg
Each port will have its dip-switch to select host or device mode.

So, here we are:
- - anyone having some suggestions or link to documentation please ?
- - is it possible to have two ports working as "peripheral" ? Not necessary for
me, but just to understand the "linux" constraints (if any).
I could, for example, use file_storage to one USB cell and ethernet-dev to the
other...
I also have to investigate how to tell file_storage which USB cell to use : map
both USB cells to the same pseudo-disk seems not good.


Thanks,
best regards

Lucio Dona'
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFLoN+FvxHCsvXy9okRAtvfAJ4pEaBgPfmKLVRgczx3C1yYlQ8QdwCfYoyO
0KCTXBxZrALLHG/7BziuZpA=
=W1D6
-----END PGP SIGNATURE-----

^ permalink raw reply

* Re: [PATCH] 460EX on-chip SATA driver<kernel 2.6.33> < resubmission : 01>
From: Stefan Roese @ 2010-03-17 12:03 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Rupjyoti Sarmah, linuxppc-dev, Rupjyoti Sarmah, linux-kernel,
	linux-ide, Rupjyoti Sarmah, Jeff Garzik
In-Reply-To: <AC311A8E81420D4EBC1F26E6479848FE065B7F30@SDCEXCHANGE01.ad.amcc.com>

Hi Rup,

On Wednesday 17 March 2010 05:23:16 Rupjyoti Sarmah wrote:
> This patch enables the on-chip DWC SATA controller of the AppliedMicro
> processor 460EX.

Apart from the other comments, did you take a look at the latest version of 
this driver in our linux-2.6-denx repository? We did some work on this driver 
for a new Canyonlands release last year. It's hard to check this for me now, 
with this line wrapped patch (the drivers diverged somewhat). So either check 
for yourself, or send a new, not line-wrapped, patch version so that I can 
better check myself.

BTW: It would be nice if you would add me to Cc on DWC-SATA related patches, 
since I've been involved in the development at some time.

Thanks.

Cheers,
Stefan

--
DENX Software Engineering GmbH,      MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich,  Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-0 Fax: (+49)-8142-66989-80 Email: office@denx.de

^ permalink raw reply

* Re: Problem with PCI bus rescan on 460EX
From: Felix Radensky @ 2010-03-17  7:57 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev@ozlabs.org, linux-pci, yinghai, Alex Chiang,
	Kenji Kaneshige
In-Reply-To: <1268812060.2335.174.camel@pasglop>

Hi Ben,

Benjamin Herrenschmidt wrote:
> On Wed, 2010-03-17 at 09:38 +0200, Felix Radensky wrote:
>   
>> Hello Kenj-san
>>
>> Kenji Kaneshige wrote:
>>     
>>> By the way, I think Yinghai's bridge resource reallocation patch series
>>> might help you. It is in Jesse's PCI tree. Please take a look.
>>>
>>>
>>>       
>> I've tried Jesse's tree on my custom board and on 460EX evaluation board
>> (Canyonlands). In both cases the kernel doesn't boot unless PCI support is
>> disabled.  Debugging is difficult as the board just resets before 
>> anything is
>> is printed on console.
>>     
>
> This is Jesse tree with the default Canyonlands defconfig ? Hrm... I'll
> have to take a look, somebody mucking with PCI resource allocation is
> very likely to break something :-)
>
>
>   

Yep, default Canyonlands defconfig and default DTS.

Felix.

^ permalink raw reply

* Re: Problem with PCI bus rescan on 460EX
From: Benjamin Herrenschmidt @ 2010-03-17  7:47 UTC (permalink / raw)
  To: Felix Radensky
  Cc: linuxppc-dev@ozlabs.org, linux-pci, yinghai, Alex Chiang,
	Kenji Kaneshige
In-Reply-To: <4BA086EF.6080708@embedded-sol.com>

On Wed, 2010-03-17 at 09:38 +0200, Felix Radensky wrote:
> Hello Kenj-san
> 
> Kenji Kaneshige wrote:
> >
> >
> > By the way, I think Yinghai's bridge resource reallocation patch series
> > might help you. It is in Jesse's PCI tree. Please take a look.
> >
> >
> I've tried Jesse's tree on my custom board and on 460EX evaluation board
> (Canyonlands). In both cases the kernel doesn't boot unless PCI support is
> disabled.  Debugging is difficult as the board just resets before 
> anything is
> is printed on console.

This is Jesse tree with the default Canyonlands defconfig ? Hrm... I'll
have to take a look, somebody mucking with PCI resource allocation is
very likely to break something :-)

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH 3/4] 8xx: Don't touch ACCESSED when no SWAP.
From: Joakim Tjernlund @ 2010-03-17  7:40 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1268774452.2335.132.camel@pasglop>

Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote on 2010/03/16 22:20:52:
>
> On Fri, 2010-02-26 at 09:29 +0100, Joakim Tjernlund wrote:
> > Only the swap function cares about the ACCESSED bit in
> > the pte. Do not waste cycles updateting ACCESSED when swap
> > is not compiled into the kernel.
> > ---
>
> Your changeset comment is a bit misleading since the code isn't actually
> updating ACCESSED... it's testing if ACCESSED is set and goes to the
> higher level fault if not (which might then update ACCESSED).

Right, I did have one or two variants that did update ACCESSED that
I experimented with, I guess that I got a bit confused by that.

The jury is still out on whether this patch is an improvement or not.

    Jocke

^ permalink raw reply

* Re: Problem with PCI bus rescan on 460EX
From: Felix Radensky @ 2010-03-17  7:38 UTC (permalink / raw)
  To: Kenji Kaneshige; +Cc: linux-pci, yinghai, Alex Chiang, linuxppc-dev@ozlabs.org
In-Reply-To: <4BA02A49.9050101@jp.fujitsu.com>

Hello Kenj-san

Kenji Kaneshige wrote:
>
>
> By the way, I think Yinghai's bridge resource reallocation patch series
> might help you. It is in Jesse's PCI tree. Please take a look.
>
>
I've tried Jesse's tree on my custom board and on 460EX evaluation board
(Canyonlands). In both cases the kernel doesn't boot unless PCI support is
disabled.  Debugging is difficult as the board just resets before 
anything is
is printed on console.

Felix.

^ 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