Skip to contentSkip to conversation

Consolidate OF IRQ handling code

PATCH New Grant Likely 1 participant 6 messages Jun 21, 2010

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

v2 cover Consolidate OF IRQ handling code

This series merges the common IRQ handling code between Microblaze and Powerpc

Changes in v2:
- The 3 patches to merge of_irq_find_parent(), of_irq_map_raw() and of_irq_map_one() have been merged into a single patch.
- Patch added to move powermac quirk handing into arch/powerpc/platforms/powermac.
- Add endian fixes patch from Rob Herring

Ben, please take a look and let me know if you like this better.

Thanks,
g.

---

Grant Likely (4):
of/irq: Move irq_of_parse_and_map() to common code of/microblaze: strip out of_irq_workarounds code of/powerpc: Move Powermac irq quirk code into powermac pic driver code of/irq: merge irq mapping code

Rob Herring (1):
of/irq: little endian fixes

 arch/microblaze/include/asm/irq.h     |   13 -
 arch/microblaze/include/asm/prom.h    |   67 ------
 arch/microblaze/kernel/irq.c          |   14 -
 arch/microblaze/kernel/prom_parse.c   |  331 -------------------------------
 arch/powerpc/include/asm/irq.h        |   13 -
 arch/powerpc/include/asm/prom.h       |   68 ------
 arch/powerpc/kernel/irq.c             |   14 -
 arch/powerpc/kernel/prom_parse.c      |  351 ---------------------------------
 arch/powerpc/platforms/powermac/pic.c |   72 ++++++-
 arch/sparc/include/asm/prom.h         |    1 
 drivers/of/Kconfig                    |    4 
 drivers/of/Makefile                   |    1 
 drivers/of/irq.c                      |  339 ++++++++++++++++++++++++++++++++
 drivers/of/of_mdio.c                  |    1 
 include/linux/of_irq.h                |   70 +++++++
 15 files changed, 487 insertions(+), 872 deletions(-)
 create mode 100644 drivers/of/irq.c
 create mode 100644 include/linux/of_irq.h
#1 lore raw

PATCH v2 1/5 of/irq: Move irq_of_parse_and_map() to common code

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.

Cc Michal Simek <[email protected]>
Cc "David S. Miller" <[email protected]>
Cc Stephen Rothwell <[email protected]>
Cc Jeremy Kerr <[email protected]>
---
 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
arch/microblaze/include/asm/irq.h +0 -13
index 31a35c3..10d75c1 100644
@@ -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 */
arch/microblaze/include/asm/prom.h +1 -25
index e7d67a3..e9fb2eb 100644
@@ -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
arch/microblaze/kernel/irq.c +2 -12
index 8f120ac..dd32b09 100644
@@ -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];
 }
arch/powerpc/include/asm/irq.h +0 -13
index e054bae..a3b5124 100644
@@ -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
arch/powerpc/include/asm/prom.h +1 -26
index ddd408a..47d41b6 100644
@@ -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
arch/powerpc/kernel/irq.c +2 -12
index 30817d9..2676ef2 100644
@@ -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;
arch/sparc/include/asm/prom.h +0 -1
index f845828..ac69574 100644
@@ -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)
 {
 }
drivers/of/Kconfig +4 -0
index 7cecc8f..b87495e 100644
@@ -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)
drivers/of/Makefile +1 -0
index f232cc9..3631a5e 100644
@@ -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
drivers/of/irq.c new file +37 -0
new file mode 100644
index 0000000..56ad1aa
@@ -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 ([email protected])
+ *  Updated and modified by Cort Dougan <[email protected]>
+ *    Copyright (C) 1996-2001 Cort Dougan
+ *  Adapted for Power Macintosh by Paul Mackerras
+ *    Copyright (C) 1996 Paul Mackerras ([email protected])
+ *
+ * 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);
drivers/of/of_mdio.c +1 -0
index 42a6715..1fce00e 100644
@@ -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>
 
include/linux/of_irq.h new file +41 -0

41 lines not on this page · raw message

#2 lore raw

PATCH v2 2/5 of/microblaze: strip out of_irq_workarounds code

In reply to Grant Likely

Microblaze doesn't have any legacy workaround in the device tree irq mapping data. All of the of_irq_workarounds stuff can be dropped

Cc Michal Simek <[email protected]>
Cc Stephen Rothwell <[email protected]>
---
 arch/microblaze/include/asm/prom.h  |   10 ---------
 arch/microblaze/kernel/prom_parse.c |   41 -----------------------------------
 2 files changed, 0 insertions(+), 51 deletions(-)
arch/microblaze/include/asm/prom.h +0 -10
index e9fb2eb..4f34bc5 100644
@@ -93,19 +93,9 @@ extern const void *of_get_mac_address(struct device_node *np);
  * OF interrupt mapping
  */
 
