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:
Linus Torvalds 2015-11-03 14:40:01 -08:00
commit 6aa2fdb87c
90 changed files with 2577 additions and 890 deletions

View file

@ -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

View file

@ -17,6 +17,7 @@ enum fwnode_type {
FWNODE_OF,
FWNODE_ACPI,
FWNODE_PDATA,
FWNODE_IRQCHIP,
};
struct fwnode_handle {

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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
*/

View file

@ -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 */

View file

@ -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 */