LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: PCI target implementation on AMCC PPC CPUs
From: David Hawkins @ 2007-09-07  2:34 UTC (permalink / raw)
  To: Leonid; +Cc: linuxppc-embedded
In-Reply-To: <406A31B117F2734987636D6CCC93EE3C022418FF@ehost011-3.exch011.intermedia.net>

Hi guys,

> You want to say  PPC440GP cannot be PCI slave without
> this non-transparent bridge because as David said
> its "interrupt pin register hardwired to zero" or
> there other reasons?  I'm trying to use
> PPC440ep(or epx) and from its datasheet I don't
> see anything about this zero hardwiring.
> Does it mean "vanilla" PPC440ep will work?

Look in the user manual p562

https://www.amcc.com/MyAMCC/retrieveDocument/PowerPC/440GP/PPC440GP_UM2002_v1_11.pdf

The processor can generate INTA#.

> I have been finished an application using AMCC
> PPC440GP as PCI target(slave) in the last 2 month.
> I use a non-transparent bridge(AMCC PCI6466) to
> make the device a target(slave) like david has said.

However in this case, the bridge was not required
to make the processor target-capable. Most likely
the board required a local PCI bus, and so the
non-transparent bridge is used to hide the board
PCI devices from the other PCI host.

In this type of design the processor is acting
a *host* on the target board. When a host wants
to interrupt the target, it asserts an interrupt
in the bridge, and that interrupt asserts an
interrupt input on the processor.

When the target processor wants to interrupt the
host it writes to a register in the bridge and
the bridge interrupt the host using its INTA#.

In both cases the bridge is the target and the
processors are both hosts.

:)

Dave

^ permalink raw reply

* Re: RE: Re: PCI target implementation on AMCC PPC CPUs
From: sdeven.lee @ 2007-09-07  2:52 UTC (permalink / raw)
  To: Leonid, David Hawkins; +Cc: linuxppc-embedded

TGVvbmlkLMT6usOjoQ0KDQoJU29ycnksIEkgd2FzIHdyb25nLCBub3QgQU1DQyBQQ0k2NDY2LCBi
dXQgUExYIFBDSTY0NjYgbm9uLXRyYW5zcGFyZW50IGJyaWRnZS4NCg0KCUkgdXNlIHRoZSBub24t
dHJhbnNwYXJlbnQgYnJpZGdlIGp1c3QgZm9yIHNvbWUgc3BlY2lhbCBwdXJwb3NlLiBJbiB0aGlz
IGNhc2UsIHRoZSBob3N0IENQVSBjYW4ndCAgYWNjZXNzIHRoZSBtZW1vcnkgdmlhIHRoZSBicmlk
Z2UuIEkga25vdyBQUEM0NDBHUCBjYW4gcnVuIGluIGFnZW50IG1vZGUganVzdCBsaWtlIHlvdXIg
YXBwbGljYXRpb24uIEJ1dCBpdCBuZWVkcyBzcGVjaWFsIGNvbm5lY3Rpb24gb2YgdGhlIHBpbnMu
ICANCg0KPT09PT09PSAyMDA3LTA5LTA3IDEwOjEzOjMyIMT61NrAtNDF1tDQtLXAo7o9PT09PT09
DQoNCj5IaToNCj4NCj5Zb3Ugd2FudCB0byBzYXkgIFBQQzQ0MEdQIGNhbm5vdCBiZSBQQ0kgc2xh
dmUgd2l0aG91dCB0aGlzIG5vbi10cmFuc3BhcmVudCBicmlkZ2UgYmVjYXVzZSBhcyBEYXZpZCBz
YWlkIGl0cyAiaW50ZXJydXB0IHBpbiByZWdpc3RlciBoYXJkd2lyZWQgdG8gemVybyIgb3IgdGhl
cmUgb3RoZXIgcmVhc29ucz8gDQo+SSdtIHRyeWluZyB0byB1c2UgUFBDNDQwZXAob3IgZXB4KSBh
bmQgZnJvbSBpdHMgZGF0YXNoZWV0IEkgZG9uJ3Qgc2VlIGFueXRoaW5nIGFib3V0IHRoaXMgemVy
byBoYXJkd2lyaW5nLiBEb2VzIGl0IG1lYW4gInZhbmlsbGEiIFBQQzQ0MGVwIHdpbGwgd29yaz8N
Cj4NCj5BbmQgd2hhdCBkaWQgeW91IHVzZSBmb3IgUENJIEhvc3Q/DQo+DQo+QWxzbywgaXMgeW91
ciBjb2RlIGF2YWlsYWJsZSBzb213aGVyZT8NCj4NCj5UaGFua3MsDQo+DQo+TGVvbmlkLg0KPi0t
LS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+RnJvbTogc2RldmVuLmxlZSBbbWFpbHRvOnNkZXZl
bi5sZWVAMTYzLmNvbV0gDQo+U2VudDogVGh1cnNkYXksIFNlcHRlbWJlciAwNiwgMjAwNyA3OjA0
IFBNDQo+VG86IERhdmlkIEhhd2tpbnMNCj5DYzogTGVvbmlkOyBsaW51eHBwYy1lbWJlZGRlZA0K
PlN1YmplY3Q6IFJlOiBSZTogUENJIHRhcmdldCBpbXBsZW1lbnRhdGlvbiBvbiBBTUNDIFBQQyBD
UFVzDQo+DQo+RGF2aWQgSGF3a2lucyzE+rrDo6ENCj4NCj4JSSBoYXZlIGJlZW4gZmluaXNoZWQg
YW4gYXBwbGljYXRpb24gdXNpbmcgQU1DQyBQUEM0NDBHUCBhcyBQQ0kgdGFyZ2V0KHNsYXZlKSBp
biB0aGUgbGFzdCAyIG1vbnRoLkkgdXNlIGEgbm9uLXRyYW5zcGFyZW50IGJyaWRnZShBTUNDIFBD
STY0NjYpIHRvIG1ha2UgdGhlIGRldmljZSBhIHRhcmdldChzbGF2ZSkgbGlrZSBkYXZpZCBoYXMg
c2FpZC4NCj4NCj49PT09PT09IDIwMDctMDktMDcgMDQ6MjY6MDEgxPrU2sC00MXW0NC0tcCjuj09
PT09PT0NCj4NCj4+SGkgTGVvbmlkLA0KPj4NCj4+SW4gY2FzZSB0aGV5IGFyZSBub3QgaW4gdGhl
IGRvY3VtZW50Og0KPj4NCj4+VGhlcmUgYXJlIHNldmVyYWwgZnVuZGFtZW50YWwgcHJvYmxlbXMg
d2l0aCB0aGUgQU1DQyA0NDBFUCBhY3RpbmcgYXMgYSANCj4+UENJIHRhcmdldC9zbGF2ZTsNCj4+
DQo+PjEuIEFzIGEgUENJIHRhcmdldCwgdGhlcmUgaXMgb25seSBvbmUgd2F5IHRvIGdlbmVyYXRl
DQo+PiAgICBhbiBpbnRlcnJ1cHQgdG8gYSBob3N0OyB5b3UgYmFzaWNhbGx5IHRvZ2dsZSB0aGUN
Cj4+ICAgIGludGVycnVwdCBwaW4uIFRoaXMgbWFrZXMgaXQgdHJpY2t5IHRvIGRldmVsb3AgYQ0K
Pj4gICAgaG9zdC10by1zbGF2ZSBjb21tdW5pY2F0aW9ucyBwcm90b2NvbCwgZWcuIGl0cw0KPj4g
ICAgaGFyZCB0byB1c2UgdGhlIHNpbmdsZSBpbnRlcnJ1cHQgdG8gaW5kaWNhdGUgdmFyaW91cw0K
Pj4gICAgaW50ZXJydXB0IHN0YXRlcywgZWcuIHRhcmdldC10by1ob3N0IGJ1ZmZlciBoYXMNCj4+
ICAgIGRhdGEgdmVyc3VzIGhvc3QtdG8tdGFyZ2V0IGJ1ZmZlciBoYXMgYmVlbiBlbXB0aWVkLg0K
Pj4gICAgSWRlYWxseSBBTUNDIHNob3VsZCBoYXZlIGltcGxlbWVudGVkIG1haWxib3hlcyBhbmQv
b3INCj4+ICAgIGRvb3JiZWxsIHJlZ2lzdGVycyBsaWtlIGFueSBvdGhlciBzYW5lIFBDSSB0YXJn
ZXQNCj4+ICAgIGRldmljZSAoZWcuIHNvbWUgdGhlIEZyZWVzY2FsZSBwcm9jZXNzb3JzLCBvciBh
bnkgb2YNCj4+ICAgIHRoZSBQTFggdGVjaG5vbG9naWVzIGNoaXBzKS4NCj4+DQo+PjIuIExvb2sg
aW4gdGhlIGRhdGEgc2hlZXQgYW5kIHNlZSBpZiB5b3UgY2FuIGZpZ3VyZSBvdXQNCj4+ICAgIGhv
dyB0aGUgaG9zdCBwcm9jZXNzb3IgY2FuIGdlbmVyYXRlIGFuIGludGVycnVwdCB0bw0KPj4gICAg
dGhlIFBvd2VyUEMgY29yZSAuLi4gb29wcywgeW91IGNhbid0LiBUaGF0IGtpbmQgb2YNCj4+ICAg
IG1ha2VzIGl0IGRpZmZpY3VsdCB0byB3b3JrIHdpdGggZG9lc24ndCBpdC4NCj4+DQo+PiAgICBB
IHdvcmsgYXJvdW5kIHdvdWxkIGJlIHRvIGhhdmUgdGhlIGhvc3Qgd3JpdGUgdG8gdGhlDQo+PiAg
ICBHUElPIHJlZ2lzdGVyIGFuZCB3aXJlIGEgR1BJTyBwaW4gYmFjayB0byBhbiBleHRlcm5hbA0K
Pj4gICAgaW50ZXJydXB0IHBpbi4gVGhlbiB5b3Ugd291bGQgbm90IGJlIGFibGUgdG8gdXNlIGFu
eQ0KPj4gICAgb3RoZXIgR1BJTyBwaW4gaW4gdGhhdCBHUElPIHJlZ2lzdGVyIHNpbmNlIHRoZXJl
IGlzDQo+PiAgICBubyB3YXkgdG8gYXJiaXRyYXRlIGhvc3QgYWNjZXNzIHZlcnN1cyBQb3dlclBD
IGNvcmUNCj4+ICAgIGFjY2Vzcy4NCj4+DQo+PlRoaXMgd2FzIHRoZSBvdGhlciByZWFzb24gSSBk
aXRjaGVkIHRoZSBBTUNDIHBhcnQgaW4gZmF2b3Igb2YgdGhlIA0KPj5GcmVlc2NhbGUgcGFydC4N
Cj4+DQo+PklmIHlvdSBhcmUgbG9va2luZyBhdCBvdGhlciBwYXJ0cywgbWFrZSBzdXJlIHlvdSBs
b29rIGluIHRoZSBQQ0kgDQo+PmNvbmZpZ3VyYXRpb24gc3BhY2Ugb2YgdGhlIHByb2Nlc3NvciBy
ZWZlcmVuY2UgbWFudWFsLiBNYW55IHByb2Nlc3NvcnMgDQo+PmhhdmUgdGhlIGludGVycnVwdCBw
aW4gcmVnaXN0ZXIgaGFyZHdpcmVkIHRvIHplcm8sIGkuZS4sIHRoZXkgY2FuIG5vdCANCj4+YmUg
dXNlZCBhcyB0YXJnZXQgZGV2aWNlcywgb25seSBob3N0cy4gSW4gdGhhdCBjYXNlIHlvdSdkIGhh
dmUgdG8gYWRkIA0KPj5hbiBpbnRlbCAyMTU1NSBub24tdHJhbnNwYXJlbnQgYnJpZGdlIHRvIG1h
a2UgdGhlIGRldmljZSBhIHRhcmdldC4NCj4+DQo+PkNoZWVycywNCj4+RGF2ZQ0KPj4NCj4+X19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18NCj4+TGludXhwcGMt
ZW1iZWRkZWQgbWFpbGluZyBsaXN0DQo+PkxpbnV4cHBjLWVtYmVkZGVkQG96bGFicy5vcmcNCj4+
aHR0cHM6Ly9vemxhYnMub3JnL21haWxtYW4vbGlzdGluZm8vbGludXhwcGMtZW1iZWRkZWQNCj4N
Cj49ID0gPSA9ID0gPSA9ID0gPSA9ID0gPSA9ID0gPSA9ID0gPSA9ID0NCj4JCQkNCj4NCj6hoaGh
oaGhoaGhoaGhoaGh1sINCj7A8aOhDQo+IA0KPgkJCQkgDQo+oaGhoaGhoaGhoaGhoaGhoXNkZXZl
bi5sZWUNCj6hoaGhoaGhoaGhoaGhoaGhc2RldmVuLmxlZUAxNjMuY29tDQo+oaGhoaGhoaGhoaGh
oaGhoaGhoaEyMDA3LTA5LTA3DQoNCj0gPSA9ID0gPSA9ID0gPSA9ID0gPSA9ID0gPSA9ID0gPSA9
ID0gPQ0KCQkJDQoNCqGhoaGhoaGhoaGhoaGhoaHWwg0KwPGjoQ0KIA0KCQkJCSANCqGhoaGhoaGh
oaGhoaGhoaFzZGV2ZW4ubGVlDQqhoaGhoaGhoaGhoaGhoaGhc2RldmVuLmxlZUAxNjMuY29tDQqh
oaGhoaGhoaGhoaGhoaGhoaGhoTIwMDctMDktMDcNCg0K

^ permalink raw reply

* Document and implement an improved flash device binding for powerpc (v5)
From: David Gibson @ 2007-09-07  3:23 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev

This patch replaces the binding for flash chips in
booting-without-of.txt with an clarified and improved version.  It
also makes drivers/mtd/maps/physmap_of.c recognize this new binding.
Finally it revises the Ebony device tree source to use the new binding
as an example.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---

Now with a 'label' property for partitions.

Index: working-2.6/Documentation/powerpc/booting-without-of.txt
===================================================================
--- working-2.6.orig/Documentation/powerpc/booting-without-of.txt	2007-09-07 11:53:10.000000000 +1000
+++ working-2.6/Documentation/powerpc/booting-without-of.txt	2007-09-07 11:53:10.000000000 +1000
@@ -50,7 +50,7 @@ Table of Contents
       g) Freescale SOC SEC Security Engines
       h) Board Control and Status (BCSR)
       i) Freescale QUICC Engine module (QE)