-/**
- * of_irq_map_init - Initialize the irq remapper
- * @flags:	flags defining workarounds to enable
- *
- * Some machines have bugs in the device-tree which require certain workarounds
- * to be applied. Call this before any interrupt mapping attempts to enable
- * those workarounds.
- */
 #define OF_IMAP_OLDWORLD_MAC	0x00000001
 #define OF_IMAP_NO_PHANDLE	0x00000002
 
-extern void of_irq_map_init(unsigned int flags);
-
 /**
  * of_irq_map_raw - Low level interrupt tree parsing
  * @parent:	the device interrupt parent
arch/microblaze/kernel/prom_parse.c +0 -41

47 lines not on this page · raw message

#3 lore raw

PATCH v2 3/5 of/powerpc: Move Powermac irq quirk code into powermac pic driver code

In reply to Grant Likely

The code that figures out what is wrong with the powermac irq device tree data belongs with the rest of the powermac irq code. This patch moves it out of prom_parse.c and into powermac/pic.c so that it is only compiled in when actually needed.

The quirk flags are also conditionally compiled out to discourage their use by other platforms.

Cc Benjamin Herrenschmidt <[email protected]>
Cc Stephen Rothwell <[email protected]>
---
 arch/powerpc/include/asm/prom.h       |   24 ++++++---
 arch/powerpc/kernel/prom_parse.c      |   85 ---------------------------------
 arch/powerpc/platforms/powermac/pic.c |   72 ++++++++++++++++++++++++++--
 3 files changed, 81 insertions(+), 100 deletions(-)
arch/powerpc/include/asm/prom.h +15 -9
index 47d41b6..4486765 100644
@@ -109,18 +109,24 @@ extern const void *of_get_mac_address(struct device_node *np);
  * OF interrupt mapping
  */
 
-/**
- * of_irq_map_init - Initialize the irq remapper
- * @flags:	flags defining workarounds to enable
- *
- * Some machines have bugs in the device-tree which require certain workarounds
- * to be applied. Call this before any interrupt mapping attempts to enable
- * those workarounds.
- */
 #define OF_IMAP_OLDWORLD_MAC	0x00000001
 #define OF_IMAP_NO_PHANDLE	0x00000002
 
-extern void of_irq_map_init(unsigned int flags);
+#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC)
+/* Workarounds only needed for 32bit powermac machines */
+extern unsigned int of_irq_workarounds;
+extern struct device_node *of_irq_dflt_pic;
+extern int of_irq_map_oldworld(struct device_node *device, int index,
+			       struct of_irq *out_irq);
+#else
+#define of_irq_workarounds (0)
+#define of_irq_dflt_pic (NULL)
+static inline int of_irq_map_oldworld(struct device_node *device, int index,
+				      struct of_irq *out_irq)
+{
+	return -EINVAL;
+}
+#endif
 
 /**
  * of_irq_map_raw - Low level interrupt tree parsing
arch/powerpc/kernel/prom_parse.c +0 -85

103 lines not on this page · raw message

arch/powerpc/platforms/powermac/pic.c +66 -6

97 lines not on this page · raw message

#4 lore raw

PATCH v2 4/5 of/irq: merge irq mapping code

In reply to Grant Likely

Merge common irq mapping code between PowerPC and Microblaze.

This patch merges of_irq_find_parent(), of_irq_map_raw() and of_irq_map_one(). The functions are dependent on one another, so all three are merged in a single patch. Other than cosmetic difference (ie. DBG() vs. pr_debug()), the implementations are identical.

of_irq_to_resource() is also merged, but in this case the implementations are different. This patch drops the microblaze version and uses the powerpc implementation unchanged. The microblaze version essentially open-coded irq_of_parse_and_map() which it does not need to do. Therefore the powerpc version is safe to adopt.

CC Michal Simek <[email protected]>
CC Benjamin Herrenschmidt <[email protected]>
CC Stephen Rothwell <[email protected]>
---
 arch/microblaze/include/asm/prom.h  |   31 ----
 arch/microblaze/kernel/prom_parse.c |  290 ----------------------------------
 arch/powerpc/include/asm/prom.h     |   47 -----
 arch/powerpc/kernel/prom_parse.c    |  266 -------------------------------
 drivers/of/irq.c                    |  301 +++++++++++++++++++++++++++++++++++
 include/linux/of_irq.h              |   29 +++
 6 files changed, 330 insertions(+), 634 deletions(-)
arch/microblaze/include/asm/prom.h +0 -31
index 4f34bc5..5fbdfe7 100644
@@ -89,34 +89,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 /* Get the MAC address */
 extern const void *of_get_mac_address(struct device_node *np);
 
-/*
- * OF interrupt mapping
- */
-
-#define OF_IMAP_OLDWORLD_MAC	0x00000001
-#define OF_IMAP_NO_PHANDLE	0x00000002
-
-/**
- * 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
@@ -131,9 +103,6 @@ extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
 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
arch/microblaze/kernel/prom_parse.c +0 -290

302 lines not on this page · raw message

arch/powerpc/include/asm/prom.h +0 -47

59 lines not on this page · raw message

arch/powerpc/kernel/prom_parse.c +0 -266

278 lines not on this page · raw message

drivers/of/irq.c +301 -0

304 lines not on this page · raw message

include/linux/of_irq.h +29 -0
index 0e37c05..5929781 100644
@@ -4,6 +4,8 @@
 #if defined(CONFIG_OF)
 struct of_irq;
 #include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
 #include <linux/of.h>
 
 /*
@@ -30,11 +32,38 @@ struct of_irq {
 	u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
 };
 
+/*
+ * Workarounds only applied to 32bit powermac machines
+ */
+#define OF_IMAP_OLDWORLD_MAC	0x00000001
+#define OF_IMAP_NO_PHANDLE	0x00000002
+
+#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC)
+extern unsigned int of_irq_workarounds;
+extern struct device_node *of_irq_dflt_pic;
+extern int of_irq_map_oldworld(struct device_node *device, int index,
+			       struct of_irq *out_irq);
+#else /* CONFIG_PPC32 && CONFIG_PPC_PMAC */
+#define of_irq_workarounds (0)
+#define of_irq_dflt_pic (NULL)
+static inline int of_irq_map_oldworld(struct device_node *device, int index,
+				      struct of_irq *out_irq)
+{
+	return -EINVAL;
+}
+#endif /* CONFIG_PPC32 && CONFIG_PPC_PMAC */
+
+
+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,
 					  const u32 *intspec,
 					  unsigned int intsize);
+extern int of_irq_to_resource(struct device_node *dev, int index,
+			      struct resource *r);
 
 #endif /* CONFIG_OF_IRQ */
 #endif /* CONFIG_OF */
#5 lore raw

PATCH v2 5/5 of/irq: little endian fixes

In reply to Grant Likely

From: Rob Herring <[email protected]>

Fix some endian issues in the irq mapping OF code.

CC Michal Simek <[email protected]>
CC Wolfram Sang <[email protected]>
CC Stephen Rothwell <[email protected]>
CC Benjamin Herrenschmidt <[email protected]>
---
 drivers/of/irq.c |   17 +++++++++--------
 1 files changed, 9 insertions(+), 8 deletions(-)
drivers/of/irq.c +9 -8
index 0b0518f..b68a924 100644
@@ -87,7 +87,7 @@ 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;
+	const __be32 *tmp, *imap, *imask;
 	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
 	int imaplen, match, i;
 
@@ -103,7 +103,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
 	do {
 		tmp = of_get_property(ipar, "#interrupt-cells", NULL);
 		if (tmp != NULL) {
-			intsize = *tmp;
+			intsize = be32_to_cpu(*tmp);
 			break;
 		}
 		tnode = ipar;
@@ -132,7 +132,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
 	} while (old && tmp == NULL);
 	of_node_put(old);
 	old = NULL;
-	addrsize = (tmp == NULL) ? 2 : *tmp;
+	addrsize = (tmp == NULL) ? 2 : be32_to_cpu(*tmp);
 
 	pr_debug(" -> addrsize=%d\n", addrsize);
 
@@ -144,8 +144,9 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
 		if (of_get_property(ipar, "interrupt-controller", NULL) !=
 				NULL) {
 			pr_debug(" -> got it !\n");
-			memcpy(out_irq->specifier, intspec,
-			       intsize * sizeof(u32));
+			for (i = 0; i < intsize; i++)
+				out_irq->specifier[i] =
+						of_read_number(intspec +i, 1);
 			out_irq->size = intsize;
 			out_irq->controller = ipar;
 			of_node_put(old);
@@ -215,9 +216,9 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
 				pr_debug(" -> parent lacks #interrupt-cells!\n");
 				goto fail;
 			}
-			newintsize = *tmp;
+			newintsize = be32_to_cpu(*tmp);
 			tmp = of_get_property(newpar, "#address-cells", NULL);
-			newaddrsize = (tmp == NULL) ? 0 : *tmp;
+			newaddrsize = (tmp == NULL) ? 0 : be32_to_cpu(*tmp);
 
 			pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
 			    newintsize, newaddrsize);
@@ -299,7 +300,7 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
 	tmp = of_get_property(p, "#interrupt-cells", NULL);
 	if (tmp == NULL)
 		goto out;
-	intsize = *tmp;
+	intsize = be32_to_cpu(*tmp);
 
 	pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);