Skip to content

Commit

Permalink
Merge tag 'irq-core-2025-03-23' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/tip/tip

Pull irq updates from Thomas Gleixner:
 "A small set of core changes for the interrupt subsystem:

   - Expose the MSI message in the existing debug filesystem dump.
     That's useful for validation and debugging.

   - Small cleanups"

* tag 'irq-core-2025-03-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  genirq: Make a few functions static
  irqdomain: Remove extern from function declarations
  genirq/msi: Expose MSI message data in debugfs
  • Loading branch information
Linus Torvalds committed Mar 25, 2025
2 parents 2df0c02 + 827bafd commit 43a7eec
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 100 deletions.
137 changes: 68 additions & 69 deletions include/linux/irqdomain.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,13 +350,13 @@ struct irq_domain *irq_domain_create_legacy(struct fwnode_handle *fwnode,
irq_hw_number_t first_hwirq,
const struct irq_domain_ops *ops,
void *host_data);
extern struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
enum irq_domain_bus_token bus_token);
extern void irq_set_default_host(struct irq_domain *host);
extern struct irq_domain *irq_get_default_host(void);
extern int irq_domain_alloc_descs(int virq, unsigned int nr_irqs,
irq_hw_number_t hwirq, int node,
const struct irq_affinity_desc *affinity);
struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
enum irq_domain_bus_token bus_token);
void irq_set_default_host(struct irq_domain *host);
struct irq_domain *irq_get_default_host(void);
int irq_domain_alloc_descs(int virq, unsigned int nr_irqs,
irq_hw_number_t hwirq, int node,
const struct irq_affinity_desc *affinity);

static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
{
Expand All @@ -370,8 +370,8 @@ static inline bool is_fwnode_irqchip(const struct fwnode_handle *fwnode)
return fwnode && fwnode->ops == &irqchip_fwnode_ops;
}

extern void irq_domain_update_bus_token(struct irq_domain *domain,
enum irq_domain_bus_token bus_token);
void irq_domain_update_bus_token(struct irq_domain *domain,
enum irq_domain_bus_token bus_token);

static inline
struct irq_domain *irq_find_matching_fwnode(struct fwnode_handle *fwnode,
Expand Down Expand Up @@ -454,7 +454,7 @@ static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_nod
return IS_ERR(d) ? NULL : d;
}

extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
unsigned int irq_create_direct_mapping(struct irq_domain *host);
#endif

static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
Expand Down Expand Up @@ -507,29 +507,29 @@ static inline struct irq_domain *irq_domain_create_tree(struct fwnode_handle *fw
return IS_ERR(d) ? NULL : d;
}

extern void irq_domain_remove(struct irq_domain *host);
void irq_domain_remove(struct irq_domain *host);

extern int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
irq_hw_number_t hwirq);
extern void irq_domain_associate_many(struct irq_domain *domain,
unsigned int irq_base,
irq_hw_number_t hwirq_base, int count);
int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
irq_hw_number_t hwirq);
void irq_domain_associate_many(struct irq_domain *domain,
unsigned int irq_base,
irq_hw_number_t hwirq_base, int count);

extern unsigned int irq_create_mapping_affinity(struct irq_domain *host,
irq_hw_number_t hwirq,
const struct irq_affinity_desc *affinity);
extern unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec);
extern void irq_dispose_mapping(unsigned int virq);
unsigned int irq_create_mapping_affinity(struct irq_domain *host,
irq_hw_number_t hwirq,
const struct irq_affinity_desc *affinity);
unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec);
void irq_dispose_mapping(unsigned int virq);

static inline unsigned int irq_create_mapping(struct irq_domain *host,
irq_hw_number_t hwirq)
{
return irq_create_mapping_affinity(host, hwirq, NULL);
}

extern struct irq_desc *__irq_resolve_mapping(struct irq_domain *domain,
irq_hw_number_t hwirq,
unsigned int *irq);
struct irq_desc *__irq_resolve_mapping(struct irq_domain *domain,
irq_hw_number_t hwirq,
unsigned int *irq);

static inline struct irq_desc *irq_resolve_mapping(struct irq_domain *domain,
irq_hw_number_t hwirq)
Expand Down Expand Up @@ -587,19 +587,21 @@ int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);

