mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
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: Grant 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: Olof Johansson <olof@lixom.net>
This commit is contained in:
@@ -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
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user