Commit cc79ca69 authored by Grant Likely's avatar Grant Likely

irq_domain: Move irq_domain code from powerpc to kernel/irq

This patch only moves the code.  It doesn't make any changes, and the
code is still only compiled for powerpc.  Follow-on patches will generalize
the code for other architectures.
Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
Tested-by: default avatarOlof Johansson <olof@lixom.net>
parent 6d9285b0
......@@ -135,6 +135,7 @@ config PPC
select HAVE_GENERIC_HARDIRQS
select HAVE_SPARSE_IRQ
select IRQ_PER_CPU
select IRQ_DOMAIN
select GENERIC_IRQ_SHOW
select GENERIC_IRQ_SHOW_LEVEL
select IRQ_FORCED_THREADING
......
......@@ -42,154 +42,10 @@ extern atomic_t ppc_n_lost_interrupts;
/* Same thing, used by the generic IRQ code */
#define NR_IRQS_LEGACY NUM_ISA_INTERRUPTS
/*
* The host code and data structures are fairly agnostic to the fact that
* we use an open firmware device-tree. We do have references to struct
* device_node in two places: in irq_find_host() to find the host matching
* a given interrupt controller node, and of course as an argument to its
* counterpart host->ops->match() callback. However, those are treated as
* generic pointers by the core and the fact that it's actually a device-node
* pointer is purely a convention between callers and implementation. This
* code could thus be used on other architectures by replacing those two
* by some sort of arch-specific void * "token" used to identify interrupt
* controllers.
*/
struct irq_data;
extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
extern irq_hw_number_t virq_to_hw(unsigned int virq);
/**
* irq_alloc_host - Allocate a new irq_domain data structure
* @of_node: optional device-tree node of the interrupt controller
* @revmap_type: type of reverse mapping to use
* @revmap_arg: for IRQ_DOMAIN_MAP_LINEAR linear only: size of the map
* @ops: map/unmap host callbacks
* @inval_irq: provide a hw number in that host space that is always invalid
*
* Allocates and initialize and irq_domain structure. Note that in the case of
* IRQ_DOMAIN_MAP_LEGACY, the map() callback will be called before this returns
* for all legacy interrupts except 0 (which is always the invalid irq for
* a legacy controller). For a IRQ_DOMAIN_MAP_LINEAR, the map is allocated by
* this call as well. For a IRQ_DOMAIN_MAP_TREE, the radix tree will be allocated
* later during boot automatically (the reverse mapping will use the slow path
* until that happens).
*/
extern struct irq_domain *irq_alloc_host(struct device_node *of_node,
unsigned int revmap_type,
unsigned int revmap_arg,
struct irq_domain_ops *ops,
irq_hw_number_t inval_irq);
/**
* irq_find_host - Locates a host for a given device node
* @node: device-tree node of the interrupt controller
*/
extern struct irq_domain *irq_find_host(struct device_node *node);
/**
* irq_set_default_host - Set a "default" host
* @host: default host pointer
*
* For convenience, it's possible to set a "default" host that will be used
* whenever NULL is passed to irq_create_mapping(). It makes life easier for
* platforms that want to manipulate a few hard coded interrupt numbers that
* aren't properly represented in the device-tree.
*/
extern void irq_set_default_host(struct irq_domain *host);
/**
* irq_set_virq_count - Set the maximum number of virt irqs
* @count: number of linux virtual irqs, capped with NR_IRQS
*
* This is mainly for use by platforms like iSeries who want to program
* the virtual irq number in the controller to avoid the reverse mapping
*/
extern void irq_set_virq_count(unsigned int count);
/**
* irq_create_mapping - Map a hardware interrupt into linux virq space
* @host: host owning this hardware interrupt or NULL for default host
* @hwirq: hardware irq number in that host space
*
* Only one mapping per hardware interrupt is permitted. Returns a linux
* virq number.
* If the sense/trigger is to be specified, set_irq_type() should be called
* on the number returned from that call.
*/
extern unsigned int irq_create_mapping(struct irq_domain *host,
irq_hw_number_t hwirq);
/**
* irq_dispose_mapping - Unmap an interrupt
* @virq: linux virq number of the interrupt to unmap
*/
extern void irq_dispose_mapping(unsigned int virq);
/**
* irq_find_mapping - Find a linux virq from an hw irq number.
* @host: host owning this hardware interrupt
* @hwirq: hardware irq number in that host space
*
* This is a slow path, for use by generic code. It's expected that an
* irq controller implementation directly calls the appropriate low level
* mapping function.
*/
extern unsigned int irq_find_mapping(struct irq_domain *host,
irq_hw_number_t hwirq);
/**
* irq_create_direct_mapping - Allocate a virq for direct mapping
* @host: host to allocate the virq for or NULL for default host
*
* This routine is used for irq controllers which can choose the hardware
* interrupt numbers they generate. In such a case it's simplest to use
* the linux virq as the hardware interrupt number.
*/
extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
/**
* irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping.
* @host: host owning this hardware interrupt
* @virq: linux irq number
* @hwirq: hardware irq number in that host space
*
* This is for use by irq controllers that use a radix tree reverse
* mapping for fast lookup.
*/
extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
irq_hw_number_t hwirq);
/**
* irq_radix_revmap_lookup - Find a linux virq from a hw irq number.
* @host: host owning this hardware interrupt
* @hwirq: hardware irq number in that host space
*
* This is a fast path, for use by irq controller code that uses radix tree
* revmaps
*/
extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
irq_hw_number_t hwirq);
/**
* irq_linear_revmap - Find a linux virq from a hw irq number.
* @host: host owning this hardware interrupt
* @hwirq: hardware irq number in that host space
*
* This is a fast path, for use by irq controller code that uses linear
* revmaps. It does fallback to the slow path if the revmap doesn't exist
* yet and will create the revmap entry with appropriate locking
*/
extern unsigned int irq_linear_revmap(struct irq_domain *host,
irq_hw_number_t hwirq);
/**
* irq_early_init - Init irq remapping subsystem
*/
......
This diff is collapsed.
......@@ -16,6 +16,17 @@
* (though a domain can cover more than one PIC if they have a flat number
* model). It's the domain callbacks that are responsible for setting the
* irq_chip on a given irq_desc after it's been mapped.
*
* The host code and data structures are agnostic to whether or not
* we use an open firmware device-tree. We do have references to struct
* device_node in two places: in irq_find_host() to find the host matching
* a given interrupt controller node, and of course as an argument to its
* counterpart domain->ops->match() callback. However, those are treated as
* generic pointers by the core and the fact that it's actually a device-node
* pointer is purely a convention between callers and implementation. This
* code could thus be used on other architectures by replacing those two
* by some sort of arch-specific void * "token" used to identify interrupt
* controllers.
*/
#ifndef _LINUX_IRQDOMAIN_H
......@@ -108,6 +119,32 @@ struct irq_domain {
};
#ifdef CONFIG_IRQ_DOMAIN
#ifdef CONFIG_PPC
extern struct irq_domain *irq_alloc_host(struct device_node *of_node,
unsigned int revmap_type,
unsigned int revmap_arg,
struct irq_domain_ops *ops,
irq_hw_number_t inval_irq);
extern struct irq_domain *irq_find_host(struct device_node *node);
extern void irq_set_default_host(struct irq_domain *host);
extern void irq_set_virq_count(unsigned int count);
extern unsigned int irq_create_mapping(struct irq_domain *host,
irq_hw_number_t hwirq);
extern void irq_dispose_mapping(unsigned int virq);
extern unsigned int irq_find_mapping(struct irq_domain *host,
irq_hw_number_t hwirq);
extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
irq_hw_number_t hwirq);
extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
irq_hw_number_t hwirq);
extern unsigned int irq_linear_revmap(struct irq_domain *host,
irq_hw_number_t hwirq);
#else /* CONFIG_PPC */
/**
* irq_domain_to_irq() - Translate from a hardware irq to a linux irq number
*
......@@ -137,15 +174,16 @@ extern void irq_domain_add(struct irq_domain *domain);
extern void irq_domain_del(struct irq_domain *domain);
extern struct irq_domain_ops irq_domain_simple_ops;
#endif /* CONFIG_IRQ_DOMAIN */
#if defined(CONFIG_IRQ_DOMAIN) && defined(CONFIG_OF_IRQ)
#if defined(CONFIG_OF_IRQ)
extern void irq_domain_add_simple(struct device_node *controller, int irq_base);
extern void irq_domain_generate_simple(const struct of_device_id *match,
u64 phys_base, unsigned int irq_start);
#else /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */
#else /* CONFIG_OF_IRQ */
static inline void irq_domain_generate_simple(const struct of_device_id *match,
u64 phys_base, unsigned int irq_start) { }
#endif /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */
#endif /* !CONFIG_OF_IRQ */
#endif /* !CONFIG_PPC */
#endif /* CONFIG_IRQ_DOMAIN */
#endif /* _LINUX_IRQDOMAIN_H */
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment