Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner:
"The irq departement delivers:
- Rework the irqdomain core infrastructure to accomodate ACPI based
systems. This is required to support ARM64 without creating
artificial device tree nodes.
- Sanitize the ACPI based ARM GIC initialization by making use of the
new firmware independent irqdomain core
- Further improvements to the generic MSI management
- Generalize the irq migration on CPU hotplug
- Improvements to the threaded interrupt infrastructure
- Allow the migration of "chained" low level interrupt handlers
- Allow optional force masking of interrupts in disable_irq[_nosysnc]
- Support for two new interrupt chips - Sigh!
- A larger set of errata fixes for ARM gicv3
- The usual pile of fixes, updates, improvements and cleanups all
over the place"
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (71 commits)
Document that IRQ_NONE should be returned when IRQ not actually handled
PCI/MSI: Allow the MSI domain to be device-specific
PCI: Add per-device MSI domain hook
of/irq: Use the msi-map property to provide device-specific MSI domain
of/irq: Split of_msi_map_rid to reuse msi-map lookup
irqchip/gic-v3-its: Parse new version of msi-parent property
PCI/MSI: Use of_msi_get_domain instead of open-coded "msi-parent" parsing
of/irq: Use of_msi_get_domain instead of open-coded "msi-parent" parsing
of/irq: Add support code for multi-parent version of "msi-parent"
irqchip/gic-v3-its: Add handling of PCI requester id.
PCI/MSI: Add helper function pci_msi_domain_get_msi_rid().
of/irq: Add new function of_msi_map_rid()
Docs: dt: Add PCI MSI map bindings
irqchip/gic-v2m: Add support for multiple MSI frames
irqchip/gic-v3: Fix translation of LPIs after conversion to irq_fwspec
irqchip/mxs: Add Alphascale ASM9260 support
irqchip/mxs: Prepare driver for hardware with different offsets
irqchip/mxs: Panic if ioremap or domain creation fails
irqdomain: Documentation updates
irqdomain/msi: Use fwnode instead of of_node
...
This commit is contained in:
commit
6aa2fdb87c
90 changed files with 2577 additions and 890 deletions
|
|
@ -201,6 +201,9 @@ int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity
|
|||
int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
|
||||
int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
|
||||
|
||||
void acpi_set_irq_model(enum acpi_irq_model_id model,
|
||||
struct fwnode_handle *fwnode);
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ enum fwnode_type {
|
|||
FWNODE_OF,
|
||||
FWNODE_ACPI,
|
||||
FWNODE_PDATA,
|
||||
FWNODE_IRQCHIP,
|
||||
};
|
||||
|
||||
struct fwnode_handle {
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);
|
|||
* @flags: flags (see IRQF_* above)
|
||||
* @thread_fn: interrupt handler function for threaded interrupts
|
||||
* @thread: thread pointer for threaded interrupts
|
||||
* @secondary: pointer to secondary irqaction (force threading)
|
||||
* @thread_flags: flags related to @thread
|
||||
* @thread_mask: bitmask for keeping track of @thread activity
|
||||
* @dir: pointer to the proc/irq/NN/name entry
|
||||
|
|
@ -113,6 +114,7 @@ struct irqaction {
|
|||
struct irqaction *next;
|
||||
irq_handler_t thread_fn;
|
||||
struct task_struct *thread;
|
||||
struct irqaction *secondary;
|
||||
unsigned int irq;
|
||||
unsigned int flags;
|
||||
unsigned long thread_flags;
|
||||
|
|
|
|||
|
|
@ -67,11 +67,12 @@ enum irqchip_irq_state;
|
|||
* request/setup_irq()
|
||||
* IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set)
|
||||
* IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context
|
||||
* IRQ_NESTED_TRHEAD - Interrupt nests into another thread
|
||||
* IRQ_NESTED_THREAD - Interrupt nests into another thread
|
||||
* IRQ_PER_CPU_DEVID - Dev_id is a per-cpu variable
|
||||
* IRQ_IS_POLLED - Always polled by another interrupt. Exclude
|
||||
* it from the spurious interrupt detection
|
||||
* mechanism and from core side polling.
|
||||
* IRQ_DISABLE_UNLAZY - Disable lazy irq disable
|
||||
*/
|
||||
enum {
|
||||
IRQ_TYPE_NONE = 0x00000000,
|
||||
|
|
@ -97,13 +98,14 @@ enum {
|
|||
IRQ_NOTHREAD = (1 << 16),
|
||||
IRQ_PER_CPU_DEVID = (1 << 17),
|
||||
IRQ_IS_POLLED = (1 << 18),
|
||||
IRQ_DISABLE_UNLAZY = (1 << 19),
|
||||
};
|
||||
|
||||
#define IRQF_MODIFY_MASK \
|
||||
(IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
|
||||
IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \
|
||||
IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID | \
|
||||
IRQ_IS_POLLED)
|
||||
IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY)
|
||||
|
||||
#define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING)
|
||||
|
||||
|
|
@ -297,21 +299,6 @@ static inline void irqd_clr_forwarded_to_vcpu(struct irq_data *d)
|
|||
__irqd_to_state(d) &= ~IRQD_FORWARDED_TO_VCPU;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions for chained handlers which can be enabled/disabled by the
|
||||
* standard disable_irq/enable_irq calls. Must be called with
|
||||
* irq_desc->lock held.
|
||||
*/
|
||||
static inline void irqd_set_chained_irq_inprogress(struct irq_data *d)
|
||||
{
|
||||
__irqd_to_state(d) |= IRQD_IRQ_INPROGRESS;
|
||||
}
|
||||
|
||||
static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
|
||||
{
|
||||
__irqd_to_state(d) &= ~IRQD_IRQ_INPROGRESS;
|
||||
}
|
||||
|
||||
static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
|
||||
{
|
||||
return d->hwirq;
|
||||
|
|
@ -452,6 +439,8 @@ extern int irq_set_affinity_locked(struct irq_data *data,
|
|||
const struct cpumask *cpumask, bool force);
|
||||
extern int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info);
|
||||
|
||||
extern void irq_migrate_all_off_this_cpu(void);
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
|
||||
void irq_move_irq(struct irq_data *data);
|
||||
void irq_move_masked_irq(struct irq_data *data);
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@
|
|||
#ifndef __LINUX_IRQCHIP_ARM_GIC_V3_H
|
||||
#define __LINUX_IRQCHIP_ARM_GIC_V3_H
|
||||
|
||||
#include <asm/sysreg.h>
|
||||
|
||||
/*
|
||||
* Distributor registers. We assume we're running non-secure, with ARE
|
||||
* being set. Secure-only and non-ARE registers are not described.
|
||||
|
|
@ -231,6 +229,7 @@
|
|||
#define GITS_BASER_PAGE_SIZE_16K (1UL << GITS_BASER_PAGE_SIZE_SHIFT)
|
||||
#define GITS_BASER_PAGE_SIZE_64K (2UL << GITS_BASER_PAGE_SIZE_SHIFT)
|
||||
#define GITS_BASER_PAGE_SIZE_MASK (3UL << GITS_BASER_PAGE_SIZE_SHIFT)
|
||||
#define GITS_BASER_PAGES_MAX 256
|
||||
|
||||
#define GITS_BASER_TYPE_NONE 0
|
||||
#define GITS_BASER_TYPE_DEVICE 1
|
||||
|
|
@ -266,16 +265,16 @@
|
|||
/*
|
||||
* Hypervisor interface registers (SRE only)
|
||||
*/
|
||||
#define ICH_LR_VIRTUAL_ID_MASK ((1UL << 32) - 1)
|
||||
#define ICH_LR_VIRTUAL_ID_MASK ((1ULL << 32) - 1)
|
||||
|
||||
#define ICH_LR_EOI (1UL << 41)
|
||||
#define ICH_LR_GROUP (1UL << 60)
|
||||
#define ICH_LR_HW (1UL << 61)
|
||||
#define ICH_LR_STATE (3UL << 62)
|
||||
#define ICH_LR_PENDING_BIT (1UL << 62)
|
||||
#define ICH_LR_ACTIVE_BIT (1UL << 63)
|
||||
#define ICH_LR_EOI (1ULL << 41)
|
||||
#define ICH_LR_GROUP (1ULL << 60)
|
||||
#define ICH_LR_HW (1ULL << 61)
|
||||
#define ICH_LR_STATE (3ULL << 62)
|
||||
#define ICH_LR_PENDING_BIT (1ULL << 62)
|
||||
#define ICH_LR_ACTIVE_BIT (1ULL << 63)
|
||||
#define ICH_LR_PHYS_ID_SHIFT 32
|
||||
#define ICH_LR_PHYS_ID_MASK (0x3ffUL << ICH_LR_PHYS_ID_SHIFT)
|
||||
#define ICH_LR_PHYS_ID_MASK (0x3ffULL << ICH_LR_PHYS_ID_SHIFT)
|
||||
|
||||
#define ICH_MISR_EOI (1 << 0)
|
||||
#define ICH_MISR_U (1 << 1)
|
||||
|
|
@ -292,19 +291,8 @@
|
|||
#define ICH_VMCR_PMR_SHIFT 24
|
||||
#define ICH_VMCR_PMR_MASK (0xffUL << ICH_VMCR_PMR_SHIFT)
|
||||
|
||||
#define ICC_EOIR1_EL1 sys_reg(3, 0, 12, 12, 1)
|
||||
#define ICC_DIR_EL1 sys_reg(3, 0, 12, 11, 1)
|
||||
#define ICC_IAR1_EL1 sys_reg(3, 0, 12, 12, 0)
|
||||
#define ICC_SGI1R_EL1 sys_reg(3, 0, 12, 11, 5)
|
||||
#define ICC_PMR_EL1 sys_reg(3, 0, 4, 6, 0)
|
||||
#define ICC_CTLR_EL1 sys_reg(3, 0, 12, 12, 4)
|
||||
#define ICC_SRE_EL1 sys_reg(3, 0, 12, 12, 5)
|
||||
#define ICC_GRPEN1_EL1 sys_reg(3, 0, 12, 12, 7)
|
||||
|
||||
#define ICC_IAR1_EL1_SPURIOUS 0x3ff
|
||||
|
||||
#define ICC_SRE_EL2 sys_reg(3, 4, 12, 9, 5)
|
||||
|
||||
#define ICC_SRE_EL2_SRE (1 << 0)
|
||||
#define ICC_SRE_EL2_ENABLE (1 << 3)
|
||||
|
||||
|
|
@ -320,54 +308,10 @@
|
|||
#define ICC_SGI1R_AFFINITY_3_SHIFT 48
|
||||
#define ICC_SGI1R_AFFINITY_3_MASK (0xffULL << ICC_SGI1R_AFFINITY_1_SHIFT)
|
||||
|
||||
/*
|
||||
* System register definitions
|
||||
*/
|
||||
#define ICH_VSEIR_EL2 sys_reg(3, 4, 12, 9, 4)
|
||||
#define ICH_HCR_EL2 sys_reg(3, 4, 12, 11, 0)
|
||||
#define ICH_VTR_EL2 sys_reg(3, 4, 12, 11, 1)
|
||||
#define ICH_MISR_EL2 sys_reg(3, 4, 12, 11, 2)
|
||||
#define ICH_EISR_EL2 sys_reg(3, 4, 12, 11, 3)
|
||||
#define ICH_ELSR_EL2 sys_reg(3, 4, 12, 11, 5)
|
||||
#define ICH_VMCR_EL2 sys_reg(3, 4, 12, 11, 7)
|
||||
|
||||
#define __LR0_EL2(x) sys_reg(3, 4, 12, 12, x)
|
||||
#define __LR8_EL2(x) sys_reg(3, 4, 12, 13, x)
|
||||
|
||||
#define ICH_LR0_EL2 __LR0_EL2(0)
|
||||
#define ICH_LR1_EL2 __LR0_EL2(1)
|
||||
#define ICH_LR2_EL2 __LR0_EL2(2)
|
||||
#define ICH_LR3_EL2 __LR0_EL2(3)
|
||||
#define ICH_LR4_EL2 __LR0_EL2(4)
|
||||
#define ICH_LR5_EL2 __LR0_EL2(5)
|
||||
#define ICH_LR6_EL2 __LR0_EL2(6)
|
||||
#define ICH_LR7_EL2 __LR0_EL2(7)
|
||||
#define ICH_LR8_EL2 __LR8_EL2(0)
|
||||
#define ICH_LR9_EL2 __LR8_EL2(1)
|
||||
#define ICH_LR10_EL2 __LR8_EL2(2)
|
||||
#define ICH_LR11_EL2 __LR8_EL2(3)
|
||||
#define ICH_LR12_EL2 __LR8_EL2(4)
|
||||
#define ICH_LR13_EL2 __LR8_EL2(5)
|
||||
#define ICH_LR14_EL2 __LR8_EL2(6)
|
||||
#define ICH_LR15_EL2 __LR8_EL2(7)
|
||||
|
||||
#define __AP0Rx_EL2(x) sys_reg(3, 4, 12, 8, x)
|
||||
#define ICH_AP0R0_EL2 __AP0Rx_EL2(0)
|
||||
#define ICH_AP0R1_EL2 __AP0Rx_EL2(1)
|
||||
#define ICH_AP0R2_EL2 __AP0Rx_EL2(2)
|
||||
#define ICH_AP0R3_EL2 __AP0Rx_EL2(3)
|
||||
|
||||
#define __AP1Rx_EL2(x) sys_reg(3, 4, 12, 9, x)
|
||||
#define ICH_AP1R0_EL2 __AP1Rx_EL2(0)
|
||||
#define ICH_AP1R1_EL2 __AP1Rx_EL2(1)
|
||||
#define ICH_AP1R2_EL2 __AP1Rx_EL2(2)
|
||||
#define ICH_AP1R3_EL2 __AP1Rx_EL2(3)
|
||||
#include <asm/arch_gicv3.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/stringify.h>
|
||||
#include <asm/msi.h>
|
||||
|
||||
/*
|
||||
* We need a value to serve as a irq-type for LPIs. Choose one that will
|
||||
* hopefully pique the interest of the reviewer.
|
||||
|
|
@ -385,23 +329,26 @@ struct rdists {
|
|||
u64 flags;
|
||||
};
|
||||
|
||||
static inline void gic_write_eoir(u64 irq)
|
||||
{
|
||||
asm volatile("msr_s " __stringify(ICC_EOIR1_EL1) ", %0" : : "r" (irq));
|
||||
isb();
|
||||
}
|
||||
|
||||
static inline void gic_write_dir(u64 irq)
|
||||
{
|
||||
asm volatile("msr_s " __stringify(ICC_DIR_EL1) ", %0" : : "r" (irq));
|
||||
isb();
|
||||
}
|
||||
|
||||
struct irq_domain;
|
||||
int its_cpu_init(void);
|
||||
int its_init(struct device_node *node, struct rdists *rdists,
|
||||
struct irq_domain *domain);
|
||||
|
||||
static inline bool gic_enable_sre(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = gic_read_sre();
|
||||
if (val & ICC_SRE_EL1_SRE)
|
||||
return true;
|
||||
|
||||
val |= ICC_SRE_EL1_SRE;
|
||||
gic_write_sre(val);
|
||||
val = gic_read_sre();
|
||||
|
||||
return !!(val & ICC_SRE_EL1_SRE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -100,16 +100,11 @@
|
|||
|
||||
struct device_node;
|
||||
|
||||
void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
|
||||
u32 offset, struct device_node *);
|
||||
void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
|
||||
int gic_cpu_if_down(unsigned int gic_nr);
|
||||
|
||||
static inline void gic_init(unsigned int nr, int start,
|
||||
void __iomem *dist , void __iomem *cpu)
|
||||
{
|
||||
gic_init_bases(nr, start, dist, cpu, 0, NULL);
|
||||
}
|
||||
void gic_init(unsigned int nr, int start,
|
||||
void __iomem *dist , void __iomem *cpu);
|
||||
|
||||
int gicv2m_of_init(struct device_node *node, struct irq_domain *parent);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@
|
|||
* helpful for interrupt controllers to implement mapping between hardware
|
||||
* irq numbers and the Linux irq number space.
|
||||
*
|
||||
* irq_domains also have a hook for translating device tree interrupt
|
||||
* representation into a hardware irq number that can be mapped back to a
|
||||
* Linux irq number without any extra platform support code.
|
||||
* irq_domains also have hooks for translating device tree or other
|
||||
* firmware interrupt representations into a hardware irq number that
|
||||
* can be mapped back to a Linux irq number without any extra platform
|
||||
* support code.
|
||||
*
|
||||
* Interrupt controller "domain" data structure. This could be defined as a
|
||||
* irq domain controller. That is, it handles the mapping between hardware
|
||||
|
|
@ -17,16 +18,12 @@
|
|||
* 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.
|
||||
* The host code and data structures use a fwnode_handle pointer to
|
||||
* identify the domain. In some cases, and in order to preserve source
|
||||
* code compatibility, this fwnode pointer is "upgraded" to a DT
|
||||
* device_node. For those firmware infrastructures that do not provide
|
||||
* a unique identifier for an interrupt controller, the irq_domain
|
||||
* code offers a fwnode allocator.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_IRQDOMAIN_H
|
||||
|
|
@ -34,6 +31,7 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
#include <linux/irqhandler.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/radix-tree.h>
|
||||
|
||||
struct device_node;
|
||||
|
|
@ -45,6 +43,24 @@ struct irq_data;
|
|||
/* Number of irqs reserved for a legacy isa controller */
|
||||
#define NUM_ISA_INTERRUPTS 16
|
||||
|
||||
#define IRQ_DOMAIN_IRQ_SPEC_PARAMS 16
|
||||
|
||||
/**
|
||||
* struct irq_fwspec - generic IRQ specifier structure
|
||||
*
|
||||
* @fwnode: Pointer to a firmware-specific descriptor
|
||||
* @param_count: Number of device-specific parameters
|
||||
* @param: Device-specific parameters
|
||||
*
|
||||
* This structure, directly modeled after of_phandle_args, is used to
|
||||
* pass a device-specific description of an interrupt.
|
||||
*/
|
||||
struct irq_fwspec {
|
||||
struct fwnode_handle *fwnode;
|
||||
int param_count;
|
||||
u32 param[IRQ_DOMAIN_IRQ_SPEC_PARAMS];
|
||||
};
|
||||
|
||||
/*
|
||||
* Should several domains have the same device node, but serve
|
||||
* different purposes (for example one domain is for PCI/MSI, and the
|
||||
|
|
@ -91,6 +107,8 @@ struct irq_domain_ops {
|
|||
unsigned int nr_irqs);
|
||||
void (*activate)(struct irq_domain *d, struct irq_data *irq_data);
|
||||
void (*deactivate)(struct irq_domain *d, struct irq_data *irq_data);
|
||||
int (*translate)(struct irq_domain *d, struct irq_fwspec *fwspec,
|
||||
unsigned long *out_hwirq, unsigned int *out_type);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -130,7 +148,7 @@ struct irq_domain {
|
|||
unsigned int flags;
|
||||
|
||||
/* Optional data */
|
||||
struct device_node *of_node;
|
||||
struct fwnode_handle *fwnode;
|
||||
enum irq_domain_bus_token bus_token;
|
||||
struct irq_domain_chip_generic *gc;
|
||||
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
|
||||
|
|
@ -163,11 +181,13 @@ enum {
|
|||
|
||||
static inline struct device_node *irq_domain_get_of_node(struct irq_domain *d)
|
||||
{
|
||||
return d->of_node;
|
||||
return to_of_node(d->fwnode);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IRQ_DOMAIN
|
||||
struct irq_domain *__irq_domain_add(struct device_node *of_node, int size,
|
||||
struct fwnode_handle *irq_domain_alloc_fwnode(void *data);
|
||||
void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
|
||||
struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
|
||||
irq_hw_number_t hwirq_max, int direct_max,
|
||||
const struct irq_domain_ops *ops,
|
||||
void *host_data);
|
||||
|
|
@ -182,10 +202,21 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
|
|||
irq_hw_number_t first_hwirq,
|
||||
const struct irq_domain_ops *ops,
|
||||
void *host_data);
|
||||
extern struct irq_domain *irq_find_matching_host(struct device_node *node,
|
||||
enum irq_domain_bus_token bus_token);
|
||||
extern struct irq_domain *irq_find_matching_fwnode(struct fwnode_handle *fwnode,
|
||||
enum irq_domain_bus_token bus_token);
|
||||
extern void irq_set_default_host(struct irq_domain *host);
|
||||
|
||||
static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
|
||||
{
|
||||
return node ? &node->fwnode : NULL;
|
||||
}
|
||||
|
||||
static inline struct irq_domain *irq_find_matching_host(struct device_node *node,
|
||||
enum irq_domain_bus_token bus_token)
|
||||
{
|
||||
return irq_find_matching_fwnode(of_node_to_fwnode(node), bus_token);
|
||||
}
|
||||
|
||||
static inline struct irq_domain *irq_find_host(struct device_node *node)
|
||||
{
|
||||
return irq_find_matching_host(node, DOMAIN_BUS_ANY);
|
||||
|
|
@ -203,14 +234,14 @@ static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_no
|
|||
const struct irq_domain_ops *ops,
|
||||
void *host_data)
|
||||
{
|
||||
return __irq_domain_add(of_node, size, size, 0, ops, host_data);
|
||||
return __irq_domain_add(of_node_to_fwnode(of_node), size, size, 0, ops, host_data);
|
||||
}
|
||||
static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
|
||||
unsigned int max_irq,
|
||||
const struct irq_domain_ops *ops,
|
||||
void *host_data)
|
||||
{
|
||||
return __irq_domain_add(of_node, 0, max_irq, max_irq, ops, host_data);
|
||||
return __irq_domain_add(of_node_to_fwnode(of_node), 0, max_irq, max_irq, ops, host_data);
|
||||
}
|
||||
static inline struct irq_domain *irq_domain_add_legacy_isa(
|
||||
struct device_node *of_node,
|
||||
|
|
@ -224,7 +255,22 @@ static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node
|
|||
const struct irq_domain_ops *ops,
|
||||
void *host_data)
|
||||
{
|
||||
return __irq_domain_add(of_node, 0, ~0, 0, ops, host_data);
|
||||
return __irq_domain_add(of_node_to_fwnode(of_node), 0, ~0, 0, ops, host_data);
|
||||
}
|
||||
|
||||
static inline struct irq_domain *irq_domain_create_linear(struct fwnode_handle *fwnode,
|
||||
unsigned int size,
|
||||
const struct irq_domain_ops *ops,
|
||||
void *host_data)
|
||||
{
|
||||
return __irq_domain_add(fwnode, size, size, 0, ops, host_data);
|
||||
}
|
||||
|
||||
static inline struct irq_domain *irq_domain_create_tree(struct fwnode_handle *fwnode,
|
||||
const struct irq_domain_ops *ops,
|
||||
void *host_data)
|
||||
{
|
||||
return __irq_domain_add(fwnode, 0, ~0, 0, ops, host_data);
|
||||
}
|
||||
|
||||
extern void irq_domain_remove(struct irq_domain *host);
|
||||
|
|
@ -239,6 +285,7 @@ extern void irq_domain_disassociate(struct irq_domain *domain,
|
|||
|
||||
extern unsigned int irq_create_mapping(struct irq_domain *host,
|
||||
irq_hw_number_t hwirq);
|
||||
extern unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec);
|
||||
extern void irq_dispose_mapping(unsigned int virq);
|
||||
|
||||
/**
|
||||
|
|
@ -290,10 +337,23 @@ extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
|
|||
void *chip_data, irq_flow_handler_t handler,
|
||||
void *handler_data, const char *handler_name);
|
||||
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
|
||||
extern struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent,
|
||||
extern struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
|
||||
unsigned int flags, unsigned int size,
|
||||
struct device_node *node,
|
||||
struct fwnode_handle *fwnode,
|
||||
const struct irq_domain_ops *ops, void *host_data);
|
||||
|
||||
static inline struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent,
|
||||
unsigned int flags,
|
||||
unsigned int size,
|
||||
struct device_node *node,
|
||||
const struct irq_domain_ops *ops,
|
||||
void *host_data)
|
||||
{
|
||||
return irq_domain_create_hierarchy(parent, flags, size,
|
||||
of_node_to_fwnode(node),
|
||||
ops, host_data);
|
||||
}
|
||||
|
||||
extern int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
|
||||
unsigned int nr_irqs, int node, void *arg,
|
||||
bool realloc);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
/**
|
||||
* enum irqreturn
|
||||
* @IRQ_NONE interrupt was not from this device
|
||||
* @IRQ_NONE interrupt was not from this device or was not handled
|
||||
* @IRQ_HANDLED interrupt was handled by this device
|
||||
* @IRQ_WAKE_THREAD handler requests to wake the handler thread
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ struct msi_controller {
|
|||
struct irq_domain;
|
||||
struct irq_chip;
|
||||
struct device_node;
|
||||
struct fwnode_handle;
|
||||
struct msi_domain_info;
|
||||
|
||||
/**
|
||||
|
|
@ -262,7 +263,7 @@ enum {
|
|||
int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,
|
||||
bool force);
|
||||
|
||||
struct irq_domain *msi_create_irq_domain(struct device_node *of_node,
|
||||
struct irq_domain *msi_create_irq_domain(struct fwnode_handle *fwnode,
|
||||
struct msi_domain_info *info,
|
||||
struct irq_domain *parent);
|
||||
int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
|
||||
|
|
@ -270,7 +271,7 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
|
|||
void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev);
|
||||
struct msi_domain_info *msi_get_domain_info(struct irq_domain *domain);
|
||||
|
||||
struct irq_domain *platform_msi_create_irq_domain(struct device_node *np,
|
||||
struct irq_domain *platform_msi_create_irq_domain(struct fwnode_handle *fwnode,
|
||||
struct msi_domain_info *info,
|
||||
struct irq_domain *parent);
|
||||
int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,
|
||||
|
|
@ -280,19 +281,26 @@ void platform_msi_domain_free_irqs(struct device *dev);
|
|||
|
||||
#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
|
||||
void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg);
|
||||
struct irq_domain *pci_msi_create_irq_domain(struct device_node *node,
|
||||
struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode,
|
||||
struct msi_domain_info *info,
|
||||
struct irq_domain *parent);
|
||||
int pci_msi_domain_alloc_irqs(struct irq_domain *domain, struct pci_dev *dev,
|
||||
int nvec, int type);
|
||||
void pci_msi_domain_free_irqs(struct irq_domain *domain, struct pci_dev *dev);
|
||||
struct irq_domain *pci_msi_create_default_irq_domain(struct device_node *node,
|
||||
struct irq_domain *pci_msi_create_default_irq_domain(struct fwnode_handle *fwnode,
|
||||
struct msi_domain_info *info, struct irq_domain *parent);
|
||||
|
||||
irq_hw_number_t pci_msi_domain_calc_hwirq(struct pci_dev *dev,
|
||||
struct msi_desc *desc);
|
||||
int pci_msi_domain_check_cap(struct irq_domain *domain,
|
||||
struct msi_domain_info *info, struct device *dev);
|
||||
u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev);
|
||||
struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev);
|
||||
#else
|
||||
static inline struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */
|
||||
|
||||
#endif /* LINUX_MSI_H */
|
||||
|
|
|
|||
|
|
@ -46,6 +46,11 @@ extern int of_irq_get(struct device_node *dev, int index);
|
|||
extern int of_irq_get_byname(struct device_node *dev, const char *name);
|
||||
extern int of_irq_to_resource_table(struct device_node *dev,
|
||||
struct resource *res, int nr_irqs);
|
||||
extern struct irq_domain *of_msi_get_domain(struct device *dev,
|
||||
struct device_node *np,
|
||||
enum irq_domain_bus_token token);
|
||||
extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
|
||||
u32 rid);
|
||||
#else
|
||||
static inline int of_irq_count(struct device_node *dev)
|
||||
{
|
||||
|
|
@ -64,6 +69,17 @@ static inline int of_irq_to_resource_table(struct device_node *dev,
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
static inline struct irq_domain *of_msi_get_domain(struct device *dev,
|
||||
struct device_node *np,
|
||||
enum irq_domain_bus_token token)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
|
||||
u32 rid)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
|
|
@ -75,6 +91,7 @@ static inline int of_irq_to_resource_table(struct device_node *dev,
|
|||
extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
|
||||
extern struct device_node *of_irq_find_parent(struct device_node *child);
|
||||
extern void of_msi_configure(struct device *dev, struct device_node *np);
|
||||
u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in);
|
||||
|
||||
#else /* !CONFIG_OF */
|
||||
static inline unsigned int irq_of_parse_and_map(struct device_node *dev,
|
||||
|
|
@ -87,6 +104,12 @@ static inline void *of_irq_find_parent(struct device_node *child)
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline u32 of_msi_map_rid(struct device *dev,
|
||||
struct device_node *msi_np, u32 rid_in)
|
||||
{
|
||||
return rid_in;
|
||||
}
|
||||
#endif /* !CONFIG_OF */
|
||||
|
||||
#endif /* __OF_IRQ_H */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue