Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe17a42e authored by Marc Zyngier's avatar Marc Zyngier Committed by Thomas Gleixner
Browse files

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: default avatarMarc Zyngier <marc.zyngier@arm.com>
Link: http://lkml.kernel.org/r/20170512115538.10767-2-marc.zyngier@arm.com


Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 08332893
Loading
Loading
Loading
Loading
+43 −25
Original line number Diff line number Diff line
@@ -746,13 +746,54 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
EXPORT_SYMBOL_GPL(irq_find_mapping);

#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)
{
	unsigned long flags;
	struct irq_desc *desc;
	struct irq_domain *domain;
	struct radix_tree_iter iter;
	void *data, **slot;
	void **slot;
	int i;

	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;

		raw_spin_lock_irqsave(&desc->lock, flags);
		domain = desc->irq_data.domain;

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

		virq_debug_show_one(m, desc);
		raw_spin_unlock_irqrestore(&desc->lock, flags);
	}