/* V2 interfaces to support hierarchy IRQ domains. */
extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
unsigned int virq);
extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
irq_hw_number_t hwirq,
const struct irq_chip *chip,
void *chip_data, irq_flow_handler_t handler,
void *handler_data, const char *handler_name);
extern void irq_domain_reset_irq_data(struct irq_data *irq_data);
struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
unsigned int virq);
void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
irq_hw_number_t hwirq,
const struct irq_chip *chip,
void *chip_data, irq_flow_handler_t handler,
void *handler_data, const char *handler_name);
void irq_domain_reset_irq_data(struct irq_data *irq_data);
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
extern struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
unsigned int flags, unsigned int size,
struct fwnode_handle *fwnode,
const struct irq_domain_ops *ops, void *host_data);
struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
unsigned int flags,
unsigned int size,
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,
Expand All @@ -613,13 +615,13 @@ static inline struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *par
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,
const struct irq_affinity_desc *affinity);
extern void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs);
extern int irq_domain_activate_irq(struct irq_data *irq_data, bool early);
extern void irq_domain_deactivate_irq(struct irq_data *irq_data);
int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
unsigned int nr_irqs, int node, void *arg,
bool realloc,
const struct irq_affinity_desc *affinity);
void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs);
int irq_domain_activate_irq(struct irq_data *irq_data, bool early);
void irq_domain_deactivate_irq(struct irq_data *irq_data);

static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
unsigned int nr_irqs, int node, void *arg)
Expand All @@ -628,32 +630,29 @@ static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
NULL);
}

extern int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain,
unsigned int irq_base,
unsigned int nr_irqs, void *arg);
extern int irq_domain_set_hwirq_and_chip(struct irq_domain *domain,
unsigned int virq,
irq_hw_number_t hwirq,
const struct irq_chip *chip,
void *chip_data);
extern void irq_domain_free_irqs_common(struct irq_domain *domain,
unsigned int virq,
unsigned int nr_irqs);
extern void irq_domain_free_irqs_top(struct irq_domain *domain,
unsigned int virq, unsigned int nr_irqs);

extern int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg);
extern int irq_domain_pop_irq(struct irq_domain *domain, int virq);

extern int irq_domain_alloc_irqs_parent(struct irq_domain *domain,
unsigned int irq_base,
unsigned int nr_irqs, void *arg);

extern void irq_domain_free_irqs_parent(struct irq_domain *domain,
unsigned int irq_base,
unsigned int nr_irqs);

extern int irq_domain_disconnect_hierarchy(struct irq_domain *domain,
int irq_domain_set_hwirq_and_chip(struct irq_domain *domain,
unsigned int virq,
irq_hw_number_t hwirq,
const struct irq_chip *chip,
void *chip_data);
void irq_domain_free_irqs_common(struct irq_domain *domain,
unsigned int virq,
unsigned int nr_irqs);
void irq_domain_free_irqs_top(struct irq_domain *domain,
unsigned int virq, unsigned int nr_irqs);

int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg);
int irq_domain_pop_irq(struct irq_domain *domain, int virq);

int irq_domain_alloc_irqs_parent(struct irq_domain *domain,
unsigned int irq_base,
unsigned int nr_irqs, void *arg);

void irq_domain_free_irqs_parent(struct irq_domain *domain,
unsigned int irq_base,
unsigned int nr_irqs);

int irq_domain_disconnect_hierarchy(struct irq_domain *domain,
unsigned int virq);

static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
Expand Down
30 changes: 15 additions & 15 deletions kernel/irq/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,21 @@ __irq_startup_managed(struct irq_desc *desc, const struct cpumask *aff,
}
#endif

static void irq_enable(struct irq_desc *desc)
{
if (!irqd_irq_disabled(&desc->irq_data)) {
unmask_irq(desc);
} else {
irq_state_clr_disabled(desc);
if (desc->irq_data.chip->irq_enable) {
desc->irq_data.chip->irq_enable(&desc->irq_data);
irq_state_clr_masked(desc);
} else {
unmask_irq(desc);
}
}
}

static int __irq_startup(struct irq_desc *desc)
{
struct irq_data *d = irq_desc_get_irq_data(desc);
Expand Down Expand Up @@ -332,21 +347,6 @@ void irq_shutdown_and_deactivate(struct irq_desc *desc)
irq_domain_deactivate_irq(&desc->irq_data);
}

void irq_enable(struct irq_desc *desc)
{
if (!irqd_irq_disabled(&desc->irq_data)) {
unmask_irq(desc);
} else {
irq_state_clr_disabled(desc);
if (desc->irq_data.chip->irq_enable) {
desc->irq_data.chip->irq_enable(&desc->irq_data);
irq_state_clr_masked(desc);
} else {
unmask_irq(desc);
}
}
}

