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

Commit b4963255 authored by Milton Miller's avatar Milton Miller Committed by Benjamin Herrenschmidt
Browse files

powerpc/xics: Factor out cpu joining/unjoining the GIQ



This factors out processors joining and unjoining the Global Interrupt
Queue into a separate function.

There is a bit of math to calculate the arguments to rtas to join
or leave the global interrupt queue, and a warning on failure
afterwards.  Make a helper for the 3 callers.

Signed-off-by: default avatarMilton Miller <miltonm@bga.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent a244a957
Loading
Loading
Loading
Loading
+13 −20
Original line number Diff line number Diff line
@@ -727,20 +727,19 @@ static void xics_set_cpu_priority(unsigned char cppr)
	iosync();
}

/* Have the calling processor join or leave the specified global queue */
static void xics_set_cpu_giq(unsigned int gserver, unsigned int join)
{
	int status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
		(1UL << interrupt_server_size) - 1 - gserver, join);
	WARN_ON(status < 0);
}

void xics_setup_cpu(void)
{
	xics_set_cpu_priority(0xff);

	/*
	 * Put the calling processor into the GIQ.  This is really only
	 * necessary from a secondary thread as the OF start-cpu interface
	 * performs this function for us on primary threads.
	 *
	 * XXX: undo of teardown on kexec needs this too, as may hotplug
	 */
	rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
		(1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
	xics_set_cpu_giq(default_distrib_server, 1);
}

void xics_teardown_cpu(void)
@@ -749,9 +748,7 @@ void xics_teardown_cpu(void)

	xics_set_cpu_priority(0);

	/*
	 * Clear IPI
	 */
	/* Clear any pending IPI request */
	if (firmware_has_feature(FW_FEATURE_LPAR))
		lpar_qirr_info(cpu, 0xff);
	else
@@ -785,9 +782,7 @@ void xics_kexec_teardown_cpu(int secondary)
	 * so leave the master cpu in the group.
	 */
	if (secondary)
		rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
				   (1UL << interrupt_server_size) - 1 -
				   default_distrib_server, 0);
		xics_set_cpu_giq(default_distrib_server, 0);
}

#ifdef CONFIG_HOTPLUG_CPU
@@ -795,7 +790,6 @@ void xics_kexec_teardown_cpu(int secondary)
/* Interrupts are disabled. */
void xics_migrate_irqs_away(void)
{
	int status;
	int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
	unsigned int irq, virq;

@@ -806,10 +800,8 @@ void xics_migrate_irqs_away(void)
	/* Reject any interrupt that was queued to us... */
	xics_set_cpu_priority(0);

	/* remove ourselves from the global interrupt queue */
	status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
		(1UL << interrupt_server_size) - 1 - default_distrib_server, 0);
	WARN_ON(status < 0);
	/* Remove ourselves from the global interrupt queue */
	xics_set_cpu_giq(default_distrib_server, 0);

	/* Allow IPIs again... */
	xics_set_cpu_priority(DEFAULT_PRIORITY);
@@ -817,6 +809,7 @@ void xics_migrate_irqs_away(void)
	for_each_irq(virq) {
		struct irq_desc *desc;
		int xics_status[2];
		int status;
		unsigned long flags;

		/* We cant set affinity on ISA interrupts */