summaryrefslogtreecommitdiffstats
path: root/include/asm-powerpc/prom.h
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-07-03 19:35:17 +1000
committerPaul Mackerras <paulus@samba.org>2006-07-03 19:55:24 +1000
commitcc9fd71c62f542233c412b5fabc1bbe0c4d5ad08 (patch)
tree67af54159a57029057765c7ce94b00081844a6c8 /include/asm-powerpc/prom.h
parentb9e5b4e6a991a5a6d521f2e20a65835404b4169f (diff)
downloadlinux-cc9fd71c62f542233c412b5fabc1bbe0c4d5ad08.tar.gz
linux-cc9fd71c62f542233c412b5fabc1bbe0c4d5ad08.tar.bz2
linux-cc9fd71c62f542233c412b5fabc1bbe0c4d5ad08.zip
[POWERPC] New device-tree interrupt parsing code
Adds new routines to prom_parse to walk the device-tree for interrupt information. This includes both direct mapping of interrupts and low level parsing functions for use with partial trees. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include/asm-powerpc/prom.h')
-rw-r--r--include/asm-powerpc/prom.h87
1 files changed, 87 insertions, 0 deletions
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index b0768f474809..48bef401bc19 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -204,6 +204,15 @@ extern int release_OF_resource(struct device_node* node, int index);
*/
+/* Helper to read a big number */
+static inline u64 of_read_number(u32 *cell, int size)
+{
+ u64 r = 0;
+ while (size--)
+ r = (r << 32) | *(cell++);
+ return r;
+}
+
/* Translate an OF address block into a CPU physical address
*/
#define OF_BAD_ADDR ((u64)-1)
@@ -240,5 +249,83 @@ extern void kdump_move_device_tree(void);
/* CPU OF node matching */
struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
+
+/*
+ * 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
+ *
+ * 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
+ * @intspec: interrupt specifier ("interrupts" property of the device)
+ * @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, u32 *intspec, 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
+ * @out_irq: structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+struct pci_dev;
+extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+
+
#endif /* __KERNEL__ */
#endif /* _POWERPC_PROM_H */