irqdomain: Let irq_domain_mapping display hierarchical domains
Hierarchical domains seem to be hard to grasp, and a number of aspiring kernel hackers find them utterly discombobulating. In order to ease their pain, let's make them appear in /sys/kernel/debug/irq_domain_mapping, such as the following: 96 0x81808 MSI 0x (null) RADIX MSI 96+ 0x00063 GICv2m 0xffff8003ee116980 RADIX GICv2m 96+ 0x00063 GICv2 0xffff00000916bfd8 LINEAR GICv2 [output compressed to fit in a commit log] This shows that IRQ96 is implemented by a stack of three domains, the + sign indicating the stacking. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Link: http://lkml.kernel.org/r/20170512115538.10767-2-marc.zyngier@arm.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
committed by
Thomas Gleixner
parent
08332893e3
commit
fe17a42e70
@@ -746,13 +746,54 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
|
|||||||
EXPORT_SYMBOL_GPL(irq_find_mapping);
|
EXPORT_SYMBOL_GPL(irq_find_mapping);
|
||||||
|
|
||||||
#ifdef CONFIG_IRQ_DOMAIN_DEBUG
|
#ifdef CONFIG_IRQ_DOMAIN_DEBUG
|
||||||
|
static void virq_debug_show_one(struct seq_file *m, struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
struct irq_domain *domain;
|
||||||
|
struct irq_data *data;
|
||||||
|
|
||||||
|
domain = desc->irq_data.domain;
|
||||||
|
data = &desc->irq_data;
|
||||||
|
|
||||||
|
while (domain) {
|
||||||
|
unsigned int irq = data->irq;
|
||||||
|
unsigned long hwirq = data->hwirq;
|
||||||
|
struct irq_chip *chip;
|
||||||
|
bool direct;
|
||||||
|
|
||||||
|
if (data == &desc->irq_data)
|
||||||
|
seq_printf(m, "%5d ", irq);
|
||||||
|
else
|
||||||
|
seq_printf(m, "%5d+ ", irq);
|
||||||
|
seq_printf(m, "0x%05lx ", hwirq);
|
||||||
|
|
||||||
|
chip = irq_data_get_irq_chip(data);
|
||||||
|
seq_printf(m, "%-15s ", (chip && chip->name) ? chip->name : "none");
|
||||||
|
|
||||||
|
seq_printf(m, data ? "0x%p " : " %p ",
|
||||||
|
irq_data_get_irq_chip_data(data));
|
||||||
|
|
||||||
|
seq_printf(m, " %c ", (desc->action && desc->action->handler) ? '*' : ' ');
|
||||||
|
direct = (irq == hwirq) && (irq < domain->revmap_direct_max_irq);
|
||||||
|
seq_printf(m, "%6s%-8s ",
|
||||||
|
(hwirq < domain->revmap_size) ? "LINEAR" : "RADIX",
|
||||||
|
direct ? "(DIRECT)" : "");
|
||||||
|
seq_printf(m, "%s\n", domain->name);
|
||||||
|
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
|
||||||
|
domain = domain->parent;
|
||||||
|
data = data->parent_data;
|
||||||
|
#else
|
||||||
|
domain = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int virq_debug_show(struct seq_file *m, void *private)
|
static int virq_debug_show(struct seq_file *m, void *private)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct irq_desc *desc;
|
struct irq_desc *desc;
|
||||||
struct irq_domain *domain;
|
struct irq_domain *domain;
|
||||||
struct radix_tree_iter iter;
|
struct radix_tree_iter iter;
|
||||||
void *data, **slot;
|
void **slot;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
seq_printf(m, " %-16s %-6s %-10s %-10s %s\n",
|
seq_printf(m, " %-16s %-6s %-10s %-10s %s\n",
|
||||||
@@ -782,30 +823,7 @@ static int virq_debug_show(struct seq_file *m, void *private)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&desc->lock, flags);
|
raw_spin_lock_irqsave(&desc->lock, flags);
|
||||||
domain = desc->irq_data.domain;
|
virq_debug_show_one(m, desc);
|
||||||
|
|
||||||
if (domain) {
|
|
||||||
struct irq_chip *chip;
|
|
||||||
int hwirq = desc->irq_data.hwirq;
|
|
||||||
bool direct;
|
|
||||||
|
|
||||||
seq_printf(m, "%5d ", i);
|
|
||||||
seq_printf(m, "0x%05x ", hwirq);
|
|
||||||
|
|
||||||
chip = irq_desc_get_chip(desc);
|
|
||||||
seq_printf(m, "%-15s ", (chip && chip->name) ? chip->name : "none");
|
|
||||||
|
|
||||||
data = irq_desc_get_chip_data(desc);
|
|
||||||
seq_printf(m, data ? "0x%p " : " %p ", data);
|
|
||||||
|
|
||||||
seq_printf(m, " %c ", (desc->action && desc->action->handler) ? '*' : ' ');
|
|
||||||
direct = (i == hwirq) && (i < domain->revmap_direct_max_irq);
|
|
||||||
seq_printf(m, "%6s%-8s ",
|
|
||||||
(hwirq < domain->revmap_size) ? "LINEAR" : "RADIX",
|
|
||||||
direct ? "(DIRECT)" : "");
|
|
||||||
seq_printf(m, "%s\n", desc->irq_data.domain->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&desc->lock, flags);
|
raw_spin_unlock_irqrestore(&desc->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user