-      j) Flash chip nodes
+      j) CFI or JEDEC memory-mapped NOR flash
       k) Global Utilities Block
 
   VII - Specifying interrupt information for devices
@@ -1757,45 +1757,69 @@ platforms are moved over to use the flat
 		};
 	};
 
-    j) Flash chip nodes
+   j) CFI or JEDEC memory-mapped NOR flash
 
     Flash chips (Memory Technology Devices) are often used for solid state
     file systems on embedded devices.
 
-    Required properties:
-
-     - device_type : has to be "rom"
-     - compatible : Should specify what this flash device is compatible with.
-       Currently, this is most likely to be "direct-mapped" (which
-       corresponds to the MTD physmap mapping driver).
-     - reg : Offset and length of the register set (or memory mapping) for
-       the device.
-     - bank-width : Width of the flash data bus in bytes. Required
-       for the NOR flashes (compatible == "direct-mapped" and others) ONLY.
-
-    Recommended properties :
-
-     - partitions : Several pairs of 32-bit values where the first value is
-       partition's offset from the start of the device and the second one is
-       partition size in bytes with LSB used to signify a read only
-       partition (so, the partition size should always be an even number).
-     - partition-names : The list of concatenated zero terminated strings
-       representing the partition names.
-     - probe-type : The type of probe which should be done for the chip
-       (JEDEC vs CFI actually). Valid ONLY for NOR flashes.
+     - compatible : should contain the specific model of flash chip(s)
+       used, if known, followed by either "cfi-flash" or "jedec-flash"
+     - reg : Address range of the flash chip
+     - bank-width : Width (in bytes) of the flash bank.  Equal to the
+       device width times the number of interleaved chips.
+     - device-width : (optional) Width of a single flash chip.  If
+       omitted, assumed to be equal to 'bank-width'.
+     - #address-cells, #size-cells : Must be present if the flash has
+       sub-nodes representing partitions (see below).  In this case
+       both #address-cells and #size-cells must be equal to 1.
+
+    For JEDEC compatible devices, the following additional properties
+    are defined:
+
+     - vendor-id : Contains the flash chip's vendor id (1 byte).
+     - device-id : Contains the flash chip's device id (1 byte).
+
+    In addition to the information on the flash bank itself, the
+    device tree may optionally contain additional information
+    describing partitions of the flash address space.  This can be
+    used on platforms which have strong conventions about which
+    portions of the flash are used for what purposes, but which don't
+    use an on-flash partition table such as RedBoot.
+
+    Each partition is represented as a sub-node of the flash device.
+    Each node's name represents the name of the corresponding
+    partition of the flash device.
+
+    Flash partitions
+     - reg : The partition's offset and size within the flash bank.
+     - label : (optional) The label / name for this flash partition.
+       If omitted, the label is taken from the node name (excluding
+       the unit address).
+     - read-only : (optional) This parameter, if present, is a hint to
+       Linux that this flash partition should only be mounted
+       read-only.  This is usually used for flash partitions
+       containing early-boot firmware images or data which should not
+       be clobbered.
 
-   Example:
+    Example:
 
- 	flash@ff000000 {
- 		device_type = "rom";
- 		compatible = "direct-mapped";
- 		probe-type = "CFI";
- 		reg = <ff000000 01000000>;
- 		bank-width = <4>;
- 		partitions = <00000000 00f80000
- 			      00f80000 00080001>;
- 		partition-names = "fs\0firmware";
- 	};
+	flash@ff000000 {
+		compatible = "amd,am29lv128ml", "cfi-flash";
+		reg = <ff000000 01000000>;
+		bank-width = <4>;
+		device-width = <1>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		fs@0 {
+			label = "fs";
+			reg = <0 f80000>;
+		};
+		firmware@f80000 {
+			label ="firmware";
+			reg = <f80000 80000>;
+			read-only;
+		};
+	};
 
    k) Global Utilities Block
 
Index: working-2.6/drivers/mtd/maps/physmap_of.c
===================================================================
--- working-2.6.orig/drivers/mtd/maps/physmap_of.c	2007-08-28 14:23:57.000000000 +1000
+++ working-2.6/drivers/mtd/maps/physmap_of.c	2007-09-07 11:53:10.000000000 +1000
@@ -4,6 +4,9 @@
  * Copyright (C) 2006 MontaVista Software Inc.
  * Author: Vitaly Wool <vwool@ru.mvista.com>
  *
+ * Revised to handle newer style flash binding by:
+ *   Copyright (C) 2007 David Gibson, IBM Corporation.
+ *
  * 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
@@ -30,56 +33,135 @@ struct physmap_flash_info {
 	struct map_info		map;
 	struct resource		*res;
 #ifdef CONFIG_MTD_PARTITIONS
-	int			nr_parts;
 	struct mtd_partition	*parts;
 #endif
 };
 
-static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL };
-#ifdef CONFIG_MTD_PARTITIONS
-static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
-#endif
-
 #ifdef CONFIG_MTD_PARTITIONS
