linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/5] of/irq: Move irq_of_parse_and_map() to common code
@ 2010-06-04 21:21 Grant Likely
  2010-06-04 21:21 ` [PATCH 3/5] of/irq: merge of_irq_find_parent() Grant Likely
                   ` (3 more replies)
  0 siblings, 4 replies; 18+ messages in thread
From: Grant Likely @ 2010-06-04 21:21 UTC (permalink / raw)
  Cc: Stephen Rothwell, Michal Simek, devicetree-discuss, linuxppc-dev,
	microblaze-uclinux, sparclinux, Jeremy Kerr, David S. Miller

Merge common code between PowerPC and Microblaze.  SPARC implements
irq_of_parse_and_map(), but the implementation is different, so it
does not use this code.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
CC: Michal Simek <monstr@monstr.eu>
CC: "David S. Miller" <davem@davemloft.net>
CC: Stephen Rothwell <sfr@canb.auug.org.au>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Jeremy Kerr <jeremy.kerr@canonical.com>
CC: microblaze-uclinux@itee.uq.edu.au
CC: linuxppc-dev@ozlabs.org
CC: sparclinux@vger.kernel.org
CC: devicetree-discuss@lists.ozlabs.org
---
 arch/microblaze/include/asm/irq.h  |   13 -----------
 arch/microblaze/include/asm/prom.h |   26 +----------------------
 arch/microblaze/kernel/irq.c       |   14 ++----------
 arch/powerpc/include/asm/irq.h     |   13 -----------
 arch/powerpc/include/asm/prom.h    |   27 +-----------------------
 arch/powerpc/kernel/irq.c          |   14 ++----------
 arch/sparc/include/asm/prom.h      |    1 -
 drivers/of/Kconfig                 |    4 ++++
 drivers/of/Makefile                |    1 +
 drivers/of/irq.c                   |   37 ++++++++++++++++++++++++++++++++
 drivers/of/of_mdio.c               |    1 +
 include/linux/of_irq.h             |   41 ++++++++++++++++++++++++++++++++++++
 12 files changed, 90 insertions(+), 102 deletions(-)
 create mode 100644 drivers/of/irq.c
 create mode 100644 include/linux/of_irq.h

diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h
index 31a35c3..10d75c1 100644
--- a/arch/microblaze/include/asm/irq.h
+++ b/arch/microblaze/include/asm/irq.h
@@ -62,17 +62,4 @@ struct irq_host;
 extern unsigned int irq_create_mapping(struct irq_host *host,
 					irq_hw_number_t hwirq);
 
-/**
- * irq_create_of_mapping - Map a hardware interrupt into linux virq space
- * @controller: Device node of the interrupt controller
- * @inspec: Interrupt specifier from the device-tree
- * @intsize: Size of the interrupt specifier from the device-tree
- *
- * This function is identical to irq_create_mapping except that it takes
- * as input informations straight from the device-tree (typically the results
- * of the of_irq_map_*() functions.
- */
-extern unsigned int irq_create_of_mapping(struct device_node *controller,
-					u32 *intspec, unsigned int intsize);
-
 #endif /* _ASM_MICROBLAZE_IRQ_H */
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index e7d67a3..e9fb2eb 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -20,6 +20,7 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
+#include <linux/of_irq.h>
 #include <linux/of_fdt.h>
 #include <linux/proc_fs.h>
 #include <linux/platform_device.h>
@@ -92,18 +93,6 @@ extern const void *of_get_mac_address(struct device_node *np);
  * OF interrupt mapping
  */
 
-/* This structure is returned when an interrupt is mapped. The controller
- * field needs to be put() after use
- */
-
-#define OF_MAX_IRQ_SPEC		4 /* We handle specifiers of at most 4 cells */
-
-struct of_irq {
-	struct device_node *controller; /* Interrupt controller node */
-	u32 size; /* Specifier size */
-	u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
-};
-
 /**
  * of_irq_map_init - Initialize the irq remapper
  * @flags:	flags defining workarounds to enable
@@ -139,19 +128,6 @@ extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
 			struct of_irq *out_irq);
 
 /**
- * of_irq_map_one - Resolve an interrupt for a device
- * @device:	the device whose interrupt is to be resolved
- * @index:	index of the interrupt to resolve
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves an interrupt, walking the tree, for a given
- * device-tree node. It's the high level pendant to of_irq_map_raw().
- * It also implements the workarounds for OldWolrd Macs.
- */
-extern int of_irq_map_one(struct device_node *device, int index,
-			struct of_irq *out_irq);
-
-/**
  * of_irq_map_pci - Resolve the interrupt for a PCI device
  * @pdev:	the device whose interrupt is to be resolved
  * @out_irq:	structure of_irq filled by this function
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
index 8f120ac..dd32b09 100644
--- a/arch/microblaze/kernel/irq.c
+++ b/arch/microblaze/kernel/irq.c
@@ -17,20 +17,10 @@
 #include <linux/seq_file.h>
 #include <linux/kernel_stat.h>
 #include <linux/irq.h>
+#include <linux/of_irq.h>
 
 #include <asm/prom.h>
 
-unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
-{
-	struct of_irq oirq;
-
-	if (of_irq_map_one(dev, index, &oirq))
-		return NO_IRQ;
-
-	return oirq.specifier[0];
-}
-EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
-
 static u32 concurrent_irq;
 
 void __irq_entry do_IRQ(struct pt_regs *regs)
@@ -104,7 +94,7 @@ unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
 EXPORT_SYMBOL_GPL(irq_create_mapping);
 
 unsigned int irq_create_of_mapping(struct device_node *controller,
-					u32 *intspec, unsigned int intsize)
+				   const u32 *intspec, unsigned int intsize)
 {
 	return intspec[0];
 }
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index e054bae..a3b5124 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -304,19 +304,6 @@ extern void irq_free_virt(unsigned int virq, unsigned int count);
 /* -- OF helpers -- */
 
 /**
- * irq_create_of_mapping - Map a hardware interrupt into linux virq space
- * @controller: Device node of the interrupt controller
- * @inspec: Interrupt specifier from the device-tree
- * @intsize: Size of the interrupt specifier from the device-tree
- *
- * This function is identical to irq_create_mapping except that it takes
- * as input informations straight from the device-tree (typically the results
- * of the of_irq_map_*() functions.
- */
-extern unsigned int irq_create_of_mapping(struct device_node *controller,
-					  const u32 *intspec, unsigned int intsize);
-
-/**
  * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
  * @device: Device node of the device whose interrupt is to be mapped
  * @index: Index of the interrupt to map
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index ddd408a..47d41b6 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -18,6 +18,7 @@
  */
 #include <linux/types.h>
 #include <linux/of_fdt.h>
+#include <linux/of_irq.h>
 #include <linux/proc_fs.h>
 #include <linux/platform_device.h>
 #include <asm/irq.h>
@@ -108,18 +109,6 @@ extern const void *of_get_mac_address(struct device_node *np);
  * OF interrupt mapping
  */
 
-/* This structure is returned when an interrupt is mapped. The controller
- * field needs to be put() after use
- */
-
-#define OF_MAX_IRQ_SPEC		 4 /* We handle specifiers of at most 4 cells */
-
-struct of_irq {
-	struct device_node *controller;	/* Interrupt controller node */
-	u32 size;			/* Specifier size */
-	u32 specifier[OF_MAX_IRQ_SPEC];	/* Specifier copy */
-};
-
 /**
  * of_irq_map_init - Initialize the irq remapper
  * @flags:	flags defining workarounds to enable
@@ -154,20 +143,6 @@ extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
 			  u32 ointsize, const u32 *addr,
 			  struct of_irq *out_irq);
 
-
-/**
- * of_irq_map_one - Resolve an interrupt for a device
- * @device:	the device whose interrupt is to be resolved
- * @index:     	index of the interrupt to resolve
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves an interrupt, walking the tree, for a given
- * device-tree node. It's the high level pendant to of_irq_map_raw().
- * It also implements the workarounds for OldWolrd Macs.
- */
-extern int of_irq_map_one(struct device_node *device, int index,
-			  struct of_irq *out_irq);
-
 /**
  * of_irq_map_pci - Resolve the interrupt for a PCI device
  * @pdev:	the device whose interrupt is to be resolved
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 30817d9..2676ef2 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -53,6 +53,8 @@
 #include <linux/bootmem.h>
 #include <linux/pci.h>
 #include <linux/debugfs.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -813,18 +815,6 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
 }
 EXPORT_SYMBOL_GPL(irq_create_of_mapping);
 
-unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
-{
-	struct of_irq oirq;
-
-	if (of_irq_map_one(dev, index, &oirq))
-		return NO_IRQ;
-
-	return irq_create_of_mapping(oirq.controller, oirq.specifier,
-				     oirq.size);
-}
-EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
-
 void irq_dispose_mapping(unsigned int virq)
 {
 	struct irq_host *host;
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h
index f845828..ac69574 100644
--- a/arch/sparc/include/asm/prom.h
+++ b/arch/sparc/include/asm/prom.h
@@ -56,7 +56,6 @@ extern void of_fill_in_cpu_data(void);
  * register them in the of_device objects, whereas powerpc computes them
  * on request.
  */
-extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
 static inline void irq_dispose_mapping(unsigned int virq)
 {
 }
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 7cecc8f..b87495e 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -6,6 +6,10 @@ config OF_DYNAMIC
 	def_bool y
 	depends on OF && PPC_OF
 
+config OF_IRQ
+	def_bool y
+	depends on OF && !SPARC
+
 config OF_DEVICE
 	def_bool y
 	depends on OF && (SPARC || PPC_OF || MICROBLAZE)
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index f232cc9..3631a5e 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,5 +1,6 @@
 obj-y = base.o
 obj-$(CONFIG_OF_FLATTREE) += fdt.o
+obj-$(CONFIG_OF_IRQ)    += irq.o
 obj-$(CONFIG_OF_DEVICE) += device.o platform.o
 obj-$(CONFIG_OF_GPIO)   += gpio.o
 obj-$(CONFIG_OF_I2C)	+= of_i2c.o
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
new file mode 100644
index 0000000..56ad1aa
--- /dev/null
+++ b/drivers/of/irq.c
@@ -0,0 +1,37 @@
+/*
+ *  Derived from arch/i386/kernel/irq.c
+ *    Copyright (C) 1992 Linus Torvalds
+ *  Adapted from arch/i386 by Gary Thomas
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *  Updated and modified by Cort Dougan <cort@fsmlabs.com>
+ *    Copyright (C) 1996-2001 Cort Dougan
+ *  Adapted for Power Macintosh by Paul Mackerras
+ *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * This file contains the code used to make IRQ descriptions in the
+ * device tree to actual irq numbers on an interrupt controller
+ * driver.
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/string.h>
+
+unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
+{
+	struct of_irq oirq;
+
+	if (of_irq_map_one(dev, index, &oirq))
+		return NO_IRQ;
+
+	return irq_create_of_mapping(oirq.controller, oirq.specifier,
+				     oirq.size);
+}
+EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 42a6715..1fce00e 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -15,6 +15,7 @@
 #include <linux/err.h>
 #include <linux/phy.h>
 #include <linux/of.h>
+#include <linux/of_irq.h>
 #include <linux/of_mdio.h>
 #include <linux/module.h>
 
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
new file mode 100644
index 0000000..0e37c05
--- /dev/null
+++ b/include/linux/of_irq.h
@@ -0,0 +1,41 @@
+#ifndef __OF_IRQ_H
+#define __OF_IRQ_H
+
+#if defined(CONFIG_OF)
+struct of_irq;
+#include <linux/types.h>
+#include <linux/of.h>
+
+/*
+ * irq_of_parse_and_map() is used ba all OF enabled platforms; but SPARC
+ * implements it differently.  However, the prototype is the same for all,
+ * so declare it here regardless of the CONFIG_OF_IRQ setting.
+ */
+extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
+
+#if defined(CONFIG_OF_IRQ)
+/**
+ * of_irq - container for device_node/irq_specifier pair for an irq controller
+ * @controller: pointer to interrupt controller device tree node
+ * @size: size of interrupt specifier
+ * @specifier: array of cells @size long specifing the specific interrupt
+ *
+ * This structure is returned when an interrupt is mapped. The controller
+ * field needs to be put() after use
+ */
+#define OF_MAX_IRQ_SPEC		4 /* We handle specifiers of at most 4 cells */
+struct of_irq {
+	struct device_node *controller; /* Interrupt controller node */
+	u32 size; /* Specifier size */
+	u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
+};
+
+extern int of_irq_map_one(struct device_node *device, int index,
+			  struct of_irq *out_irq);
+extern unsigned int irq_create_of_mapping(struct device_node *controller,
+					  const u32 *intspec,
+					  unsigned int intsize);
+
+#endif /* CONFIG_OF_IRQ */
+#endif /* CONFIG_OF */
+#endif /* __OF_IRQ_H */

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 3/5] of/irq: merge of_irq_find_parent()
  2010-06-04 21:21 [PATCH 1/5] of/irq: Move irq_of_parse_and_map() to common code Grant Likely
@ 2010-06-04 21:21 ` Grant Likely
  2010-06-10  6:38   ` Benjamin Herrenschmidt
  2010-06-04 21:21 ` [PATCH 4/5] of/irq: Merge of_irq_map_raw() Grant Likely
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 18+ messages in thread
From: Grant Likely @ 2010-06-04 21:21 UTC (permalink / raw)
  Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
	devicetree-discuss, linuxppc-dev

Merge common code between PowerPC and Microblaze.  Also create a new
arch hook, of_irq_find_parent_by_phandle() to handle arch-specific
quirks.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
CC: Michal Simek <monstr@monstr.eu>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Stephen Rothwell <sfr@canb.auug.org.au>
CC: microblaze-uclinux@itee.uq.edu.au
CC: linuxppc-dev@lists.ozlabs.org
CC: devicetree-discuss@lists.ozlabs.org
---
 arch/microblaze/kernel/prom_parse.c |   22 +++-------------------
 arch/powerpc/kernel/prom_parse.c    |   30 +++++-------------------------
 drivers/of/irq.c                    |   28 ++++++++++++++++++++++++++++
 include/linux/of_irq.h              |    2 ++
 4 files changed, 38 insertions(+), 44 deletions(-)

diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
index af1b2a7..946f14d 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -648,25 +648,9 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
  * Interrupt remapper
  */
 
-static struct device_node *of_irq_find_parent(struct device_node *child)
+struct device_node *of_irq_find_parent_by_phandle(phandle p)
 {
-	struct device_node *p;
-	const phandle *parp;
-
-	if (!of_node_get(child))
-		return NULL;
-
-	do {
-		parp = of_get_property(child, "interrupt-parent", NULL);
-		if (parp == NULL)
-			p = of_get_parent(child);
-		else
-			p = of_find_node_by_phandle(*parp);
-		of_node_put(child);
-		child = p;
-	} while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
-
-	return p;
+	return of_find_node_by_phandle(p);
 }
 
 int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
@@ -783,7 +767,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
 			pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
 
 			/* Get the interrupt parent */
-			newpar = of_find_node_by_phandle((phandle)*imap);
+			newpar = of_irq_find_parent_by_phandle((phandle)*imap);
 			imap++;
 			--imaplen;
 
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 8362620..39e977d 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -685,29 +685,12 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 static unsigned int of_irq_workarounds;
 static struct device_node *of_irq_dflt_pic;
 
-static struct device_node *of_irq_find_parent(struct device_node *child)
+struct device_node *of_irq_find_parent_by_phandle(phandle p)
 {
-	struct device_node *p;
-	const phandle *parp;
-
-	if (!of_node_get(child))
-		return NULL;
-
-	do {
-		parp = of_get_property(child, "interrupt-parent", NULL);
-		if (parp == NULL)
-			p = of_get_parent(child);
-		else {
-			if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
-				p = of_node_get(of_irq_dflt_pic);
-			else
-				p = of_find_node_by_phandle(*parp);
-		}
-		of_node_put(child);
-		child = p;
-	} while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
+	if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
+		return of_node_get(of_irq_dflt_pic);
 
-	return p;
+	return of_find_node_by_phandle(p);
 }
 
 /* This doesn't need to be called if you don't have any special workaround
@@ -859,10 +842,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
 			DBG(" -> match=%d (imaplen=%d)\n", match, imaplen);
 
 			/* Get the interrupt parent */
-			if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
-				newpar = of_node_get(of_irq_dflt_pic);
-			else
-				newpar = of_find_node_by_phandle((phandle)*imap);
+			newpar = of_irq_find_parent_by_phandle((phandle)*imap);
 			imap++;
 			--imaplen;
 
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 56ad1aa..ad569ca 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -24,6 +24,34 @@
 #include <linux/of_irq.h>
 #include <linux/string.h>
 
+/**
+ * of_irq_find_parent - Given a device node, find its interrupt parent node
+ * @child: pointer to device node
+ *
+ * Returns a pointer to the interrupt parent node, or NULL if the interrupt
+ * parent could not be determined.
+ */
+struct device_node *of_irq_find_parent(struct device_node *child)
+{
+	struct device_node *p;
+	const phandle *parp;
+
+	if (!of_node_get(child))
+		return NULL;
+
+	do {
+		parp = of_get_property(child, "interrupt-parent", NULL);
+		if (parp == NULL)
+			p = of_get_parent(child);
+		else
+			p = of_irq_find_parent_by_phandle(*parp);
+		of_node_put(child);
+		child = p;
+	} while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
+
+	return p;
+}
+
 unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
 {
 	struct of_irq oirq;
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index 0e37c05..f98b27b 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -30,6 +30,8 @@ struct of_irq {
 	u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
 };
 
+extern struct device_node *of_irq_find_parent_by_phandle(phandle p);
+extern struct device_node *of_irq_find_parent(struct device_node *child);
 extern int of_irq_map_one(struct device_node *device, int index,
 			  struct of_irq *out_irq);
 extern unsigned int irq_create_of_mapping(struct device_node *controller,

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 4/5] of/irq: Merge of_irq_map_raw()
  2010-06-04 21:21 [PATCH 1/5] of/irq: Move irq_of_parse_and_map() to common code Grant Likely
  2010-06-04 21:21 ` [PATCH 3/5] of/irq: merge of_irq_find_parent() Grant Likely
@ 2010-06-04 21:21 ` Grant Likely
  2010-06-10  6:38   ` Benjamin Herrenschmidt
  2010-06-04 21:21 ` [PATCH 5/5] of/irq: merge of_irq_map_one() Grant Likely
  2010-06-10  6:33 ` [PATCH 1/5] of/irq: Move irq_of_parse_and_map() to common code Benjamin Herrenschmidt
  3 siblings, 1 reply; 18+ messages in thread
From: Grant Likely @ 2010-06-04 21:21 UTC (permalink / raw)
  Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
	devicetree-discuss, linuxppc-dev

Merge common code between PowerPC and Microblaze

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
CC: Michal Simek <monstr@monstr.eu>
CC: Wolfram Sang <w.sang@pengutronix.de>
CC: Stephen Rothwell <sfr@canb.auug.org.au>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: microblaze-uclinux@itee.uq.edu.au
CC: linuxppc-dev@ozlabs.org
CC: devicetree-discuss@lists.ozlabs.org
---
 arch/microblaze/include/asm/prom.h  |   21 ----
 arch/microblaze/kernel/prom_parse.c |  176 ---------------------------------
 arch/powerpc/include/asm/prom.h     |   21 ----
 arch/powerpc/kernel/prom_parse.c    |  171 --------------------------------
 drivers/of/irq.c                    |  188 +++++++++++++++++++++++++++++++++++
 include/linux/of_irq.h              |    2 
 6 files changed, 190 insertions(+), 389 deletions(-)

diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index da7069c..89fca70 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -94,27 +94,6 @@ extern const void *of_get_mac_address(struct device_node *np);
  */
 
 /**
- * of_irq_map_raw - Low level interrupt tree parsing
- * @parent:	the device interrupt parent
- * @intspec:	interrupt specifier ("interrupts" property of the device)
- * @ointsize:	size of the passed in interrupt specifier
- * @addr:	address specifier (start of "reg" property of the device)
- * @out_irq:	structure of_irq filled by this function
- *
- * Returns 0 on success and a negative number on error
- *
- * This function is a low-level interrupt tree walking function. It
- * can be used to do a partial walk with synthetized reg and interrupts
- * properties, for example when resolving PCI interrupts when no device
- * node exist for the parent.
- *
- */
-
-extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
-			u32 ointsize, const u32 *addr,
-			struct of_irq *out_irq);
-
-/**
  * of_irq_map_pci - Resolve the interrupt for a PCI device
  * @pdev:	the device whose interrupt is to be resolved
  * @out_irq:	structure of_irq filled by this function
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
index 946f14d..02ec946 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -653,182 +653,6 @@ struct device_node *of_irq_find_parent_by_phandle(phandle p)
 	return of_find_node_by_phandle(p);
 }
 
-int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
-		const u32 *addr, struct of_irq *out_irq)
-{
-	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
-	const u32 *tmp, *imap, *imask;
-	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
-	int imaplen, match, i;
-
-	pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],"
-		"ointsize=%d\n",
-		parent->full_name, intspec[0], intspec[1], ointsize);
-
-	ipar = of_node_get(parent);
-
-	/* First get the #interrupt-cells property of the current cursor
-	 * that tells us how to interpret the passed-in intspec. If there
-	 * is none, we are nice and just walk up the tree
-	 */
-	do {
-		tmp = of_get_property(ipar, "#interrupt-cells", NULL);
-		if (tmp != NULL) {
-			intsize = *tmp;
-			break;
-		}
-		tnode = ipar;
-		ipar = of_irq_find_parent(ipar);
-		of_node_put(tnode);
-	} while (ipar);
-	if (ipar == NULL) {
-		pr_debug(" -> no parent found !\n");
-		goto fail;
-	}
-
-	pr_debug("of_irq_map_raw: ipar=%s, size=%d\n",
-			ipar->full_name, intsize);
-
-	if (ointsize != intsize)
-		return -EINVAL;
-
-	/* Look for this #address-cells. We have to implement the old linux
-	 * trick of looking for the parent here as some device-trees rely on it
-	 */
-	old = of_node_get(ipar);
-	do {
-		tmp = of_get_property(old, "#address-cells", NULL);
-		tnode = of_get_parent(old);
-		of_node_put(old);
-		old = tnode;
-	} while (old && tmp == NULL);
-	of_node_put(old);
-	old = NULL;
-	addrsize = (tmp == NULL) ? 2 : *tmp;
-
-	pr_debug(" -> addrsize=%d\n", addrsize);
-
-	/* Now start the actual "proper" walk of the interrupt tree */
-	while (ipar != NULL) {
-		/* Now check if cursor is an interrupt-controller and if it is
-		 * then we are done
-		 */
-		if (of_get_property(ipar, "interrupt-controller", NULL) !=
-				NULL) {
-			pr_debug(" -> got it !\n");
-			memcpy(out_irq->specifier, intspec,
-				intsize * sizeof(u32));
-			out_irq->size = intsize;
-			out_irq->controller = ipar;
-			of_node_put(old);
-			return 0;
-		}
-
-		/* Now look for an interrupt-map */
-		imap = of_get_property(ipar, "interrupt-map", &imaplen);
-		/* No interrupt map, check for an interrupt parent */
-		if (imap == NULL) {
-			pr_debug(" -> no map, getting parent\n");
-			newpar = of_irq_find_parent(ipar);
-			goto skiplevel;
-		}
-		imaplen /= sizeof(u32);
-
-		/* Look for a mask */
-		imask = of_get_property(ipar, "interrupt-map-mask", NULL);
-
-		/* If we were passed no "reg" property and we attempt to parse
-		 * an interrupt-map, then #address-cells must be 0.
-		 * Fail if it's not.
-		 */
-		if (addr == NULL && addrsize != 0) {
-			pr_debug(" -> no reg passed in when needed !\n");
-			goto fail;
-		}
-
-		/* Parse interrupt-map */
-		match = 0;
-		while (imaplen > (addrsize + intsize + 1) && !match) {
-			/* Compare specifiers */
-			match = 1;
-			for (i = 0; i < addrsize && match; ++i) {
-				u32 mask = imask ? imask[i] : 0xffffffffu;
-				match = ((addr[i] ^ imap[i]) & mask) == 0;
-			}
-			for (; i < (addrsize + intsize) && match; ++i) {
-				u32 mask = imask ? imask[i] : 0xffffffffu;
-				match =
-					((intspec[i-addrsize] ^ imap[i])
-						& mask) == 0;
-			}
-			imap += addrsize + intsize;
-			imaplen -= addrsize + intsize;
-
-			pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
-
-			/* Get the interrupt parent */
-			newpar = of_irq_find_parent_by_phandle((phandle)*imap);
-			imap++;
-			--imaplen;
-
-			/* Check if not found */
-			if (newpar == NULL) {
-				pr_debug(" -> imap parent not found !\n");
-				goto fail;
-			}
-
-			/* Get #interrupt-cells and #address-cells of new
-			 * parent
-			 */
-			tmp = of_get_property(newpar, "#interrupt-cells", NULL);
-			if (tmp == NULL) {
-				pr_debug(" -> parent lacks "
-						"#interrupt-cells!\n");
-				goto fail;
-			}
-			newintsize = *tmp;
-			tmp = of_get_property(newpar, "#address-cells", NULL);
-			newaddrsize = (tmp == NULL) ? 0 : *tmp;
-
-			pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
-				newintsize, newaddrsize);
-
-			/* Check for malformed properties */
-			if (imaplen < (newaddrsize + newintsize))
-				goto fail;
-
-			imap += newaddrsize + newintsize;
-			imaplen -= newaddrsize + newintsize;
-
-			pr_debug(" -> imaplen=%d\n", imaplen);
-		}
-		if (!match)
-			goto fail;
-
-		of_node_put(old);
-		old = of_node_get(newpar);
-		addrsize = newaddrsize;
-		intsize = newintsize;
-		intspec = imap - intsize;
-		addr = intspec - addrsize;
-
-skiplevel:
-		/* Iterate again with new parent */
-		pr_debug(" -> new parent: %s\n",
-				newpar ? newpar->full_name : "<>");
-		of_node_put(ipar);
-		ipar = newpar;
-		newpar = NULL;
-	}
-fail:
-	of_node_put(ipar);
-	of_node_put(old);
-	of_node_put(newpar);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(of_irq_map_raw);
-
 int of_irq_map_one(struct device_node *device,
 			int index, struct of_irq *out_irq)
 {
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 47d41b6..187ef4e 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -123,27 +123,6 @@ extern const void *of_get_mac_address(struct device_node *np);
 extern void of_irq_map_init(unsigned int flags);
 
 /**
- * of_irq_map_raw - Low level interrupt tree parsing
- * @parent:	the device interrupt parent
- * @intspec:	interrupt specifier ("interrupts" property of the device)
- * @ointsize:   size of the passed in interrupt specifier
- * @addr:	address specifier (start of "reg" property of the device)
- * @out_irq:	structure of_irq filled by this function
- *
- * Returns 0 on success and a negative number on error
- *
- * This function is a low-level interrupt tree walking function. It
- * can be used to do a partial walk with synthetized reg and interrupts
- * properties, for example when resolving PCI interrupts when no device
- * node exist for the parent.
- *
- */
-
-extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
-			  u32 ointsize, const u32 *addr,
-			  struct of_irq *out_irq);
-
-/**
  * of_irq_map_pci - Resolve the interrupt for a PCI device
  * @pdev:	the device whose interrupt is to be resolved
  * @out_irq:	structure of_irq filled by this function
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 39e977d..89ca7b3 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -731,177 +731,6 @@ void of_irq_map_init(unsigned int flags)
 
 }
 
-int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
-		const u32 *addr, struct of_irq *out_irq)
-{
-	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
-	const u32 *tmp, *imap, *imask;
-	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
-	int imaplen, match, i;
-
-	DBG("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
-	    parent->full_name, intspec[0], intspec[1], ointsize);
-
-	ipar = of_node_get(parent);
-
-	/* First get the #interrupt-cells property of the current cursor
-	 * that tells us how to interpret the passed-in intspec. If there
-	 * is none, we are nice and just walk up the tree
-	 */
-	do {
-		tmp = of_get_property(ipar, "#interrupt-cells", NULL);
-		if (tmp != NULL) {
-			intsize = *tmp;
-			break;
-		}
-		tnode = ipar;
-		ipar = of_irq_find_parent(ipar);
-		of_node_put(tnode);
-	} while (ipar);
-	if (ipar == NULL) {
-		DBG(" -> no parent found !\n");
-		goto fail;
-	}
-
-	DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize);
-
-	if (ointsize != intsize)
-		return -EINVAL;
-
-	/* Look for this #address-cells. We have to implement the old linux
-	 * trick of looking for the parent here as some device-trees rely on it
-	 */
-	old = of_node_get(ipar);
-	do {
-		tmp = of_get_property(old, "#address-cells", NULL);
-		tnode = of_get_parent(old);
-		of_node_put(old);
-		old = tnode;
-	} while(old && tmp == NULL);
-	of_node_put(old);
-	old = NULL;
-	addrsize = (tmp == NULL) ? 2 : *tmp;
-
-	DBG(" -> addrsize=%d\n", addrsize);
-
-	/* Now start the actual "proper" walk of the interrupt tree */
-	while (ipar != NULL) {
-		/* Now check if cursor is an interrupt-controller and if it is
-		 * then we are done
-		 */
-		if (of_get_property(ipar, "interrupt-controller", NULL) !=
-				NULL) {
-			DBG(" -> got it !\n");
-			memcpy(out_irq->specifier, intspec,
-			       intsize * sizeof(u32));
-			out_irq->size = intsize;
-			out_irq->controller = ipar;
-			of_node_put(old);
-			return 0;
-		}
-
-		/* Now look for an interrupt-map */
-		imap = of_get_property(ipar, "interrupt-map", &imaplen);
-		/* No interrupt map, check for an interrupt parent */
-		if (imap == NULL) {
-			DBG(" -> no map, getting parent\n");
-			newpar = of_irq_find_parent(ipar);
-			goto skiplevel;
-		}
-		imaplen /= sizeof(u32);
-
-		/* Look for a mask */
-		imask = of_get_property(ipar, "interrupt-map-mask", NULL);
-
-		/* If we were passed no "reg" property and we attempt to parse
-		 * an interrupt-map, then #address-cells must be 0.
-		 * Fail if it's not.
-		 */
-		if (addr == NULL && addrsize != 0) {
-			DBG(" -> no reg passed in when needed !\n");
-			goto fail;
-		}
-
-		/* Parse interrupt-map */
-		match = 0;
-		while (imaplen > (addrsize + intsize + 1) && !match) {
-			/* Compare specifiers */
-			match = 1;
-			for (i = 0; i < addrsize && match; ++i) {
-				u32 mask = imask ? imask[i] : 0xffffffffu;
-				match = ((addr[i] ^ imap[i]) & mask) == 0;
-			}
-			for (; i < (addrsize + intsize) && match; ++i) {
-				u32 mask = imask ? imask[i] : 0xffffffffu;
-				match =
-				   ((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
-			}
-			imap += addrsize + intsize;
-			imaplen -= addrsize + intsize;
-
-			DBG(" -> match=%d (imaplen=%d)\n", match, imaplen);
-
-			/* Get the interrupt parent */
-			newpar = of_irq_find_parent_by_phandle((phandle)*imap);
-			imap++;
-			--imaplen;
-
-			/* Check if not found */
-			if (newpar == NULL) {
-				DBG(" -> imap parent not found !\n");
-				goto fail;
-			}
-
-			/* Get #interrupt-cells and #address-cells of new
-			 * parent
-			 */
-			tmp = of_get_property(newpar, "#interrupt-cells", NULL);
-			if (tmp == NULL) {
-				DBG(" -> parent lacks #interrupt-cells !\n");
-				goto fail;
-			}
-			newintsize = *tmp;
-			tmp = of_get_property(newpar, "#address-cells", NULL);
-			newaddrsize = (tmp == NULL) ? 0 : *tmp;
-
-			DBG(" -> newintsize=%d, newaddrsize=%d\n",
-			    newintsize, newaddrsize);
-
-			/* Check for malformed properties */
-			if (imaplen < (newaddrsize + newintsize))
-				goto fail;
-
-			imap += newaddrsize + newintsize;
-			imaplen -= newaddrsize + newintsize;
-
-			DBG(" -> imaplen=%d\n", imaplen);
-		}
-		if (!match)
-			goto fail;
-
-		of_node_put(old);
-		old = of_node_get(newpar);
-		addrsize = newaddrsize;
-		intsize = newintsize;
-		intspec = imap - intsize;
-		addr = intspec - addrsize;
-
-	skiplevel:
-		/* Iterate again with new parent */
-		DBG(" -> new parent: %s\n", newpar ? newpar->full_name : "<>");
-		of_node_put(ipar);
-		ipar = newpar;
-		newpar = NULL;
-	}
- fail:
-	of_node_put(ipar);
-	of_node_put(old);
-	of_node_put(newpar);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(of_irq_map_raw);
-
 #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
 static int of_irq_map_oldworld(struct device_node *device, int index,
 			       struct of_irq *out_irq)
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index ad569ca..351c87a 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -52,6 +52,194 @@ struct device_node *of_irq_find_parent(struct device_node *child)
 	return p;
 }
 
+/**
+ * of_irq_map_raw - Low level interrupt tree parsing
+ * @parent:	the device interrupt parent
+ * @intspec:	interrupt specifier ("interrupts" property of the device)
+ * @ointsize:	size of the passed in interrupt specifier
+ * @addr:	address specifier (start of "reg" property of the device)
+ * @out_irq:	structure of_irq filled by this function
+ *
+ * Returns 0 on success and a negative number on error
+ *
+ * This function is a low-level interrupt tree walking function. It
+ * can be used to do a partial walk with synthetized reg and interrupts
+ * properties, for example when resolving PCI interrupts when no device
+ * node exist for the parent.
+ */
+int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
+		const u32 *addr, struct of_irq *out_irq)
+{
+	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
+	const u32 *tmp, *imap, *imask;
+	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
+	int imaplen, match, i;
+
+	pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
+		 parent->full_name, intspec[0], intspec[1], ointsize);
+
+	ipar = of_node_get(parent);
+
+	/* First get the #interrupt-cells property of the current cursor
+	 * that tells us how to interpret the passed-in intspec. If there
+	 * is none, we are nice and just walk up the tree
+	 */
+	do {
+		tmp = of_get_property(ipar, "#interrupt-cells", NULL);
+		if (tmp != NULL) {
+			intsize = *tmp;
+			break;
+		}
+		tnode = ipar;
+		ipar = of_irq_find_parent(ipar);
+		of_node_put(tnode);
+	} while (ipar);
+	if (ipar == NULL) {
+		pr_debug(" -> no parent found !\n");
+		goto fail;
+	}
+
+	pr_debug("of_irq_map_raw: ipar=%s, size=%d\n",
+		 ipar->full_name, intsize);
+
+	if (ointsize != intsize)
+		return -EINVAL;
+
+	/* Look for this #address-cells. We have to implement the old linux
+	 * trick of looking for the parent here as some device-trees rely on it
+	 */
+	old = of_node_get(ipar);
+	do {
+		tmp = of_get_property(old, "#address-cells", NULL);
+		tnode = of_get_parent(old);
+		of_node_put(old);
+		old = tnode;
+	} while (old && tmp == NULL);
+	of_node_put(old);
+	old = NULL;
+	addrsize = (tmp == NULL) ? 2 : *tmp;
+
+	pr_debug(" -> addrsize=%d\n", addrsize);
+
+	/* Now start the actual "proper" walk of the interrupt tree */
+	while (ipar != NULL) {
+		/* Now check if cursor is an interrupt-controller and if it is
+		 * then we are done
+		 */
+		if (of_get_property(ipar, "interrupt-controller", NULL) !=
+				NULL) {
+			pr_debug(" -> got it !\n");
+			memcpy(out_irq->specifier, intspec,
+			       intsize * sizeof(u32));
+			out_irq->size = intsize;
+			out_irq->controller = ipar;
+			of_node_put(old);
+			return 0;
+		}
+
+		/* Now look for an interrupt-map */
+		imap = of_get_property(ipar, "interrupt-map", &imaplen);
+		/* No interrupt map, check for an interrupt parent */
+		if (imap == NULL) {
+			pr_debug(" -> no map, getting parent\n");
+			newpar = of_irq_find_parent(ipar);
+			goto skiplevel;
+		}
+		imaplen /= sizeof(u32);
+
+		/* Look for a mask */
+		imask = of_get_property(ipar, "interrupt-map-mask", NULL);
+
+		/* If we were passed no "reg" property and we attempt to parse
+		 * an interrupt-map, then #address-cells must be 0.
+		 * Fail if it's not.
+		 */
+		if (addr == NULL && addrsize != 0) {
+			pr_debug(" -> no reg passed in when needed !\n");
+			goto fail;
+		}
+
+		/* Parse interrupt-map */
+		match = 0;
+		while (imaplen > (addrsize + intsize + 1) && !match) {
+			/* Compare specifiers */
+			match = 1;
+			for (i = 0; i < addrsize && match; ++i) {
+				u32 mask = imask ? imask[i] : 0xffffffffu;
+				match = ((addr[i] ^ imap[i]) & mask) == 0;
+			}
+			for (; i < (addrsize + intsize) && match; ++i) {
+				u32 mask = imask ? imask[i] : 0xffffffffu;
+				match =
+				   ((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
+			}
+			imap += addrsize + intsize;
+			imaplen -= addrsize + intsize;
+
+			pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
+
+			/* Get the interrupt parent */
+			newpar = of_irq_find_parent_by_phandle((phandle)*imap);
+			imap++;
+			--imaplen;
+
+			/* Check if not found */
+			if (newpar == NULL) {
+				pr_debug(" -> imap parent not found !\n");
+				goto fail;
+			}
+
+			/* Get #interrupt-cells and #address-cells of new
+			 * parent
+			 */
+			tmp = of_get_property(newpar, "#interrupt-cells", NULL);
+			if (tmp == NULL) {
+				pr_debug(" -> parent lacks #interrupt-cells!\n");
+				goto fail;
+			}
+			newintsize = *tmp;
+			tmp = of_get_property(newpar, "#address-cells", NULL);
+			newaddrsize = (tmp == NULL) ? 0 : *tmp;
+
+			pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
+			    newintsize, newaddrsize);
+
+			/* Check for malformed properties */
+			if (imaplen < (newaddrsize + newintsize))
+				goto fail;
+
+			imap += newaddrsize + newintsize;
+			imaplen -= newaddrsize + newintsize;
+
+			pr_debug(" -> imaplen=%d\n", imaplen);
+		}
+		if (!match)
+			goto fail;
+
+		of_node_put(old);
+		old = of_node_get(newpar);
+		addrsize = newaddrsize;
+		intsize = newintsize;
+		intspec = imap - intsize;
+		addr = intspec - addrsize;
+
+	skiplevel:
+		/* Iterate again with new parent */
+		pr_debug(" -> new parent: %s\n",
+			 newpar ? newpar->full_name : "<>");
+		of_node_put(ipar);
+		ipar = newpar;
+		newpar = NULL;
+	}
+ fail:
+	of_node_put(ipar);
+	of_node_put(old);
+	of_node_put(newpar);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(of_irq_map_raw);
+
 unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
 {
 	struct of_irq oirq;
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index f98b27b..51c520b 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -32,6 +32,8 @@ struct of_irq {
 
 extern struct device_node *of_irq_find_parent_by_phandle(phandle p);
 extern struct device_node *of_irq_find_parent(struct device_node *child);
+extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
+			 u32 ointsize, const u32 *addr, struct of_irq *out_irq);
 extern int of_irq_map_one(struct device_node *device, int index,
 			  struct of_irq *out_irq);
 extern unsigned int irq_create_of_mapping(struct device_node *controller,

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 5/5] of/irq: merge of_irq_map_one()
  2010-06-04 21:21 [PATCH 1/5] of/irq: Move irq_of_parse_and_map() to common code Grant Likely
  2010-06-04 21:21 ` [PATCH 3/5] of/irq: merge of_irq_find_parent() Grant Likely
  2010-06-04 21:21 ` [PATCH 4/5] of/irq: Merge of_irq_map_raw() Grant Likely
@ 2010-06-04 21:21 ` Grant Likely
  2010-06-10  6:40   ` Benjamin Herrenschmidt
  2010-06-10  6:33 ` [PATCH 1/5] of/irq: Move irq_of_parse_and_map() to common code Benjamin Herrenschmidt
  3 siblings, 1 reply; 18+ messages in thread
From: Grant Likely @ 2010-06-04 21:21 UTC (permalink / raw)
  Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
	devicetree-discuss, linuxppc-dev

Merge common implementation of of_irq_map_one().  Rename it to
__of_irq_map_one() so that arch code can either use the stock
implementation, or override it to handle platform quirks.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
CC: Michal Simek <monstr@monstr.eu>
CC: Wolfram Sang <w.sang@pengutronix.de>
CC: Stephen Rothwell <sfr@canb.auug.org.au>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: microblaze-uclinux@itee.uq.edu.au
CC: linuxppc-dev@ozlabs.org
CC: devicetree-discuss@lists.ozlabs.org
---
 arch/microblaze/include/asm/prom.h  |    3 -
 arch/microblaze/kernel/prom_parse.c |   73 ------------------------------
 arch/powerpc/include/asm/prom.h     |    3 -
 arch/powerpc/kernel/prom_parse.c    |   55 -----------------------
 drivers/of/irq.c                    |   85 +++++++++++++++++++++++++++++++++++
 include/linux/of_irq.h              |    6 ++
 6 files changed, 91 insertions(+), 134 deletions(-)

diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index 89fca70..3659930 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -107,9 +107,6 @@ extern const void *of_get_mac_address(struct device_node *np);
 struct pci_dev;
 extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
 
-extern int of_irq_to_resource(struct device_node *dev, int index,
-			struct resource *r);
-
 /**
  * of_iomap - Maps the memory mapped IO for a given device_node
  * @device:	the device whose io range will be mapped
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
index 02ec946..70c0471 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -656,49 +656,7 @@ struct device_node *of_irq_find_parent_by_phandle(phandle p)
 int of_irq_map_one(struct device_node *device,
 			int index, struct of_irq *out_irq)
 {
-	struct device_node *p;
-	const u32 *intspec, *tmp, *addr;
-	u32 intsize, intlen;
-	int res;
-
-	pr_debug("of_irq_map_one: dev=%s, index=%d\n",
-			device->full_name, index);
-
-	/* Get the interrupts property */
-	intspec = of_get_property(device, "interrupts", (int *) &intlen);
-	if (intspec == NULL)
-		return -EINVAL;
-	intlen /= sizeof(u32);
-
-	pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen);
-
-	/* Get the reg property (if any) */
-	addr = of_get_property(device, "reg", NULL);
-
-	/* Look for the interrupt parent. */
-	p = of_irq_find_parent(device);
-	if (p == NULL)
-		return -EINVAL;
-
-	/* Get size of interrupt specifier */
-	tmp = of_get_property(p, "#interrupt-cells", NULL);
-	if (tmp == NULL) {
-		of_node_put(p);
-		return -EINVAL;
-	}
-	intsize = *tmp;
-
-	pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
-
-	/* Check index */
-	if ((index + 1) * intsize > intlen)
-		return -EINVAL;
-
-	/* Get new specifier and map it */
-	res = of_irq_map_raw(p, intspec + index * intsize, intsize,
-				addr, out_irq);
-	of_node_put(p);
-	return res;
+	return __of_irq_map_one(device, index, out_irq);
 }
 EXPORT_SYMBOL_GPL(of_irq_map_one);
 
@@ -740,35 +698,6 @@ const void *of_get_mac_address(struct device_node *np)
 }
 EXPORT_SYMBOL(of_get_mac_address);
 
-int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
-{
-	struct of_irq out_irq;
-	int irq;
-	int res;
-
-	res = of_irq_map_one(dev, index, &out_irq);
-
-	/* Get irq for the device */
-	if (res) {
-		pr_debug("IRQ not found... code = %d", res);
-		return NO_IRQ;
-	}
-	/* Assuming single interrupt controller... */
-	irq = out_irq.specifier[0];
-
-	pr_debug("IRQ found = %d", irq);
-
-	/* Only dereference the resource if both the
-	 * resource and the irq are valid. */
-	if (r && irq != NO_IRQ) {
-		r->start = r->end = irq;
-		r->flags = IORESOURCE_IRQ;
-	}
-
-	return irq;
-}
-EXPORT_SYMBOL_GPL(of_irq_to_resource);
-
 void __iomem *of_iomap(struct device_node *np, int index)
 {
 	struct resource res;
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 187ef4e..2440984 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -136,9 +136,6 @@ extern void of_irq_map_init(unsigned int flags);
 struct pci_dev;
 extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
 
-extern int of_irq_to_resource(struct device_node *dev, int index,
-			struct resource *r);
-
 /**
  * of_iomap - Maps the memory mapped IO for a given device_node
  * @device:	the device whose io range will be mapped
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 89ca7b3..ef518e3 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -777,49 +777,11 @@ static int of_irq_map_oldworld(struct device_node *device, int index,
 
 int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
 {
-	struct device_node *p;
-	const u32 *intspec, *tmp, *addr;
-	u32 intsize, intlen;
-	int res = -EINVAL;
-
-	DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
-
 	/* OldWorld mac stuff is "special", handle out of line */
 	if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
 		return of_irq_map_oldworld(device, index, out_irq);
 
-	/* Get the interrupts property */
-	intspec = of_get_property(device, "interrupts", &intlen);
-	if (intspec == NULL)
-		return -EINVAL;
-	intlen /= sizeof(u32);
-
-	/* Get the reg property (if any) */
-	addr = of_get_property(device, "reg", NULL);
-
-	/* Look for the interrupt parent. */
-	p = of_irq_find_parent(device);
-	if (p == NULL)
-		return -EINVAL;
-
-	/* Get size of interrupt specifier */
-	tmp = of_get_property(p, "#interrupt-cells", NULL);
-	if (tmp == NULL)
-		goto out;
-	intsize = *tmp;
-
-	DBG(" intsize=%d intlen=%d\n", intsize, intlen);
-
-	/* Check index */
-	if ((index + 1) * intsize > intlen)
-		goto out;
-
-	/* Get new specifier and map it */
-	res = of_irq_map_raw(p, intspec + index * intsize, intsize,
-			     addr, out_irq);
-out:
-	of_node_put(p);
-	return res;
+	return __of_irq_map_one(device, index, out_irq);
 }
 EXPORT_SYMBOL_GPL(of_irq_map_one);
 
@@ -861,21 +823,6 @@ const void *of_get_mac_address(struct device_node *np)
 }
 EXPORT_SYMBOL(of_get_mac_address);
 
-int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
-{
-	int irq = irq_of_parse_and_map(dev, index);
-
-	/* Only dereference the resource if both the
-	 * resource and the irq are valid. */
-	if (r && irq != NO_IRQ) {
-		r->start = r->end = irq;
-		r->flags = IORESOURCE_IRQ;
-	}
-
-	return irq;
-}
-EXPORT_SYMBOL_GPL(of_irq_to_resource);
-
 void __iomem *of_iomap(struct device_node *np, int index)
 {
 	struct resource res;
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 351c87a..dd420e5 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -31,7 +31,7 @@
  * Returns a pointer to the interrupt parent node, or NULL if the interrupt
  * parent could not be determined.
  */
-struct device_node *of_irq_find_parent(struct device_node *child)
+static struct device_node *of_irq_find_parent(struct device_node *child)
 {
 	struct device_node *p;
 	const phandle *parp;
@@ -240,6 +240,67 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
 }
 EXPORT_SYMBOL_GPL(of_irq_map_raw);
 
+/**
+ * of_irq_map_one - Resolve an interrupt for a device
+ * @device: the device whose interrupt is to be resolved
+ * @index: index of the interrupt to resolve
+ * @out_irq: structure of_irq filled by this function
+ *
+ * This function resolves an interrupt, walking the tree, for a given
+ * device-tree node. It's the high level pendant to of_irq_map_raw().
+ *
+ * Architecture code must provide of_irq_map_one() which can simply be a
+ * wrapper around __of_irq_map_one(), or can override it to deal with
+ * arch specific quirks and bugs.
+ */
+int __of_irq_map_one(struct device_node *device, int index,
+		     struct of_irq *out_irq)
+{
+	struct device_node *p;
+	const u32 *intspec, *tmp, *addr;
+	u32 intsize, intlen;
+	int res = -EINVAL;
+
+	pr_debug("of_irq_map_one: dev=%s, index=%d\n",
+		 device->full_name, index);
+
+	/* Get the interrupts property */
+	intspec = of_get_property(device, "interrupts", &intlen);
+	if (intspec == NULL)
+		return -EINVAL;
+	intlen /= sizeof(u32);
+
+	pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen);
+
+	/* Get the reg property (if any) */
+	addr = of_get_property(device, "reg", NULL);
+
+	/* Look for the interrupt parent. */
+	p = of_irq_find_parent(device);
+	if (p == NULL)
+		return -EINVAL;
+
+	/* Get size of interrupt specifier */
+	tmp = of_get_property(p, "#interrupt-cells", NULL);
+	if (tmp == NULL)
+		goto out;
+	intsize = *tmp;
+
+	pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
+
+	/* Check index */
+	if ((index + 1) * intsize > intlen)
+		goto out;
+
+	/* Get new specifier and map it */
+	res = of_irq_map_raw(p, intspec + index * intsize, intsize,
+			     addr, out_irq);
+ out:
+	of_node_put(p);
+	return res;
+}
+EXPORT_SYMBOL_GPL(__of_irq_map_one);
+
 unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
 {
 	struct of_irq oirq;
@@ -251,3 +312,25 @@ unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
 				     oirq.size);
 }
 EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
+
+/**
+ * of_irq_to_resource - Decode a node's IRQ and return it as a resource
+ * @dev: pointer to device tree node
+ * @index: zero-based index of the irq
+ * @r: pointer to resource structure to return result into.
+ */
+unsigned int of_irq_to_resource(struct device_node *dev, int index,
+				struct resource *r)
+{
+	unsigned int irq = irq_of_parse_and_map(dev, index);
+
+	/* Only dereference the resource if both the
+	 * resource and the irq are valid. */
+	if (r && irq != NO_IRQ) {
+		r->start = r->end = irq;
+		r->flags = IORESOURCE_IRQ;
+	}
+
+	return irq;
+}
+EXPORT_SYMBOL_GPL(of_irq_to_resource);
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index 51c520b..935a14d 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -5,6 +5,7 @@
 struct of_irq;
 #include <linux/types.h>
 #include <linux/of.h>
+#include <linux/ioport.h>
 
 /*
  * irq_of_parse_and_map() is used ba all OF enabled platforms; but SPARC
@@ -31,14 +32,17 @@ struct of_irq {
 };
 
 extern struct device_node *of_irq_find_parent_by_phandle(phandle p);
-extern struct device_node *of_irq_find_parent(struct device_node *child);
 extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
 			 u32 ointsize, const u32 *addr, struct of_irq *out_irq);
+extern int __of_irq_map_one(struct device_node *device, int index,
+			    struct of_irq *out_irq);
 extern int of_irq_map_one(struct device_node *device, int index,
 			  struct of_irq *out_irq);
 extern unsigned int irq_create_of_mapping(struct device_node *controller,
 					  const u32 *intspec,
 					  unsigned int intsize);
+extern unsigned int of_irq_to_resource(struct device_node *dev, int index,
+				       struct resource *r);
 
 #endif /* CONFIG_OF_IRQ */
 #endif /* CONFIG_OF */

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/5] of/irq: Move irq_of_parse_and_map() to common code
  2010-06-04 21:21 [PATCH 1/5] of/irq: Move irq_of_parse_and_map() to common code Grant Likely
                   ` (2 preceding siblings ...)
  2010-06-04 21:21 ` [PATCH 5/5] of/irq: merge of_irq_map_one() Grant Likely
@ 2010-06-10  6:33 ` Benjamin Herrenschmidt
  3 siblings, 0 replies; 18+ messages in thread
From: Benjamin Herrenschmidt @ 2010-06-10  6:33 UTC (permalink / raw)
  To: Grant Likely
  Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
	devicetree-discuss, linuxppc-dev, sparclinux, Jeremy Kerr,
	David S. Miller

On Fri, 2010-06-04 at 15:21 -0600, Grant Likely wrote:
> Merge common code between PowerPC and Microblaze.  SPARC implements
> irq_of_parse_and_map(), but the implementation is different, so it
> does not use this code.
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> CC: Michal Simek <monstr@monstr.eu>
> CC: "David S. Miller" <davem@davemloft.net>
> CC: Stephen Rothwell <sfr@canb.auug.org.au>

Acked-by : Benjamin Herrenschmidt <benh@kernel.crashing.org>

> CC: Jeremy Kerr <jeremy.kerr@canonical.com>
> CC: microblaze-uclinux@itee.uq.edu.au
> CC: linuxppc-dev@ozlabs.org
> CC: sparclinux@vger.kernel.org
> CC: devicetree-discuss@lists.ozlabs.org
> ---
>  arch/microblaze/include/asm/irq.h  |   13 -----------
>  arch/microblaze/include/asm/prom.h |   26 +----------------------
>  arch/microblaze/kernel/irq.c       |   14 ++----------
>  arch/powerpc/include/asm/irq.h     |   13 -----------
>  arch/powerpc/include/asm/prom.h    |   27 +-----------------------
>  arch/powerpc/kernel/irq.c          |   14 ++----------
>  arch/sparc/include/asm/prom.h      |    1 -
>  drivers/of/Kconfig                 |    4 ++++
>  drivers/of/Makefile                |    1 +
>  drivers/of/irq.c                   |   37 ++++++++++++++++++++++++++++++++
>  drivers/of/of_mdio.c               |    1 +
>  include/linux/of_irq.h             |   41 ++++++++++++++++++++++++++++++++++++
>  12 files changed, 90 insertions(+), 102 deletions(-)
>  create mode 100644 drivers/of/irq.c
>  create mode 100644 include/linux/of_irq.h
> 
> diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h
> index 31a35c3..10d75c1 100644
> --- a/arch/microblaze/include/asm/irq.h
> +++ b/arch/microblaze/include/asm/irq.h
> @@ -62,17 +62,4 @@ struct irq_host;
>  extern unsigned int irq_create_mapping(struct irq_host *host,
>  					irq_hw_number_t hwirq);
>  
> -/**
> - * irq_create_of_mapping - Map a hardware interrupt into linux virq space
> - * @controller: Device node of the interrupt controller
> - * @inspec: Interrupt specifier from the device-tree
> - * @intsize: Size of the interrupt specifier from the device-tree
> - *
> - * This function is identical to irq_create_mapping except that it takes
> - * as input informations straight from the device-tree (typically the results
> - * of the of_irq_map_*() functions.
> - */
> -extern unsigned int irq_create_of_mapping(struct device_node *controller,
> -					u32 *intspec, unsigned int intsize);
> -
>  #endif /* _ASM_MICROBLAZE_IRQ_H */
> diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
> index e7d67a3..e9fb2eb 100644
> --- a/arch/microblaze/include/asm/prom.h
> +++ b/arch/microblaze/include/asm/prom.h
> @@ -20,6 +20,7 @@
>  #ifndef __ASSEMBLY__
>  
>  #include <linux/types.h>
> +#include <linux/of_irq.h>
>  #include <linux/of_fdt.h>
>  #include <linux/proc_fs.h>
>  #include <linux/platform_device.h>
> @@ -92,18 +93,6 @@ extern const void *of_get_mac_address(struct device_node *np);
>   * OF interrupt mapping
>   */
>  
> -/* This structure is returned when an interrupt is mapped. The controller
> - * field needs to be put() after use
> - */
> -
> -#define OF_MAX_IRQ_SPEC		4 /* We handle specifiers of at most 4 cells */
> -
> -struct of_irq {
> -	struct device_node *controller; /* Interrupt controller node */
> -	u32 size; /* Specifier size */
> -	u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
> -};
> -
>  /**
>   * of_irq_map_init - Initialize the irq remapper
>   * @flags:	flags defining workarounds to enable
> @@ -139,19 +128,6 @@ extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
>  			struct of_irq *out_irq);
>  
>  /**
> - * of_irq_map_one - Resolve an interrupt for a device
> - * @device:	the device whose interrupt is to be resolved
> - * @index:	index of the interrupt to resolve
> - * @out_irq:	structure of_irq filled by this function
> - *
> - * This function resolves an interrupt, walking the tree, for a given
> - * device-tree node. It's the high level pendant to of_irq_map_raw().
> - * It also implements the workarounds for OldWolrd Macs.
> - */
> -extern int of_irq_map_one(struct device_node *device, int index,
> -			struct of_irq *out_irq);
> -
> -/**
>   * of_irq_map_pci - Resolve the interrupt for a PCI device
>   * @pdev:	the device whose interrupt is to be resolved
>   * @out_irq:	structure of_irq filled by this function
> diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
> index 8f120ac..dd32b09 100644
> --- a/arch/microblaze/kernel/irq.c
> +++ b/arch/microblaze/kernel/irq.c
> @@ -17,20 +17,10 @@
>  #include <linux/seq_file.h>
>  #include <linux/kernel_stat.h>
>  #include <linux/irq.h>
> +#include <linux/of_irq.h>
>  
>  #include <asm/prom.h>
>  
> -unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
> -{
> -	struct of_irq oirq;
> -
> -	if (of_irq_map_one(dev, index, &oirq))
> -		return NO_IRQ;
> -
> -	return oirq.specifier[0];
> -}
> -EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
> -
>  static u32 concurrent_irq;
>  
>  void __irq_entry do_IRQ(struct pt_regs *regs)
> @@ -104,7 +94,7 @@ unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
>  EXPORT_SYMBOL_GPL(irq_create_mapping);
>  
>  unsigned int irq_create_of_mapping(struct device_node *controller,
> -					u32 *intspec, unsigned int intsize)
> +				   const u32 *intspec, unsigned int intsize)
>  {
>  	return intspec[0];
>  }
> diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
> index e054bae..a3b5124 100644
> --- a/arch/powerpc/include/asm/irq.h
> +++ b/arch/powerpc/include/asm/irq.h
> @@ -304,19 +304,6 @@ extern void irq_free_virt(unsigned int virq, unsigned int count);
>  /* -- OF helpers -- */
>  
>  /**
> - * irq_create_of_mapping - Map a hardware interrupt into linux virq space
> - * @controller: Device node of the interrupt controller
> - * @inspec: Interrupt specifier from the device-tree
> - * @intsize: Size of the interrupt specifier from the device-tree
> - *
> - * This function is identical to irq_create_mapping except that it takes
> - * as input informations straight from the device-tree (typically the results
> - * of the of_irq_map_*() functions.
> - */
> -extern unsigned int irq_create_of_mapping(struct device_node *controller,
> -					  const u32 *intspec, unsigned int intsize);
> -
> -/**
>   * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
>   * @device: Device node of the device whose interrupt is to be mapped
>   * @index: Index of the interrupt to map
> diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
> index ddd408a..47d41b6 100644
> --- a/arch/powerpc/include/asm/prom.h
> +++ b/arch/powerpc/include/asm/prom.h
> @@ -18,6 +18,7 @@
>   */
>  #include <linux/types.h>
>  #include <linux/of_fdt.h>
> +#include <linux/of_irq.h>
>  #include <linux/proc_fs.h>
>  #include <linux/platform_device.h>
>  #include <asm/irq.h>
> @@ -108,18 +109,6 @@ extern const void *of_get_mac_address(struct device_node *np);
>   * OF interrupt mapping
>   */
>  
> -/* This structure is returned when an interrupt is mapped. The controller
> - * field needs to be put() after use
> - */
> -
> -#define OF_MAX_IRQ_SPEC		 4 /* We handle specifiers of at most 4 cells */
> -
> -struct of_irq {
> -	struct device_node *controller;	/* Interrupt controller node */
> -	u32 size;			/* Specifier size */
> -	u32 specifier[OF_MAX_IRQ_SPEC];	/* Specifier copy */
> -};
> -
>  /**
>   * of_irq_map_init - Initialize the irq remapper
>   * @flags:	flags defining workarounds to enable
> @@ -154,20 +143,6 @@ extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
>  			  u32 ointsize, const u32 *addr,
>  			  struct of_irq *out_irq);
>  
> -
> -/**
> - * of_irq_map_one - Resolve an interrupt for a device
> - * @device:	the device whose interrupt is to be resolved
> - * @index:     	index of the interrupt to resolve
> - * @out_irq:	structure of_irq filled by this function
> - *
> - * This function resolves an interrupt, walking the tree, for a given
> - * device-tree node. It's the high level pendant to of_irq_map_raw().
> - * It also implements the workarounds for OldWolrd Macs.
> - */
> -extern int of_irq_map_one(struct device_node *device, int index,
> -			  struct of_irq *out_irq);
> -
>  /**
>   * of_irq_map_pci - Resolve the interrupt for a PCI device
>   * @pdev:	the device whose interrupt is to be resolved
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index 30817d9..2676ef2 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -53,6 +53,8 @@
>  #include <linux/bootmem.h>
>  #include <linux/pci.h>
>  #include <linux/debugfs.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
>  
>  #include <asm/uaccess.h>
>  #include <asm/system.h>
> @@ -813,18 +815,6 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
>  }
>  EXPORT_SYMBOL_GPL(irq_create_of_mapping);
>  
> -unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
> -{
> -	struct of_irq oirq;
> -
> -	if (of_irq_map_one(dev, index, &oirq))
> -		return NO_IRQ;
> -
> -	return irq_create_of_mapping(oirq.controller, oirq.specifier,
> -				     oirq.size);
> -}
> -EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
> -
>  void irq_dispose_mapping(unsigned int virq)
>  {
>  	struct irq_host *host;
> diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h
> index f845828..ac69574 100644
> --- a/arch/sparc/include/asm/prom.h
> +++ b/arch/sparc/include/asm/prom.h
> @@ -56,7 +56,6 @@ extern void of_fill_in_cpu_data(void);
>   * register them in the of_device objects, whereas powerpc computes them
>   * on request.
>   */
> -extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
>  static inline void irq_dispose_mapping(unsigned int virq)
>  {
>  }
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index 7cecc8f..b87495e 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -6,6 +6,10 @@ config OF_DYNAMIC
>  	def_bool y
>  	depends on OF && PPC_OF
>  
> +config OF_IRQ
> +	def_bool y
> +	depends on OF && !SPARC
> +
>  config OF_DEVICE
>  	def_bool y
>  	depends on OF && (SPARC || PPC_OF || MICROBLAZE)
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index f232cc9..3631a5e 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -1,5 +1,6 @@
>  obj-y = base.o
>  obj-$(CONFIG_OF_FLATTREE) += fdt.o
> +obj-$(CONFIG_OF_IRQ)    += irq.o
>  obj-$(CONFIG_OF_DEVICE) += device.o platform.o
>  obj-$(CONFIG_OF_GPIO)   += gpio.o
>  obj-$(CONFIG_OF_I2C)	+= of_i2c.o
> diff --git a/drivers/of/irq.c b/drivers/of/irq.c
> new file mode 100644
> index 0000000..56ad1aa
> --- /dev/null
> +++ b/drivers/of/irq.c
> @@ -0,0 +1,37 @@
> +/*
> + *  Derived from arch/i386/kernel/irq.c
> + *    Copyright (C) 1992 Linus Torvalds
> + *  Adapted from arch/i386 by Gary Thomas
> + *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
> + *  Updated and modified by Cort Dougan <cort@fsmlabs.com>
> + *    Copyright (C) 1996-2001 Cort Dougan
> + *  Adapted for Power Macintosh by Paul Mackerras
> + *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + *
> + * This file contains the code used to make IRQ descriptions in the
> + * device tree to actual irq numbers on an interrupt controller
> + * driver.
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/string.h>
> +
> +unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
> +{
> +	struct of_irq oirq;
> +
> +	if (of_irq_map_one(dev, index, &oirq))
> +		return NO_IRQ;
> +
> +	return irq_create_of_mapping(oirq.controller, oirq.specifier,
> +				     oirq.size);
> +}
> +EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
> diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
> index 42a6715..1fce00e 100644
> --- a/drivers/of/of_mdio.c
> +++ b/drivers/of/of_mdio.c
> @@ -15,6 +15,7 @@
>  #include <linux/err.h>
>  #include <linux/phy.h>
>  #include <linux/of.h>
> +#include <linux/of_irq.h>
>  #include <linux/of_mdio.h>
>  #include <linux/module.h>
>  
> diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
> new file mode 100644
> index 0000000..0e37c05
> --- /dev/null
> +++ b/include/linux/of_irq.h
> @@ -0,0 +1,41 @@
> +#ifndef __OF_IRQ_H
> +#define __OF_IRQ_H
> +
> +#if defined(CONFIG_OF)
> +struct of_irq;
> +#include <linux/types.h>
> +#include <linux/of.h>
> +
> +/*
> + * irq_of_parse_and_map() is used ba all OF enabled platforms; but SPARC
> + * implements it differently.  However, the prototype is the same for all,
> + * so declare it here regardless of the CONFIG_OF_IRQ setting.
> + */
> +extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
> +
> +#if defined(CONFIG_OF_IRQ)
> +/**
> + * of_irq - container for device_node/irq_specifier pair for an irq controller
> + * @controller: pointer to interrupt controller device tree node
> + * @size: size of interrupt specifier
> + * @specifier: array of cells @size long specifing the specific interrupt
> + *
> + * This structure is returned when an interrupt is mapped. The controller
> + * field needs to be put() after use
> + */
> +#define OF_MAX_IRQ_SPEC		4 /* We handle specifiers of at most 4 cells */
> +struct of_irq {
> +	struct device_node *controller; /* Interrupt controller node */
> +	u32 size; /* Specifier size */
> +	u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
> +};
> +
> +extern int of_irq_map_one(struct device_node *device, int index,
> +			  struct of_irq *out_irq);
> +extern unsigned int irq_create_of_mapping(struct device_node *controller,
> +					  const u32 *intspec,
> +					  unsigned int intsize);
> +
> +#endif /* CONFIG_OF_IRQ */
> +#endif /* CONFIG_OF */
> +#endif /* __OF_IRQ_H */

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/5] of/irq: merge of_irq_find_parent()
  2010-06-04 21:21 ` [PATCH 3/5] of/irq: merge of_irq_find_parent() Grant Likely
@ 2010-06-10  6:38   ` Benjamin Herrenschmidt
  2010-06-21 21:11     ` Grant Likely
  0 siblings, 1 reply; 18+ messages in thread
From: Benjamin Herrenschmidt @ 2010-06-10  6:38 UTC (permalink / raw)
  To: Grant Likely
  Cc: Stephen Rothwell, Michal Simek, linuxppc-dev, devicetree-discuss,
	microblaze-uclinux

On Fri, 2010-06-04 at 15:21 -0600, Grant Likely wrote:
> Merge common code between PowerPC and Microblaze.  Also create a new
> arch hook, of_irq_find_parent_by_phandle() to handle arch-specific
> quirks.

First, you changeset comment should be much more verbose as to
what that arch specific quirk is about etc... it took me time to figure
it out again :-)

I dislike the naming you use. Your "of_irq_find_parent_by_phandle"
doesn't ring "right" to me.

I'm tempted to say we should put the quirks in the common code, your
attempt at "abstracting" them just makes the code much harder to follow.

Also, if we stick to your approach the "default" variant should either
be an inline protected by an ifndef or a weak function.

Cheers,
Ben.

> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> CC: Michal Simek <monstr@monstr.eu>
> CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> CC: Stephen Rothwell <sfr@canb.auug.org.au>
> CC: microblaze-uclinux@itee.uq.edu.au
> CC: linuxppc-dev@lists.ozlabs.org
> CC: devicetree-discuss@lists.ozlabs.org
> ---
>  arch/microblaze/kernel/prom_parse.c |   22 +++-------------------
>  arch/powerpc/kernel/prom_parse.c    |   30 +++++-------------------------
>  drivers/of/irq.c                    |   28 ++++++++++++++++++++++++++++
>  include/linux/of_irq.h              |    2 ++
>  4 files changed, 38 insertions(+), 44 deletions(-)
> 
> diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
> index af1b2a7..946f14d 100644
> --- a/arch/microblaze/kernel/prom_parse.c
> +++ b/arch/microblaze/kernel/prom_parse.c
> @@ -648,25 +648,9 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
>   * Interrupt remapper
>   */
>  
> -static struct device_node *of_irq_find_parent(struct device_node *child)
> +struct device_node *of_irq_find_parent_by_phandle(phandle p)
>  {
> -	struct device_node *p;
> -	const phandle *parp;
> -
> -	if (!of_node_get(child))
> -		return NULL;
> -
> -	do {
> -		parp = of_get_property(child, "interrupt-parent", NULL);
> -		if (parp == NULL)
> -			p = of_get_parent(child);
> -		else
> -			p = of_find_node_by_phandle(*parp);
> -		of_node_put(child);
> -		child = p;
> -	} while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
> -
> -	return p;
> +	return of_find_node_by_phandle(p);
>  }
>  
>  int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
> @@ -783,7 +767,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
>  			pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
>  
>  			/* Get the interrupt parent */
> -			newpar = of_find_node_by_phandle((phandle)*imap);
> +			newpar = of_irq_find_parent_by_phandle((phandle)*imap);
>  			imap++;
>  			--imaplen;
>  
> diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
> index 8362620..39e977d 100644
> --- a/arch/powerpc/kernel/prom_parse.c
> +++ b/arch/powerpc/kernel/prom_parse.c
> @@ -685,29 +685,12 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
>  static unsigned int of_irq_workarounds;
>  static struct device_node *of_irq_dflt_pic;
>  
> -static struct device_node *of_irq_find_parent(struct device_node *child)
> +struct device_node *of_irq_find_parent_by_phandle(phandle p)
>  {
> -	struct device_node *p;
> -	const phandle *parp;
> -
> -	if (!of_node_get(child))
> -		return NULL;
> -
> -	do {
> -		parp = of_get_property(child, "interrupt-parent", NULL);
> -		if (parp == NULL)
> -			p = of_get_parent(child);
> -		else {
> -			if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
> -				p = of_node_get(of_irq_dflt_pic);
> -			else
> -				p = of_find_node_by_phandle(*parp);
> -		}
> -		of_node_put(child);
> -		child = p;
> -	} while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
> +	if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
> +		return of_node_get(of_irq_dflt_pic);
>  
> -	return p;
> +	return of_find_node_by_phandle(p);
>  }
>  
>  /* This doesn't need to be called if you don't have any special workaround
> @@ -859,10 +842,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
>  			DBG(" -> match=%d (imaplen=%d)\n", match, imaplen);
>  
>  			/* Get the interrupt parent */
> -			if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
> -				newpar = of_node_get(of_irq_dflt_pic);
> -			else
> -				newpar = of_find_node_by_phandle((phandle)*imap);
> +			newpar = of_irq_find_parent_by_phandle((phandle)*imap);
>  			imap++;
>  			--imaplen;
>  
> diff --git a/drivers/of/irq.c b/drivers/of/irq.c
> index 56ad1aa..ad569ca 100644
> --- a/drivers/of/irq.c
> +++ b/drivers/of/irq.c
> @@ -24,6 +24,34 @@
>  #include <linux/of_irq.h>
>  #include <linux/string.h>
>  
> +/**
> + * of_irq_find_parent - Given a device node, find its interrupt parent node
> + * @child: pointer to device node
> + *
> + * Returns a pointer to the interrupt parent node, or NULL if the interrupt
> + * parent could not be determined.
> + */
> +struct device_node *of_irq_find_parent(struct device_node *child)
> +{
> +	struct device_node *p;
> +	const phandle *parp;
> +
> +	if (!of_node_get(child))
> +		return NULL;
> +
> +	do {
> +		parp = of_get_property(child, "interrupt-parent", NULL);
> +		if (parp == NULL)
> +			p = of_get_parent(child);
> +		else
> +			p = of_irq_find_parent_by_phandle(*parp);
> +		of_node_put(child);
> +		child = p;
> +	} while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
> +
> +	return p;
> +}
> +
>  unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
>  {
>  	struct of_irq oirq;
> diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
> index 0e37c05..f98b27b 100644
> --- a/include/linux/of_irq.h
> +++ b/include/linux/of_irq.h
> @@ -30,6 +30,8 @@ struct of_irq {
>  	u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
>  };
>  
> +extern struct device_node *of_irq_find_parent_by_phandle(phandle p);
> +extern struct device_node *of_irq_find_parent(struct device_node *child);
>  extern int of_irq_map_one(struct device_node *device, int index,
>  			  struct of_irq *out_irq);
>  extern unsigned int irq_create_of_mapping(struct device_node *controller,

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 4/5] of/irq: Merge of_irq_map_raw()
  2010-06-04 21:21 ` [PATCH 4/5] of/irq: Merge of_irq_map_raw() Grant Likely
@ 2010-06-10  6:38   ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 18+ messages in thread
From: Benjamin Herrenschmidt @ 2010-06-10  6:38 UTC (permalink / raw)
  To: Grant Likely
  Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
	devicetree-discuss, linuxppc-dev

On Fri, 2010-06-04 at 15:21 -0600, Grant Likely wrote:
> Merge common code between PowerPC and Microblaze
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> CC: Michal Simek <monstr@monstr.eu>
> CC: Wolfram Sang <w.sang@pengutronix.de>
> CC: Stephen Rothwell <sfr@canb.auug.org.au>

Acked-by : Benjamin Herrenschmidt <benh@kernel.crashing.org>

I haven't double checked that the code was absolutely identical... if
you haven't, please do so :-)

Cheers,
Ben.

> CC: microblaze-uclinux@itee.uq.edu.au
> CC: linuxppc-dev@ozlabs.org
> CC: devicetree-discuss@lists.ozlabs.org
> ---
>  arch/microblaze/include/asm/prom.h  |   21 ----
>  arch/microblaze/kernel/prom_parse.c |  176 ---------------------------------
>  arch/powerpc/include/asm/prom.h     |   21 ----
>  arch/powerpc/kernel/prom_parse.c    |  171 --------------------------------
>  drivers/of/irq.c                    |  188 +++++++++++++++++++++++++++++++++++
>  include/linux/of_irq.h              |    2 
>  6 files changed, 190 insertions(+), 389 deletions(-)
> 
> diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
> index da7069c..89fca70 100644
> --- a/arch/microblaze/include/asm/prom.h
> +++ b/arch/microblaze/include/asm/prom.h
> @@ -94,27 +94,6 @@ extern const void *of_get_mac_address(struct device_node *np);
>   */
>  
>  /**
> - * of_irq_map_raw - Low level interrupt tree parsing
> - * @parent:	the device interrupt parent
> - * @intspec:	interrupt specifier ("interrupts" property of the device)
> - * @ointsize:	size of the passed in interrupt specifier
> - * @addr:	address specifier (start of "reg" property of the device)
> - * @out_irq:	structure of_irq filled by this function
> - *
> - * Returns 0 on success and a negative number on error
> - *
> - * This function is a low-level interrupt tree walking function. It
> - * can be used to do a partial walk with synthetized reg and interrupts
> - * properties, for example when resolving PCI interrupts when no device
> - * node exist for the parent.
> - *
> - */
> -
> -extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
> -			u32 ointsize, const u32 *addr,
> -			struct of_irq *out_irq);
> -
> -/**
>   * of_irq_map_pci - Resolve the interrupt for a PCI device
>   * @pdev:	the device whose interrupt is to be resolved
>   * @out_irq:	structure of_irq filled by this function
> diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
> index 946f14d..02ec946 100644
> --- a/arch/microblaze/kernel/prom_parse.c
> +++ b/arch/microblaze/kernel/prom_parse.c
> @@ -653,182 +653,6 @@ struct device_node *of_irq_find_parent_by_phandle(phandle p)
>  	return of_find_node_by_phandle(p);
>  }
>  
> -int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
> -		const u32 *addr, struct of_irq *out_irq)
> -{
> -	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
> -	const u32 *tmp, *imap, *imask;
> -	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
> -	int imaplen, match, i;
> -
> -	pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],"
> -		"ointsize=%d\n",
> -		parent->full_name, intspec[0], intspec[1], ointsize);
> -
> -	ipar = of_node_get(parent);
> -
> -	/* First get the #interrupt-cells property of the current cursor
> -	 * that tells us how to interpret the passed-in intspec. If there
> -	 * is none, we are nice and just walk up the tree
> -	 */
> -	do {
> -		tmp = of_get_property(ipar, "#interrupt-cells", NULL);
> -		if (tmp != NULL) {
> -			intsize = *tmp;
> -			break;
> -		}
> -		tnode = ipar;
> -		ipar = of_irq_find_parent(ipar);
> -		of_node_put(tnode);
> -	} while (ipar);
> -	if (ipar == NULL) {
> -		pr_debug(" -> no parent found !\n");
> -		goto fail;
> -	}
> -
> -	pr_debug("of_irq_map_raw: ipar=%s, size=%d\n",
> -			ipar->full_name, intsize);
> -
> -	if (ointsize != intsize)
> -		return -EINVAL;
> -
> -	/* Look for this #address-cells. We have to implement the old linux
> -	 * trick of looking for the parent here as some device-trees rely on it
> -	 */
> -	old = of_node_get(ipar);
> -	do {
> -		tmp = of_get_property(old, "#address-cells", NULL);
> -		tnode = of_get_parent(old);
> -		of_node_put(old);
> -		old = tnode;
> -	} while (old && tmp == NULL);
> -	of_node_put(old);
> -	old = NULL;
> -	addrsize = (tmp == NULL) ? 2 : *tmp;
> -
> -	pr_debug(" -> addrsize=%d\n", addrsize);
> -
> -	/* Now start the actual "proper" walk of the interrupt tree */
> -	while (ipar != NULL) {
> -		/* Now check if cursor is an interrupt-controller and if it is
> -		 * then we are done
> -		 */
> -		if (of_get_property(ipar, "interrupt-controller", NULL) !=
> -				NULL) {
> -			pr_debug(" -> got it !\n");
> -			memcpy(out_irq->specifier, intspec,
> -				intsize * sizeof(u32));
> -			out_irq->size = intsize;
> -			out_irq->controller = ipar;
> -			of_node_put(old);
> -			return 0;
> -		}
> -
> -		/* Now look for an interrupt-map */
> -		imap = of_get_property(ipar, "interrupt-map", &imaplen);
> -		/* No interrupt map, check for an interrupt parent */
> -		if (imap == NULL) {
> -			pr_debug(" -> no map, getting parent\n");
> -			newpar = of_irq_find_parent(ipar);
> -			goto skiplevel;
> -		}
> -		imaplen /= sizeof(u32);
> -
> -		/* Look for a mask */
> -		imask = of_get_property(ipar, "interrupt-map-mask", NULL);
> -
> -		/* If we were passed no "reg" property and we attempt to parse
> -		 * an interrupt-map, then #address-cells must be 0.
> -		 * Fail if it's not.
> -		 */
> -		if (addr == NULL && addrsize != 0) {
> -			pr_debug(" -> no reg passed in when needed !\n");
> -			goto fail;
> -		}
> -
> -		/* Parse interrupt-map */
> -		match = 0;
> -		while (imaplen > (addrsize + intsize + 1) && !match) {
> -			/* Compare specifiers */
> -			match = 1;
> -			for (i = 0; i < addrsize && match; ++i) {
> -				u32 mask = imask ? imask[i] : 0xffffffffu;
> -				match = ((addr[i] ^ imap[i]) & mask) == 0;
> -			}
> -			for (; i < (addrsize + intsize) && match; ++i) {
> -				u32 mask = imask ? imask[i] : 0xffffffffu;
> -				match =
> -					((intspec[i-addrsize] ^ imap[i])
> -						& mask) == 0;
> -			}
> -			imap += addrsize + intsize;
> -			imaplen -= addrsize + intsize;
> -
> -			pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
> -
> -			/* Get the interrupt parent */
> -			newpar = of_irq_find_parent_by_phandle((phandle)*imap);
> -			imap++;
> -			--imaplen;
> -
> -			/* Check if not found */
> -			if (newpar == NULL) {
> -				pr_debug(" -> imap parent not found !\n");
> -				goto fail;
> -			}
> -
> -			/* Get #interrupt-cells and #address-cells of new
> -			 * parent
> -			 */
> -			tmp = of_get_property(newpar, "#interrupt-cells", NULL);
> -			if (tmp == NULL) {
> -				pr_debug(" -> parent lacks "
> -						"#interrupt-cells!\n");
> -				goto fail;
> -			}
> -			newintsize = *tmp;
> -			tmp = of_get_property(newpar, "#address-cells", NULL);
> -			newaddrsize = (tmp == NULL) ? 0 : *tmp;
> -
> -			pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
> -				newintsize, newaddrsize);
> -
> -			/* Check for malformed properties */
> -			if (imaplen < (newaddrsize + newintsize))
> -				goto fail;
> -
> -			imap += newaddrsize + newintsize;
> -			imaplen -= newaddrsize + newintsize;
> -
> -			pr_debug(" -> imaplen=%d\n", imaplen);
> -		}
> -		if (!match)
> -			goto fail;
> -
> -		of_node_put(old);
> -		old = of_node_get(newpar);
> -		addrsize = newaddrsize;
> -		intsize = newintsize;
> -		intspec = imap - intsize;
> -		addr = intspec - addrsize;
> -
> -skiplevel:
> -		/* Iterate again with new parent */
> -		pr_debug(" -> new parent: %s\n",
> -				newpar ? newpar->full_name : "<>");
> -		of_node_put(ipar);
> -		ipar = newpar;
> -		newpar = NULL;
> -	}
> -fail:
> -	of_node_put(ipar);
> -	of_node_put(old);
> -	of_node_put(newpar);
> -
> -	return -EINVAL;
> -}
> -EXPORT_SYMBOL_GPL(of_irq_map_raw);
> -
>  int of_irq_map_one(struct device_node *device,
>  			int index, struct of_irq *out_irq)
>  {
> diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
> index 47d41b6..187ef4e 100644
> --- a/arch/powerpc/include/asm/prom.h
> +++ b/arch/powerpc/include/asm/prom.h
> @@ -123,27 +123,6 @@ extern const void *of_get_mac_address(struct device_node *np);
>  extern void of_irq_map_init(unsigned int flags);
>  
>  /**
> - * of_irq_map_raw - Low level interrupt tree parsing
> - * @parent:	the device interrupt parent
> - * @intspec:	interrupt specifier ("interrupts" property of the device)
> - * @ointsize:   size of the passed in interrupt specifier
> - * @addr:	address specifier (start of "reg" property of the device)
> - * @out_irq:	structure of_irq filled by this function
> - *
> - * Returns 0 on success and a negative number on error
> - *
> - * This function is a low-level interrupt tree walking function. It
> - * can be used to do a partial walk with synthetized reg and interrupts
> - * properties, for example when resolving PCI interrupts when no device
> - * node exist for the parent.
> - *
> - */
> -
> -extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
> -			  u32 ointsize, const u32 *addr,
> -			  struct of_irq *out_irq);
> -
> -/**
>   * of_irq_map_pci - Resolve the interrupt for a PCI device
>   * @pdev:	the device whose interrupt is to be resolved
>   * @out_irq:	structure of_irq filled by this function
> diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
> index 39e977d..89ca7b3 100644
> --- a/arch/powerpc/kernel/prom_parse.c
> +++ b/arch/powerpc/kernel/prom_parse.c
> @@ -731,177 +731,6 @@ void of_irq_map_init(unsigned int flags)
>  
>  }
>  
> -int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
> -		const u32 *addr, struct of_irq *out_irq)
> -{
> -	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
> -	const u32 *tmp, *imap, *imask;
> -	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
> -	int imaplen, match, i;
> -
> -	DBG("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
> -	    parent->full_name, intspec[0], intspec[1], ointsize);
> -
> -	ipar = of_node_get(parent);
> -
> -	/* First get the #interrupt-cells property of the current cursor
> -	 * that tells us how to interpret the passed-in intspec. If there
> -	 * is none, we are nice and just walk up the tree
> -	 */
> -	do {
> -		tmp = of_get_property(ipar, "#interrupt-cells", NULL);
> -		if (tmp != NULL) {
> -			intsize = *tmp;
> -			break;
> -		}
> -		tnode = ipar;
> -		ipar = of_irq_find_parent(ipar);
> -		of_node_put(tnode);
> -	} while (ipar);
> -	if (ipar == NULL) {
> -		DBG(" -> no parent found !\n");
> -		goto fail;
> -	}
> -
> -	DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize);
> -
> -	if (ointsize != intsize)
> -		return -EINVAL;
> -
> -	/* Look for this #address-cells. We have to implement the old linux
> -	 * trick of looking for the parent here as some device-trees rely on it
> -	 */
> -	old = of_node_get(ipar);
> -	do {
> -		tmp = of_get_property(old, "#address-cells", NULL);
> -		tnode = of_get_parent(old);
> -		of_node_put(old);
> -		old = tnode;
> -	} while(old && tmp == NULL);
> -	of_node_put(old);
> -	old = NULL;
> -	addrsize = (tmp == NULL) ? 2 : *tmp;
> -
> -	DBG(" -> addrsize=%d\n", addrsize);
> -
> -	/* Now start the actual "proper" walk of the interrupt tree */
> -	while (ipar != NULL) {
> -		/* Now check if cursor is an interrupt-controller and if it is
> -		 * then we are done
> -		 */
> -		if (of_get_property(ipar, "interrupt-controller", NULL) !=
> -				NULL) {
> -			DBG(" -> got it !\n");
> -			memcpy(out_irq->specifier, intspec,
> -			       intsize * sizeof(u32));
> -			out_irq->size = intsize;
> -			out_irq->controller = ipar;
> -			of_node_put(old);
> -			return 0;
> -		}
> -
> -		/* Now look for an interrupt-map */
> -		imap = of_get_property(ipar, "interrupt-map", &imaplen);
> -		/* No interrupt map, check for an interrupt parent */
> -		if (imap == NULL) {
> -			DBG(" -> no map, getting parent\n");
> -			newpar = of_irq_find_parent(ipar);
> -			goto skiplevel;
> -		}
> -		imaplen /= sizeof(u32);
> -
> -		/* Look for a mask */
> -		imask = of_get_property(ipar, "interrupt-map-mask", NULL);
> -
> -		/* If we were passed no "reg" property and we attempt to parse
> -		 * an interrupt-map, then #address-cells must be 0.
> -		 * Fail if it's not.
> -		 */
> -		if (addr == NULL && addrsize != 0) {
> -			DBG(" -> no reg passed in when needed !\n");
> -			goto fail;
> -		}
> -
> -		/* Parse interrupt-map */
> -		match = 0;
> -		while (imaplen > (addrsize + intsize + 1) && !match) {
> -			/* Compare specifiers */
> -			match = 1;
> -			for (i = 0; i < addrsize && match; ++i) {
> -				u32 mask = imask ? imask[i] : 0xffffffffu;
> -				match = ((addr[i] ^ imap[i]) & mask) == 0;
> -			}
> -			for (; i < (addrsize + intsize) && match; ++i) {
> -				u32 mask = imask ? imask[i] : 0xffffffffu;
> -				match =
> -				   ((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
> -			}
> -			imap += addrsize + intsize;
> -			imaplen -= addrsize + intsize;
> -
> -			DBG(" -> match=%d (imaplen=%d)\n", match, imaplen);
> -
> -			/* Get the interrupt parent */
> -			newpar = of_irq_find_parent_by_phandle((phandle)*imap);
> -			imap++;
> -			--imaplen;
> -
> -			/* Check if not found */
> -			if (newpar == NULL) {
> -				DBG(" -> imap parent not found !\n");
> -				goto fail;
> -			}
> -
> -			/* Get #interrupt-cells and #address-cells of new
> -			 * parent
> -			 */
> -			tmp = of_get_property(newpar, "#interrupt-cells", NULL);
> -			if (tmp == NULL) {
> -				DBG(" -> parent lacks #interrupt-cells !\n");
> -				goto fail;
> -			}
> -			newintsize = *tmp;
> -			tmp = of_get_property(newpar, "#address-cells", NULL);
> -			newaddrsize = (tmp == NULL) ? 0 : *tmp;
> -
> -			DBG(" -> newintsize=%d, newaddrsize=%d\n",
> -			    newintsize, newaddrsize);
> -
> -			/* Check for malformed properties */
> -			if (imaplen < (newaddrsize + newintsize))
> -				goto fail;
> -
> -			imap += newaddrsize + newintsize;
> -			imaplen -= newaddrsize + newintsize;
> -
> -			DBG(" -> imaplen=%d\n", imaplen);
> -		}
> -		if (!match)
> -			goto fail;
> -
> -		of_node_put(old);
> -		old = of_node_get(newpar);
> -		addrsize = newaddrsize;
> -		intsize = newintsize;
> -		intspec = imap - intsize;
> -		addr = intspec - addrsize;
> -
> -	skiplevel:
> -		/* Iterate again with new parent */
> -		DBG(" -> new parent: %s\n", newpar ? newpar->full_name : "<>");
> -		of_node_put(ipar);
> -		ipar = newpar;
> -		newpar = NULL;
> -	}
> - fail:
> -	of_node_put(ipar);
> -	of_node_put(old);
> -	of_node_put(newpar);
> -
> -	return -EINVAL;
> -}
> -EXPORT_SYMBOL_GPL(of_irq_map_raw);
> -
>  #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
>  static int of_irq_map_oldworld(struct device_node *device, int index,
>  			       struct of_irq *out_irq)
> diff --git a/drivers/of/irq.c b/drivers/of/irq.c
> index ad569ca..351c87a 100644
> --- a/drivers/of/irq.c
> +++ b/drivers/of/irq.c
> @@ -52,6 +52,194 @@ struct device_node *of_irq_find_parent(struct device_node *child)
>  	return p;
>  }
>  
> +/**
> + * of_irq_map_raw - Low level interrupt tree parsing
> + * @parent:	the device interrupt parent
> + * @intspec:	interrupt specifier ("interrupts" property of the device)
> + * @ointsize:	size of the passed in interrupt specifier
> + * @addr:	address specifier (start of "reg" property of the device)
> + * @out_irq:	structure of_irq filled by this function
> + *
> + * Returns 0 on success and a negative number on error
> + *
> + * This function is a low-level interrupt tree walking function. It
> + * can be used to do a partial walk with synthetized reg and interrupts
> + * properties, for example when resolving PCI interrupts when no device
> + * node exist for the parent.
> + */
> +int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
> +		const u32 *addr, struct of_irq *out_irq)
> +{
> +	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
> +	const u32 *tmp, *imap, *imask;
> +	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
> +	int imaplen, match, i;
> +
> +	pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
> +		 parent->full_name, intspec[0], intspec[1], ointsize);
> +
> +	ipar = of_node_get(parent);
> +
> +	/* First get the #interrupt-cells property of the current cursor
> +	 * that tells us how to interpret the passed-in intspec. If there
> +	 * is none, we are nice and just walk up the tree
> +	 */
> +	do {
> +		tmp = of_get_property(ipar, "#interrupt-cells", NULL);
> +		if (tmp != NULL) {
> +			intsize = *tmp;
> +			break;
> +		}
> +		tnode = ipar;
> +		ipar = of_irq_find_parent(ipar);
> +		of_node_put(tnode);
> +	} while (ipar);
> +	if (ipar == NULL) {
> +		pr_debug(" -> no parent found !\n");
> +		goto fail;
> +	}
> +
> +	pr_debug("of_irq_map_raw: ipar=%s, size=%d\n",
> +		 ipar->full_name, intsize);
> +
> +	if (ointsize != intsize)
> +		return -EINVAL;
> +
> +	/* Look for this #address-cells. We have to implement the old linux
> +	 * trick of looking for the parent here as some device-trees rely on it
> +	 */
> +	old = of_node_get(ipar);
> +	do {
> +		tmp = of_get_property(old, "#address-cells", NULL);
> +		tnode = of_get_parent(old);
> +		of_node_put(old);
> +		old = tnode;
> +	} while (old && tmp == NULL);
> +	of_node_put(old);
> +	old = NULL;
> +	addrsize = (tmp == NULL) ? 2 : *tmp;
> +
> +	pr_debug(" -> addrsize=%d\n", addrsize);
> +
> +	/* Now start the actual "proper" walk of the interrupt tree */
> +	while (ipar != NULL) {
> +		/* Now check if cursor is an interrupt-controller and if it is
> +		 * then we are done
> +		 */
> +		if (of_get_property(ipar, "interrupt-controller", NULL) !=
> +				NULL) {
> +			pr_debug(" -> got it !\n");
> +			memcpy(out_irq->specifier, intspec,
> +			       intsize * sizeof(u32));
> +			out_irq->size = intsize;
> +			out_irq->controller = ipar;
> +			of_node_put(old);
> +			return 0;
> +		}
> +
> +		/* Now look for an interrupt-map */
> +		imap = of_get_property(ipar, "interrupt-map", &imaplen);
> +		/* No interrupt map, check for an interrupt parent */
> +		if (imap == NULL) {
> +			pr_debug(" -> no map, getting parent\n");
> +			newpar = of_irq_find_parent(ipar);
> +			goto skiplevel;
> +		}
> +		imaplen /= sizeof(u32);
> +
> +		/* Look for a mask */
> +		imask = of_get_property(ipar, "interrupt-map-mask", NULL);
> +
> +		/* If we were passed no "reg" property and we attempt to parse
> +		 * an interrupt-map, then #address-cells must be 0.
> +		 * Fail if it's not.
> +		 */
> +		if (addr == NULL && addrsize != 0) {
> +			pr_debug(" -> no reg passed in when needed !\n");
> +			goto fail;
> +		}
> +
> +		/* Parse interrupt-map */
> +		match = 0;
> +		while (imaplen > (addrsize + intsize + 1) && !match) {
> +			/* Compare specifiers */
> +			match = 1;
> +			for (i = 0; i < addrsize && match; ++i) {
> +				u32 mask = imask ? imask[i] : 0xffffffffu;
> +				match = ((addr[i] ^ imap[i]) & mask) == 0;
> +			}
> +			for (; i < (addrsize + intsize) && match; ++i) {
> +				u32 mask = imask ? imask[i] : 0xffffffffu;
> +				match =
> +				   ((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
> +			}
> +			imap += addrsize + intsize;
> +			imaplen -= addrsize + intsize;
> +
> +			pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
> +
> +			/* Get the interrupt parent */
> +			newpar = of_irq_find_parent_by_phandle((phandle)*imap);
> +			imap++;
> +			--imaplen;
> +
> +			/* Check if not found */
> +			if (newpar == NULL) {
> +				pr_debug(" -> imap parent not found !\n");
> +				goto fail;
> +			}
> +
> +			/* Get #interrupt-cells and #address-cells of new
> +			 * parent
> +			 */
> +			tmp = of_get_property(newpar, "#interrupt-cells", NULL);
> +			if (tmp == NULL) {
> +				pr_debug(" -> parent lacks #interrupt-cells!\n");
> +				goto fail;
> +			}
> +			newintsize = *tmp;
> +			tmp = of_get_property(newpar, "#address-cells", NULL);
> +			newaddrsize = (tmp == NULL) ? 0 : *tmp;
> +
> +			pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
> +			    newintsize, newaddrsize);
> +
> +			/* Check for malformed properties */
> +			if (imaplen < (newaddrsize + newintsize))
> +				goto fail;
> +
> +			imap += newaddrsize + newintsize;
> +			imaplen -= newaddrsize + newintsize;
> +
> +			pr_debug(" -> imaplen=%d\n", imaplen);
> +		}
> +		if (!match)
> +			goto fail;
> +
> +		of_node_put(old);
> +		old = of_node_get(newpar);
> +		addrsize = newaddrsize;
> +		intsize = newintsize;
> +		intspec = imap - intsize;
> +		addr = intspec - addrsize;
> +
> +	skiplevel:
> +		/* Iterate again with new parent */
> +		pr_debug(" -> new parent: %s\n",
> +			 newpar ? newpar->full_name : "<>");
> +		of_node_put(ipar);
> +		ipar = newpar;
> +		newpar = NULL;
> +	}
> + fail:
> +	of_node_put(ipar);
> +	of_node_put(old);
> +	of_node_put(newpar);
> +
> +	return -EINVAL;
> +}
> +EXPORT_SYMBOL_GPL(of_irq_map_raw);
> +
>  unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
>  {
>  	struct of_irq oirq;
> diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
> index f98b27b..51c520b 100644
> --- a/include/linux/of_irq.h
> +++ b/include/linux/of_irq.h
> @@ -32,6 +32,8 @@ struct of_irq {
>  
>  extern struct device_node *of_irq_find_parent_by_phandle(phandle p);
>  extern struct device_node *of_irq_find_parent(struct device_node *child);
> +extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
> +			 u32 ointsize, const u32 *addr, struct of_irq *out_irq);
>  extern int of_irq_map_one(struct device_node *device, int index,
>  			  struct of_irq *out_irq);
>  extern unsigned int irq_create_of_mapping(struct device_node *controller,

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/5] of/irq: merge of_irq_map_one()
  2010-06-04 21:21 ` [PATCH 5/5] of/irq: merge of_irq_map_one() Grant Likely
@ 2010-06-10  6:40   ` Benjamin Herrenschmidt
  2010-06-10 23:36     ` Grant Likely
  0 siblings, 1 reply; 18+ messages in thread
From: Benjamin Herrenschmidt @ 2010-06-10  6:40 UTC (permalink / raw)
  To: Grant Likely
  Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
	devicetree-discuss, linuxppc-dev

On Fri, 2010-06-04 at 15:21 -0600, Grant Likely wrote:
> Merge common implementation of of_irq_map_one().  Rename it to
> __of_irq_map_one() so that arch code can either use the stock
> implementation, or override it to handle platform quirks.

Similar comment to before, I think the breakup of functions causes more
complication and bloat than just keeping the quirks in the generic code.

Cheers,
Ben.

> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> CC: Michal Simek <monstr@monstr.eu>
> CC: Wolfram Sang <w.sang@pengutronix.de>
> CC: Stephen Rothwell <sfr@canb.auug.org.au>
> CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> CC: microblaze-uclinux@itee.uq.edu.au
> CC: linuxppc-dev@ozlabs.org
> CC: devicetree-discuss@lists.ozlabs.org
> ---
>  arch/microblaze/include/asm/prom.h  |    3 -
>  arch/microblaze/kernel/prom_parse.c |   73 ------------------------------
>  arch/powerpc/include/asm/prom.h     |    3 -
>  arch/powerpc/kernel/prom_parse.c    |   55 -----------------------
>  drivers/of/irq.c                    |   85 +++++++++++++++++++++++++++++++++++
>  include/linux/of_irq.h              |    6 ++
>  6 files changed, 91 insertions(+), 134 deletions(-)
> 
> diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
> index 89fca70..3659930 100644
> --- a/arch/microblaze/include/asm/prom.h
> +++ b/arch/microblaze/include/asm/prom.h
> @@ -107,9 +107,6 @@ extern const void *of_get_mac_address(struct device_node *np);
>  struct pci_dev;
>  extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
>  
> -extern int of_irq_to_resource(struct device_node *dev, int index,
> -			struct resource *r);
> -
>  /**
>   * of_iomap - Maps the memory mapped IO for a given device_node
>   * @device:	the device whose io range will be mapped
> diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
> index 02ec946..70c0471 100644
> --- a/arch/microblaze/kernel/prom_parse.c
> +++ b/arch/microblaze/kernel/prom_parse.c
> @@ -656,49 +656,7 @@ struct device_node *of_irq_find_parent_by_phandle(phandle p)
>  int of_irq_map_one(struct device_node *device,
>  			int index, struct of_irq *out_irq)
>  {
> -	struct device_node *p;
> -	const u32 *intspec, *tmp, *addr;
> -	u32 intsize, intlen;
> -	int res;
> -
> -	pr_debug("of_irq_map_one: dev=%s, index=%d\n",
> -			device->full_name, index);
> -
> -	/* Get the interrupts property */
> -	intspec = of_get_property(device, "interrupts", (int *) &intlen);
> -	if (intspec == NULL)
> -		return -EINVAL;
> -	intlen /= sizeof(u32);
> -
> -	pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen);
> -
> -	/* Get the reg property (if any) */
> -	addr = of_get_property(device, "reg", NULL);
> -
> -	/* Look for the interrupt parent. */
> -	p = of_irq_find_parent(device);
> -	if (p == NULL)
> -		return -EINVAL;
> -
> -	/* Get size of interrupt specifier */
> -	tmp = of_get_property(p, "#interrupt-cells", NULL);
> -	if (tmp == NULL) {
> -		of_node_put(p);
> -		return -EINVAL;
> -	}
> -	intsize = *tmp;
> -
> -	pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
> -
> -	/* Check index */
> -	if ((index + 1) * intsize > intlen)
> -		return -EINVAL;
> -
> -	/* Get new specifier and map it */
> -	res = of_irq_map_raw(p, intspec + index * intsize, intsize,
> -				addr, out_irq);
> -	of_node_put(p);
> -	return res;
> +	return __of_irq_map_one(device, index, out_irq);
>  }
>  EXPORT_SYMBOL_GPL(of_irq_map_one);
>  
> @@ -740,35 +698,6 @@ const void *of_get_mac_address(struct device_node *np)
>  }
>  EXPORT_SYMBOL(of_get_mac_address);
>  
> -int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
> -{
> -	struct of_irq out_irq;
> -	int irq;
> -	int res;
> -
> -	res = of_irq_map_one(dev, index, &out_irq);
> -
> -	/* Get irq for the device */
> -	if (res) {
> -		pr_debug("IRQ not found... code = %d", res);
> -		return NO_IRQ;
> -	}
> -	/* Assuming single interrupt controller... */
> -	irq = out_irq.specifier[0];
> -
> -	pr_debug("IRQ found = %d", irq);
> -
> -	/* Only dereference the resource if both the
> -	 * resource and the irq are valid. */
> -	if (r && irq != NO_IRQ) {
> -		r->start = r->end = irq;
> -		r->flags = IORESOURCE_IRQ;
> -	}
> -
> -	return irq;
> -}
> -EXPORT_SYMBOL_GPL(of_irq_to_resource);
> -
>  void __iomem *of_iomap(struct device_node *np, int index)
>  {
>  	struct resource res;
> diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
> index 187ef4e..2440984 100644
> --- a/arch/powerpc/include/asm/prom.h
> +++ b/arch/powerpc/include/asm/prom.h
> @@ -136,9 +136,6 @@ extern void of_irq_map_init(unsigned int flags);
>  struct pci_dev;
>  extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
>  
> -extern int of_irq_to_resource(struct device_node *dev, int index,
> -			struct resource *r);
> -
>  /**
>   * of_iomap - Maps the memory mapped IO for a given device_node
>   * @device:	the device whose io range will be mapped
> diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
> index 89ca7b3..ef518e3 100644
> --- a/arch/powerpc/kernel/prom_parse.c
> +++ b/arch/powerpc/kernel/prom_parse.c
> @@ -777,49 +777,11 @@ static int of_irq_map_oldworld(struct device_node *device, int index,
>  
>  int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
>  {
> -	struct device_node *p;
> -	const u32 *intspec, *tmp, *addr;
> -	u32 intsize, intlen;
> -	int res = -EINVAL;
> -
> -	DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
> -
>  	/* OldWorld mac stuff is "special", handle out of line */
>  	if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
>  		return of_irq_map_oldworld(device, index, out_irq);
>  
> -	/* Get the interrupts property */
> -	intspec = of_get_property(device, "interrupts", &intlen);
> -	if (intspec == NULL)
> -		return -EINVAL;
> -	intlen /= sizeof(u32);
> -
> -	/* Get the reg property (if any) */
> -	addr = of_get_property(device, "reg", NULL);
> -
> -	/* Look for the interrupt parent. */
> -	p = of_irq_find_parent(device);
> -	if (p == NULL)
> -		return -EINVAL;
> -
> -	/* Get size of interrupt specifier */
> -	tmp = of_get_property(p, "#interrupt-cells", NULL);
> -	if (tmp == NULL)
> -		goto out;
> -	intsize = *tmp;
> -
> -	DBG(" intsize=%d intlen=%d\n", intsize, intlen);
> -
> -	/* Check index */
> -	if ((index + 1) * intsize > intlen)
> -		goto out;
> -
> -	/* Get new specifier and map it */
> -	res = of_irq_map_raw(p, intspec + index * intsize, intsize,
> -			     addr, out_irq);
> -out:
> -	of_node_put(p);
> -	return res;
> +	return __of_irq_map_one(device, index, out_irq);
>  }
>  EXPORT_SYMBOL_GPL(of_irq_map_one);
>  
> @@ -861,21 +823,6 @@ const void *of_get_mac_address(struct device_node *np)
>  }
>  EXPORT_SYMBOL(of_get_mac_address);
>  
> -int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
> -{
> -	int irq = irq_of_parse_and_map(dev, index);
> -
> -	/* Only dereference the resource if both the
> -	 * resource and the irq are valid. */
> -	if (r && irq != NO_IRQ) {
> -		r->start = r->end = irq;
> -		r->flags = IORESOURCE_IRQ;
> -	}
> -
> -	return irq;
> -}
> -EXPORT_SYMBOL_GPL(of_irq_to_resource);
> -
>  void __iomem *of_iomap(struct device_node *np, int index)
>  {
>  	struct resource res;
> diff --git a/drivers/of/irq.c b/drivers/of/irq.c
> index 351c87a..dd420e5 100644
> --- a/drivers/of/irq.c
> +++ b/drivers/of/irq.c
> @@ -31,7 +31,7 @@
>   * Returns a pointer to the interrupt parent node, or NULL if the interrupt
>   * parent could not be determined.
>   */
> -struct device_node *of_irq_find_parent(struct device_node *child)
> +static struct device_node *of_irq_find_parent(struct device_node *child)
>  {
>  	struct device_node *p;
>  	const phandle *parp;
> @@ -240,6 +240,67 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
>  }
>  EXPORT_SYMBOL_GPL(of_irq_map_raw);
>  
> +/**
> + * of_irq_map_one - Resolve an interrupt for a device
> + * @device: the device whose interrupt is to be resolved
> + * @index: index of the interrupt to resolve
> + * @out_irq: structure of_irq filled by this function
> + *
> + * This function resolves an interrupt, walking the tree, for a given
> + * device-tree node. It's the high level pendant to of_irq_map_raw().
> + *
> + * Architecture code must provide of_irq_map_one() which can simply be a
> + * wrapper around __of_irq_map_one(), or can override it to deal with
> + * arch specific quirks and bugs.
> + */
> +int __of_irq_map_one(struct device_node *device, int index,
> +		     struct of_irq *out_irq)
> +{
> +	struct device_node *p;
> +	const u32 *intspec, *tmp, *addr;
> +	u32 intsize, intlen;
> +	int res = -EINVAL;
> +
> +	pr_debug("of_irq_map_one: dev=%s, index=%d\n",
> +		 device->full_name, index);
> +
> +	/* Get the interrupts property */
> +	intspec = of_get_property(device, "interrupts", &intlen);
> +	if (intspec == NULL)
> +		return -EINVAL;
> +	intlen /= sizeof(u32);
> +
> +	pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen);
> +
> +	/* Get the reg property (if any) */
> +	addr = of_get_property(device, "reg", NULL);
> +
> +	/* Look for the interrupt parent. */
> +	p = of_irq_find_parent(device);
> +	if (p == NULL)
> +		return -EINVAL;
> +
> +	/* Get size of interrupt specifier */
> +	tmp = of_get_property(p, "#interrupt-cells", NULL);
> +	if (tmp == NULL)
> +		goto out;
> +	intsize = *tmp;
> +
> +	pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
> +
> +	/* Check index */
> +	if ((index + 1) * intsize > intlen)
> +		goto out;
> +
> +	/* Get new specifier and map it */
> +	res = of_irq_map_raw(p, intspec + index * intsize, intsize,
> +			     addr, out_irq);
> + out:
> +	of_node_put(p);
> +	return res;
> +}
> +EXPORT_SYMBOL_GPL(__of_irq_map_one);
> +
>  unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
>  {
>  	struct of_irq oirq;
> @@ -251,3 +312,25 @@ unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
>  				     oirq.size);
>  }
>  EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
> +
> +/**
> + * of_irq_to_resource - Decode a node's IRQ and return it as a resource
> + * @dev: pointer to device tree node
> + * @index: zero-based index of the irq
> + * @r: pointer to resource structure to return result into.
> + */
> +unsigned int of_irq_to_resource(struct device_node *dev, int index,
> +				struct resource *r)
> +{
> +	unsigned int irq = irq_of_parse_and_map(dev, index);
> +
> +	/* Only dereference the resource if both the
> +	 * resource and the irq are valid. */
> +	if (r && irq != NO_IRQ) {
> +		r->start = r->end = irq;
> +		r->flags = IORESOURCE_IRQ;
> +	}
> +
> +	return irq;
> +}
> +EXPORT_SYMBOL_GPL(of_irq_to_resource);
> diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
> index 51c520b..935a14d 100644
> --- a/include/linux/of_irq.h
> +++ b/include/linux/of_irq.h
> @@ -5,6 +5,7 @@
>  struct of_irq;
>  #include <linux/types.h>
>  #include <linux/of.h>
> +#include <linux/ioport.h>
>  
>  /*
>   * irq_of_parse_and_map() is used ba all OF enabled platforms; but SPARC
> @@ -31,14 +32,17 @@ struct of_irq {
>  };
>  
>  extern struct device_node *of_irq_find_parent_by_phandle(phandle p);
> -extern struct device_node *of_irq_find_parent(struct device_node *child);
>  extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
>  			 u32 ointsize, const u32 *addr, struct of_irq *out_irq);
> +extern int __of_irq_map_one(struct device_node *device, int index,
> +			    struct of_irq *out_irq);
>  extern int of_irq_map_one(struct device_node *device, int index,
>  			  struct of_irq *out_irq);
>  extern unsigned int irq_create_of_mapping(struct device_node *controller,
>  					  const u32 *intspec,
>  					  unsigned int intsize);
> +extern unsigned int of_irq_to_resource(struct device_node *dev, int index,
> +				       struct resource *r);
>  
>  #endif /* CONFIG_OF_IRQ */
>  #endif /* CONFIG_OF */

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/5] of/irq: merge of_irq_map_one()
  2010-06-10  6:40   ` Benjamin Herrenschmidt
@ 2010-06-10 23:36     ` Grant Likely
  2010-06-11  1:17       ` Benjamin Herrenschmidt
  2010-06-11  1:30       ` PCIe bus seems work while 'dma' can't under linux jxnuxdy
  0 siblings, 2 replies; 18+ messages in thread
From: Grant Likely @ 2010-06-10 23:36 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
	devicetree-discuss, linuxppc-dev

On Thu, Jun 10, 2010 at 12:40 AM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Fri, 2010-06-04 at 15:21 -0600, Grant Likely wrote:
>> Merge common implementation of of_irq_map_one(). =A0Rename it to
>> __of_irq_map_one() so that arch code can either use the stock
>> implementation, or override it to handle platform quirks.
>
> Similar comment to before, I think the breakup of functions causes more
> complication and bloat than just keeping the quirks in the generic code.

Okay.  I had been trying to avoid #ifdefs in the common code, but
you're probably right.  I'll rework.

g.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/5] of/irq: merge of_irq_map_one()
  2010-06-10 23:36     ` Grant Likely
@ 2010-06-11  1:17       ` Benjamin Herrenschmidt
  2010-06-17 23:11         ` Grant Likely
  2010-06-11  1:30       ` PCIe bus seems work while 'dma' can't under linux jxnuxdy
  1 sibling, 1 reply; 18+ messages in thread
From: Benjamin Herrenschmidt @ 2010-06-11  1:17 UTC (permalink / raw)
  To: Grant Likely
  Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
	devicetree-discuss, linuxppc-dev

On Thu, 2010-06-10 at 17:36 -0600, Grant Likely wrote:
> 
> Okay.  I had been trying to avoid #ifdefs in the common code, but
> you're probably right.  I'll rework. 

Not even ifdef's ... just move the quirk map there. You can always
#define the quirk variable to 0 on archs that have no quirks, to
make it compile away if you believe it represents bloat, but they
are simple well localized things so I doubt it matters.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* PCIe bus seems work while 'dma' can't under linux
  2010-06-10 23:36     ` Grant Likely
  2010-06-11  1:17       ` Benjamin Herrenschmidt
@ 2010-06-11  1:30       ` jxnuxdy
  2010-06-11  7:21         ` Benjamin Herrenschmidt
  2010-06-15  7:05         ` jxnuxdy
  1 sibling, 2 replies; 18+ messages in thread
From: jxnuxdy @ 2010-06-11  1:30 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Stephen Rothwell, Michal Simek, devicetree-discuss,
	microblaze-uclinux

Hi guys,

I encountered a PCIe problem under linux, the two PCIe bus on my board seems work, at least I can access the registers through the PCIe bus, however the dma for the PCIe bus can't work, so I just dumped the pci device, but I am curiously to find there is no regions displayed on PCIe controlers, why? is it relate with my 'dma' issue then?


bash-2.04# cat /proc/pci
PCI devices found:
  Bus  0, device   0, function  0:
    Class 0b20  Header Type 01: PCI device 1957:0032 (rev 17).
  Bus  1, device   0, function  0:
    Class 0580  Header Type 00: PCI device 11ab:db90 (rev 1).
      Prefetchable 64 bit memory at 0x80000000 [0x800fffff].
      Prefetchable 64 bit memory at 0x84000000 [0x87ffffff].
  Bus  9, device   0, function  0:
    Class 0b20  Header Type 01: PCI device 1957:0032 (rev 17).
  Bus 10, device   0, function  0:
    Class 0580  Header Type 00: PCI device 11ab:db90 (rev 1).
      Prefetchable 64 bit memory at 0xa0000000 [0xa00fffff].
      Prefetchable 64 bit memory at 0xa4000000 [0xa7ffffff].
bash-2.04# lspci -vv
00:00.0 Power PC: Unknown device 1957:0032 (rev 11)
        !!! Invalid class 0b20 for header type 01
        Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
        Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
        Latency: 0, cache line size 08
        Bus: primary=00, secondary=01, subordinate=06, sec-latency=0
        I/O behind bridge: 00000000-00000fff
        Memory behind bridge: 80000000-9fffffff
        BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
        Capabilities: [44] Power Management version 2
                Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
                Status: D0 PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [4c] #10 [0041]

01:00.0 Memory controller: Galileo Technology Ltd.: Unknown device db90 (rev 01)
        Subsystem: Galileo Technology Ltd.: Unknown device 11ab
        Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
        Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
        Latency: 0, cache line size 08
        Interrupt: pin A routed to IRQ 0
        Region 0: Memory at 80000000 (64-bit, prefetchable) [size=1M]
        Region 2: Memory at 84000000 (64-bit, prefetchable) [size=64M]
        Capabilities: [40] Power Management version 2
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [50] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable-
                Address: 0000000000000000  Data: 0000
        Capabilities: [60] #10 [0011]

09:00.0 Power PC: Unknown device 1957:0032 (rev 11)
        !!! Invalid class 0b20 for header type 01
        Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
        Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
        Latency: 0, cache line size 08
        Bus: primary=00, secondary=0a, subordinate=0f, sec-latency=0
        I/O behind bridge: 00000000-00000fff
        Memory behind bridge: a0000000-bfffffff
        BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
        Capabilities: [44] Power Management version 2
                Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
                Status: D0 PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [4c] #10 [0041]

0a:00.0 Memory controller: Galileo Technology Ltd.: Unknown device db90 (rev 01)
        Subsystem: Galileo Technology Ltd.: Unknown device 11ab
        Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
        Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
        Latency: 0, cache line size 08
        Interrupt: pin A routed to IRQ 0
        Region 0: Memory at a0000000 (64-bit, prefetchable) [size=1M]
        Region 2: Memory at a4000000 (64-bit, prefetchable) [size=64M]
        Capabilities: [40] Power Management version 2
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [50] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable-
                Address: 0000000000000000  Data: 0000
        Capabilities: [60] #10 [0011]

bash-2.04# 

Thanks
Denny

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PCIe bus seems work while 'dma' can't under linux
  2010-06-11  1:30       ` PCIe bus seems work while 'dma' can't under linux jxnuxdy
@ 2010-06-11  7:21         ` Benjamin Herrenschmidt
  2010-06-15  7:05         ` jxnuxdy
  1 sibling, 0 replies; 18+ messages in thread
From: Benjamin Herrenschmidt @ 2010-06-11  7:21 UTC (permalink / raw)
  To: jxnuxdy
  Cc: linuxppc-dev, Michal Simek, devicetree-discuss,
	microblaze-uclinux, Stephen Rothwell

On Fri, 2010-06-11 at 09:30 +0800, jxnuxdy wrote:
> Hi guys,
> 
> I encountered a PCIe problem under linux, the two PCIe bus on my board seems work, 
> at least I can access the registers through the PCIe bus, however the dma for the
> PCIe bus can't work, so I just dumped the pci device, but I am curiously to find
> there is no regions displayed on PCIe controlers, why? is it relate with my 'dma' issue then?

It would help if you told us a bit more what the HW is, what you are
doing with it, etc...

IE. What is your host, what is your device, what platform, etc...

DMA should work provided that your platform code sets it up properly.
The DMA regions don't appear in /proc/pci or lspci.

Cheers,
Ben.

> 
> bash-2.04# cat /proc/pci
> PCI devices found:
>   Bus  0, device   0, function  0:
>     Class 0b20  Header Type 01: PCI device 1957:0032 (rev 17).
>   Bus  1, device   0, function  0:
>     Class 0580  Header Type 00: PCI device 11ab:db90 (rev 1).
>       Prefetchable 64 bit memory at 0x80000000 [0x800fffff].
>       Prefetchable 64 bit memory at 0x84000000 [0x87ffffff].
>   Bus  9, device   0, function  0:
>     Class 0b20  Header Type 01: PCI device 1957:0032 (rev 17).
>   Bus 10, device   0, function  0:
>     Class 0580  Header Type 00: PCI device 11ab:db90 (rev 1).
>       Prefetchable 64 bit memory at 0xa0000000 [0xa00fffff].
>       Prefetchable 64 bit memory at 0xa4000000 [0xa7ffffff].
> bash-2.04# lspci -vv
> 00:00.0 Power PC: Unknown device 1957:0032 (rev 11)
>         !!! Invalid class 0b20 for header type 01
>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
>         Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
>         Latency: 0, cache line size 08
>         Bus: primary=00, secondary=01, subordinate=06, sec-latency=0
>         I/O behind bridge: 00000000-00000fff
>         Memory behind bridge: 80000000-9fffffff
>         BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
>         Capabilities: [44] Power Management version 2
>                 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
>                 Status: D0 PME-Enable- DSel=0 DScale=0 PME-
>         Capabilities: [4c] #10 [0041]
> 
> 01:00.0 Memory controller: Galileo Technology Ltd.: Unknown device db90 (rev 01)
>         Subsystem: Galileo Technology Ltd.: Unknown device 11ab
>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
>         Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
>         Latency: 0, cache line size 08
>         Interrupt: pin A routed to IRQ 0
>         Region 0: Memory at 80000000 (64-bit, prefetchable) [size=1M]
>         Region 2: Memory at 84000000 (64-bit, prefetchable) [size=64M]
>         Capabilities: [40] Power Management version 2
>                 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
>                 Status: D0 PME-Enable- DSel=0 DScale=0 PME-
>         Capabilities: [50] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable-
>                 Address: 0000000000000000  Data: 0000
>         Capabilities: [60] #10 [0011]
> 
> 09:00.0 Power PC: Unknown device 1957:0032 (rev 11)
>         !!! Invalid class 0b20 for header type 01
>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
>         Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
>         Latency: 0, cache line size 08
>         Bus: primary=00, secondary=0a, subordinate=0f, sec-latency=0
>         I/O behind bridge: 00000000-00000fff
>         Memory behind bridge: a0000000-bfffffff
>         BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
>         Capabilities: [44] Power Management version 2
>                 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
>                 Status: D0 PME-Enable- DSel=0 DScale=0 PME-
>         Capabilities: [4c] #10 [0041]
> 
> 0a:00.0 Memory controller: Galileo Technology Ltd.: Unknown device db90 (rev 01)
>         Subsystem: Galileo Technology Ltd.: Unknown device 11ab
>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
>         Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
>         Latency: 0, cache line size 08
>         Interrupt: pin A routed to IRQ 0
>         Region 0: Memory at a0000000 (64-bit, prefetchable) [size=1M]
>         Region 2: Memory at a4000000 (64-bit, prefetchable) [size=64M]
>         Capabilities: [40] Power Management version 2
>                 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
>                 Status: D0 PME-Enable- DSel=0 DScale=0 PME-
>         Capabilities: [50] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable-
>                 Address: 0000000000000000  Data: 0000
>         Capabilities: [60] #10 [0011]
> 
> bash-2.04# 
> 
> Thanks
> Denny
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re:Re: PCIe bus seems work while 'dma' can't under linux
  2010-06-11  1:30       ` PCIe bus seems work while 'dma' can't under linux jxnuxdy
  2010-06-11  7:21         ` Benjamin Herrenschmidt
@ 2010-06-15  7:05         ` jxnuxdy
  2010-06-15  7:12           ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 18+ messages in thread
From: jxnuxdy @ 2010-06-15  7:05 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev, Michal Simek, Stephen Rothwell, devicetree-discuss,
	microblaze-uclinux

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

Thanks Benjamin, the regions don't display as what we expect, that's why we suspect if there any configuration probelms in CPU host bridge, but we changed the uboot/linux a lot, seems take no effect on that problems.

We use CPU MPC8544, and connect two PCIE devices to CPU PCIE1 and PCIE2 directly without a  extended PCIE bridge, so we disabled PCIE3 and PCI controlers in uboot level.

More settings pls take a look at the attach file log.txt.


Many thanks,
Denny
----------------------------------------------------------------------------------------------------------------------------
在2010-06-11 15:21:24,"Benjamin Herrenschmidt" <benh@kernel.crashing.org> 写道:
>On Fri, 2010-06-11 at 09:30 +0800, jxnuxdy wrote:
>> Hi guys,
>> 
>> I encountered a PCIe problem under linux, the two PCIe bus on my board seems work, 
>> at least I can access the registers through the PCIe bus, however the dma for the
>> PCIe bus can't work, so I just dumped the pci device, but I am curiously to find
>> there is no regions displayed on PCIe controlers, why? is it relate with my 'dma' issue then?
>
>It would help if you told us a bit more what the HW is, what you are
>doing with it, etc...
>
>IE. What is your host, what is your device, what platform, etc...
>
>DMA should work provided that your platform code sets it up properly.
>The DMA regions don't appear in /proc/pci or lspci.
>
>Cheers,
>Ben.
>
>> 
>> bash-2.04# cat /proc/pci
>> PCI devices found:
>>   Bus  0, device   0, function  0:
>>     Class 0b20  Header Type 01: PCI device 1957:0032 (rev 17).
>>   Bus  1, device   0, function  0:
>>     Class 0580  Header Type 00: PCI device 11ab:db90 (rev 1).
>>       Prefetchable 64 bit memory at 0x80000000 [0x800fffff].
>>       Prefetchable 64 bit memory at 0x84000000 [0x87ffffff].
>>   Bus  9, device   0, function  0:
>>     Class 0b20  Header Type 01: PCI device 1957:0032 (rev 17).
>>   Bus 10, device   0, function  0:
>>     Class 0580  Header Type 00: PCI device 11ab:db90 (rev 1).
>>       Prefetchable 64 bit memory at 0xa0000000 [0xa00fffff].
>>       Prefetchable 64 bit memory at 0xa4000000 [0xa7ffffff].
>> bash-2.04# lspci -vv
>> 00:00.0 Power PC: Unknown device 1957:0032 (rev 11)
>>         !!! Invalid class 0b20 for header type 01
>>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
>>         Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
>>         Latency: 0, cache line size 08
>>         Bus: primary=00, secondary=01, subordinate=06, sec-latency=0
>>         I/O behind bridge: 00000000-00000fff
>>         Memory behind bridge: 80000000-9fffffff
>>         BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
>>         Capabilities: [44] Power Management version 2
>>                 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
>>                 Status: D0 PME-Enable- DSel=0 DScale=0 PME-
>>         Capabilities: [4c] #10 [0041]
>> 
>> 01:00.0 Memory controller: Galileo Technology Ltd.: Unknown device db90 (rev 01)
>>         Subsystem: Galileo Technology Ltd.: Unknown device 11ab
>>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
>>         Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
>>         Latency: 0, cache line size 08
>>         Interrupt: pin A routed to IRQ 0
>>         Region 0: Memory at 80000000 (64-bit, prefetchable) [size=1M]
>>         Region 2: Memory at 84000000 (64-bit, prefetchable) [size=64M]
>>         Capabilities: [40] Power Management version 2
>>                 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
>>                 Status: D0 PME-Enable- DSel=0 DScale=0 PME-
>>         Capabilities: [50] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable-
>>                 Address: 0000000000000000  Data: 0000
>>         Capabilities: [60] #10 [0011]
>> 
>> 09:00.0 Power PC: Unknown device 1957:0032 (rev 11)
>>         !!! Invalid class 0b20 for header type 01
>>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
>>         Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
>>         Latency: 0, cache line size 08
>>         Bus: primary=00, secondary=0a, subordinate=0f, sec-latency=0
>>         I/O behind bridge: 00000000-00000fff
>>         Memory behind bridge: a0000000-bfffffff
>>         BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
>>         Capabilities: [44] Power Management version 2
>>                 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
>>                 Status: D0 PME-Enable- DSel=0 DScale=0 PME-
>>         Capabilities: [4c] #10 [0041]
>> 
>> 0a:00.0 Memory controller: Galileo Technology Ltd.: Unknown device db90 (rev 01)
>>         Subsystem: Galileo Technology Ltd.: Unknown device 11ab
>>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
>>         Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
>>         Latency: 0, cache line size 08
>>         Interrupt: pin A routed to IRQ 0
>>         Region 0: Memory at a0000000 (64-bit, prefetchable) [size=1M]
>>         Region 2: Memory at a4000000 (64-bit, prefetchable) [size=64M]
>>         Capabilities: [40] Power Management version 2
>>                 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
>>                 Status: D0 PME-Enable- DSel=0 DScale=0 PME-
>>         Capabilities: [50] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable-
>>                 Address: 0000000000000000  Data: 0000
>>         Capabilities: [60] #10 [0011]
>> 
>> bash-2.04# 
>> 
>> Thanks
>> Denny
>> 
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
>
>_______________________________________________
>Linuxppc-dev mailing list
>Linuxppc-dev@lists.ozlabs.org
>https://lists.ozlabs.org/listinfo/linuxppc-dev

[-- Attachment #2: log.txt --]
[-- Type: text/plain, Size: 63314 bytes --]


U-Boot 1.1.3 (Jun 14 2010 - 19:26:53)

CPU:   8544_E, Version: 1.1, (0x803c0111)
Core:  E500, Version: 2.2, (0x80210022)
Clock Configuration:
       CPU: 800 MHz, CCB: 400 MHz,
       DDR: 200 MHz, LBC:  50 MHz
L1:    D-cache 32 kB enabled
       I-cache 32 kB enabled
Board: C48
CPU Board Revision 0.0 (0x0000)
    PCI2: disabled
I2C:   ready
DRAM:  Initializing DDRSDRAM 
memsize = 200 
    DDR: 512 MB
POST RAM test disabled.
Now running in RAM - U-Boot at: 1fb7c000
trap_init : 0x0
system inventory subsystem initialized 
FLASH: 64 MB
L2 cache 256KB: enabled
PCI:
               Scanning PCI bus 00
        01  00  11ab  db90  0580  00
               Scanning PCI bus 02
        03  00  11ab  db90  0580  00
In:    serial
Out:   serial
Err:   serial
Net:   
ENET0: PHY is Marvell 88E1112 (1410c97)

set_bootstatus: BS_LOAD_OS, platform_idx = 11 

Hit ESC to stop autoboot:  0 
## Booting image at fb400000 ...
   Image Name:   Linux-2.6.14.2
   Image Type:   PowerPC Linux Multi-File Image (gzip compressed)
   Data Size:    2506379 Bytes =  2.4 MB
   Load Address: 00000000
   Entry Point:  00000000
   Contents:
   Image 0:  1429862 Bytes =  1.4 MB
   Image 1:  1076503 Bytes =  1 MB
   Uncompressing Multi-File Image ... ## Current stack ends at 0x1FB5ABD0 => set upper limit to 0x00800000
## initrd at 0xFB55D1B4 ... 0xFB663ECA (len=1076503=0x106D17)
   Loading Ramdisk to 1fa53000, end 1fb59d17 ... OK
 initrd_start = 1fa53000, initrd_end = 1fb59d17 
## Transferring control to Linux (at address 00000000) ...
Memory CAM mapping: CAM0=256Mb, CAM1=256Mb, CAM2=0Mb residual: 0Mb
tlbcam_index=2
Linux version 2.6.14.2 (dxiao@blc-10-6) (gcc version 3.4.6) #25 Fri Jun 11 17:59:39 PDT 2010
silkworm85xx_setup_arch
mpc85xx_setup: Doing Pcie bridge setup
Scanning PcieBus...
cpld_init: platform (101) not supported
Brocade Silkworm port (C) 2006 Brocade Communications Systems, Inc.
  DMA zone: 131072 pages, LIFO batch:31
  Normal zone: 0 pages, LIFO batch:1
  HighMem zone: 0 pages, LIFO batch:1
Built 1 zonelists
Kernel command line: ip=off console=ttyS1,9600 noinitrd rootfstype=jffs2 root=/dev/mtdblock1 rw
OpenPIC Version 1.2 (1 CPUs and 60 IRQ sources) at fafb9000
PID hash table entries: 4096 (order: 12, 65536 bytes)
Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
Memory: 514944k available (2280k kernel code, 668k data, 144k init, 0k highmem)
Mount-cache hash table entries: 512
checking if image is initramfs...it isn't (no cpio magic); looks like an initrd
Freeing initrd memory: 1051k freed
softlockup thread 0 started up.
NET: Registered protocol family 16
PCI:: Probing PCI hardware
PCI: 0000:00:00.0: class b20 doesn't match header type 01. Ignoring class.
PCI: 0001:02:00.0: class b20 doesn't match header type 01. Ignoring class.
Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
JFFS2 version 2.2. (NAND) (C) 2001-2003 Red Hat, Inc.
Initializing Cryptographic API
Generic RTC Driver v1.07
SWBD Platform Driver v1.0: [type 101, rev 2].
Config Silkworm 
PowerPC Book-E Watchdog Timer Loaded
Serial: 8250/16550 driver $Revision: 1.90 $ 2 ports, IRQ sharing disabled
ttyS0 at MMIO 0xe0004600 (irq = 26) is a 16550A
ttyS1 at MMIO 0xe0004500 (irq = 26) is a 16550A
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered
RAMDISK driver initialized: 16 RAM disks of 32768K size 1024 blocksize
loop: loaded (max 8 devices)
eth0: Gianfar Ethernet Controller Version 1.1, 00:e0:0c:00:00:fd 
eth0: Running with NAPI enabled
eth0: 256/256 RX/TX BD ring size
mtdchar: write-caching enabled
silkworm: Using SWBD101  flash configuration
Boot flash: Found 1 x16 devices at 0x0 in 16-bit bank
 Amd/Fujitsu Extended Query Table at 0x0040
Boot flash: CFI does not contain boot bank location. Assuming top.
number of CFI chips: 1
cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.
Creating 6 MTD partitions on "Boot flash":
0x00000000-0x00800000 : "unused (mtd0)"
0x00800000-0x03400000 : "filesys: kernel and initrd (mtd1)"
0x03400000-0x03c00000 : "kernel: kernel and initrd (mtd2)"
0x03c00000-0x03c40000 : "bootenv0: boot environment (mtd3)"
0x03c40000-0x03c80000 : "bootenv1: boot environment (mtd4)"
0x03c80000-0x04000000 : "bootimage (mtd5)"
i2c /dev entries driver
MPC adapter: Platform type [101],  Did not register I2C multiplexor callback.
MPC adapter: Platform type [101],  Did not register I2C multiplexor callback.
NET: Registered protocol family 2
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)
TCP established hash table entries: 131072 (order: 7, 524288 bytes)
TCP bind hash table entries: 65536 (order: 6, 262144 bytes)
TCP: Hash tables configured (established 131072 bind 65536)
TCP reno registered
ip_conntrack version 2.3 (4096 buckets, 32768 max) - 216 bytes per conntrack
ip_tables: (C) 2000-2002 Netfilter core team
arp_tables: (C) 2002 David S. Miller
TCP bic registered
Initializing IPsec netlink socket
NET: Registered protocol family 1
NET: Registered protocol family 10
IPv6 over IPv4 tunneling driver
ip6_tables: (C) 2000-2002 Netfilter core team
NET: Registered protocol family 17
NET: Registered protocol family 15
VFS: Mounted root (jffs2 filesystem).
Freeing unused kernel memory: 144k init
INIT: version 2.78 booting
INIT: Entering runlevel: 2
Installing dpci dpci_switch_module: module license 'unspecified' taints kernel.
switch module
Installing dgen module
eth0: PHY is Generic MII (ffffffff)
/etc/rc.d/rc2.d/S30diags: /nfabos/bin/diagburnin.sh: No such file or directory
bash-2.04# eth0: Full Duplex
eth0: Speed 100BT
eth0: Link is up

bash-2.04# nfdiag
SWBD: modelId 0x0 extId 0x4e
CHOW48 platform.
slot: 0, bus: 1, dev: 0, size: 4194304, vAddr = 0x0, dmaAddr = 0x0 pciFd 0x4
DMA CPU Address 0xdf000000  PCI Address 0x9f000000 for slot 0 cheetah3 0
slot: 0, bus: 3, dev: 0, size: 4194304, vAddr = 0x0, dmaAddr = 0x0 pciFd 0x4
DMA CPU Address 0xdec00000  PCI Address 0x9ec00000 for slot 0 cheetah3 1

main (lc0)> pci -o read -s 0 -b 0 -u 0 -a 0 -l 0x128


00     BusNo 0     DevNo 0

00000000 1957 0032 0006 0010 0011 0b20 0008 0001              .W.2............
00000010 0000 0000 0000 0000 0100 0006 0000 0000              ................
00000020 8000 9ff0 1001 0001 0000 0000 0000 0000              ................
00000030 0000 0000 0044 0000 0000 0000 0000 0000              .....D..........
00000040 0000 0000 4c01 fe02 0000 0000 0010 0041              ....L..........A
00000050 0001 0000 2810 0000 d481 0003 0008 0011              ....(...........
00000060 07c0 0000 03c0 0040 0000 0000 0000 0000              .......@........
00000070 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000080 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000090 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000A0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000B0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000C0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000D0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000E0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000F0 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000100 0001 0001 0000 0000 0000 0000 2010 0006              ................
00000110 0000 0000 0000 0000 00a0 0000 0000 0000              ................
00000120 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000130 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000140 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000150 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000160 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000170 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000180 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000190 0000 0000 0000 0000 0000 0000 0000 0000              ................
000001A0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000001B0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000001C0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000001D0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000001E0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000001F0 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000200 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000210 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000220 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000230 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000240 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000250 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000260 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000270 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000280 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000290 0000 0000 0000 0000 0000 0000 0000 0000              ................
000002A0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000002B0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000002C0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000002D0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000002E0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000002F0 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000300 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000310 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000320 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000330 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000340 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000350 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000360 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000370 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000380 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000390 0000 0000 0000 0000 0000 0000 0000 0000              ................
000003A0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000003B0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000003C0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000003D0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000003E0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000003F0 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000400 0000 0000 0016 0000 04e2 0000 0000 0000              ................
00000410 0004 0000 0001 0000 0000 0000 4040 0000              ............@@..
00000420 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000430 0000 0000 0000 0000 8121 009e b04c 0004              .........!...L..
00000440 0010 0000 0000 0000 0000 0000 0000 0000              ................
00000450 d7ce 0014 1e20 01fc 0000 0000 0c5c 0000              .............\..
00000460 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000470 1957 0032 0011 0b20 0000 0000 0001 0000              .W.2............
00000480 3d48 0000 0000 0000 07f0 0000 0000 0000              =H..............
00000490 07c0 0000 0000 0000 0000 0000 0000 0000              ................


main (lc0)> pci -o read -u 0 -s 0 -b 1 -a 0x0 -l 0xff
 

00     BusNo 1     DevNo 0

00000000 11ab db90 0006 0010 0001 0580 0008 0000              ................
00000010 000c 8000 0000 0000 000c 8400 0000 0000              ................
00000020 0000 0000 0000 0000 0000 0000 11ab 11ab              ................
00000030 0000 0000 0040 0000 0000 0000 0100 0000              .....@..........
00000040 5001 0002 0000 0000 0000 0000 0000 0000              P...............
00000050 6005 0080 0000 0000 0000 0000 0000 0000              `...............
00000060 0010 0011 0080 003c 2000 0000 a411 0003              .......<........
00000070 0008 1011 0000 0000 0000 0000 0000 0000              ................
00000080 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000090 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000A0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000B0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000C0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000D0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000E0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000F0 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000100 0001 0001 0000 0000 0000 0000 0010 0006              ................
00000110 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000120 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000130 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000140 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000150 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000160 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000170 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000180 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000190 0000 0000 0000 0000 0000 0000 0000 0000              ................
000001A0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000001B0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000001C0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000001D0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000001E0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000001F0 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000200 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000210 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000220 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000230 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000240 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000250 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000260 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000270 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000280 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000290 0000 0000 0000 0000 0000 0000 0000 0000              ................
000002A0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000002B0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000002C0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000002D0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000002E0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000002F0 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000300 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000310 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000320 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000330 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000340 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000350 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000360 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000370 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000380 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000390 0000 0000 0000 0000 0000 0000 0000 0000              ................
000003A0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000003B0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000003C0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000003D0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000003E0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000003F0 0000 0000 0000 0000 0000 0000 

main (lc0)> pci -o read -s 0 -u 0 -a 0x0 -b 2 -l 0x40


00     BusNo 2     DevNo 0

00000000 1957 0032 0006 0010 0011 0b20 0008 0001              .W.2............
00000010 0000 0000 0000 0000 0300 000f 0000 0000              ................
00000020 a000 bff0 1001 0001 0000 0000 0000 0000              ................
00000030 0000 0000 0044 0000 0000 0000 0000 0000              .....D..........
00000040 0000 0000 4c01 fe02 0000 0000 0010 0041              ....L..........A
00000050 0001 0000 2810 0000 d481 0003 0008 0011              ....(...........
00000060 07c0 0000 03c0 0040 0000 0000 0000 0000              .......@........
00000070 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000080 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000090 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000A0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000B0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000C0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000D0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000E0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000F0 0000 0000 0000 0000 0000 0000 0000 0000              ................


main (lc0)> pci -o read -s 0 -u 0 -a 0x0 -b 3 -l 0x40


00     BusNo 3     DevNo 0

00000000 11ab db90 0006 0010 0001 0580 0008 0000              ................
00000010 000c a000 0000 0000 000c a400 0000 0000              ................
00000020 0000 0000 0000 0000 0000 0000 11ab 11ab              ................
00000030 0000 0000 0040 0000 0000 0000 0100 0000              .....@..........
00000040 5001 0002 0000 0000 0000 0000 0000 0000              P...............
00000050 6005 0080 0000 0000 0000 0000 0000 0000              `...............
00000060 0010 0011 0080 003c 2000 0000 a411 0003              .......<........
00000070 0008 1011 0000 0000 0000 0000 0000 0000              ................
00000080 0000 0000 0000 0000 0000 0000 0000 0000              ................
00000090 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000A0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000B0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000C0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000D0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000E0 0000 0000 0000 0000 0000 0000 0000 0000              ................
000000F0 0000 0000 0000 0000 0000 0000 0000 0000              ................


main (lc0)> mem -o read -a 0xe000a000 -l 0x400

E000A000 $830100f8 $00000000 $00000000 $0010ffff                  ................
E000A010 $0400ffff $00000028 $00000000 $00000000                  .......(........
E000A020 $00000000 $00000000 $00000000 $00000000                  ................
E000A030 $00000000 $00000000 $00000000 $00000000                  ................
E000A040 $00000000 $00000000 $00000000 $00000000                  ................
E000A050 $00000000 $00000000 $00000000 $00000000                  ................
E000A060 $00000000 $00000000 $00000000 $00000000                  ................
E000A070 $00000000 $00000000 $00000000 $00000000                  ................
E000A080 $00000000 $00000000 $00000000 $00000000                  ................
E000A090 $00000000 $00000000 $00000000 $00000000                  ................
E000A0A0 $00000000 $00000000 $00000000 $00000000                  ................
E000A0B0 $00000000 $00000000 $00000000 $00000000                  ................
E000A0C0 $00000000 $00000000 $00000000 $00000000                  ................
E000A0D0 $00000000 $00000000 $00000000 $00000000                  ................
E000A0E0 $00000000 $00000000 $00000000 $00000000                  ................
E000A0F0 $00000000 $00000000 $00000000 $00000000                  ................
E000A100 $00000000 $00000000 $00000000 $00000000                  ................
E000A110 $00000000 $00000000 $00000000 $00000000                  ................
E000A120 $00000000 $00000000 $00000000 $00000000                  ................
E000A130 $00000000 $00000000 $00000000 $00000000                  ................
E000A140 $00000000 $00000000 $00000000 $00000000                  ................
E000A150 $00000000 $00000000 $00000000 $00000000                  ................
E000A160 $00000000 $00000000 $00000000 $00000000                  ................
E000A170 $00000000 $00000000 $00000000 $00000000                  ................
E000A180 $00000000 $00000000 $00000000 $00000000                  ................
E000A190 $00000000 $00000000 $00000000 $00000000                  ................
E000A1A0 $00000000 $00000000 $00000000 $00000000                  ................
E000A1B0 $00000000 $00000000 $00000000 $00000000                  ................
E000A1C0 $00000000 $00000000 $00000000 $00000000                  ................
E000A1D0 $00000000 $00000000 $00000000 $00000000                  ................
E000A1E0 $00000000 $00000000 $00000000 $00000000                  ................
E000A1F0 $00000000 $00000000 $00000000 $00000000                  ................
E000A200 $00000000 $00000000 $00000000 $00000000                  ................
E000A210 $00000000 $00000000 $00000000 $00000000                  ................
E000A220 $00000000 $00000000 $00000000 $00000000                  ................
E000A230 $00000000 $00000000 $00000000 $00000000                  ................
E000A240 $00000000 $00000000 $00000000 $00000000                  ................
E000A250 $00000000 $00000000 $00000000 $00000000                  ................
E000A260 $00000000 $00000000 $00000000 $00000000                  ................
E000A270 $00000000 $00000000 $00000000 $00000000                  ................
E000A280 $00000000 $00000000 $00000000 $00000000                  ................
E000A290 $00000000 $00000000 $00000000 $00000000                  ................
E000A2A0 $00000000 $00000000 $00000000 $00000000                  ................
E000A2B0 $00000000 $00000000 $00000000 $00000000                  ................
E000A2C0 $00000000 $00000000 $00000000 $00000000                  ................
E000A2D0 $00000000 $00000000 $00000000 $00000000                  ................
E000A2E0 $00000000 $00000000 $00000000 $00000000                  ................
E000A2F0 $00000000 $00000000 $00000000 $00000000                  ................
E000A300 $00000000 $00000000 $00000000 $00000000                  ................
E000A310 $00000000 $00000000 $00000000 $00000000                  ................
E000A320 $00000000 $00000000 $00000000 $00000000                  ................
E000A330 $00000000 $00000000 $00000000 $00000000                  ................
E000A340 $00000000 $00000000 $00000000 $00000000                  ................
E000A350 $00000000 $00000000 $00000000 $00000000                  ................
E000A360 $00000000 $00000000 $00000000 $00000000                  ................
E000A370 $00000000 $00000000 $00000000 $00000000                  ................
E000A380 $00000000 $00000000 $00000000 $00000000                  ................
E000A390 $00000000 $00000000 $00000000 $00000000                  ................
E000A3A0 $00000000 $00000000 $00000000 $00000000                  ................
E000A3B0 $00000000 $00000000 $00000000 $00000000                  ................
E000A3C0 $00000000 $00000000 $00000000 $00000000                  ................
E000A3D0 $00000000 $00000000 $00000000 $00000000                  ................
E000A3E0 $00000000 $00000000 $00000000 $00000000                  ................
E000A3F0 $00000000 $00000000 $00000000 $00000000                  ................
E000A400 $00000000 $00000000 $00000000 $00000000                  ................
E000A410 $00000000 $00000000 $00000000 $00000000                  ................
E000A420 $00000000 $00000000 $00000000 $00000000                  ................
E000A430 $00000000 $00000000 $00000000 $00000000                  ................
E000A440 $00000000 $00000000 $00000000 $00000000                  ................
E000A450 $00000000 $00000000 $00000000 $00000000                  ................
E000A460 $00000000 $00000000 $00000000 $00000000                  ................
E000A470 $00000000 $00000000 $00000000 $00000000                  ................
E000A480 $00000000 $00000000 $00000000 $00000000                  ................
E000A490 $00000000 $00000000 $00000000 $00000000                  ................
E000A4A0 $00000000 $00000000 $00000000 $00000000                  ................
E000A4B0 $00000000 $00000000 $00000000 $00000000                  ................
E000A4C0 $00000000 $00000000 $00000000 $00000000                  ................
E000A4D0 $00000000 $00000000 $00000000 $00000000                  ................
E000A4E0 $00000000 $00000000 $00000000 $00000000                  ................
E000A4F0 $00000000 $00000000 $00000000 $00000000                  ................
E000A500 $00000000 $00000000 $00000000 $00000000                  ................
E000A510 $00000000 $00000000 $00000000 $00000000                  ................
E000A520 $00000000 $00000000 $00000000 $00000000                  ................
E000A530 $00000000 $00000000 $00000000 $00000000                  ................
E000A540 $00000000 $00000000 $00000000 $00000000                  ................
E000A550 $00000000 $00000000 $00000000 $00000000                  ................
E000A560 $00000000 $00000000 $00000000 $00000000                  ................
E000A570 $00000000 $00000000 $00000000 $00000000                  ................
E000A580 $00000000 $00000000 $00000000 $00000000                  ................
E000A590 $00000000 $00000000 $00000000 $00000000                  ................
E000A5A0 $00000000 $00000000 $00000000 $00000000                  ................
E000A5B0 $00000000 $00000000 $00000000 $00000000                  ................
E000A5C0 $00000000 $00000000 $00000000 $00000000                  ................
E000A5D0 $00000000 $00000000 $00000000 $00000000                  ................
E000A5E0 $00000000 $00000000 $00000000 $00000000                  ................
E000A5F0 $00000000 $00000000 $00000000 $00000000                  ................
E000A600 $00000000 $00000000 $00000000 $00000000                  ................
E000A610 $00000000 $00000000 $00000000 $00000000                  ................
E000A620 $00000000 $00000000 $00000000 $00000000                  ................
E000A630 $00000000 $00000000 $00000000 $00000000                  ................
E000A640 $00000000 $00000000 $00000000 $00000000                  ................
E000A650 $00000000 $00000000 $00000000 $00000000                  ................
E000A660 $00000000 $00000000 $00000000 $00000000                  ................
E000A670 $00000000 $00000000 $00000000 $00000000                  ................
E000A680 $00000000 $00000000 $00000000 $00000000                  ................
E000A690 $00000000 $00000000 $00000000 $00000000                  ................
E000A6A0 $00000000 $00000000 $00000000 $00000000                  ................
E000A6B0 $00000000 $00000000 $00000000 $00000000                  ................
E000A6C0 $00000000 $00000000 $00000000 $00000000                  ................
E000A6D0 $00000000 $00000000 $00000000 $00000000                  ................
E000A6E0 $00000000 $00000000 $00000000 $00000000                  ................
E000A6F0 $00000000 $00000000 $00000000 $00000000                  ................
E000A700 $00000000 $00000000 $00000000 $00000000                  ................
E000A710 $00000000 $00000000 $00000000 $00000000                  ................
E000A720 $00000000 $00000000 $00000000 $00000000                  ................
E000A730 $00000000 $00000000 $00000000 $00000000                  ................
E000A740 $00000000 $00000000 $00000000 $00000000                  ................
E000A750 $00000000 $00000000 $00000000 $00000000                  ................
E000A760 $00000000 $00000000 $00000000 $00000000                  ................
E000A770 $00000000 $00000000 $00000000 $00000000                  ................
E000A780 $00000000 $00000000 $00000000 $00000000                  ................
E000A790 $00000000 $00000000 $00000000 $00000000                  ................
E000A7A0 $00000000 $00000000 $00000000 $00000000                  ................
E000A7B0 $00000000 $00000000 $00000000 $00000000                  ................
E000A7C0 $00000000 $00000000 $00000000 $00000000                  ................
E000A7D0 $00000000 $00000000 $00000000 $00000000                  ................
E000A7E0 $00000000 $00000000 $00000000 $00000000                  ................
E000A7F0 $00000000 $00000000 $00000000 $00000000                  ................
E000A800 $00000000 $00000000 $00000000 $00000000                  ................
E000A810 $00000000 $00000000 $00000000 $00000000                  ................
E000A820 $00000000 $00000000 $00000000 $00000000                  ................
E000A830 $00000000 $00000000 $00000000 $00000000                  ................
E000A840 $00000000 $00000000 $00000000 $00000000                  ................
E000A850 $00000000 $00000000 $00000000 $00000000                  ................
E000A860 $00000000 $00000000 $00000000 $00000000                  ................
E000A870 $00000000 $00000000 $00000000 $00000000                  ................
E000A880 $00000000 $00000000 $00000000 $00000000                  ................
E000A890 $00000000 $00000000 $00000000 $00000000                  ................
E000A8A0 $00000000 $00000000 $00000000 $00000000                  ................
E000A8B0 $00000000 $00000000 $00000000 $00000000                  ................
E000A8C0 $00000000 $00000000 $00000000 $00000000                  ................
E000A8D0 $00000000 $00000000 $00000000 $00000000                  ................
E000A8E0 $00000000 $00000000 $00000000 $00000000                  ................
E000A8F0 $00000000 $00000000 $00000000 $00000000                  ................
E000A900 $00000000 $00000000 $00000000 $00000000                  ................
E000A910 $00000000 $00000000 $00000000 $00000000                  ................
E000A920 $00000000 $00000000 $00000000 $00000000                  ................
E000A930 $00000000 $00000000 $00000000 $00000000                  ................
E000A940 $00000000 $00000000 $00000000 $00000000                  ................
E000A950 $00000000 $00000000 $00000000 $00000000                  ................
E000A960 $00000000 $00000000 $00000000 $00000000                  ................
E000A970 $00000000 $00000000 $00000000 $00000000                  ................
E000A980 $00000000 $00000000 $00000000 $00000000                  ................
E000A990 $00000000 $00000000 $00000000 $00000000                  ................
E000A9A0 $00000000 $00000000 $00000000 $00000000                  ................
E000A9B0 $00000000 $00000000 $00000000 $00000000                  ................
E000A9C0 $00000000 $00000000 $00000000 $00000000                  ................
E000A9D0 $00000000 $00000000 $00000000 $00000000                  ................
E000A9E0 $00000000 $00000000 $00000000 $00000000                  ................
E000A9F0 $00000000 $00000000 $00000000 $00000000                  ................
E000AA00 $00000000 $00000000 $00000000 $00000000                  ................
E000AA10 $00000000 $00000000 $00000000 $00000000                  ................
E000AA20 $00000000 $00000000 $00000000 $00000000                  ................
E000AA30 $00000000 $00000000 $00000000 $00000000                  ................
E000AA40 $00000000 $00000000 $00000000 $00000000                  ................
E000AA50 $00000000 $00000000 $00000000 $00000000                  ................
E000AA60 $00000000 $00000000 $00000000 $00000000                  ................
E000AA70 $00000000 $00000000 $00000000 $00000000                  ................
E000AA80 $00000000 $00000000 $00000000 $00000000                  ................
E000AA90 $00000000 $00000000 $00000000 $00000000                  ................
E000AAA0 $00000000 $00000000 $00000000 $00000000                  ................
E000AAB0 $00000000 $00000000 $00000000 $00000000                  ................
E000AAC0 $00000000 $00000000 $00000000 $00000000                  ................
E000AAD0 $00000000 $00000000 $00000000 $00000000                  ................
E000AAE0 $00000000 $00000000 $00000000 $00000000                  ................
E000AAF0 $00000000 $00000000 $00000000 $00000000                  ................
E000AB00 $00000000 $00000000 $00000000 $00000000                  ................
E000AB10 $00000000 $00000000 $00000000 $00000000                  ................
E000AB20 $00000000 $00000000 $00000000 $00000000                  ................
E000AB30 $00000000 $00000000 $00000000 $00000000                  ................
E000AB40 $00000000 $00000000 $00000000 $00000000                  ................
E000AB50 $00000000 $00000000 $00000000 $00000000                  ................
E000AB60 $00000000 $00000000 $00000000 $00000000                  ................
E000AB70 $00000000 $00000000 $00000000 $00000000                  ................
E000AB80 $00000000 $00000000 $00000000 $00000000                  ................
E000AB90 $00000000 $00000000 $00000000 $00000000                  ................
E000ABA0 $00000000 $00000000 $00000000 $00000000                  ................
E000ABB0 $00000000 $00000000 $00000000 $00000000                  ................
E000ABC0 $00000000 $00000000 $00000000 $00000000                  ................
E000ABD0 $00000000 $00000000 $00000000 $00000000                  ................
E000ABE0 $00000000 $00000000 $00000000 $00000000                  ................
E000ABF0 $00000000 $00000000 $02080100 $00000000                  ................
E000AC00 $00000000 $00000000 $00000000 $00000000                  ................
E000AC10 $80044023 $00000000 $00000000 $00000000                  ..@#............
E000AC20 $00080000 $00000000 $00080000 $00000000                  ................
E000AC30 $8004401c $00000000 $00000000 $00000000                  ..@.............
E000AC40 $00000000 $00000000 $000e3000 $00000000                  ..........0.....
E000AC50 $80088016 $00000000 $00000000 $00000000                  ................
E000AC60 $00000000 $00000000 $00000000 $00000000                  ................
E000AC70 $00044023 $00000000 $00000000 $00000000                  ..@#............
E000AC80 $00000000 $00000000 $00000000 $00000000                  ................
E000AC90 $00044023 $00000000 $00000000 $00000000                  ..@#............
E000ACA0 $00000000 $00000000 $00000000 $00000000                  ................
E000ACB0 $00000000 $00000000 $00000000 $00000000                  ................
E000ACC0 $00000000 $00000000 $00000000 $00000000                  ................
E000ACD0 $00000000 $00000000 $00000000 $00000000                  ................
E000ACE0 $00000000 $00000000 $00000000 $00000000                  ................
E000ACF0 $00000000 $00000000 $00000000 $00000000                  ................
E000AD00 $00000000 $00000000 $00000000 $00000000                  ................
E000AD10 $00000000 $00000000 $00000000 $00000000                  ................
E000AD20 $00000000 $00000000 $00000000 $00000000                  ................
E000AD30 $00000000 $00000000 $00000000 $00000000                  ................
E000AD40 $00000000 $00000000 $00000000 $00000000                  ................
E000AD50 $00000000 $00000000 $00000000 $00000000                  ................
E000AD60 $00000000 $00000000 $00000000 $00000000                  ................
E000AD70 $00000000 $00000000 $00000000 $00000000                  ................
E000AD80 $00000000 $00000000 $00000000 $00000000                  ................
E000AD90 $00000000 $00000000 $00000000 $00000000                  ................
E000ADA0 $00000000 $00000000 $00000000 $00000000                  ................
E000ADB0 $a0f5501e $00000000 $00000000 $00000000                  ..P.............
E000ADC0 $00000000 $00000000 $00000000 $00000000                  ................
E000ADD0 $20f44023 $00000000 $00000000 $00000000                  ..@#............
E000ADE0 $00000000 $00000000 $00000000 $00000000                  ................
E000ADF0 $20f44023 $00000000 $00000000 $00000000                  ..@#............
E000AE00 $80020000 $00000000 $00bdfe00 $00000000                  ................
E000AE10 $00000000 $00000000 $00000000 $00000000                  ................
E000AE20 $00000041 $00000000 $00000800 $00000000                  ...A............
E000AE30 $00000000 $00000000 $00000000 $00000000                  ................
E000AE40 $00000000 $00000000 $00000000 $00000000                  ................
E000AE50 $00000000 $00000000 $00000000 $00000000                  ................
E000AE60 $00000000 $00000000 $00000000 $00000000                  ................
E000AE70 $00000000 $00000000 $00000000 $00000000                  ................
E000AE80 $00000000 $00000000 $00000000 $00000000                  ................
E000AE90 $00000000 $00000000 $00000000 $00000000                  ................
E000AEA0 $00000000 $00000000 $00000000 $00000000                  ................
E000AEB0 $00000000 $00000000 $00000000 $00000000                  ................
E000AEC0 $00000000 $00000000 $00000000 $00000000                  ................
E000AED0 $00000000 $00000000 $00000000 $00000000                  ................
E000AEE0 $00000000 $00000000 $00000000 $00000000                  ................
E000AEF0 $00000000 $00000000 $00000000 $00000000                  ................
E000AF00 $80400080 $00000000 $00000000 $00000000                  .@..............
E000AF10 $c8800000 $a0000000 $00000000 $00000000                  ................
E000AF20 $00008000 $00000000 $00000000 $00000000                  ................
E000AF30 $00000000 $00000000 $00000000 $00000000                  ................
E000AF40 $00000000 $00000000 $00000000 $00000000                  ................
E000AF50 $00000000 $00000000 $00000000 $00000000                  ................
E000AF60 $00000000 $00000000 $00000000 $00000000                  ................
E000AF70 $00000000 $00000000 $00000000 $00000000                  ................
E000AF80 $00000000 $00000000 $00000000 $00000000                  ................
E000AF90 $00000000 $00000000 $00000000 $00000000                  ................
E000AFA0 $00000000 $00000000 $00000000 $00000000                  ................
E000AFB0 $00000000 $00000000 $00000000 $00000000                  ................
E000AFC0 $00000000 $00000000 $00000000 $00000000                  ................
E000AFD0 $00000000 $00000000 $00000000 $00000000                  ................
E000AFE0 $00000000 $00000000 $00000000 $00000000                  ................
E000AFF0 $00000000 $00000000 $00000000 $00000000                  ................


main (lc0)> mem -o read -a 0xe0009000 0x400

Invalid usage

main (lc0)> mem -o read -a 0xe0009000 -l 0x400

E0009000 $800300fc $00000000 $00000000 $0010ffff                  ................
E0009010 $0400ffff $00000028 $00000000 $00000000                  .......(........
E0009020 $00000000 $00000000 $00000000 $00000000                  ................
E0009030 $00000000 $00000000 $00000000 $00000000                  ................
E0009040 $00000000 $00000000 $00000000 $00000000                  ................
E0009050 $00000000 $00000000 $00000000 $00000000                  ................
E0009060 $00000000 $00000000 $00000000 $00000000                  ................
E0009070 $00000000 $00000000 $00000000 $00000000                  ................
E0009080 $00000000 $00000000 $00000000 $00000000                  ................
E0009090 $00000000 $00000000 $00000000 $00000000                  ................
E00090A0 $00000000 $00000000 $00000000 $00000000                  ................
E00090B0 $00000000 $00000000 $00000000 $00000000                  ................
E00090C0 $00000000 $00000000 $00000000 $00000000                  ................
E00090D0 $00000000 $00000000 $00000000 $00000000                  ................
E00090E0 $00000000 $00000000 $00000000 $00000000                  ................
E00090F0 $00000000 $00000000 $00000000 $00000000                  ................
E0009100 $00000000 $00000000 $00000000 $00000000                  ................
E0009110 $00000000 $00000000 $00000000 $00000000                  ................
E0009120 $00000000 $00000000 $00000000 $00000000                  ................
E0009130 $00000000 $00000000 $00000000 $00000000                  ................
E0009140 $00000000 $00000000 $00000000 $00000000                  ................
E0009150 $00000000 $00000000 $00000000 $00000000                  ................
E0009160 $00000000 $00000000 $00000000 $00000000                  ................
E0009170 $00000000 $00000000 $00000000 $00000000                  ................
E0009180 $00000000 $00000000 $00000000 $00000000                  ................
E0009190 $00000000 $00000000 $00000000 $00000000                  ................
E00091A0 $00000000 $00000000 $00000000 $00000000                  ................
E00091B0 $00000000 $00000000 $00000000 $00000000                  ................
E00091C0 $00000000 $00000000 $00000000 $00000000                  ................
E00091D0 $00000000 $00000000 $00000000 $00000000                  ................
E00091E0 $00000000 $00000000 $00000000 $00000000                  ................
E00091F0 $00000000 $00000000 $00000000 $00000000                  ................
E0009200 $00000000 $00000000 $00000000 $00000000                  ................
E0009210 $00000000 $00000000 $00000000 $00000000                  ................
E0009220 $00000000 $00000000 $00000000 $00000000                  ................
E0009230 $00000000 $00000000 $00000000 $00000000                  ................
E0009240 $00000000 $00000000 $00000000 $00000000                  ................
E0009250 $00000000 $00000000 $00000000 $00000000                  ................
E0009260 $00000000 $00000000 $00000000 $00000000                  ................
E0009270 $00000000 $00000000 $00000000 $00000000                  ................
E0009280 $00000000 $00000000 $00000000 $00000000                  ................
E0009290 $00000000 $00000000 $00000000 $00000000                  ................
E00092A0 $00000000 $00000000 $00000000 $00000000                  ................
E00092B0 $00000000 $00000000 $00000000 $00000000                  ................
E00092C0 $00000000 $00000000 $00000000 $00000000                  ................
E00092D0 $00000000 $00000000 $00000000 $00000000                  ................
E00092E0 $00000000 $00000000 $00000000 $00000000                  ................
E00092F0 $00000000 $00000000 $00000000 $00000000                  ................
E0009300 $00000000 $00000000 $00000000 $00000000                  ................
E0009310 $00000000 $00000000 $00000000 $00000000                  ................
E0009320 $00000000 $00000000 $00000000 $00000000                  ................
E0009330 $00000000 $00000000 $00000000 $00000000                  ................
E0009340 $00000000 $00000000 $00000000 $00000000                  ................
E0009350 $00000000 $00000000 $00000000 $00000000                  ................
E0009360 $00000000 $00000000 $00000000 $00000000                  ................
E0009370 $00000000 $00000000 $00000000 $00000000                  ................
E0009380 $00000000 $00000000 $00000000 $00000000                  ................
E0009390 $00000000 $00000000 $00000000 $00000000                  ................
E00093A0 $00000000 $00000000 $00000000 $00000000                  ................
E00093B0 $00000000 $00000000 $00000000 $00000000                  ................
E00093C0 $00000000 $00000000 $00000000 $00000000                  ................
E00093D0 $00000000 $00000000 $00000000 $00000000                  ................
E00093E0 $00000000 $00000000 $00000000 $00000000                  ................
E00093F0 $00000000 $00000000 $00000000 $00000000                  ................
E0009400 $00000000 $00000000 $00000000 $00000000                  ................
E0009410 $00000000 $00000000 $00000000 $00000000                  ................
E0009420 $00000000 $00000000 $00000000 $00000000                  ................
E0009430 $00000000 $00000000 $00000000 $00000000                  ................
E0009440 $00000000 $00000000 $00000000 $00000000                  ................
E0009450 $00000000 $00000000 $00000000 $00000000                  ................
E0009460 $00000000 $00000000 $00000000 $00000000                  ................
E0009470 $00000000 $00000000 $00000000 $00000000                  ................
E0009480 $00000000 $00000000 $00000000 $00000000                  ................
E0009490 $00000000 $00000000 $00000000 $00000000                  ................
E00094A0 $00000000 $00000000 $00000000 $00000000                  ................
E00094B0 $00000000 $00000000 $00000000 $00000000                  ................
E00094C0 $00000000 $00000000 $00000000 $00000000                  ................
E00094D0 $00000000 $00000000 $00000000 $00000000                  ................
E00094E0 $00000000 $00000000 $00000000 $00000000                  ................
E00094F0 $00000000 $00000000 $00000000 $00000000                  ................
E0009500 $00000000 $00000000 $00000000 $00000000                  ................
E0009510 $00000000 $00000000 $00000000 $00000000                  ................
E0009520 $00000000 $00000000 $00000000 $00000000                  ................
E0009530 $00000000 $00000000 $00000000 $00000000                  ................
E0009540 $00000000 $00000000 $00000000 $00000000                  ................
E0009550 $00000000 $00000000 $00000000 $00000000                  ................
E0009560 $00000000 $00000000 $00000000 $00000000                  ................
E0009570 $00000000 $00000000 $00000000 $00000000                  ................
E0009580 $00000000 $00000000 $00000000 $00000000                  ................
E0009590 $00000000 $00000000 $00000000 $00000000                  ................
E00095A0 $00000000 $00000000 $00000000 $00000000                  ................
E00095B0 $00000000 $00000000 $00000000 $00000000                  ................
E00095C0 $00000000 $00000000 $00000000 $00000000                  ................
E00095D0 $00000000 $00000000 $00000000 $00000000                  ................
E00095E0 $00000000 $00000000 $00000000 $00000000                  ................
E00095F0 $00000000 $00000000 $00000000 $00000000                  ................
E0009600 $00000000 $00000000 $00000000 $00000000                  ................
E0009610 $00000000 $00000000 $00000000 $00000000                  ................
E0009620 $00000000 $00000000 $00000000 $00000000                  ................
E0009630 $00000000 $00000000 $00000000 $00000000                  ................
E0009640 $00000000 $00000000 $00000000 $00000000                  ................
E0009650 $00000000 $00000000 $00000000 $00000000                  ................
E0009660 $00000000 $00000000 $00000000 $00000000                  ................
E0009670 $00000000 $00000000 $00000000 $00000000                  ................
E0009680 $00000000 $00000000 $00000000 $00000000                  ................
E0009690 $00000000 $00000000 $00000000 $00000000                  ................
E00096A0 $00000000 $00000000 $00000000 $00000000                  ................
E00096B0 $00000000 $00000000 $00000000 $00000000                  ................
E00096C0 $00000000 $00000000 $00000000 $00000000                  ................
E00096D0 $00000000 $00000000 $00000000 $00000000                  ................
E00096E0 $00000000 $00000000 $00000000 $00000000                  ................
E00096F0 $00000000 $00000000 $00000000 $00000000                  ................
E0009700 $00000000 $00000000 $00000000 $00000000                  ................
E0009710 $00000000 $00000000 $00000000 $00000000                  ................
E0009720 $00000000 $00000000 $00000000 $00000000                  ................
E0009730 $00000000 $00000000 $00000000 $00000000                  ................
E0009740 $00000000 $00000000 $00000000 $00000000                  ................
E0009750 $00000000 $00000000 $00000000 $00000000                  ................
E0009760 $00000000 $00000000 $00000000 $00000000                  ................
E0009770 $00000000 $00000000 $00000000 $00000000                  ................
E0009780 $00000000 $00000000 $00000000 $00000000                  ................
E0009790 $00000000 $00000000 $00000000 $00000000                  ................
E00097A0 $00000000 $00000000 $00000000 $00000000                  ................
E00097B0 $00000000 $00000000 $00000000 $00000000                  ................
E00097C0 $00000000 $00000000 $00000000 $00000000                  ................
E00097D0 $00000000 $00000000 $00000000 $00000000                  ................
E00097E0 $00000000 $00000000 $00000000 $00000000                  ................
E00097F0 $00000000 $00000000 $00000000 $00000000                  ................
E0009800 $00000000 $00000000 $00000000 $00000000                  ................
E0009810 $00000000 $00000000 $00000000 $00000000                  ................
E0009820 $00000000 $00000000 $00000000 $00000000                  ................
E0009830 $00000000 $00000000 $00000000 $00000000                  ................
E0009840 $00000000 $00000000 $00000000 $00000000                  ................
E0009850 $00000000 $00000000 $00000000 $00000000                  ................
E0009860 $00000000 $00000000 $00000000 $00000000                  ................
E0009870 $00000000 $00000000 $00000000 $00000000                  ................
E0009880 $00000000 $00000000 $00000000 $00000000                  ................
E0009890 $00000000 $00000000 $00000000 $00000000                  ................
E00098A0 $00000000 $00000000 $00000000 $00000000                  ................
E00098B0 $00000000 $00000000 $00000000 $00000000                  ................
E00098C0 $00000000 $00000000 $00000000 $00000000                  ................
E00098D0 $00000000 $00000000 $00000000 $00000000                  ................
E00098E0 $00000000 $00000000 $00000000 $00000000                  ................
E00098F0 $00000000 $00000000 $00000000 $00000000                  ................
E0009900 $00000000 $00000000 $00000000 $00000000                  ................
E0009910 $00000000 $00000000 $00000000 $00000000                  ................
E0009920 $00000000 $00000000 $00000000 $00000000                  ................
E0009930 $00000000 $00000000 $00000000 $00000000                  ................
E0009940 $00000000 $00000000 $00000000 $00000000                  ................
E0009950 $00000000 $00000000 $00000000 $00000000                  ................
E0009960 $00000000 $00000000 $00000000 $00000000                  ................
E0009970 $00000000 $00000000 $00000000 $00000000                  ................
E0009980 $00000000 $00000000 $00000000 $00000000                  ................
E0009990 $00000000 $00000000 $00000000 $00000000                  ................
E00099A0 $00000000 $00000000 $00000000 $00000000                  ................
E00099B0 $00000000 $00000000 $00000000 $00000000                  ................
E00099C0 $00000000 $00000000 $00000000 $00000000                  ................
E00099D0 $00000000 $00000000 $00000000 $00000000                  ................
E00099E0 $00000000 $00000000 $00000000 $00000000                  ................
E00099F0 $00000000 $00000000 $00000000 $00000000                  ................
E0009A00 $00000000 $00000000 $00000000 $00000000                  ................
E0009A10 $00000000 $00000000 $00000000 $00000000                  ................
E0009A20 $00000000 $00000000 $00000000 $00000000                  ................
E0009A30 $00000000 $00000000 $00000000 $00000000                  ................
E0009A40 $00000000 $00000000 $00000000 $00000000                  ................
E0009A50 $00000000 $00000000 $00000000 $00000000                  ................
E0009A60 $00000000 $00000000 $00000000 $00000000                  ................
E0009A70 $00000000 $00000000 $00000000 $00000000                  ................
E0009A80 $00000000 $00000000 $00000000 $00000000                  ................
E0009A90 $00000000 $00000000 $00000000 $00000000                  ................
E0009AA0 $00000000 $00000000 $00000000 $00000000                  ................
E0009AB0 $00000000 $00000000 $00000000 $00000000                  ................
E0009AC0 $00000000 $00000000 $00000000 $00000000                  ................
E0009AD0 $00000000 $00000000 $00000000 $00000000                  ................
E0009AE0 $00000000 $00000000 $00000000 $00000000                  ................
E0009AF0 $00000000 $00000000 $00000000 $00000000                  ................
E0009B00 $00000000 $00000000 $00000000 $00000000                  ................
E0009B10 $00000000 $00000000 $00000000 $00000000                  ................
E0009B20 $00000000 $00000000 $00000000 $00000000                  ................
E0009B30 $00000000 $00000000 $00000000 $00000000                  ................
E0009B40 $00000000 $00000000 $00000000 $00000000                  ................
E0009B50 $00000000 $00000000 $00000000 $00000000                  ................
E0009B60 $00000000 $00000000 $00000000 $00000000                  ................
E0009B70 $00000000 $00000000 $00000000 $00000000                  ................
E0009B80 $00000000 $00000000 $00000000 $00000000                  ................
E0009B90 $00000000 $00000000 $00000000 $00000000                  ................
E0009BA0 $00000000 $00000000 $00000000 $00000000                  ................
E0009BB0 $00000000 $00000000 $00000000 $00000000                  ................
E0009BC0 $00000000 $00000000 $00000000 $00000000                  ................
E0009BD0 $00000000 $00000000 $00000000 $00000000                  ................
E0009BE0 $00000000 $00000000 $00000000 $00000000                  ................
E0009BF0 $00000000 $00000000 $02080100 $00000000                  ................
E0009C00 $00000000 $00000000 $00000000 $00000000                  ................
E0009C10 $80044023 $00000000 $00000000 $00000000                  ..@#............
E0009C20 $000a0000 $00000000 $000a0000 $00000000                  ................
E0009C30 $8004401c $00000000 $00000000 $00000000                  ..@.............
E0009C40 $00000000 $00000000 $000e3800 $00000000                  ..........8.....
E0009C50 $80088016 $00000000 $00000000 $00000000                  ................
E0009C60 $00000000 $00000000 $00000000 $00000000                  ................
E0009C70 $00044023 $00000000 $00000000 $00000000                  ..@#............
E0009C80 $00000000 $00000000 $00000000 $00000000                  ................
E0009C90 $00044023 $00000000 $00000000 $00000000                  ..@#............
E0009CA0 $00000000 $00000000 $00000000 $00000000                  ................
E0009CB0 $00000000 $00000000 $00000000 $00000000                  ................
E0009CC0 $00000000 $00000000 $00000000 $00000000                  ................
E0009CD0 $00000000 $00000000 $00000000 $00000000                  ................
E0009CE0 $00000000 $00000000 $00000000 $00000000                  ................
E0009CF0 $00000000 $00000000 $00000000 $00000000                  ................
E0009D00 $00000000 $00000000 $00000000 $00000000                  ................
E0009D10 $00000000 $00000000 $00000000 $00000000                  ................
E0009D20 $00000000 $00000000 $00000000 $00000000                  ................
E0009D30 $00000000 $00000000 $00000000 $00000000                  ................
E0009D40 $00000000 $00000000 $00000000 $00000000                  ................
E0009D50 $00000000 $00000000 $00000000 $00000000                  ................
E0009D60 $00000000 $00000000 $00000000 $00000000                  ................
E0009D70 $00000000 $00000000 $00000000 $00000000                  ................
E0009D80 $00000000 $00000000 $00000000 $00000000                  ................
E0009D90 $00000000 $00000000 $00000000 $00000000                  ................
E0009DA0 $00000000 $00000000 $00000000 $00000000                  ................
E0009DB0 $a0f5501e $00000000 $00000000 $00000000                  ..P.............
E0009DC0 $00000000 $00000000 $00000000 $00000000                  ................
E0009DD0 $20f44023 $00000000 $00000000 $00000000                  ..@#............
E0009DE0 $00000000 $00000000 $00000000 $00000000                  ................
E0009DF0 $20f44023 $00000000 $00000000 $00000000                  ..@#............
E0009E00 $80020000 $00000000 $00bdfe00 $00000000                  ................
E0009E10 $00000000 $00000000 $00000000 $00000000                  ................
E0009E20 $00000041 $00000000 $00000800 $00000000                  ...A............
E0009E30 $00000000 $00000000 $00000000 $00000000                  ................
E0009E40 $00000000 $00000000 $00000000 $00000000                  ................
E0009E50 $00000000 $00000000 $00000000 $00000000                  ................
E0009E60 $00000000 $00000000 $00000000 $00000000                  ................
E0009E70 $00000000 $00000000 $00000000 $00000000                  ................
E0009E80 $00000000 $00000000 $00000000 $00000000                  ................
E0009E90 $00000000 $00000000 $00000000 $00000000                  ................
E0009EA0 $00000000 $00000000 $00000000 $00000000                  ................
E0009EB0 $00000000 $00000000 $00000000 $00000000                  ................
E0009EC0 $00000000 $00000000 $00000000 $00000000                  ................
E0009ED0 $00000000 $00000000 $00000000 $00000000                  ................
E0009EE0 $00000000 $00000000 $00000000 $00000000                  ................
E0009EF0 $00000000 $00000000 $00000000 $00000000                  ................
E0009F00 $80400080 $00000000 $00000000 $00000000                  .@..............
E0009F10 $c8800000 $a0000000 $00000000 $00000000                  ................
E0009F20 $00008000 $00000000 $00000000 $00000000                  ................
E0009F30 $00000000 $00000000 $00000000 $00000000                  ................
E0009F40 $00000000 $00000000 $00000000 $00000000                  ................
E0009F50 $00000000 $00000000 $00000000 $00000000                  ................
E0009F60 $00000000 $00000000 $00000000 $00000000                  ................
E0009F70 $00000000 $00000000 $00000000 $00000000                  ................
E0009F80 $00000000 $00000000 $00000000 $00000000                  ................
E0009F90 $00000000 $00000000 $00000000 $00000000                  ................
E0009FA0 $00000000 $00000000 $00000000 $00000000                  ................
E0009FB0 $00000000 $00000000 $00000000 $00000000                  ................
E0009FC0 $00000000 $00000000 $00000000 $00000000                  ................
E0009FD0 $00000000 $00000000 $00000000 $00000000                  ................
E0009FE0 $00000000 $00000000 $00000000 $00000000                  ................
E0009FF0 $00000000 $00000000 $00000000 $00000000                  ................


main (lc0)> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Re:Re: PCIe bus seems work while 'dma' can't under linux
  2010-06-15  7:05         ` jxnuxdy
@ 2010-06-15  7:12           ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 18+ messages in thread
From: Benjamin Herrenschmidt @ 2010-06-15  7:12 UTC (permalink / raw)
  To: jxnuxdy
  Cc: linuxppc-dev, Michal Simek, Stephen Rothwell, devicetree-discuss,
	microblaze-uclinux

On Tue, 2010-06-15 at 15:05 +0800, jxnuxdy wrote:
> Thanks Benjamin, the regions don't display as what we expect, that's why we suspect if there any configuration probelms in CPU host bridge, but we changed the uboot/linux a lot, seems take no effect on that problems.
> 
> We use CPU MPC8544, and connect two PCIE devices to CPU PCIE1 and PCIE2 directly without a  extended PCIE bridge, so we disabled PCIE3 and PCI controlers in uboot level.
> 
> More settings pls take a look at the attach file log.txt.

I'm not familiar with those freescale parts, so I'll let others comment
on your settings since it's most likely to be where the problem is.

Cheers,
Ben.

> 
> Many thanks,
> Denny
> ----------------------------------------------------------------------------------------------------------------------------
> 在2010-06-11 15:21:24,"Benjamin Herrenschmidt" <benh@kernel.crashing.org> 写道:
> >On Fri, 2010-06-11 at 09:30 +0800, jxnuxdy wrote:
> >> Hi guys,
> >> 
> >> I encountered a PCIe problem under linux, the two PCIe bus on my board seems work, 
> >> at least I can access the registers through the PCIe bus, however the dma for the
> >> PCIe bus can't work, so I just dumped the pci device, but I am curiously to find
> >> there is no regions displayed on PCIe controlers, why? is it relate with my 'dma' issue then?
> >
> >It would help if you told us a bit more what the HW is, what you are
> >doing with it, etc...
> >
> >IE. What is your host, what is your device, what platform, etc...
> >
> >DMA should work provided that your platform code sets it up properly.
> >The DMA regions don't appear in /proc/pci or lspci.
> >
> >Cheers,
> >Ben.
> >
> >> 
> >> bash-2.04# cat /proc/pci
> >> PCI devices found:
> >>   Bus  0, device   0, function  0:
> >>     Class 0b20  Header Type 01: PCI device 1957:0032 (rev 17).
> >>   Bus  1, device   0, function  0:
> >>     Class 0580  Header Type 00: PCI device 11ab:db90 (rev 1).
> >>       Prefetchable 64 bit memory at 0x80000000 [0x800fffff].
> >>       Prefetchable 64 bit memory at 0x84000000 [0x87ffffff].
> >>   Bus  9, device   0, function  0:
> >>     Class 0b20  Header Type 01: PCI device 1957:0032 (rev 17).
> >>   Bus 10, device   0, function  0:
> >>     Class 0580  Header Type 00: PCI device 11ab:db90 (rev 1).
> >>       Prefetchable 64 bit memory at 0xa0000000 [0xa00fffff].
> >>       Prefetchable 64 bit memory at 0xa4000000 [0xa7ffffff].
> >> bash-2.04# lspci -vv
> >> 00:00.0 Power PC: Unknown device 1957:0032 (rev 11)
> >>         !!! Invalid class 0b20 for header type 01
> >>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
> >>         Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
> >>         Latency: 0, cache line size 08
> >>         Bus: primary=00, secondary=01, subordinate=06, sec-latency=0
> >>         I/O behind bridge: 00000000-00000fff
> >>         Memory behind bridge: 80000000-9fffffff
> >>         BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
> >>         Capabilities: [44] Power Management version 2
> >>                 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
> >>                 Status: D0 PME-Enable- DSel=0 DScale=0 PME-
> >>         Capabilities: [4c] #10 [0041]
> >> 
> >> 01:00.0 Memory controller: Galileo Technology Ltd.: Unknown device db90 (rev 01)
> >>         Subsystem: Galileo Technology Ltd.: Unknown device 11ab
> >>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
> >>         Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
> >>         Latency: 0, cache line size 08
> >>         Interrupt: pin A routed to IRQ 0
> >>         Region 0: Memory at 80000000 (64-bit, prefetchable) [size=1M]
> >>         Region 2: Memory at 84000000 (64-bit, prefetchable) [size=64M]
> >>         Capabilities: [40] Power Management version 2
> >>                 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
> >>                 Status: D0 PME-Enable- DSel=0 DScale=0 PME-
> >>         Capabilities: [50] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable-
> >>                 Address: 0000000000000000  Data: 0000
> >>         Capabilities: [60] #10 [0011]
> >> 
> >> 09:00.0 Power PC: Unknown device 1957:0032 (rev 11)
> >>         !!! Invalid class 0b20 for header type 01
> >>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
> >>         Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
> >>         Latency: 0, cache line size 08
> >>         Bus: primary=00, secondary=0a, subordinate=0f, sec-latency=0
> >>         I/O behind bridge: 00000000-00000fff
> >>         Memory behind bridge: a0000000-bfffffff
> >>         BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
> >>         Capabilities: [44] Power Management version 2
> >>                 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
> >>                 Status: D0 PME-Enable- DSel=0 DScale=0 PME-
> >>         Capabilities: [4c] #10 [0041]
> >> 
> >> 0a:00.0 Memory controller: Galileo Technology Ltd.: Unknown device db90 (rev 01)
> >>         Subsystem: Galileo Technology Ltd.: Unknown device 11ab
> >>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
> >>         Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
> >>         Latency: 0, cache line size 08
> >>         Interrupt: pin A routed to IRQ 0
> >>         Region 0: Memory at a0000000 (64-bit, prefetchable) [size=1M]
> >>         Region 2: Memory at a4000000 (64-bit, prefetchable) [size=64M]
> >>         Capabilities: [40] Power Management version 2
> >>                 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
> >>                 Status: D0 PME-Enable- DSel=0 DScale=0 PME-
> >>         Capabilities: [50] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable-
> >>                 Address: 0000000000000000  Data: 0000
> >>         Capabilities: [60] #10 [0011]
> >> 
> >> bash-2.04# 
> >> 
> >> Thanks
> >> Denny
> >> 
> >> _______________________________________________
> >> Linuxppc-dev mailing list
> >> Linuxppc-dev@lists.ozlabs.org
> >> https://lists.ozlabs.org/listinfo/linuxppc-dev
> >
> >
> >_______________________________________________
> >Linuxppc-dev mailing list
> >Linuxppc-dev@lists.ozlabs.org
> >https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/5] of/irq: merge of_irq_map_one()
  2010-06-11  1:17       ` Benjamin Herrenschmidt
@ 2010-06-17 23:11         ` Grant Likely
  2010-06-17 23:57           ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 18+ messages in thread
From: Grant Likely @ 2010-06-17 23:11 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
	devicetree-discuss, linuxppc-dev

On Thu, Jun 10, 2010 at 7:17 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Thu, 2010-06-10 at 17:36 -0600, Grant Likely wrote:
>>
>> Okay. =A0I had been trying to avoid #ifdefs in the common code, but
>> you're probably right. =A0I'll rework.
>
> Not even ifdef's ... just move the quirk map there. You can always
> #define the quirk variable to 0 on archs that have no quirks, to
> make it compile away if you believe it represents bloat, but they
> are simple well localized things so I doubt it matters.

They're pretty small, but powermac32 is the only code that actually
uses the quirk facility.  Everything else parses sanely it would
appear.  I'd rather have them localized to the powermac code and
eliminate the quirks from the common code.

If other platforms show up with bad irq mappings, then I want to take
the approach of fixing the data rather than adding more quirks cases.

Anyway, let me try my hand at reworking to be a lot clearer and see
what it looks like.

g.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/5] of/irq: merge of_irq_map_one()
  2010-06-17 23:11         ` Grant Likely
@ 2010-06-17 23:57           ` Benjamin Herrenschmidt
  2010-06-18  0:39             ` Grant Likely
  0 siblings, 1 reply; 18+ messages in thread
From: Benjamin Herrenschmidt @ 2010-06-17 23:57 UTC (permalink / raw)
  To: Grant Likely
  Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
	devicetree-discuss, linuxppc-dev

On Thu, 2010-06-17 at 17:11 -0600, Grant Likely wrote:
> On Thu, Jun 10, 2010 at 7:17 PM, Benjamin Herrenschmidt
> <benh@kernel.crashing.org> wrote:
> > On Thu, 2010-06-10 at 17:36 -0600, Grant Likely wrote:
> >>
> >> Okay.  I had been trying to avoid #ifdefs in the common code, but
> >> you're probably right.  I'll rework.
> >
> > Not even ifdef's ... just move the quirk map there. You can always
> > #define the quirk variable to 0 on archs that have no quirks, to
> > make it compile away if you believe it represents bloat, but they
> > are simple well localized things so I doubt it matters.
> 
> They're pretty small, but powermac32 is the only code that actually
> uses the quirk facility.  Everything else parses sanely it would
> appear.  I'd rather have them localized to the powermac code and
> eliminate the quirks from the common code.

Maybe, but the way you end up gutting out some internal functions of the
parser so they can be overriden by the arch is just plain gross :-) And
more bloat than just having a localized quirk test which can easily
compile to nothing when powermac isn't built.

IE. I'd rather you then add some kind of of_irq_map_fixup() or something
like that in the generic code that can be an empty inline when powermac
isn't there, and be defined by powerpc to do the right thing then,
rather than move the core of the function to a separate weak version.

Because the day you fix a bug in the weak variant, or change a calling
convention, you'll forget to also update the "overrides" in the arch.

> If other platforms show up with bad irq mappings, then I want to take
> the approach of fixing the data rather than adding more quirks cases.
> 
> Anyway, let me try my hand at reworking to be a lot clearer and see
> what it looks like.

Ben.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/5] of/irq: merge of_irq_map_one()
  2010-06-17 23:57           ` Benjamin Herrenschmidt
@ 2010-06-18  0:39             ` Grant Likely
  0 siblings, 0 replies; 18+ messages in thread
From: Grant Likely @ 2010-06-18  0:39 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
	devicetree-discuss, linuxppc-dev

On Thu, Jun 17, 2010 at 5:57 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Thu, 2010-06-17 at 17:11 -0600, Grant Likely wrote:
>> On Thu, Jun 10, 2010 at 7:17 PM, Benjamin Herrenschmidt
>> <benh@kernel.crashing.org> wrote:
>> > On Thu, 2010-06-10 at 17:36 -0600, Grant Likely wrote:
>> >>
>> >> Okay. =A0I had been trying to avoid #ifdefs in the common code, but
>> >> you're probably right. =A0I'll rework.
>> >
>> > Not even ifdef's ... just move the quirk map there. You can always
>> > #define the quirk variable to 0 on archs that have no quirks, to
>> > make it compile away if you believe it represents bloat, but they
>> > are simple well localized things so I doubt it matters.
>>
>> They're pretty small, but powermac32 is the only code that actually
>> uses the quirk facility. =A0Everything else parses sanely it would
>> appear. =A0I'd rather have them localized to the powermac code and
>> eliminate the quirks from the common code.
>
> Maybe, but the way you end up gutting out some internal functions of the
> parser so they can be overriden by the arch is just plain gross :-)

Heh, I won't dispute that.  Give me a day or so.  If I can't come up
with anything better, then I'll just move it all over.

g.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/5] of/irq: merge of_irq_find_parent()
  2010-06-10  6:38   ` Benjamin Herrenschmidt
@ 2010-06-21 21:11     ` Grant Likely
  0 siblings, 0 replies; 18+ messages in thread
From: Grant Likely @ 2010-06-21 21:11 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Stephen Rothwell, Michal Simek, linuxppc-dev, devicetree-discuss,
	microblaze-uclinux

On Thu, Jun 10, 2010 at 12:38 AM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Fri, 2010-06-04 at 15:21 -0600, Grant Likely wrote:
>> Merge common code between PowerPC and Microblaze. =A0Also create a new
>> arch hook, of_irq_find_parent_by_phandle() to handle arch-specific
>> quirks.
>
> First, you changeset comment should be much more verbose as to
> what that arch specific quirk is about etc... it took me time to figure
> it out again :-)
>
> I dislike the naming you use. Your "of_irq_find_parent_by_phandle"
> doesn't ring "right" to me.
>
> I'm tempted to say we should put the quirks in the common code, your
> attempt at "abstracting" them just makes the code much harder to follow.
>
> Also, if we stick to your approach the "default" variant should either
> be an inline protected by an ifndef or a weak function.

Alright, I've rewritten all the IRQ changes and I've left the quirk
handling in common code, while moving the powermac quirk code into
arch/powerpc/platforms/powermac.  I'll repost today.

g.

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2010-06-21 21:11 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-04 21:21 [PATCH 1/5] of/irq: Move irq_of_parse_and_map() to common code Grant Likely
2010-06-04 21:21 ` [PATCH 3/5] of/irq: merge of_irq_find_parent() Grant Likely
2010-06-10  6:38   ` Benjamin Herrenschmidt
2010-06-21 21:11     ` Grant Likely
2010-06-04 21:21 ` [PATCH 4/5] of/irq: Merge of_irq_map_raw() Grant Likely
2010-06-10  6:38   ` Benjamin Herrenschmidt
2010-06-04 21:21 ` [PATCH 5/5] of/irq: merge of_irq_map_one() Grant Likely
2010-06-10  6:40   ` Benjamin Herrenschmidt
2010-06-10 23:36     ` Grant Likely
2010-06-11  1:17       ` Benjamin Herrenschmidt
2010-06-17 23:11         ` Grant Likely
2010-06-17 23:57           ` Benjamin Herrenschmidt
2010-06-18  0:39             ` Grant Likely
2010-06-11  1:30       ` PCIe bus seems work while 'dma' can't under linux jxnuxdy
2010-06-11  7:21         ` Benjamin Herrenschmidt
2010-06-15  7:05         ` jxnuxdy
2010-06-15  7:12           ` Benjamin Herrenschmidt
2010-06-10  6:33 ` [PATCH 1/5] of/irq: Move irq_of_parse_and_map() to common code Benjamin Herrenschmidt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).