static void __irq_disable(struct irq_desc *desc, bool mask)
{
if (irqd_irq_disabled(&desc->irq_data)) {
Expand Down
9 changes: 0 additions & 9 deletions kernel/irq/internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,26 +90,19 @@ extern int irq_startup(struct irq_desc *desc, bool resend, bool force);

extern void irq_shutdown(struct irq_desc *desc);
extern void irq_shutdown_and_deactivate(struct irq_desc *desc);
extern void irq_enable(struct irq_desc *desc);
extern void irq_disable(struct irq_desc *desc);
extern void irq_percpu_enable(struct irq_desc *desc, unsigned int cpu);
extern void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu);
extern void mask_irq(struct irq_desc *desc);
extern void unmask_irq(struct irq_desc *desc);
extern void unmask_threaded_irq(struct irq_desc *desc);

extern unsigned int kstat_irqs_desc(struct irq_desc *desc, const struct cpumask *cpumask);

#ifdef CONFIG_SPARSE_IRQ
static inline void irq_mark_irq(unsigned int irq) { }
#else
extern void irq_mark_irq(unsigned int irq);
#endif

extern int __irq_get_irqchip_state(struct irq_data *data,
enum irqchip_irq_state which,
bool *state);

irqreturn_t __handle_irq_event_percpu(struct irq_desc *desc);
irqreturn_t handle_irq_event_percpu(struct irq_desc *desc);
irqreturn_t handle_irq_event(struct irq_desc *desc);
Expand Down Expand Up @@ -139,8 +132,6 @@ static inline void unregister_handler_proc(unsigned int irq,

extern bool irq_can_set_affinity_usr(unsigned int irq);

extern void irq_set_thread_affinity(struct irq_desc *desc);

extern int irq_do_set_affinity(struct irq_data *data,
const struct cpumask *dest, bool force);

Expand Down
2 changes: 1 addition & 1 deletion kernel/irq/irqdesc.c
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,7 @@ unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
return desc && desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, cpu) : 0;
}

unsigned int kstat_irqs_desc(struct irq_desc *desc, const struct cpumask *cpumask)
static unsigned int kstat_irqs_desc(struct irq_desc *desc, const struct cpumask *cpumask)
{
unsigned int sum = 0;
int cpu;
Expand Down
5 changes: 2 additions & 3 deletions kernel/irq/irqdomain.c
Original file line number Diff line number Diff line change
Expand Up @@ -1589,9 +1589,8 @@ static void irq_domain_free_irqs_hierarchy(struct irq_domain *domain,
}
}

int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain,
unsigned int irq_base,
unsigned int nr_irqs, void *arg)
static int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain, unsigned int irq_base,
unsigned int nr_irqs, void *arg)
{
if (!domain->ops->alloc) {
pr_debug("domain->ops->alloc() is NULL\n");
Expand Down
7 changes: 4 additions & 3 deletions kernel/irq/manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ static int __init setup_forced_irqthreads(char *arg)
early_param("threadirqs", setup_forced_irqthreads);
#endif

static int __irq_get_irqchip_state(struct irq_data *d, enum irqchip_irq_state which, bool *state);

static void __synchronize_hardirq(struct irq_desc *desc, bool sync_chip)
{
struct irq_data *irqd = irq_desc_get_irq_data(desc);
Expand Down Expand Up @@ -187,7 +189,7 @@ bool irq_can_set_affinity_usr(unsigned int irq)
* set_cpus_allowed_ptr() here as we hold desc->lock and this
* code can be called from hard interrupt context.
*/
void irq_set_thread_affinity(struct irq_desc *desc)
static void irq_set_thread_affinity(struct irq_desc *desc)
{
struct irqaction *action;

Expand Down Expand Up @@ -2789,8 +2791,7 @@ void teardown_percpu_nmi(unsigned int irq)
irq_put_desc_unlock(desc, flags);
}

int __irq_get_irqchip_state(struct irq_data *data, enum irqchip_irq_state which,
bool *state)
static int __irq_get_irqchip_state(struct irq_data *data, enum irqchip_irq_state which, bool *state)
{
struct irq_chip *chip;
int err = -EINVAL;
Expand Down
19 changes: 19 additions & 0 deletions kernel/irq/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/mutex.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/sysfs.h>
#include <linux/types.h>
#include <linux/xarray.h>
Expand Down Expand Up @@ -756,12 +757,30 @@ static int msi_domain_translate(struct irq_domain *domain, struct irq_fwspec *fw
return info->ops->msi_translate(domain, fwspec, hwirq, type);
}

#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
static void msi_domain_debug_show(struct seq_file *m, struct irq_domain *d,
struct irq_data *irqd, int ind)
{
struct msi_desc *desc = irq_data_get_msi_desc(irqd);

if (!desc)
return;

seq_printf(m, "\n%*saddress_hi: 0x%08x", ind + 1, "", desc->msg.address_hi);
seq_printf(m, "\n%*saddress_lo: 0x%08x", ind + 1, "", desc->msg.address_lo);
seq_printf(m, "\n%*smsg_data: 0x%08x\n", ind + 1, "", desc->msg.data);
}
#endif

static const struct irq_domain_ops msi_domain_ops = {
.alloc = msi_domain_alloc,
.free = msi_domain_free,
.activate = msi_domain_activate,
.deactivate = msi_domain_deactivate,
.translate = msi_domain_translate,
#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
.debug_show = msi_domain_debug_show,
#endif
};

static irq_hw_number_t msi_domain_ops_get_hwirq(struct msi_domain_info *info,
Expand Down

0 comments on commit 43a7eec

Please sign in to comment.