-static int parse_flash_partitions(struct device_node *node,
-		struct mtd_partition **parts)
+static int parse_obsolete_partitions(struct of_device *dev,
+				     struct physmap_flash_info *info,
+				     struct device_node *dp)
 {
-	int i, plen, retval = -ENOMEM;
-	const  u32  *part;
-	const  char *name;
-
-	part = of_get_property(node, "partitions", &plen);
-	if (part == NULL)
-		goto err;
-
-	retval = plen / (2 * sizeof(u32));
-	*parts = kzalloc(retval * sizeof(struct mtd_partition), GFP_KERNEL);
-	if (*parts == NULL) {
+	int i, plen, nr_parts;
+	const struct {
+		u32 offset, len;
+	} *part;
+	const char *names;
+
+	part = of_get_property(dp, "partitions", &plen);
+	if (!part)
+		return -ENOENT;
+
+	dev_warn(&dev->dev, "Device tree uses obsolete partition map binding\n");
+
+	nr_parts = plen / sizeof(part[0]);
+
+	info->parts = kzalloc(nr_parts * sizeof(struct mtd_partition), GFP_KERNEL);
+	if (!info->parts) {
 		printk(KERN_ERR "Can't allocate the flash partition data!\n");
-		goto err;
+		return -ENOMEM;
 	}
 
-	name = of_get_property(node, "partition-names", &plen);
+	names = of_get_property(dp, "partition-names", &plen);
 
-	for (i = 0; i < retval; i++) {
-		(*parts)[i].offset = *part++;
-		(*parts)[i].size   = *part & ~1;
-		if (*part++ & 1) /* bit 0 set signifies read only partition */
-			(*parts)[i].mask_flags = MTD_WRITEABLE;
+	for (i = 0; i < nr_parts; i++) {
+		info->parts[i].offset = part->offset;
+		info->parts[i].size   = part->len & ~1;
+		if (part->len & 1) /* bit 0 set signifies read only partition */
+			info->parts[i].mask_flags = MTD_WRITEABLE;
 
-		if (name != NULL && plen > 0) {
-			int len = strlen(name) + 1;
+		if (names && (plen > 0)) {
+			int len = strlen(names) + 1;
 
-			(*parts)[i].name = (char *)name;
+			info->parts[i].name = (char *)names;
 			plen -= len;
-			name += len;
-		} else
-			(*parts)[i].name = "unnamed";
+			names += len;
+		} else {
+			info->parts[i].name = "unnamed";
+		}
+
+		part++;
 	}
-err:
-	return retval;
+
+	return nr_parts;
 }
-#endif
+
+static int __devinit process_partitions(struct physmap_flash_info *info,
+					struct of_device *dev)
+{
+	const char *partname;
+	static const char *part_probe_types[]
+		= { "cmdlinepart", "RedBoot", NULL };
+	struct device_node *dp = dev->node, *pp;
+	int nr_parts, i;
+
+	/* First look for RedBoot table or partitions on the command
+	 * line, these take precedence over device tree information */
+	nr_parts = parse_mtd_partitions(info->mtd, part_probe_types,
+					&info->parts, 0);
+	if (nr_parts > 0) {
+		add_mtd_partitions(info->mtd, info->parts, nr_parts);
+		return 0;
+	}
+
+	/* First count the subnodes */
+	nr_parts = 0;
+	for (pp = dp->child; pp; pp = pp->sibling)
+		nr_parts++;
+
+	if (nr_parts) {
+		info->parts = kzalloc(nr_parts * sizeof(struct mtd_partition),
+				      GFP_KERNEL);
+		if (!info->parts) {
+			printk(KERN_ERR "Can't allocate the flash partition data!\n");
+			return -ENOMEM;
+		}
+
+		for (pp = dp->child, i = 0 ; pp; pp = pp->sibling, i++) {
+			const u32 *reg;
+			int len;
+
+			reg = of_get_property(pp, "reg", &len);
+			if (!reg || (len != 2*sizeof(u32))) {
+				dev_err(&dev->dev, "Invalid 'reg' on %s\n",
+					dp->full_name);
+				kfree(info->parts);
+				info->parts = NULL;
+				return -EINVAL;
+			}
+			info->parts[i].offset = reg[0];
+			info->parts[i].size = reg[1];
+
+			partname = of_get_property(pp, "label", &len);
+			if (!partname)
+				partname = of_get_property(pp, "name", &len);
+			info->parts[i].name = (char *)partname;
+
+			if (of_get_property(pp, "read-only", &len))
+				info->parts[i].mask_flags = MTD_WRITEABLE;
+		}
+	} else {
+		nr_parts = parse_obsolete_partitions(dev, info, dp);
+	}
+
+	if (nr_parts < 0)
+		return nr_parts;
+
+	if (nr_parts > 0)
+		add_mtd_partitions(info->mtd, info->parts, nr_parts);
+	else
+		add_mtd_device(info->mtd);
+
+	return 0;
+}
+#else /* MTD_PARTITIONS */
+static int __devinit process_partitions(struct physmap_flash_info *info,
+					struct device_node *dev)
+{
+	add_mtd_device(info->mtd);
+	return 0;
+}
+#endif /* MTD_PARTITIONS */
 
 static int of_physmap_remove(struct of_device *dev)
 {
@@ -92,7 +174,7 @@ static int of_physmap_remove(struct of_d
 
 	if (info->mtd != NULL) {
 #ifdef CONFIG_MTD_PARTITIONS
-		if (info->nr_parts) {
+		if (info->parts) {
 			del_mtd_partitions(info->mtd);
 			kfree(info->parts);
 		} else {
@@ -115,17 +197,51 @@ static int of_physmap_remove(struct of_d
 	return 0;
 }
 
+/* Helper function to handle probing of the obsolete "direct-mapped"
+ * compatible binding, which has an extra "probe-type" property
+ * describing the type of flash probe necessary. */
+static struct mtd_info * __devinit obsolete_probe(struct of_device *dev,
+						  struct map_info *map)
+{
+	struct device_node *dp = dev->node;
+	const char *of_probe;
+	struct mtd_info *mtd;
+	static const char *rom_probe_types[]
+		= { "cfi_probe", "jedec_probe", "map_rom"};
+	int i;
+
+	dev_warn(&dev->dev, "Device tree uses obsolete \"direct-mapped\" "
+		 "flash binding\n");
+
+	of_probe = of_get_property(dp, "probe-type", NULL);
+	if (!of_probe) {
+		for (i = 0; i < ARRAY_SIZE(rom_probe_types); i++) {
+			mtd = do_map_probe(rom_probe_types[i], map);
+			if (mtd)
+				return mtd;
+		}
+		return NULL;
+	} else if (strcmp(of_probe, "CFI") == 0) {
+		return do_map_probe("cfi_probe", map);
+	} else if (strcmp(of_probe, "JEDEC") == 0) {
+		return do_map_probe("jedec_probe", map);
+	} else {
+ 		if (strcmp(of_probe, "ROM") != 0)
+			dev_dbg(&dev->dev, "obsolete_probe: don't know probe type "
+				"'%s', mapping as rom\n", of_probe);
+		return do_map_probe("mtd_rom", map);
+	}
+}
+
 static int __devinit of_physmap_probe(struct of_device *dev, const struct of_device_id *match)
 {
 	struct device_node *dp = dev->node;
 	struct resource res;
 	struct physmap_flash_info *info;
-	const char **probe_type;
-	const char *of_probe;
+	const char *probe_type = (const char *)match->data;
 	const u32 *width;
 	int err;
 
-
 	if (of_address_to_resource(dp, 0, &res)) {
 		dev_err(&dev->dev, "Can't get the flash mapping!\n");
 		err = -EINVAL;
@@ -174,21 +290,11 @@ static int __devinit of_physmap_probe(st
 
 	simple_map_init(&info->map);
 
-	of_probe = of_get_property(dp, "probe-type", NULL);
-	if (of_probe == NULL) {
-		probe_type = rom_probe_types;
-		for (; info->mtd == NULL && *probe_type != NULL; probe_type++)
-			info->mtd = do_map_probe(*probe_type, &info->map);
-	} else if (!strcmp(of_probe, "CFI"))
-		info->mtd = do_map_probe("cfi_probe", &info->map);
-	else if (!strcmp(of_probe, "JEDEC"))
-		info->mtd = do_map_probe("jedec_probe", &info->map);
-	else {
- 		if (strcmp(of_probe, "ROM"))
-			dev_dbg(&dev->dev, "map_probe: don't know probe type "
-			"'%s', mapping as rom\n", of_probe);
-		info->mtd = do_map_probe("mtd_rom", &info->map);
-	}
+	if (probe_type)
+		info->mtd = do_map_probe(probe_type, &info->map);
+	else
+		info->mtd = obsolete_probe(dev, &info->map);
+
 	if (info->mtd == NULL) {
 		dev_err(&dev->dev, "map_probe failed\n");
 		err = -ENXIO;
@@ -196,19 +302,7 @@ static int __devinit of_physmap_probe(st
 	}
 	info->mtd->owner = THIS_MODULE;
 
-#ifdef CONFIG_MTD_PARTITIONS
-	err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0);
-	if (err > 0) {
-		add_mtd_partitions(info->mtd, info->parts, err);
-	} else if ((err = parse_flash_partitions(dp, &info->parts)) > 0) {
-		dev_info(&dev->dev, "Using OF partition information\n");
-		add_mtd_partitions(info->mtd, info->parts, err);
-		info->nr_parts = err;
-	} else
-#endif
-
-	add_mtd_device(info->mtd);
-	return 0;
+	return process_partitions(info, dev);
 
 err_out:
 	of_physmap_remove(dev);
@@ -221,6 +315,21 @@ err_out:
 
 static struct of_device_id of_physmap_match[] = {
 	{
+		.compatible	= "cfi-flash",
+		.data		= (void *)"cfi_probe",
+	},
+	{
+		/* FIXME: JEDEC chips can't be safely and reliably
+		 * probed, although the mtd code gets it right in
+		 * practice most of the time.  We should use the
+		 * vendor and device ids specified by the binding to
+		 * bypass the heuristic probe code, but the mtd layer
+		 * provides, at present, no interface for doing so
+		 * :(. */
+		.compatible	= "jedec-flash",
+		.data		= (void *)"jedec_probe",
+	},
+	{
 		.type		= "rom",
 		.compatible	= "direct-mapped"
 	},
Index: working-2.6/arch/powerpc/boot/dts/ebony.dts
===================================================================
--- working-2.6.orig/arch/powerpc/boot/dts/ebony.dts	2007-09-05 15:56:35.000000000 +1000
+++ working-2.6/arch/powerpc/boot/dts/ebony.dts	2007-09-07 11:53:10.000000000 +1000
@@ -142,13 +142,16 @@
 				interrupt-parent = <&UIC1>;
 
 				small-flash@0,80000 {
-					device_type = "rom";
-					compatible = "direct-mapped";
-					probe-type = "JEDEC";
+					compatible = "jedec-flash";
 					bank-width = <1>;
-					partitions = <0 80000>;
-					partition-names = "OpenBIOS";
 					reg = <0 80000 80000>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+					partition@0 {
+						label = "OpenBIOS";
+						reg = <0 80000>;
+						read-only;
+					};
 				};
 
 				ds1743@1,0 {
@@ -158,14 +161,19 @@
 				};
 
 				large-flash@2,0 {
-					device_type = "rom";
-					compatible = "direct-mapped";
-					probe-type = "JEDEC";
+					compatible = "jedec-flash";
 					bank-width = <1>;
-					partitions = <0 380000
-						      380000 80000>;
-					partition-names = "fs", "firmware";
 					reg = <2 0 400000>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+					partition@0 {
+						label = "fs";
+						reg = <0 380000>;
+					};
+					partition@380000 {
+						label = "firmware";
+						reg = <380000 80000>;
+					};
 				};
 
 				ir@3,0 {


-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [patch 2/6] cuimage for Bamboo board
From: David Gibson @ 2007-09-07  3:26 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <20070905114243.3c787838@weaponx.rchland.ibm.com>

On Wed, Sep 05, 2007 at 11:42:43AM -0500, Josh Boyer wrote:
> Updated patch below.  NOTE: This relies on Scott Wood's strtoull patch
> as PIBS stores the MAC addresses as ASCII strings in flash.
> 
> 
> Add a cuboot wrapper for the Bamboo board.  This also removes some obsoleted
> linker declarations that have been moved into ops.h
> 
> Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>

Acked-by: David Gibson <david@gibson.dropbear.id.au>

Except..
[snip]
> --- linux-2.6.orig/arch/powerpc/boot/treeboot-bamboo.c
> +++ linux-2.6/arch/powerpc/boot/treeboot-bamboo.c

It's not the fault of this patch, but since bamboo actually boots from
PIBS, not OpenBIOS, it probably shouldn't be lumped in with the
treeboot stuff.  PIBS should be able to load ELF images directly,
rather than using the silly treeboot header, for one thing.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH v7 3/3] [POWERPC] MPC832x_RDB: update dts to use SPI1in QE, register mmc_spi stub
From: David Gibson @ 2007-09-07  3:37 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: linuxppc-dev, Timur Tabi
In-Reply-To: <3299c27fe2551315c6f5ecff3569f2e0@kernel.crashing.org>

On Thu, Sep 06, 2007 at 04:13:56PM +0200, Segher Boessenkool wrote:
> >> This kind of thing is typically hardcoded into the firmware (just like
> >> the device tree is) -- just put it somewhere _next to_ the device 
> >> tree,
> >> not _in_ it.
> >
> > What is next to the device tree?
> 
> "Anywhere else in the firmware".
> 
> > AFAIK, there is no other standard data structure that could take place 
> > of the par_io nodes in the DTS.
> 
> The device tree is not a dumping ground for all your "I need some
> standard data structure" stuff.  Use an XML file if you have to ;-)

Actually, I think "I need a standard data structure" is well within
the purview of what we hoped the flat device tree could do.  We don't
have to follow IEEE1275 slavishly.

To isolate this sort of thing out from the device tree "proper", we
may wish to define some new "virtual" device nodes to go at the root
level (in the same way that /chosen and /aliases already have defined
purposes that don't involve describing real devices).

I can't speak specifically to the par_io nodes, because their function
was not obvious to me from my glance at the examples we have, and I
don't recall whatever previous discussions they were described in.

We do want, where possible, though, to make it unambiguous what things
are describing immutable facts about the hardware and what are hints
or startup configuration only.

> > I agree with your points, Segher, but replacing the par_io node with a 
> > bunch of par_io_config_pin() calls in the kernel is not really an 
> > improvement, I think.  Until we migrate the QE pin configuration code 
> > to U-boot, I suggest that we keep the device tree structure as-is and 
> > continue to use it for new code.  That way, it will all stay in one 
> > place.
> 
> Sure, some migration plan is in order, things won't change overnight.
> That doesn't mean you don't need to start planning _now_ ;-)

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Flash Filesystem
From: schardt @ 2007-09-07  7:34 UTC (permalink / raw)
  To: Linux PPC Linux PPC

Hi

i've some problems using the on board flash memory with linux.
i added the support for adm/fujittsu flash in kernel config and add the
right parameters for the "cfi  flash device in physical memory".

cat /proc/mtd gives me

dev:    size   erasesize  name
mtd0: 00400000 00010000 "physmap-flash.0"

i added /dev/mtd0 c 90 0 and /dev/mtdblock0 b 31 0

how do i add a partition and filesystem ????
fdisk /dev/mtd0  seems me not to be correct :)

Greets
Georg





-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
Forschungszentrum Jülich GmbH
52425 Jülich

Sitz der Gesellschaft: Jülich
Eingetragen im Handelsregister des Amtsgerichts Düren Nr. HR B 3498
Vorsitzende des Aufsichtsrats: MinDirig'in Bärbel Brumme-Bothe
Vorstand: Prof. Dr. Achim Bachem (Vorsitzender), Dr. Ulrich Krafft (stellv. 
Vorsitzender)
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------

^ permalink raw reply

* Re: [RFC/PATCH 1/2] Basic generic time/clocksource code for PowerPC
From: Gabriel Paubert @ 2007-09-07  8:21 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20070906172415.GA18226@ld0162-tx32.am.freescale.net>

On Thu, Sep 06, 2007 at 12:24:15PM -0500, Scott Wood wrote:
> On Thu, Sep 06, 2007 at 07:05:47PM +0200, Gabriel Paubert wrote:
> > On Thu, Sep 06, 2007 at 12:01:23PM -0500, Scott Wood wrote:
> > > On Thu, Sep 06, 2007 at 06:55:35PM +0200, Gabriel Paubert wrote:
> > > > So who will be in charge of updating the RTC now? The update 
> > > > every 11 min is there to stay on x86(-64) it seems.
> > > 
> > > Put something in crontab to run hwclock periodically.
> > 
> > I have many machines on which cron is not even installed.
> 
> OK, so use something else that waits in a loop and periodically updates
> the clock.  It shouldn't be the kernel's responsibility.

It ha been the kernel's reposnibility ever since the NTP code
was included with the kernel. The only way to move it out
is to agree to something with NTP folks.

It is going to break working setups who rely on this feature, 
which is a big no-no.

The solution now used by i386/x86-64/sparc64 is
CONFIG_GENERIC_CMOS_UPDATE. Maybe powerpc should be switched
to use something similar, but the generic code has some
problems (it assumes that you have to set the clock
on a half-second, which is not the case of the RTC on 
my boards to start with).

Now I'm aware that some PowerPC RTC are messy to handle
in a timer/interrupt/whatever because some hardware designers
thought it was wise to put the RTC on a dog-slow bus like
I2C. You have however a variable to disable this update
if you want (no_sync_cmos_clock), set it to 1 by default
but please let people that use (and need) the functionality
enable it (even do it by default when the RTC access is fast).

	Gabriel

^ permalink raw reply

* Re: [PATCH 2.6.23] PS3: Ignore storage devices that are still being probed
From: Geoff Levand @ 2007-09-07  8:49 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Linux/PPC Development, Andrew Morton, Paul Mackerras,
	Cell Broadband Engine OSS Development
In-Reply-To: <Pine.LNX.4.62.0709061813090.22591@pademelon.sonytel.be>

Geert Uytterhoeven wrote:
> PS3: A storage device may show up in the repository before the hypervisor has
> finished probing:
>   - If its type is not yet known, it shows up as PS3_DEV_TYPE_STOR_DUMMY,
>   - If its regions are being probed, it shows up as having zero regions.
> If any of these happen, consider the device not yet present.  The storage
> probe thread will retry later.
> 
> This fixes the timing-dependent problem where a kernel booted from FLASH ROM
> sometimes cannot find the hard disk.
> 
> Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

Paul,

This fixes a problem reported by users, so it would be nice for it to go
in for 2.6.23 if possible.  Sorry for it being so late. 

Acked-by: Geoff Levand <geoffrey.levand@am.sony.com>

^ permalink raw reply

* Re: [RFC/PATCH 1/2] Basic generic time/clocksource code for PowerPC
From: Gabriel Paubert @ 2007-09-07  8:50 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18144.17628.612658.91528@cargo.ozlabs.ibm.com>

On Fri, Sep 07, 2007 at 04:20:12AM +1000, Paul Mackerras wrote:
> Gabriel Paubert writes:
> 
> > On Fri, Sep 07, 2007 at 12:41:38AM +1000, Paul Mackerras wrote:
> > > This changes PowerPC to use the generic time infrastructure for
> > > gettimeofday et al.  We register a clocksource which uses the timebase
> > > register, or the RTC on the 601.
> > > 
> > > It also gets rid of the RTC update stuff.  IIRC we discussed removing
> > > this some time ago but never actually did it.
> > 
> > So who will be in charge of updating the RTC now? The update 
> > every 11 min is there to stay on x86(-64) it seems.
> 
> I had an impression that ntpd would do it, but that seems to be wrong.
> 
> I also have been unable to find where in the kernel source there is
> code for x86[-64] to do the RTC updates.  Do you know where it is?

It goes through CONFIG_CMOS_UPDATE, which is set to Y by default
on i386/x86-64/sparc64.

> 
> Doing the updates from timer_interrupt will no longer really be
> suitable since it is not called at regular intervals any more.  The
> best thing would be for the ntp code to set up a timer when it reaches
> synchronization.

This is what CONFIG_CMOS_UPDATE does through the sync_cmos_timer
variable. 

> 
> > Removing this will have strange side effects: as an example,
> > your laptop clock will be good if it synchronized on NTP, 
> > then you put it to sleep, disconnect the network and RTC read 
> > on wake up returns a wrong value, giving wrong timestamps.
> 
> No, the suspend/resume code reads the RTC on both suspend and resume,
> and advances xtime by the difference between the two readings.  So the
> time might be out by up to a second after resume, but it shouldn't be
> way off, assuming that your RTC is advancing at the right speed.

Ok, I did not know this. Well, my PreP boards never sleep (not worth
when doing real time data acquisition at 100-200 Hz interrupt rate)
but I rely on ntp and a fairly precise time setup at boot in some cases.

Actually I have slightly modified my kernels: I loop waiting 
for the second boundary to set the time and also use one full 
second of the RTC to calibrate the timebase, even that has
its own issues since I cannot use the last and first second 
of every minute because of RTC vagaries:

http://www.st.com/stonline/products/literature/an/5228.pdf

and that does not describe also the calibration which shortens 
or lengthens also specific seconds but I can afford to 
systematically set the calibration factor to 0:

http://www.st.com/stonline/products/literature/an/6393.pdf

This is the only way I found to have reproducible timebase
measurements on these machines; it means that it takes up to 
3 seconds to calibrate the timebase at boot, but it's better
than to have ntp error rate starting to depend on the phase
of the moon (this was my impression when I first found the
problem :-)), or more precisely on which second in the minute
the timebase calibration is performed.

> 
> > As someone who has a network of tens of machines using
> > NTP for synchornisation I think it is a very bad idea
> > unless we have a replacement.
> 
> OK, but I think that doing it in timer_interrupt is the wrong place.

Indeed, but please bring up something using the CONFIG_CMOS_UPDATE
infrastructure. I'm aware that some RTC have awfully slow accesses
(the more recent, the longest the latency it seems), but it is always 
possible to disable it through the no_sync_cmos_clock variable.
Default it to 1 if you want, after all it should not be the job
of the kernel if you have an hypervisor too, I don't care as long as 
you give me the possibility of enabling automatic RTC updates.

	Regards,
	Gabriel

^ permalink raw reply

* Re: [PATCH] powerpc: Add workaround for MPICs with broken register reads
From: Olof Johansson @ 2007-09-07  9:16 UTC (permalink / raw)
  To: Milton Miller; +Cc: ppcdev
In-Reply-To: <d62ce2299f9d423f95cd8ee50b3b7cff@bga.com>

On Thu, Sep 06, 2007 at 09:55:21AM -0500, Milton Miller wrote:
> On Wed Sep 5 12:44:17 EST 2007, Olof Johansson wrote:
>> diff --git a/arch/powerpc/platforms/Kconfig 
>> b/arch/powerpc/platforms/Kconfig
>> index 041df77..b9f1efa 100644
>> --- a/arch/powerpc/platforms/Kconfig
>> +++ b/arch/powerpc/platforms/Kconfig
>> @@ -137,6 +137,10 @@ config MPIC_U3_HT_IRQS
>>         depends on PPC_MAPLE
>>         default y
>>
>> +config MPIC_BROKEN_REGREAD
>> +       bool
>> +       depends on PPC_PASEMI
>> +
>>  config IBMVIO
>>         depends on PPC_PSERIES || PPC_ISERIES
>>         bool
>> diff --git a/arch/powerpc/platforms/pasemi/Kconfig 
>> b/arch/powerpc/platforms/pasemi/Kconfig
>> index 95cd90f..117d90a 100644
>> --- a/arch/powerpc/platforms/pasemi/Kconfig
>> +++ b/arch/powerpc/platforms/pasemi/Kconfig
>> @@ -5,6 +5,7 @@ config PPC_PASEMI
>>         select MPIC
>>         select PPC_UDBG_16550
>>         select PPC_NATIVE
>> +       select MPIC_BROKEN_REGREAD
>>         help
>>           This option enables support for PA Semi's PWRficient line
>>           of SoC processors, including PA6T-1682M
>
>
> Since you are using select (and not default y), instead of the depends on 
> PPC_PASEMI how about adding a short description of what the config does as 
> help text, in case some future mpic has a similar bug?

Thanks Milton, that's a reasonable suggestion (not that any of the other
options do it, including the very vague MPIC_WEIRD :-).

New patch posted shortly.


-Olof

^ permalink raw reply

* [PATCH v2] powerpc: Add workaround for MPICs with broken register reads
From: Olof Johansson @ 2007-09-07  9:21 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev, miltonm
In-Reply-To: <20070905024417.GE27139@lixom.net>

Some versions of PWRficient 1682M have an interrupt controller in which
the first register in each pair for interrupt sources doesn't always
read with the right polarity/sense values.

To work around this, keep a software copy of the register instead. Since
it's not modified from the mpic itself, it's a feasible solution. Still,
keep it under a config option to avoid wasting memory on other platforms.

Signed-off-by: Olof Johansson <olof@lixom.net>


diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 041df77..f2e7049 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -137,6 +137,18 @@ config MPIC_U3_HT_IRQS
 	depends on PPC_MAPLE
 	default y
 
+config MPIC_BROKEN_REGREAD
+	bool "MPIC workaround for broken register reads"
+	depends on MPIC
+	help
+	  Say Y here to enable a MPIC driver workaround for some chips that
+	  have a bug that causes some interrupt source information to not
+	  read back properly. It is safe to use on other chips as well, but
+	  enabling it uses about 8KB of memory to keep copies of the register
+	  contents in software.
+
+	  Say N if you are unsure.
+
 config IBMVIO
 	depends on PPC_PSERIES || PPC_ISERIES
 	bool
diff --git a/arch/powerpc/platforms/pasemi/Kconfig b/arch/powerpc/platforms/pasemi/Kconfig
index 95cd90f..117d90a 100644
--- a/arch/powerpc/platforms/pasemi/Kconfig
+++ b/arch/powerpc/platforms/pasemi/Kconfig
@@ -5,6 +5,7 @@ config PPC_PASEMI
 	select MPIC
 	select PPC_UDBG_16550
 	select PPC_NATIVE
+	select MPIC_BROKEN_REGREAD
 	help
 	  This option enables support for PA Semi's PWRficient line
 	  of SoC processors, including PA6T-1682M
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 74c64c0..c0fe063 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -228,8 +228,13 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigne
 	unsigned int	isu = src_no >> mpic->isu_shift;
 	unsigned int	idx = src_no & mpic->isu_mask;
 
-	return _mpic_read(mpic->reg_type, &mpic->isus[isu],
-			  reg + (idx * MPIC_INFO(IRQ_STRIDE)));
+#ifdef CONFIG_MPIC_BROKEN_REGREAD
+	if (reg == 0)
+		return mpic->isu_reg0_shadow[idx];
+	else
+#endif
+		return _mpic_read(mpic->reg_type, &mpic->isus[isu],
+				  reg + (idx * MPIC_INFO(IRQ_STRIDE)));
 }
 
 static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
@@ -240,6 +245,11 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
 
 	_mpic_write(mpic->reg_type, &mpic->isus[isu],
 		    reg + (idx * MPIC_INFO(IRQ_STRIDE)), value);
+
+#ifdef CONFIG_MPIC_BROKEN_REGREAD
+	if (reg == 0)
+		mpic->isu_reg0_shadow[idx] = value;
+#endif
 }
 
 #define mpic_read(b,r)		_mpic_read(mpic->reg_type,&(b),(r))
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
index 262db6b..c877fa7 100644
--- a/include/asm-powerpc/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -309,6 +309,10 @@ struct mpic
 	unsigned long		*hwirq_bitmap;
 #endif
 
+#ifdef CONFIG_MPIC_BROKEN_REGREAD
+	u32			isu_reg0_shadow[MPIC_MAX_IRQ_SOURCES];
+#endif
+
 	/* link */
 	struct mpic		*next;
 

^ permalink raw reply related

* Re: How to use MMC-over-SPI on MPC8313E
From: Vitaly Bordug @ 2007-09-07  9:22 UTC (permalink / raw)
  To: Vinu; +Cc: linuxppc-dev
In-Reply-To: <46E02F48.6090005@gen10technology.com>

On Thu, 06 Sep 2007 11:48:08 -0500
Vinu wrote:

> Hi all,
> 
> I am working on MPC8313ERDB  Eval board, and want to  use SD Memory
> card to store Linux OS and file system.
> The SD card controller is connected directly with the SPI bus.
> 
> I simply don't know how to use MMC-over-SPI  technology to make SD
> card usable.
> 
> It would be a great help if anybody have any documentation or driver
> etc.
> 

Please search list - there is 8323 support... We /mvista/ did such a thing not long ago. All the stuff releated to spi/mmc layer is already in mainline kernel, you'll just need to do board-specific patch for 8313 which should be similar to mentioned.
-- 
Sincerely, Vitaly

^ permalink raw reply

* Re: How to use MMC-over-SPI on MPC8313E
From: Sven Luther @ 2007-09-07  9:59 UTC (permalink / raw)
  To: Vinu; +Cc: linuxppc-dev
In-Reply-To: <46E02F48.6090005@gen10technology.com>

On Thu, Sep 06, 2007 at 11:48:08AM -0500, Vinu wrote:
> Hi all,
> 
> I am working on MPC8313ERDB  Eval board, and want to  use SD Memory card 
> to store Linux OS and file system.
> The SD card controller is connected directly with the SPI bus.
> 
> I simply don't know how to use MMC-over-SPI  technology to make SD card 
> usable.
> 
> It would be a great help if anybody have any documentation or driver etc.

I have recently written a MMC-over-SPI driver for a MPC875 card. It used
the block device directly, and is rather straightforward, but maybe not
so nice as it could be. I need to unbrand it, and can send it to you
later on. Please ping me this WE if you are interested.

Friendly,

Sven Luther

^ permalink raw reply

* [PATCH 1/2][RESEND] ehea: propagate physical port state
From: Jan-Bernd Themann @ 2007-09-07 10:30 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel, linux-ppc,
	Christoph Raisch, Marcus Eder, Stefan Roscher

Introduces a module parameter to decide whether the physical
port link state is propagated to the network stack or not.
It makes sense not to take the physical port state into account
on machines with more logical partitions that communicate
with each other. This is always possible no matter what the physical
port state is. Thus eHEA can be considered as a switch there.

Signed-off-by: Jan-Bernd Themann <themann@de.ibm.com>

---
 drivers/net/ehea/ehea.h      |    5 ++++-
 drivers/net/ehea/ehea_main.c |   14 +++++++++++++-
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index d67f97b..8d58be5 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0073"
+#define DRV_VERSION	"EHEA_0074"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
@@ -402,6 +402,8 @@ struct ehea_mc_list {
 
 #define EHEA_PORT_UP 1
 #define EHEA_PORT_DOWN 0
+#define EHEA_PHY_LINK_UP 1
+#define EHEA_PHY_LINK_DOWN 0
 #define EHEA_MAX_PORT_RES 16
 struct ehea_port {
 	struct ehea_adapter *adapter;	 /* adapter that owns this port */
@@ -427,6 +429,7 @@ struct ehea_port {
 	u32 msg_enable;
 	u32 sig_comp_iv;
 	u32 state;
+	u8 phy_link;
 	u8 full_duplex;
 	u8 autoneg;
 	u8 num_def_qps;
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index db57474..1e9fd6f 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -53,17 +53,21 @@ static int rq3_entries = EHEA_DEF_ENTRIES_RQ3;
 static int sq_entries = EHEA_DEF_ENTRIES_SQ;
 static int use_mcs = 0;
 static int num_tx_qps = EHEA_NUM_TX_QP;
+static int prop_carrier_state = 0;
 
 module_param(msg_level, int, 0);
 module_param(rq1_entries, int, 0);
 module_param(rq2_entries, int, 0);
 module_param(rq3_entries, int, 0);
 module_param(sq_entries, int, 0);
+module_param(prop_carrier_state, int, 0);
 module_param(use_mcs, int, 0);
 module_param(num_tx_qps, int, 0);
 
 MODULE_PARM_DESC(num_tx_qps, "Number of TX-QPS");
 MODULE_PARM_DESC(msg_level, "msg_level");
+MODULE_PARM_DESC(prop_carrier_state, "Propagate carrier state of physical "
+		 "port to stack. 1:yes, 0:no.  Default = 0 ");
 MODULE_PARM_DESC(rq3_entries, "Number of entries for Receive Queue 3 "
 		 "[2^x - 1], x = [6..14]. Default = "
 		 __MODULE_STRING(EHEA_DEF_ENTRIES_RQ3) ")");
@@ -814,7 +818,9 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed)
 			ehea_error("Failed setting port speed");
 		}
 	}
-	netif_carrier_on(port->netdev);
+	if (!prop_carrier_state || (port->phy_link == EHEA_PHY_LINK_UP))
+		netif_carrier_on(port->netdev);
+
 	kfree(cb4);
 out:
 	return ret;
@@ -869,13 +875,19 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe)
 			}
 
 		if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PORT_UP, eqe)) {
+			port->phy_link = EHEA_PHY_LINK_UP;
 			if (netif_msg_link(port))
 				ehea_info("%s: Physical port up",
 					  port->netdev->name);
+			if (prop_carrier_state)
+				netif_carrier_on(port->netdev);
 		} else {
+			port->phy_link = EHEA_PHY_LINK_DOWN;
 			if (netif_msg_link(port))
 				ehea_info("%s: Physical port down",
 					  port->netdev->name);
+			if (prop_carrier_state)
+				netif_carrier_off(port->netdev);
 		}
 
 		if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PRIMARY, eqe))
-- 
1.5.2

^ permalink raw reply related

* [PATCH 2/2][RESEND] ehea: fix last_rx update
From: Jan-Bernd Themann @ 2007-09-07 10:30 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel, linux-ppc,
	Christoph Raisch, Marcus Eder, Stefan Roscher

Update last_rx in registered device struct instead of
in the dummy device.

Signed-off-by: Jan-Bernd Themann <themann@de.ibm.com>

---
 drivers/net/ehea/ehea_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 1e9fd6f..717b129 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -471,7 +471,7 @@ static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev,
 			else
 				netif_receive_skb(skb);
 
-			dev->last_rx = jiffies;
+			port->netdev->last_rx = jiffies;
 		} else {
 			pr->p_stats.poll_receive_errors++;
 			port_reset = ehea_treat_poll_error(pr, rq, cqe,
-- 
1.5.2

^ permalink raw reply related

* [PATCH 0/5] DMA engine driver for Freescale MPC85xx processors.
From: Zhang Wei @ 2007-09-07 10:53 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

Hi,

These patches are DMA engine driver for Freescale MPC85xx processors
which the update for supporting new DMA engine API.

[PATCH 1/5] Add Freescale DMA and DMA channel to Documentation/powerpc/booting-without-of.txt file.
[PATCH 2/5] Add Freescale DMA engine driver maintainer.
[PATCH 3/5] Add DMA of-node to mpc8641hpcn board dts
[PATCH 4/5] Add of-device and DMA bus support to MPC8641HPCN board.
[PATCH 5/5] Add DMA engine driver for Freescale MPC85xx processors.

Best Regards,
Zhang Wei

^ permalink raw reply

* [PATCH 1/5] Add Freescale DMA and DMA channel to Documentation/powerpc/booting-without-of.txt file.
From: Zhang Wei @ 2007-09-07 10:53 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev
In-Reply-To: <11891624353752-git-send-email-wei.zhang@freescale.com>

This patch adds Freescale DMA and DMA channel definition to
Documentation/powerpc/booting-without-of.txt file.

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Ebony Zhu <ebony.zhu@freescale.com>
---
 Documentation/powerpc/booting-without-of.txt |   67 ++++++++++++++++++++++++++
 1 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index 76733a3..d114edf 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -52,6 +52,8 @@ Table of Contents
       i) Freescale QUICC Engine module (QE)
       j) Flash chip nodes
       k) Global Utilities Block
+      l) Freescale DMA
+      m) Freescale DMA channel
 
   VII - Specifying interrupt information for devices
     1) interrupts property
@@ -1824,6 +1826,71 @@ platforms are moved over to use the flattened-device-tree model.
 		fsl,has-rstcr;
 	};
 
+   l) Freescale DMA
+
+   The DMA for dma-engine driver of Freescale MPC8540 silicon DMA
+   controller which also fit for MPC8560, MPC8555,
+   MPC8548, MPC8641 and MPC8349 silicon DMA controller,
+
+   For each DMA node, you should define channels included.
+   Please see below 'm) Freescale DMA channel' for DMA channel's definition.
+
+   Required properties:
+
+    - compatible : Should be "fsl,dma".
+    - reg : Offset and length of DMA general status register.
+    - ranges : Should be defined as specified in 1) to describe the
+               DMA controller channels.
+
+  Example:
+	dma@21000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "fsl,dma";
+		reg = <21300 4>;
+		ranges = <0 21100 200>;
+		dma-channel@0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8540-dma-channel";
+			reg = <0 80>;
+			interrupt-parent = <&mpic>;
+			interrupts = <14 2>;
+		};
+		dma-channel@80 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8540-dma-channel";
+			reg = <80 80>;
+			interrupt-parent = <&mpic>;
+			interrupts = <15 2>;
+		};
+		dma-channel@100 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8540-dma-channel";
+			reg = <100 80>;
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+		dma-channel@180 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8540-dma-channel";
+			reg = <180 80>;
+			interrupt-parent = <&mpic>;
+			interrupts = <17 2>;
+		};
+	};
+
+   m) Freescale DMA channel
+
+   Required properties:
+
+    - compatible : Should be "fsl,mpc8540-dma-channel"
+                   or "fsl,mpc8349-dma-channel"
+    - reg : Offset and length of the register set for the DMA channel.
+
    More devices will be defined as this spec matures.
 
 VII - Specifying interrupt information for devices
-- 
1.5.2

^ permalink raw reply related

* [PATCH 2/5] Add Freescale DMA engine driver maintainer.
From: Zhang Wei @ 2007-09-07 10:53 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev
In-Reply-To: <1189162437484-git-send-email-wei.zhang@freescale.com>

