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

Commit 63b746b1 authored by Paul Burton's avatar Paul Burton Committed by Marc Zyngier
Browse files

irqchip: mips-gic: Inline gic_local_irq_domain_map()



The gic_local_irq_domain_map() function has only one callsite in
gic_irq_domain_map(), and the split between the two functions makes it
unclear that they duplicate calculations & checks.

Inline gic_local_irq_domain_map() into gic_irq_domain_map() in order to
clean this up. Doing this makes the following small issues obvious, and
the patch tidies them up:

 - Both functions used GIC_HWIRQ_TO_LOCAL() to convert a hwirq number to
   a local IRQ number. We now only do this once. Although the compiler
   ought to have optimised this away before anyway, the change leaves us
   with less duplicate code.

 - gic_local_irq_domain_map() had a check for invalid local interrupt
   numbers (intr > GIC_LOCAL_INT_FDC). This condition can never occur
   because any hwirq higher than those used for local interrupts is a
   shared interrupt, which gic_irq_domain_map() already handles
   separately. We therefore remove this check.

 - The decision of whether to map the interrupt to gic_cpu_pin or
   timer_cpu_pin can be handled within the existing switch statement in
   gic_irq_domain_map(), shortening the code a little.

The change additionally prepares us nicely for the following patch of
the series which would otherwise need to duplicate the check for whether
a local interrupt should be percpu_devid or just percpu (ie. the switch
statement from gic_irq_domain_map()) in gic_local_irq_domain_map().

Signed-off-by: default avatarPaul Burton <paul.burton@mips.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent 4e4cb1b1
Loading
Loading
Loading
Loading
+22 −36
Original line number Original line Diff line number Diff line
@@ -382,39 +382,6 @@ static void gic_irq_dispatch(struct irq_desc *desc)
	gic_handle_shared_int(true);
	gic_handle_shared_int(true);
}
}


static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
				    irq_hw_number_t hw)
{
	int intr = GIC_HWIRQ_TO_LOCAL(hw);
	int i;
	unsigned long flags;
	u32 val;

	if (!gic_local_irq_is_routable(intr))
		return -EPERM;

	if (intr > GIC_LOCAL_INT_FDC) {
		pr_err("Invalid local IRQ %d\n", intr);
		return -EINVAL;
	}

	if (intr == GIC_LOCAL_INT_TIMER) {
		/* CONFIG_MIPS_CMP workaround (see __gic_init) */
		val = GIC_MAP_PIN_MAP_TO_PIN | timer_cpu_pin;
	} else {
		val = GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin;
	}

	spin_lock_irqsave(&gic_lock, flags);
	for (i = 0; i < gic_vpes; i++) {
		write_gic_vl_other(mips_cm_vp_id(i));
		write_gic_vo_map(intr, val);
	}
	spin_unlock_irqrestore(&gic_lock, flags);

	return 0;
}

static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
				     irq_hw_number_t hw, unsigned int cpu)
				     irq_hw_number_t hw, unsigned int cpu)
{
{
@@ -457,7 +424,10 @@ static int gic_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
			      irq_hw_number_t hwirq)
			      irq_hw_number_t hwirq)
{
{
	int err;
	unsigned long flags;
	unsigned int intr;
	int err, i;
	u32 map;


	if (hwirq >= GIC_SHARED_HWIRQ_BASE) {
	if (hwirq >= GIC_SHARED_HWIRQ_BASE) {
		/* verify that shared irqs don't conflict with an IPI irq */
		/* verify that shared irqs don't conflict with an IPI irq */
@@ -474,8 +444,14 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
		return gic_shared_irq_domain_map(d, virq, hwirq, 0);
		return gic_shared_irq_domain_map(d, virq, hwirq, 0);
	}
	}


	switch (GIC_HWIRQ_TO_LOCAL(hwirq)) {
	intr = GIC_HWIRQ_TO_LOCAL(hwirq);
	map = GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin;

	switch (intr) {
	case GIC_LOCAL_INT_TIMER:
	case GIC_LOCAL_INT_TIMER:
		/* CONFIG_MIPS_CMP workaround (see __gic_init) */
		map = GIC_MAP_PIN_MAP_TO_PIN | timer_cpu_pin;
		/* fall-through */
	case GIC_LOCAL_INT_PERFCTR:
	case GIC_LOCAL_INT_PERFCTR:
	case GIC_LOCAL_INT_FDC:
	case GIC_LOCAL_INT_FDC:
		/*
		/*
@@ -504,7 +480,17 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
		break;
		break;
	}
	}


	return gic_local_irq_domain_map(d, virq, hwirq);
	if (!gic_local_irq_is_routable(intr))
		return -EPERM;

	spin_lock_irqsave(&gic_lock, flags);
	for (i = 0; i < gic_vpes; i++) {
		write_gic_vl_other(mips_cm_vp_id(i));
		write_gic_vo_map(intr, map);
	}
	spin_unlock_irqrestore(&gic_lock, flags);

	return 0;
}
}


static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq,
static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq,