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

Commit 9ba6c38e authored by Balbir Singh's avatar Balbir Singh Committed by android-build-merger
Browse files

powerpc/xics: Work around limitations of OPAL XICS priority handling

am: 1ced52ea

Change-Id: I30f63b7a7acaec17a4207821bbee8e94ff45aa87
parents 182cdba4 1ced52ea
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -91,6 +91,16 @@ static unsigned int icp_opal_get_irq(void)

static void icp_opal_set_cpu_priority(unsigned char cppr)
{
	/*
	 * Here be dragons. The caller has asked to allow only IPI's and not
	 * external interrupts. But OPAL XIVE doesn't support that. So instead
	 * of allowing no interrupts allow all. That's still not right, but
	 * currently the only caller who does this is xics_migrate_irqs_away()
	 * and it works in that case.
	 */
	if (cppr >= DEFAULT_PRIORITY)
		cppr = LOWEST_PRIORITY;

	xics_set_base_cppr(cppr);
	opal_int_set_cppr(cppr);
	iosync();
+14 −3
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/delay.h>

#include <asm/prom.h>
#include <asm/io.h>
@@ -198,9 +199,6 @@ void xics_migrate_irqs_away(void)
	/* Remove ourselves from the global interrupt queue */
	xics_set_cpu_giq(xics_default_distrib_server, 0);

	/* Allow IPIs again... */
	icp_ops->set_priority(DEFAULT_PRIORITY);

	for_each_irq_desc(virq, desc) {
		struct irq_chip *chip;
		long server;
@@ -255,6 +253,19 @@ void xics_migrate_irqs_away(void)
unlock:
		raw_spin_unlock_irqrestore(&desc->lock, flags);
	}

	/* Allow "sufficient" time to drop any inflight IRQ's */
	mdelay(5);

	/*
	 * Allow IPIs again. This is done at the very end, after migrating all
	 * interrupts, the expectation is that we'll only get woken up by an IPI
	 * interrupt beyond this point, but leave externals masked just to be
	 * safe. If we're using icp-opal this may actually allow all
	 * interrupts anyway, but that should be OK.
	 */
	icp_ops->set_priority(DEFAULT_PRIORITY);

}
#endif /* CONFIG_HOTPLUG_CPU */