This patch adds Freescale DMA engine driver maintainer.

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
---
 MAINTAINERS |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 01f222e..1be4f23 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1527,6 +1527,13 @@ L:	linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
 W:	http://linux-fbdev.sourceforge.net/
 S:	Maintained
 
+FREESCALE DMA DRIVER
+P;	Zhang Wei
+M:	wei.zhang@freescale.com
+L:	linuxppc-embedded@ozlabs.org
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 FREESCALE SOC FS_ENET DRIVER
 P:	Pantelis Antoniou
 M:	pantelis.antoniou@gmail.com
-- 
1.5.2

^ permalink raw reply related

* [PATCH 3/5] Add DMA of-node to mpc8641hpcn board dts
From: Zhang Wei @ 2007-09-07 10:53 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev
In-Reply-To: <11891624382764-git-send-email-wei.zhang@freescale.com>

This patch adds DMA of-node to MPC8641HPCN board dts.

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Ebony Zhu <ebony.zhu@freescale.com>
---
 arch/powerpc/boot/dts/mpc8641_hpcn.dts |   40 ++++++++++++++++++++++++++++++++
 1 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index 5d82709..e0175a4 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -433,5 +433,45 @@
 			device_type = "open-pic";
 			big-endian;
 		};
+
+		dma@21000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,dma";
+			reg = <21300 4>;
+			ranges = <0 21100 200>;
+			dma-channel@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "fsl,mpc8540-dma-channel";
+				reg = <0 80>;
+				interrupt-parent = <&mpic>;
+				interrupts = <14 2>;
+			};
+			dma-channel@80 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "fsl,mpc8540-dma-channel";
+				reg = <80 80>;
+				interrupt-parent = <&mpic>;
+				interrupts = <15 2>;
+			};
+			dma-channel@100 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "fsl,mpc8540-dma-channel";
+				reg = <100 80>;
+				interrupt-parent = <&mpic>;
+				interrupts = <16 2>;
+			};
+			dma-channel@180 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "fsl,mpc8540-dma-channel";
+				reg = <180 80>;
+				interrupt-parent = <&mpic>;
+				interrupts = <17 2>;
+			};
+		};
 	};
 };
-- 
1.5.2

^ permalink raw reply related

* [PATCH 4/5] Add of-device and DMA bus support to MPC8641HPCN board.
From: Zhang Wei @ 2007-09-07 10:53 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev
In-Reply-To: <11891624391565-git-send-email-wei.zhang@freescale.com>

This patch adds of-device and DMA device bus support
to MPC8641HPCN board.

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
---
 arch/powerpc/platforms/86xx/mpc86xx_hpcn.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index e9eaa07..e141259 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -18,6 +18,7 @@
 #include <linux/kdev_t.h>
 #include <linux/delay.h>
 #include <linux/seq_file.h>
+#include <linux/of_platform.h>
 
 #include <asm/system.h>
 #include <asm/time.h>
@@ -444,3 +445,19 @@ define_machine(mpc86xx_hpcn) {
 	.progress		= udbg_progress,
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
 };
+
+static struct of_device_id mpc86xx_of_ids[] = {
+	{ .type = "soc", },
+	{ .compatible = "fsl,dma", },
+	{},
+};
+
+static __init int mpc86xx_of_device_init(void)
+{
+	if (!machine_is(mpc86xx_hpcn))
+		return 0;
+
+	return of_platform_bus_probe(NULL, mpc86xx_of_ids, NULL);
+}
+
+device_initcall(mpc86xx_of_device_init);
-- 
1.5.2

^ permalink raw reply related

* [PATCH 5/5] Add DMA engine driver for Freescale MPC85xx processors.
From: Zhang Wei @ 2007-09-07 10:54 UTC (permalink / raw)
  To: paulus, shannon.nelson; +Cc: linuxppc-dev, linux-kernel

The driver implements DMA engine API for Freescale MPC85xx DMA
controller, which could be used for MEM<-->MEM, IO_ADDR<-->MEM
and IO_ADDR<-->IO_ADDR data transfer.
The driver supports the Basic mode of Freescale MPC85xx DMA controller.
The MPC85xx processors supported include MPC8540/60, MPC8555, MPC8548,
MPC8641 and so on.
The support for MPC83xx(MPC8349, MPC8360) is experimental.

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Ebony Zhu <ebony.zhu@freescale.com>
---
 drivers/dma/Kconfig  |    8 +
 drivers/dma/Makefile |    1 +
 drivers/dma/fsldma.c |  995 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/dma/fsldma.h |  188 ++++++++++
 4 files changed, 1192 insertions(+), 0 deletions(-)
 create mode 100644 drivers/dma/fsldma.c
 create mode 100644 drivers/dma/fsldma.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 8f670da..a99e925 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -40,4 +40,12 @@ config INTEL_IOP_ADMA
         ---help---
           Enable support for the Intel(R) IOP Series RAID engines.
 
+config FSL_DMA
+	bool "Freescale MPC85xx/MPC83xx DMA support"
+	depends on DMA_ENGINE && PPC
+	---help---
+	  Enable support for the Freescale DMA engine. Now, it support
+	  MPC8560/40, MPC8555, MPC8548 and MPC8641 processors.
+	  The MPC8349, MPC8360 support is experimental.
+
 endmenu
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index b3839b6..50ab26c 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
 obj-$(CONFIG_NET_DMA) += iovlock.o
 obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
 obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
