mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
08a543ad33
This patch adds irq_domain infrastructure for translating from hardware irq numbers to linux irqs. This is particularly important for architectures adding device tree support because the current implementation (excluding PowerPC and SPARC) cannot handle translation for more than a single interrupt controller. irq_domain supports device tree translation for any number of interrupt controllers. This patch converts x86, Microblaze, ARM and MIPS to use irq_domain for device tree irq translation. x86 is untested beyond compiling it, irq_domain is enabled for MIPS and Microblaze, but the old behaviour is preserved until the core code is modified to actually register an irq_domain yet. On ARM it works and is required for much of the new ARM device tree board support. PowerPC has /not/ been converted to use this new infrastructure. It is still missing some features before it can replace the virq infrastructure already in powerpc (see documentation on irq_domain_map/unmap for details). Followup patches will add the missing pieces and migrate PowerPC to use irq_domain. SPARC has its own method of managing interrupts from the device tree and is unaffected by this change. Acked-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
79 lines
2.6 KiB
C
79 lines
2.6 KiB
C
#ifndef __OF_IRQ_H
|
|
#define __OF_IRQ_H
|
|
|
|
#if defined(CONFIG_OF)
|
|
struct of_irq;
|
|
#include <linux/types.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/irq.h>
|
|
#include <linux/ioport.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 */
|
|
};
|
|
|
|
/*
|
|
* 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);
|
|
#ifdef CONFIG_IRQ_DOMAIN
|
|
extern void irq_dispose_mapping(unsigned int irq);
|
|
#endif
|
|
extern int of_irq_to_resource(struct device_node *dev, int index,
|
|
struct resource *r);
|
|
extern int of_irq_count(struct device_node *dev);
|
|
extern int of_irq_to_resource_table(struct device_node *dev,
|
|
struct resource *res, int nr_irqs);
|
|
extern struct device_node *of_irq_find_parent(struct device_node *child);
|
|
|
|
|
|
#endif /* CONFIG_OF_IRQ */
|
|
#endif /* CONFIG_OF */
|
|
#endif /* __OF_IRQ_H */
|