+obj-$(CONFIG_FSL_DMA) += fsldma.o
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
new file mode 100644
index 0000000..9e2d56b
--- /dev/null
+++ b/drivers/dma/fsldma.c
@@ -0,0 +1,995 @@
+/*
+ * Freescale MPC85xx, MPC83xx DMA Engine support
+ *
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author:
+ *   Zhang Wei <wei.zhang@freescale.com>, Jul 2007
+ *   Ebony Zhu <ebony.zhu@freescale.com>, May 2007
+ *
+ * Description:
+ *   DMA engine driver for Freescale MPC8540 DMA controller, which is
+ *   also fit for MPC8560, MPC8555, MPC8548, MPC8641, and etc.
+ *   The support for MPC8349 DMA contorller is also added. But it's
+ *   ONLY experimental for MPC8349 now.
+ *
+ * This 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/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/dmaengine.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/of_platform.h>
+
+#include "fsldma.h"
+
+static LIST_HEAD(recy_ln_chain);	/* ld chain for recycle */
+static spinlock_t recy_ln_lock = SPIN_LOCK_UNLOCKED;
+
+static void dma_do_tasklet(unsigned long unused);
+static DECLARE_TASKLET(dma_tasklet, dma_do_tasklet, 0);
+
+#define to_fsl_chan(chan) container_of(chan, struct fsl_dma_chan, common)
+#define to_fsl_desc(lh) container_of(lh, struct fsl_desc_sw, node)
+#define tx_to_fsl_desc(tx) container_of(tx, struct fsl_desc_sw, async_tx)
+
+static void dma_init(struct fsl_dma_chan *fsl_chan)
+{
+	/* Reset the channel */
+	MIX_OUT(fsl_chan, &fsl_chan->reg_base->mr, 0, 32);
+
+	switch (fsl_chan->feature & FSL_DMA_IP_MASK) {
+	case FSL_DMA_IP_86XX:
+		/* Set the channel to below modes:
+		 * EIE - Error interrupt enable
+		 * EOSIE - End of segments interrupt enable (basic mode)
+		 * EOLNIE - End of links interrupt enable
+		 */
+		MIX_OUT(fsl_chan, &fsl_chan->reg_base->mr, FSL_DMA_MR_EIE
+				| FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32);
+		break;
+	case FSL_DMA_IP_83XX:
+		/* Set the channel to below modes:
+		 * EOTIE - End-of-transfer interrupt enable
+		 */
+		MIX_OUT(fsl_chan, &fsl_chan->reg_base->mr, FSL_DMA_MR_EOTIE,
+				32);
+		break;
+	}
+
+}
+
+static void set_sr(struct fsl_dma_chan *fsl_chan, dma_addr_t val)
+{
+	MIX_OUT(fsl_chan, &fsl_chan->reg_base->sr, val, 32);
+}
+
+static dma_addr_t get_sr(struct fsl_dma_chan *fsl_chan)
+{
+	return MIX_IN(fsl_chan, &fsl_chan->reg_base->sr, 32);
+}
+
+static void get_desc(struct fsl_dma_chan *fsl_chan, struct fsl_dma_ld_hw *hw,
+			struct fsl_ld_desc *ld)
+{
+	BUG_ON(!hw);
+
+	ld->src = MIX_TO_CPU(fsl_chan, hw->src_addr, 64);
+	ld->dest = MIX_TO_CPU(fsl_chan, hw->dst_addr, 64);
+	ld->count = MIX_TO_CPU(fsl_chan, hw->count, 32);
+	ld->next_ld_desc = MIX_TO_CPU(fsl_chan, hw->next_ln_addr, 64);
+
+	switch (fsl_chan->feature & FSL_DMA_IP_MASK) {
+	case FSL_DMA_IP_86XX:
+		ld->src &= (dma_addr_t)0x0000ffffffffffffull;
+		ld->dest &= (dma_addr_t)0x0000ffffffffffffull;
+		break;
+	case FSL_DMA_IP_83XX:
+		ld->next_ld_desc &= ~FSL_DMA_SNEN;
+		break;
+	}
+}
+
+static void set_desc(struct fsl_dma_chan *fsl_chan, struct fsl_dma_ld_hw *hw,
+			struct fsl_ld_desc *ld)
+{
+	hw->src_addr = (__mix64)CPU_TO_MIX(fsl_chan, ld->src, 64);
+	hw->dst_addr = (__mix64)CPU_TO_MIX(fsl_chan, ld->dest, 64);
+	hw->count = (__mix32)CPU_TO_MIX(fsl_chan, ld->count, 32);
+	hw->next_ln_addr = (__mix64)CPU_TO_MIX(fsl_chan, ld->next_ld_desc, 64);
+
+	switch (fsl_chan->feature & FSL_DMA_IP_MASK) {
+	case FSL_DMA_IP_86XX:
+		hw->src_addr.be |= CPU_TO_MIX(fsl_chan,
+					(u64)FSL_DMA_SATR_SREADTYPE_SNOOP_READ
+					<< 32, 64);
+		hw->dst_addr.be |= CPU_TO_MIX(fsl_chan,
+					(u64)FSL_DMA_DATR_DWRITETYPE_SNOOP_WRITE
+					<< 32, 64);
+		break;
+	case FSL_DMA_IP_83XX:
+		hw->next_ln_addr.le |= CPU_TO_MIX(fsl_chan, FSL_DMA_SNEN, 64);
+		break;
+	}
+}
+
+static void set_cdar(struct fsl_dma_chan *fsl_chan, dma_addr_t addr)
+{
+	MIX_OUT(fsl_chan, &fsl_chan->reg_base->cdar, addr | FSL_DMA_SNEN, 64);
+}
+
+static dma_addr_t get_cdar(struct fsl_dma_chan *fsl_chan)
+{
+	return MIX_IN(fsl_chan, &fsl_chan->reg_base->cdar, 64) & ~FSL_DMA_SNEN;
+}
+
+static void set_ndar(struct fsl_dma_chan *fsl_chan, dma_addr_t addr)
+{
+	MIX_OUT(fsl_chan, &fsl_chan->reg_base->ndar, addr, 64);
+}
+
+static dma_addr_t get_ndar(struct fsl_dma_chan *fsl_chan)
+{
+	return MIX_IN(fsl_chan, &fsl_chan->reg_base->ndar, 64);
+}
+
+static int dma_is_idle(struct fsl_dma_chan *fsl_chan)
+{
+	return (get_sr(fsl_chan) & FSL_DMA_SR_CB) == 0;
+}
+
+static void dma_start(struct fsl_dma_chan *fsl_chan)
+{
+	MIX_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+		MIX_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) | FSL_DMA_MR_CS,
+		32);
+}
+
+static void dma_halt(struct fsl_dma_chan *fsl_chan)
+{
+	MIX_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+		MIX_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) & ~FSL_DMA_MR_CS,
+		32);
+}
+
+static void set_ld_eol(struct fsl_dma_chan *fsl_chan,
+			struct fsl_desc_sw *desc)
+{
+	struct fsl_ld_desc ld;
+	get_desc(fsl_chan, &desc->hw, &ld);
+	ld.next_ld_desc |= FSL_DMA_EOL;
+	set_desc(fsl_chan, &desc->hw, &ld);
+}
+
+static void append_ld_queue(struct fsl_dma_chan *fsl_chan,
+		struct fsl_desc_sw *new_desc)
+{
+	struct fsl_ld_desc ld;
+	struct fsl_desc_sw *queue_tail = to_fsl_desc(fsl_chan->ld_queue.prev);
+
+	if (list_empty(&fsl_chan->ld_queue))
+		return;
+
+	get_desc(fsl_chan, &queue_tail->hw, &ld);
+	/* Link to the new descript physical address and
+	 * Enable End-of-segment interrupt for
+	 * the last link descriptor.
+	 * (the previous node's next link descriptor)
+	 */
+	ld.next_ld_desc = new_desc->async_tx.phys | FSL_DMA_EOSIE;
+	set_desc(fsl_chan, &queue_tail->hw, &ld);
+}
+
+static void fsl_dma_set_src(dma_addr_t addr,
+				struct dma_async_tx_descriptor *tx, int index)
+{
+	struct fsl_desc_sw *desc_node, *desc = tx_to_fsl_desc(tx);
+	struct fsl_dma_chan *fsl_chan = to_fsl_chan(tx->chan);
+
+	list_for_each_entry(desc_node, &desc->async_tx.tx_list, node) {
+		struct fsl_ld_desc ld;
+		get_desc(fsl_chan, &desc_node->hw, &ld);
+		ld.src = addr;
+		set_desc(fsl_chan, &desc_node->hw, &ld);
+		addr += FSL_DMA_BCR_MAX_CNT;
+	}
+}
+
+static void fsl_dma_set_dest(dma_addr_t addr,
+				struct dma_async_tx_descriptor *tx, int index)
+{
+	struct fsl_desc_sw *desc_node, *desc = tx_to_fsl_desc(tx);
+	struct fsl_dma_chan *fsl_chan = to_fsl_chan(tx->chan);
+
+	list_for_each_entry(desc_node, &desc->async_tx.tx_list, node) {
+		struct fsl_ld_desc ld;
+		get_desc(fsl_chan, &desc_node->hw, &ld);
+		ld.dest = addr;
+		set_desc(fsl_chan, &desc_node->hw, &ld);
+		addr += FSL_DMA_BCR_MAX_CNT;
+	}
+}
+
+static dma_cookie_t fsl_dma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct fsl_desc_sw *desc = tx_to_fsl_desc(tx);
+	struct fsl_dma_chan *fsl_chan = to_fsl_chan(tx->chan);
+	unsigned long flags;
+	dma_cookie_t cookie;
+
+	/* cookie increment and adding to ld_queue must be atomic */
+	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+
+	cookie = fsl_chan->common.cookie;
+	cookie++;
+	if (cookie < 0)
+		cookie = 1;
+	desc->async_tx.cookie = cookie;
+	fsl_chan->common.cookie = desc->async_tx.cookie;
+
+	append_ld_queue(fsl_chan, desc);
+	list_splice_init(&desc->async_tx.tx_list, fsl_chan->ld_queue.prev);
+
+	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+
+	return cookie;
+}
+
+/**
+ * fsl_dma_alloc_descriptor - Allocate descriptor from channel's DMA pool.
+ *
+ * Return - The descriptor allocated. NULL for failed.
+ */
+static struct fsl_desc_sw *fsl_dma_alloc_descriptor(
+					struct fsl_dma_chan *fsl_chan,
+					gfp_t flags)
+{
+	dma_addr_t pdesc;
+	struct fsl_desc_sw *desc_sw;
+
+	desc_sw = dma_pool_alloc(fsl_chan->desc_pool, flags, &pdesc);
+	if (desc_sw) {
+		memset(desc_sw, 0, sizeof(struct fsl_desc_sw));
+		dma_async_tx_descriptor_init(&desc_sw->async_tx,
+						&fsl_chan->common);
+		desc_sw->async_tx.tx_set_src = fsl_dma_set_src;
+		desc_sw->async_tx.tx_set_dest = fsl_dma_set_dest;
+		desc_sw->async_tx.tx_submit = fsl_dma_tx_submit;
+		INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
+		desc_sw->async_tx.phys = pdesc;
+	}
+
+	return desc_sw;
+}
+
+
+/**
+ * fsl_dma_alloc_chan_resources - Allocate resources for DMA channel.
+ *
+ * This function will create a dma pool for descriptor allocation.
+ *
+ * Return - The number of descriptors allocated.
+ */
+static int fsl_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+	LIST_HEAD(tmp_list);
+
+	/* We need the descriptor to be aligned to 32bytes
+	 * for meeting FSL DMA specification requirement.
+	 */
+	fsl_chan->desc_pool = dma_pool_create("fsl_dma_engine_desc_pool",
+			fsl_chan->device->dev, sizeof(struct fsl_desc_sw),
+			32, 0);
+	if (!fsl_chan->desc_pool) {
+		dev_err(fsl_chan->device->dev, "No memory for channel %d "
+			"descriptor dma pool.\n", fsl_chan->id);
+		return 0;
+	}
+
+	return 1;
+}
+
+/**
+ * fsl_dma_free_chan_resources - Free all resources of the channel.
+ */
+static void fsl_dma_free_chan_resources(struct dma_chan *chan)
+{
+	struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+	struct fsl_desc_sw *desc, *_desc;
+	unsigned long flags;
+
+	dev_dbg(fsl_chan->device->dev, "Free all channel resources.\n");
+	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+	list_for_each_entry_safe(desc, _desc, &fsl_chan->ld_queue, node) {
+#ifdef FSL_DMA_LD_DEBUG
+		dev_dbg(fsl_chan->device->dev,
+				"LD %p will be released.\n", desc);
+#endif
+		list_del(&desc->node);
+		/* free link descritpor */
+		dma_pool_free(fsl_chan->desc_pool, desc, desc->async_tx.phys);
+	}
+	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+	dma_pool_destroy(fsl_chan->desc_pool);
+}
+
+static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
+				struct dma_chan *chan, size_t len, int int_en)
+{
+	struct fsl_dma_chan *fsl_chan;
+	struct fsl_desc_sw *first = NULL, *prev = NULL, *new;
+	size_t copy;
+	struct fsl_dma_device *fdev;
+	LIST_HEAD(link_chain);
+
+	if (!chan)
+		return NULL;
+
+	if (!len)
+		return NULL;
+
+	fsl_chan = to_fsl_chan(chan);
+	fdev = fsl_chan->device;
+
+	do {
+		struct fsl_ld_desc ld;
+
+		/* Allocate the link descriptor from DMA pool */
+		new = fsl_dma_alloc_descriptor(fsl_chan, GFP_ATOMIC);
+		if (!new) {
+			dev_err(fdev->dev,
+					"No free memory for link descriptor\n");
+			return NULL;
+		}
+#ifdef FSL_DMA_LD_DEBUG
+		dev_dbg(fdev->dev, "new link desc alloc %p\n", new);
+#endif
+
+		copy = min(len, FSL_DMA_BCR_MAX_CNT);
+
+		memset(&ld, 0, sizeof(struct fsl_ld_desc));
+		ld.count = copy;
+		set_desc(fsl_chan, &new->hw, &ld);
+
+		if (!first)
+			first = new;
+		else {
+			get_desc(fsl_chan, &prev->hw, &ld);
+			ld.next_ld_desc = new->async_tx.phys;
+			set_desc(fsl_chan, &prev->hw, &ld);
+		}
+
+		new->async_tx.cookie = 0;
+		new->async_tx.ack = 1;
+
+		prev = new;
+		len -= copy;
+
+		/* Insert the link descriptor to the LD ring */
+		list_add_tail(&new->node, &first->async_tx.tx_list);
+	} while (len);
+
+	new->async_tx.ack = 0; /* client is in control of this ack */
+	new->async_tx.cookie = -EBUSY;
+
+	/* Set End-of-link to the last link descriptor of new list*/
+	set_ld_eol(fsl_chan, new);
+
+	return first ? &first->async_tx : NULL;
+}
+
+/**
+ * fsl_dma_update_completed_cookie - Update the completed cookie.
+ */
+static void fsl_dma_update_completed_cookie(struct fsl_dma_chan *fsl_chan)
+{
+	struct fsl_desc_sw *cur_desc;
+	dma_addr_t ld_phy;
+
+	ld_phy = get_cdar(fsl_chan) & FSL_DMA_NLDA_MASK;
+
+	if (ld_phy) {
+		cur_desc = (struct fsl_desc_sw *)bus_to_virt(ld_phy);
+
+		if (cur_desc->async_tx.cookie) {
+			if (dma_is_idle(fsl_chan))
+				fsl_chan->completed_cookie =
+					cur_desc->async_tx.cookie;
+			else
+				fsl_chan->completed_cookie =
+					cur_desc->async_tx.cookie - 1;
+		}
+	}
+}
+
+/**
+ * fsl_chan_ld_cleanup -- Clean up link descriptors
+ *
+ * This function clean up the ld_queue of DMA channel.
+ * If 'in_intr' is set, the function will move the link descriptor to
+ * the recycle list. Otherwise, free it directly.
+ */
+static void fsl_chan_ld_cleanup(struct fsl_dma_chan *fsl_chan, int in_intr)
+{
+	struct fsl_desc_sw *desc, *_desc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+
+	fsl_dma_update_completed_cookie(fsl_chan);
+	dev_dbg(fsl_chan->device->dev,
+			"chan completed_cookie = %d\n",
+			fsl_chan->completed_cookie);
+	list_for_each_entry_safe(desc, _desc, &fsl_chan->ld_queue, node) {
+		if (DMA_IN_PROGRESS == dma_async_is_complete(
+					desc->async_tx.cookie,
+					fsl_chan->completed_cookie,
+					fsl_chan->common.cookie))
+			break;
+
+		/* Remove from ld_queue list */
+		list_del(&desc->node);
+
+		/* If this function is called by interrupt action,
+		 * we just move to recycle list.
+		 * Otherwise, we free it.
+		 */
+		if (in_intr)
+			list_add_tail(&desc->node, &recy_ln_chain);
+		else {
+			/* Run the link descriptor callback function */
+			if (desc->async_tx.callback) {
+				spin_unlock_irqrestore(&fsl_chan->desc_lock,
+								flags);
+				dev_dbg(fsl_chan->device->dev,
+					"link descriptor %p callback\n", desc);
+				desc->async_tx.callback(
+						desc->async_tx.callback_param);
+				spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+			}
+
+			dev_dbg(fsl_chan->device->dev,
+				"link descriptor %p will be recycle.\n", desc);
+			dma_pool_free(fsl_chan->desc_pool, desc,
+						desc->async_tx.phys);
+		}
+	}
+	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+}
+
+/**
+ * fsl_chan_xfer_ld_queue -- Transfer the link descriptors in channel
+ *                           ld_queue.
+ */
+static void fsl_chan_xfer_ld_queue(struct fsl_dma_chan *fsl_chan)
+{
+	struct list_head *ld_node;
+	dma_addr_t next_dest_addr;
+	unsigned long flags;
+
+	if (!dma_is_idle(fsl_chan))
+		return;
+
+	dma_halt(fsl_chan);
+
+	/* If there are some link descriptors
+	 * not transfered in queue. We need to start it.
+	 */
+	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+
+	/* Find the first un-transfer desciptor */
+	for (ld_node = fsl_chan->ld_queue.next;
+		(ld_node != &fsl_chan->ld_queue)
+			&& (DMA_SUCCESS == dma_async_is_complete(
+					to_fsl_desc(ld_node)->async_tx.cookie,
+					fsl_chan->completed_cookie,
+					fsl_chan->common.cookie));
+		ld_node = ld_node->next);
+
+	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+
+	if (ld_node != &fsl_chan->ld_queue) {
+		/* Get the ld start address from ld_queue */
+		next_dest_addr = to_fsl_desc(ld_node)->async_tx.phys;
+		dev_dbg(fsl_chan->device->dev,
+			"xfer LDs staring from 0x%016llx\n",
+			(u64)next_dest_addr);
+		set_cdar(fsl_chan, next_dest_addr);
+		dma_start(fsl_chan);
+	} else {
+		set_cdar(fsl_chan, 0);
+		set_ndar(fsl_chan, 0);
+	}
+}
+
+/**
+ * fsl_dma_memcpy_issue_pending -- Issue the DMA start command
+ */
+static void fsl_dma_memcpy_issue_pending(struct dma_chan *chan)
+{
+	struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+
+#ifdef FSL_DMA_LD_DEBUG
+	struct fsl_desc_sw *ld;
+	unsigned long flags;
+
+	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+	if (list_empty(&fsl_chan->ld_queue)) {
+		spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+		return;
+	}
+
+	dev_dbg(fsl_chan->device->dev, "--memcpy issue--\n");
+	list_for_each_entry(ld, &fsl_chan->ld_queue, node) {
+		int i;
+		dev_dbg(fsl_chan->device->dev, "Ch %d, LD %08x\n",
+				fsl_chan->id, ld->async_tx.phys);
+		for (i = 0; i < 8; i++)
+			dev_dbg(fsl_chan->device->dev,
+					"LD offset %d: %08x\n",
+					i, *(((u32 *)&ld->hw) + i));
+	}
+	dev_dbg(fsl_chan->device->dev, "----------------\n");
+	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+#endif
+
+	fsl_chan_xfer_ld_queue(fsl_chan);
+}
+
+static void fsl_dma_dependency_added(struct dma_chan *chan)
+{
+	struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+
+	fsl_chan_ld_cleanup(fsl_chan, 0);
+}
+
+/**
+ * fsl_dma_is_complete -- Determine the DMA status
+ */
+static enum dma_status fsl_dma_is_complete(struct dma_chan *chan,
+					dma_cookie_t cookie,
+					dma_cookie_t *done,
+					dma_cookie_t *used)
+{
+	struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+	dma_cookie_t last_used;
+	dma_cookie_t last_complete;
+
+	fsl_chan_ld_cleanup(fsl_chan, 0);
+
+	last_used = chan->cookie;
+	last_complete = fsl_chan->completed_cookie;
+
+	if (done)
+		*done = last_complete;
+
+	if (used)
+		*used = last_used;
+
+	return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data)
+{
+	struct fsl_dma_chan *fsl_chan = (struct fsl_dma_chan *)data;
+	dma_addr_t stat;
+
+	stat = get_sr(fsl_chan);
+	dev_dbg(fsl_chan->device->dev, "event: channel %d, stat = 0x%x\n",
+						fsl_chan->id, stat);
+	set_sr(fsl_chan, stat);		/* Clear the event register */
+
+	stat &= ~(FSL_DMA_SR_CB | FSL_DMA_SR_CH);
+	if (!stat)
+		return IRQ_NONE;
+
+	/* If the link descriptor segment transfer finishes,
+	 * we will recycle the used descriptor.
+	 */
+	if (stat & FSL_DMA_SR_EOSI) {
+		dev_dbg(fsl_chan->device->dev, "event: End-of-segments INT\n");
+		dev_dbg(fsl_chan->device->dev, "event: clndar 0x%016llx, "
+				"nlndar 0x%016llx\n", (u64)get_cdar(fsl_chan),
+				(u64)get_ndar(fsl_chan));
+		stat &= ~FSL_DMA_SR_EOSI;
+		fsl_chan_ld_cleanup(fsl_chan, 1);
+	}
+
+	/* If it current transfer is the end-of-transfer,
+	 * we should clear the Channel Start bit for
+	 * prepare next transfer.
+	 */
+	if (stat & (FSL_DMA_SR_EOLNI | FSL_DMA_SR_EOCDI)) {
+		dev_dbg(fsl_chan->device->dev, "event: End-of-link INT\n");
+		stat &= ~FSL_DMA_SR_EOLNI;
+		fsl_chan_xfer_ld_queue(fsl_chan);
+	}
+
+	if (stat)
+		dev_dbg(fsl_chan->device->dev, "event: unhandled sr 0x%02x\n",
+					stat);
+
+	dev_dbg(fsl_chan->device->dev, "event: Exit\n");
+	tasklet_hi_schedule(&dma_tasklet);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t fsl_dma_do_interrupt(int irq, void *data)
+{
+	struct fsl_dma_device *fdev = (struct fsl_dma_device *)data;
+	struct fsl_dma_chan *fsl_chan = NULL;
+	u32 gsr;
+	int ch_nr;
+	struct dma_chan *int_chan;
+
+	gsr = (fdev->feature & FSL_DMA_BIG_ENDIAN) ? in_be32(fdev->reg_base)
+			: in_le32(fdev->reg_base);
+	ch_nr = (32 - ffs(gsr)) / 8;
+
+	list_for_each_entry(int_chan, &fdev->common.channels, device_node)
+		if (to_fsl_chan(int_chan)->id == ch_nr)
+			fsl_chan = to_fsl_chan(int_chan);
+
+	return fsl_chan ? fsl_dma_chan_do_interrupt(irq, fsl_chan) : IRQ_NONE;
+
+}
+
+static void dma_do_tasklet(unsigned long unused)
+{
+	struct fsl_desc_sw *desc, *_desc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&recy_ln_lock, flags);
+	list_for_each_entry_safe(desc, _desc, &recy_ln_chain, node) {
+		struct fsl_dma_chan *fsl_chan =
+					to_fsl_chan(desc->async_tx.chan);
+		/* Run the link descriptor callback function */
+		if (desc->async_tx.callback) {
+			spin_unlock_irqrestore(&recy_ln_lock, flags);
+			dev_dbg(fsl_chan->device->dev,
+				"dma_tasklet: link descriptor %p callback\n",
+				desc);
+			desc->async_tx.callback(
+					desc->async_tx.callback_param);
+			spin_lock_irqsave(&recy_ln_lock, flags);
+		}
+		/* Recycle it! */
+		list_del(&desc->node);
+		dev_dbg(fsl_chan->device->dev,
+			"dma_tasklet: link descriptor %p will be recycle.\n",
+			desc);
+		dma_pool_free(fsl_chan->desc_pool, desc,
+					desc->async_tx.phys);
+	}
+	spin_unlock_irqrestore(&recy_ln_lock, flags);
+}
+
+static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan)
+{
+	struct dma_chan *chan;
+	int err = 0;
+	dma_addr_t addr;
+	dma_cookie_t cookie;
+	u8 *src, *dest;
+	int i;
+	size_t test_size;
+	struct dma_async_tx_descriptor *tx1, *tx2, *tx3;
+	struct fsl_dma_device *fdev;
+
+	BUG_ON(!fsl_chan);
+
+	fdev = fsl_chan->device;
+	test_size = 4096;
+
+	src = kmalloc(test_size * 2, GFP_KERNEL);
+	if (!src) {
+		dev_err(fdev->dev,
+				"selftest: Can not alloc memory for test!\n");
+		err = -ENOMEM;
+		goto out;
+	}
+
+	dest = src + test_size;
+
+	for (i = 0; i < test_size; i++)
+		src[i] = (u8) i;
+
+	chan = &fsl_chan->common;
+
+	if (fsl_dma_alloc_chan_resources(chan) < 1) {
+		dev_err(fdev->dev,
+				"selftest: Can not alloc resources for DMA\n");
+		err = -ENODEV;
+		goto out;
+	}
+
+	/* TX 1 */
+	tx1 = fsl_dma_prep_memcpy(chan, test_size / 2, 0);
+	async_tx_ack(tx1);
+	addr = dma_map_single(chan->device->dev, src, test_size / 2,
+							DMA_TO_DEVICE);
+	fsl_dma_set_src(addr, tx1, 0);
+	addr = dma_map_single(chan->device->dev, dest, test_size / 2,
+							DMA_FROM_DEVICE);
+	fsl_dma_set_dest(addr, tx1, 0);
+
+	cookie = fsl_dma_tx_submit(tx1);
+	fsl_dma_memcpy_issue_pending(chan);
+
+	while (fsl_dma_is_complete(chan, cookie, NULL, NULL)
+			!= DMA_SUCCESS);
+
+	/* Test free and re-alloc channel resources */
+	fsl_dma_free_chan_resources(chan);
+
+	if (fsl_dma_alloc_chan_resources(chan) < 1) {
+		dev_err(fdev->dev,
+				"selftest: Can not alloc resources for DMA\n");
+		err = -ENODEV;
+		goto out;
+	}
+
+	/* Continue to test
+	 * TX 2
+	 */
+	tx2 = fsl_dma_prep_memcpy(chan, test_size / 4, 0);
+	async_tx_ack(tx2);
+	addr = dma_map_single(chan->device->dev, src + test_size / 2,
+					test_size / 4, DMA_TO_DEVICE);
+	fsl_dma_set_src(addr, tx2, 0);
+	addr = dma_map_single(chan->device->dev, dest + test_size / 2,
+					test_size / 4, DMA_FROM_DEVICE);
+	fsl_dma_set_dest(addr, tx2, 0);
+
+	/* TX 3 */
+	tx3 = fsl_dma_prep_memcpy(chan, test_size / 4, 0);
+	async_tx_ack(tx3);
+	addr = dma_map_single(chan->device->dev, src + test_size * 3 / 4,
+					test_size / 4, DMA_TO_DEVICE);
+	fsl_dma_set_src(addr, tx3, 0);
+	addr = dma_map_single(chan->device->dev, dest + test_size * 3 / 4,
+					test_size / 4, DMA_FROM_DEVICE);
+	fsl_dma_set_dest(addr, tx3, 0);
+
+	/* Test exchanging the prepared tx sort */
+	cookie = fsl_dma_tx_submit(tx3);
+	cookie = fsl_dma_tx_submit(tx2);
+
+	fsl_dma_memcpy_issue_pending(chan);
+	while (fsl_dma_is_complete(chan, cookie, NULL, NULL)
+			!= DMA_SUCCESS);
+	err = memcmp(src, dest, test_size);
+	if (err) {
+		for (i = 0; (*(src + i) == *(dest + i)) && (i < test_size);
+				i++);
+		dev_err(fdev->dev, "selftest: Test failed, data %d/%d is "
+				"error! src 0x%x, dest 0x%x\n",
+				i, test_size, *(src + i), *(dest + i));
+	}
+
+	fsl_dma_free_chan_resources(chan);
+
+out:
+	kfree(src);
+	return err;
+}
+
+static struct dma_chan *of_find_dma_chan_by_phandle(phandle phandle)
+{
+	struct device_node *np;
+	struct dma_chan *chan;
+	struct fsl_dma_device *fdev;
+
+	np = of_find_node_by_phandle(phandle);
+	if (!np || !of_device_is_compatible(np->parent, "fsl,dma"))
+		return NULL;
+
+	fdev = dev_get_drvdata(&of_find_device_by_node(np->parent)->dev);
+
+	list_for_each_entry(chan, &fdev->common.channels, device_node)
+		if (to_of_device(to_fsl_chan(chan)->chan_dev)->node == np)
+			return chan;
+	return NULL;
+}
+EXPORT_SYMBOL(of_find_dma_chan_by_phandle);
+
+static int __devinit of_fsl_dma_probe(struct of_device *dev,
+			const struct of_device_id *match)
+{
+	int err;
+	unsigned int irq;
+	struct fsl_dma_device *fdev;
+
+	fdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL);
+	if (!fdev) {
+		dev_err(&dev->dev, "No enough memory for 'priv'\n");
+		err = -ENOMEM;
+		goto err;
+	}
+	fdev->dev = &dev->dev;
+	INIT_LIST_HEAD(&fdev->common.channels);
+
+	/* get DMA controller register base */
+	err = of_address_to_resource(dev->node, 0, &fdev->reg);
+	if (err) {
+		dev_err(&dev->dev, "Can't get %s property 'reg'\n",
+				dev->node->full_name);
+		goto err;
+	}
+
+	dev_info(&dev->dev, "Probe the Freescale DMA driver for %s "
+			"controller at 0x%08x...\n",
+			match->compatible, fdev->reg.start);
+	fdev->reg_base = ioremap(fdev->reg.start, fdev->reg.end
+						- fdev->reg.start + 1);
+
+	dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask);
+	fdev->common.device_alloc_chan_resources = fsl_dma_alloc_chan_resources;
+	fdev->common.device_free_chan_resources = fsl_dma_free_chan_resources;
+	fdev->common.device_prep_dma_memcpy = fsl_dma_prep_memcpy;
+	fdev->common.device_is_tx_complete = fsl_dma_is_complete;
+	fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending;
+	fdev->common.device_dependency_added = fsl_dma_dependency_added;
+	fdev->common.dev = &dev->dev;
+
+	irq = irq_of_parse_and_map(dev->node, 0);
+	if (irq != NO_IRQ) {
+		err = request_irq(irq, &fsl_dma_do_interrupt, IRQF_SHARED,
+					"fsldma-device", fdev);
+		if (err) {
+			dev_err(&dev->dev, "DMA device request_irq error "
+				"with return %d\n", err);
+			goto err;
+		}
+	}
+
+	dev_set_drvdata(&(dev->dev), fdev);
+	dma_async_device_register(&fdev->common);
+	return 0;
+
+err:
+	iounmap(fdev->reg_base);
+	kfree(fdev);
+	return err;
+}
+
+static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
+			const struct of_device_id *match)
+{
+	struct fsl_dma_device *fdev;
+	struct fsl_dma_chan *new_fsl_chan;
+	int err;
+
+	fdev = dev_get_drvdata(dev->dev.parent);
+	BUG_ON(!fdev);
+
+	/* alloc channel */
+	new_fsl_chan = kzalloc(sizeof(struct fsl_dma_chan), GFP_KERNEL);
+	if (!new_fsl_chan) {
+		dev_err(&dev->dev, "No free memory for allocating "
+				"dma channels!\n");
+		err = -ENOMEM;
+		goto err;
+	}
+
+	/* get dma channel register base */
+	err = of_address_to_resource(dev->node, 0, &new_fsl_chan->reg);
+	if (err) {
+		dev_err(&dev->dev, "Can't get %s property 'reg'\n",
+				dev->node->full_name);
+		goto err;
+	}
+
+	if (strcmp(match->compatible, "fsl,mpc8540-dma-channel") == 0)
+		new_fsl_chan->feature = FSL_DMA_IP_86XX | FSL_DMA_BIG_ENDIAN;
+	else if (strcmp(match->compatible, "fsl,mpc8349-dma-channel") == 0)
+		new_fsl_chan->feature = FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN;
+	else {
+		dev_err(&dev->dev, "No channel operations!\n");
+		err = -EINVAL;
+		goto err;
+	}
+
+	if (!fdev->feature)
+		fdev->feature = new_fsl_chan->feature;
+
+	/* If the DMA device's feature is different than its channels',
+	 * report the bug.
+	 */
+	BUG_ON(fdev->feature != new_fsl_chan->feature);
+
+	new_fsl_chan->device = fdev;
+	new_fsl_chan->chan_dev = &dev->dev;
+	new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start,
+			new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1);
+
+	new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7;
+
+	/* Init the channel */
+	dma_init(new_fsl_chan);
+
+	/* Clear cdar registers */
+	set_cdar(new_fsl_chan, 0);
+
+	spin_lock_init(&new_fsl_chan->desc_lock);
+	INIT_LIST_HEAD(&new_fsl_chan->ld_queue);
+
+	new_fsl_chan->common.device = &fdev->common;
+
+	/* Add the channel to DMA device channel list */
+	list_add_tail(&new_fsl_chan->common.device_node,
+			&fdev->common.channels);
+	fdev->common.chancnt++;
+
+	new_fsl_chan->irq = irq_of_parse_and_map(dev->node, 0);
+	if (new_fsl_chan->irq != NO_IRQ) {
+		err = request_irq(new_fsl_chan->irq,
+					&fsl_dma_chan_do_interrupt, IRQF_SHARED,
+					"fsldma-channel", new_fsl_chan);
+		if (err) {
+			dev_err(&dev->dev, "DMA channel %s request_irq error "
+				"with return %d\n", dev->node->full_name, err);
+			goto err;
+		}
+	}
+
+	err = fsl_dma_self_test(new_fsl_chan);
+	if (err)
+		goto err;
+
+	dev_info(&dev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id,
+				match->compatible, new_fsl_chan->irq);
+
+	return 0;
+err:
+	dma_halt(new_fsl_chan);
+	iounmap(new_fsl_chan->reg_base);
+	free_irq(new_fsl_chan->irq, new_fsl_chan);
+	list_del(&new_fsl_chan->common.device_node);
+	kfree(new_fsl_chan);
+	return err;
+}
+
+static struct of_device_id of_fsl_dma_ids[] = {
+	{ .compatible = "fsl,dma", },
+};
+
+static struct of_platform_driver of_fsl_dma_driver = {
+	.name = "of-fsl-dma",
+	.match_table = of_fsl_dma_ids,
+	.probe = of_fsl_dma_probe,
+};
+
+static __init int of_fsl_dma_init(void)
+{
+	return of_register_platform_driver(&of_fsl_dma_driver);
+}
+
+static struct of_device_id of_fsl_dma_chan_ids[] = {
+	{ .compatible = "fsl,mpc8540-dma-channel", },
+	{ .compatible = "fsl,mpc8349-dma-channel", },
+};
+
+static struct of_platform_driver of_fsl_dma_chan_driver = {
+	.name = "of-fsl-dma-channel",
+	.match_table = of_fsl_dma_chan_ids,
+	.probe = of_fsl_dma_chan_probe,
+};
+
+static __init int of_fsl_dma_chan_init(void)
+{
+	return of_register_platform_driver(&of_fsl_dma_chan_driver);
+}
+
+subsys_initcall(of_fsl_dma_init);
+device_initcall(of_fsl_dma_chan_init);
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
new file mode 100644
index 0000000..05be9ed
--- /dev/null
+++ b/drivers/dma/fsldma.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author:
+ *   Zhang Wei <wei.zhang@freescale.com>, Jul 2007
+ *   Ebony Zhu <ebony.zhu@freescale.com>, May 2007
+ *
+ * Description:
+ *   This file defines data structures needed by Freescale
+ *   MPC8540 and MPC8349 DMA controller.
+ *
+ * This 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.
+ *
+ */
+#ifndef __FSLDMA_H
+#define __FSLDMA_H
+
+#include <linux/device.h>
+#include <linux/dmapool.h>
+#include <linux/dmaengine.h>
+
+#define FSL_DMA_MR_CS		0x00000001
+#define FSL_DMA_MR_CC		0x00000002
+#define FSL_DMA_MR_EIE		0x00000040
+#define FSL_DMA_MR_XFE		0x00000020
+#define FSL_DMA_MR_EOLNIE	0x00000100
+#define FSL_DMA_MR_EOLSIE	0x00000080
+#define FSL_DMA_MR_EOSIE	0x00000200
+#define FSL_DMA_MR_CDSM		0x00000010
+#define FSL_DMA_MR_CTM		0x00000004
+
+/* Special MR definition for MPC8349 */
+#define FSL_DMA_MR_EOTIE	0x00000080
+
+#define FSL_DMA_SR_CH		0x00000020
+#define FSL_DMA_SR_CB		0x00000004
+#define FSL_DMA_SR_TE		0x00000080
+#define FSL_DMA_SR_EOSI		0x00000002
+#define FSL_DMA_SR_EOLSI	0x00000001
+#define FSL_DMA_SR_EOCDI	0x00000001
+#define FSL_DMA_SR_EOLNI	0x00000008
+
+#define FSL_DMA_SATR_SBPATMU			0x20000000
+#define FSL_DMA_SATR_STRANSINT_RIO		0x00c00000
+#define FSL_DMA_SATR_SREADTYPE_SNOOP_READ	0x00050000
+#define FSL_DMA_SATR_SREADTYPE_BP_IORH		0x00020000
+#define FSL_DMA_SATR_SREADTYPE_BP_NREAD		0x00040000
+#define FSL_DMA_SATR_SREADTYPE_BP_MREAD		0x00070000
+
+#define FSL_DMA_DATR_DBPATMU			0x20000000
+#define FSL_DMA_DATR_DTRANSINT_RIO		0x00c00000
+#define FSL_DMA_DATR_DWRITETYPE_SNOOP_WRITE	0x00050000
+#define FSL_DMA_DATR_DWRITETYPE_BP_FLUSH	0x00010000
+
+#define FSL_DMA_EOL		((u64)0x1)
+#define FSL_DMA_SNEN		((u64)0x10)
+#define FSL_DMA_EOSIE		0x8
+#define FSL_DMA_NLDA_MASK	(~(u64)0x1f)
+
+#define FSL_DMA_BCR_MAX_CNT	0x03ffffffu
+
+#define FSL_DMA_DGSR_TE		0x80
+#define FSL_DMA_DGSR_CH		0x20
+#define FSL_DMA_DGSR_PE		0x10
+#define FSL_DMA_DGSR_EOLNI	0x08
+#define FSL_DMA_DGSR_CB		0x04
+#define FSL_DMA_DGSR_EOSI	0x02
+#define FSL_DMA_DGSR_EOLSI	0x01
+
+
+typedef union mix32 {
+	__le32	le;
+	__be32	be;
+} __mix32;
+
+typedef union mix64 {
+	__le64	le;
+	__be64	be;
+} __mix64;
+
+struct fsl_dma_ld_hw {
+	__mix64	src_addr;
+	__mix64	dst_addr;
+	__mix64	next_ln_addr;
+	__mix32	count;
+	__mix32	reserve;
+} __attribute__((aligned(32)));
+
+struct fsl_ld_desc {
+	dma_addr_t dest;
+	dma_addr_t src;
+	u32 count;
+	dma_addr_t next_ld_desc;
+};
+
+struct fsl_desc_sw {
+	struct fsl_dma_ld_hw hw;
+	struct list_head node;
+	struct dma_async_tx_descriptor async_tx;
+	struct list_head *ld;
+	void *priv;
+} __attribute__((aligned(32)));
+
+struct fsl_dma_chan_regs {
+	__mix32	mr;		/* 0x00 - Mode Register */
+	__mix32	sr;		/* 0x04 - Status Register */
+	__mix64	cdar;		/* 0x08 - Cureent descriptor address register */
+	__mix64	sar;		/* 0x10 - Source Address Register */
+	__mix64	dar;		/* 0x18 - Destination Address Register */
+	__mix32	bcr;		/* 0x20 - Byte Count Register */
+	__mix64	ndar;		/* 0x24 - Next Descriptor Address Register */
+};
+
+struct fsl_dma_device {
+	void __iomem *reg_base;		/* DGSR register base */
+	struct resource reg;		/* Resource for register */
+	struct device *dev;
+	struct dma_device common;
+	u32 feature;			/* The same as DMA channels */
+};
+
+/* Define macros for fsl_dma_chan->feature property */
+#define FSL_DMA_LITTLE_ENDIAN	0x00000000
+#define FSL_DMA_BIG_ENDIAN	0x00000001
+
+#define FSL_DMA_IP_MASK		0x00000ff0
+#define FSL_DMA_IP_86XX		0x00000010
+#define FSL_DMA_IP_83XX		0x00000020
+
+struct fsl_dma_chan {
+	struct fsl_dma_chan_regs __iomem *reg_base;
+	dma_cookie_t completed_cookie;	/* The maximum cookie completed */
+	spinlock_t desc_lock;
+	struct list_head ld_queue;	/* Link descriptors queue */
+	struct fsl_dma_device *device;
+	struct dma_chan common;
+	struct dma_pool *desc_pool;
+	struct device *chan_dev;
+	struct resource reg;		/* Resource for register */
+	int irq;
+	int id;				/* Raw id of this channel */
+	u32 feature;
+};
+
+#ifndef __powerpc64
+static u64 in_be64(const u64 __iomem *addr)
+{
+	return ((u64)in_be32((u32 *)addr) << 32) | (in_be32((u32 *)addr + 1));
+}
+
+static void out_be64(u64 __iomem *addr, u64 val)
+{
+	out_be32((u32 *)addr, val >> 32);
+	out_be32((u32 *)addr + 1, (u32)val);
+}
+
+/* There is no asm instructions for 64 bits reverse loads and stores */
+static u64 in_le64(const u64 __iomem *addr)
+{
+	return le64_to_cpu(in_be64(addr));
+}
+
+static void out_le64(u64 __iomem *addr, u64 val)
+{
+	out_be64(addr, cpu_to_le64(val));
+}
+#endif
+
+#define MIX_IN(fsl_chan, addr, width)					\
+		(((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ?		\
+			in_be##width(&(addr)->be) : in_le##width(&(addr)->le))
+#define MIX_OUT(fsl_chan, addr, val, width)				\
+		(((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ?		\
+			out_be##width(&(addr)->be, val) :		\
+			out_le##width(&(addr)->le, val))
+
+#define MIX_TO_CPU(fsl_chan, mix, width)				\
+		(((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ?		\
+			be##width##_to_cpu((mix).be) :			\
+			le##width##_to_cpu((mix).le))
+#define CPU_TO_MIX(fsl_chan, mix, width)				\
+		(((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ?		\
+			cpu_to_be##width(mix) : cpu_to_le##width(mix))
+
+#endif	/* __FSLDMA_H */
-- 
1.5.2

^ permalink raw reply related

* random panic and freezes on mpc8349 itx
From: Nicolas Schichan @ 2007-09-07 12:05 UTC (permalink / raw)
  To: linuxppc-embedded


Hi,

I am currently working with an MPC8349ITX board and I have some trouble with 
the kernel as soon as it reaches userland.

If I boot the kernel with all the memory (256MB) available (no mem=... on the 
command line), I get random freezes or random kernel panics. Some times it 
won't even run init. Some times it will panic badly if I try to put some 
pressure to the system (stress --cpu 256). Some times it will hang 
immediately after logging in, ...

If I boot the kernel with mem=64M, these freeze and random panic disapear and 
I am able to run the stress program without any problems.

I have had this strange behaviour on both kernel 2.6.20 and 2.6.22 with 
mpc834x_itx_defconfig (both from kernel.org) (ARCH=powerpc).

I am inclined to say that it is not a broken RAM chip problem because if I use 
a 2.6.17 from kernel.org with all the RAM available (ARCH=ppc) configured 
with mpc834x_sys_defconfig (there was no defconfig for the itx board on this 
version) everything runs fine and I am able to run the stress program without 
any problems.

The panic does not happen very often, 90% of the time, the board hangs and 
stops responding to ping. When a panic do happen it is almost always in a 
different place.

Does any of you have met this problem before ? If you have any clues about 
what is hapenning I'd be glad to hear about it :)

Thank you for your attention,

Regards,

-- 
Nicolas Schichan

^ permalink raw reply

* Re: random panic and freezes on mpc8349 itx
From: Clemens Koller @ 2007-09-07 12:24 UTC (permalink / raw)
  To: Nicolas Schichan; +Cc: linuxppc-embedded
In-Reply-To: <200709071405.06500.nschichan@freebox.fr>

Hi, Nicolas!

Nicolas Schichan schrieb:
> Hi,
> 
> I am currently working with an MPC8349ITX board and I have some trouble with 
> the kernel as soon as it reaches userland.
> 
> If I boot the kernel with all the memory (256MB) available (no mem=... on the 
> command line), I get random freezes or random kernel panics. Some times it 
> won't even run init. Some times it will panic badly if I try to put some 
> pressure to the system (stress --cpu 256). Some times it will hang 
> immediately after logging in, ...

Just some ideas how I prefer to roughly track down random crashes:

Check if the problems dependend of supply voltages, grounding or temperature.
Mounting a prototype to an aluminum board improved uptime a lot in one case.
If you don't see any variations at all, I would guess it's a problem caused
by software.

> If I boot the kernel with mem=64M, these freeze and random panic disapear and 
> I am able to run the stress program without any problems.
> 
> I have had this strange behaviour on both kernel 2.6.20 and 2.6.22 with 
> mpc834x_itx_defconfig (both from kernel.org) (ARCH=powerpc).
> 
> I am inclined to say that it is not a broken RAM chip problem because if I use 
> a 2.6.17 from kernel.org with all the RAM available (ARCH=ppc) configured 
> with mpc834x_sys_defconfig (there was no defconfig for the itx board on this 
> version) everything runs fine and I am able to run the stress program without 
> any problems.

Hmm... check the cpu/memory timing manually (by dumping some registers) and compare.
The two ARCHitectures might do things quite different in the meanwhile.
Otherwise, if you can stay within one ARCH, git bisect might be your friend here.

Regards,
-- 
Clemens Koller
__________________________________
R&D Imaging Devices
Anagramm GmbH
Rupert-Mayer-Straße 45/1
Linhof Werksgelände
D-81379 München
Tel.089-741518-50
Fax 089-741518-19
http://www.anagramm-technology.com

^ permalink raw reply

* Please pull from 'for-2.6.24' branch of 4xx tree
From: Josh Boyer @ 2007-09-07 13:16 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

Hi Paul,

Please do

git pull \
git://git.infradead.org/users/jwboyer/powerpc.git for-2.6.24

It contains the latest 4xx patches for 2.6.24.  Support for 440EPx and
405GP boards are added, a bugfix for 440EP, and a small cleanup of some
DTS files.

josh

 arch/powerpc/boot/4xx.c                |  108 +++++
 arch/powerpc/boot/4xx.h                |    1 +
 arch/powerpc/boot/Makefile             |    5 +-
 arch/powerpc/boot/cuboot-sequoia.c     |   56 +++
 arch/powerpc/boot/dcr.h                |    5 +
 arch/powerpc/boot/dts/ebony.dts        |    4 -
 arch/powerpc/boot/dts/holly.dts        |    4 -
 arch/powerpc/boot/dts/kuroboxHD.dts    |    3 -
 arch/powerpc/boot/dts/kuroboxHG.dts    |    3 -
 arch/powerpc/boot/dts/prpmc2800.dts    |    4 -
 arch/powerpc/boot/dts/sequoia.dts      |  286 ++++++++++++
 arch/powerpc/boot/dts/walnut.dts       |  183 ++++++++
 arch/powerpc/boot/treeboot-walnut.c    |  131 ++++++
 arch/powerpc/configs/sequoia_defconfig |  776 ++++++++++++++++++++++++++++++++
 arch/powerpc/configs/walnut_defconfig  |  773 +++++++++++++++++++++++++++++++
 arch/powerpc/kernel/cputable.c         |   18 +
 arch/powerpc/kernel/head_44x.S         |    2 +-
 arch/powerpc/platforms/40x/Kconfig     |   14 +-
 arch/powerpc/platforms/40x/Makefile    |    2 +-
 arch/powerpc/platforms/40x/walnut.c    |   68 +++
 arch/powerpc/platforms/44x/Kconfig     |   17 +-
 arch/powerpc/platforms/44x/Makefile    |    1 +
 arch/powerpc/platforms/44x/bamboo.c    |    2 +-
 arch/powerpc/platforms/44x/sequoia.c   |   66 +++
 arch/powerpc/platforms/Kconfig         |    2 +-
 arch/powerpc/platforms/Makefile        |    2 +-
 26 files changed, 2504 insertions(+), 32 deletions(-)
 create mode 100644 arch/powerpc/boot/cuboot-sequoia.c
 create mode 100644 arch/powerpc/boot/dts/sequoia.dts
 create mode 100644 arch/powerpc/boot/dts/walnut.dts
 create mode 100644 arch/powerpc/boot/treeboot-walnut.c
 create mode 100644 arch/powerpc/configs/sequoia_defconfig
 create mode 100644 arch/powerpc/configs/walnut_defconfig
 create mode 100644 arch/powerpc/platforms/40x/walnut.c
 create mode 100644 arch/powerpc/platforms/44x/sequoia.c

Josh Boyer (6):
      [POWERPC] Remove dtc build cruft from DTS files
      [POWERPC] Fix bus probe on Bamboo board
      [POWERPC] Walnut DTS
      [POWERPC] Walnut defconfig
      [POWERPC] Walnut board support
      [POWERPC] Walnut zImage wrapper

Valentine Barshak (4):
      [POWERPC] PowerPC 440EPx: Sequoia device tree
      [POWERPC] PowerPC 440EPx: Sequoia defconfig
      [POWERPC] PowerPC 440EPx: Sequoia board support
      [POWERPC] PowerPC 440EPx: Sequoia bootwrapper

^ permalink raw reply

* Re: dtc: Assume properties preced subnodes in the flattened tree
From: Jon Loeliger @ 2007-09-07 13:41 UTC (permalink / raw)
  To: David Gibson; +Cc: linuxppc-dev
In-Reply-To: <20070904004303.GC20549@localhost.localdomain>

So, like, the other day David Gibson mumbled:
> With kernel commit eff2ebd207af9f501af0ef667a7d14befcb36c1b, we
> clarified that in the flattened tree format, a particular nodes
> properties are required to precede its subdnodes.
> 
> At present however, both dtc and libfdt will process trees which don't
> meet this condition.  This patch simplifies the code for
> fdt_get_property() based on assuming that constraint.  dtc continues
> to be able to handle such an invalid tree - on the grounds that it's
> useful for dtc to be able to correct such a broken tree - but this
> patch adds a warning when this condition is not met while reading a
> flattened tree.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>


Applied.

Thanks,
jdl

^ 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