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

Commit a08588ea authored by Paul Burton's avatar Paul Burton Committed by Thomas Gleixner
Browse files

irqchip/mips-gic: Fix shifts to extract register fields



The MIPS GIC driver is incorrectly using __fls to shift registers,
intending to shift to the least significant bit of a value based upon
its mask but instead shifting off all but the value's top bit. It should
actually be using __ffs to shift to the first, not last, bit of the
value.

Apparently the system I used when testing commit 3680746a
("irqchip: mips-gic: Convert remaining shared reg access to new
accessors") and commit b2b2e584 ("irqchip: mips-gic: Clean up mti,
reserved-cpu-vectors handling") managed to work correctly despite this
issue, but not all systems do...

Fixes: 3680746a ("irqchip: mips-gic: Convert remaining shared reg access to new accessors")
Fixes: b2b2e584 ("irqchip: mips-gic: Clean up mti, reserved-cpu-vectors handling")
Signed-off-by: default avatarPaul Burton <paul.burton@imgtec.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Link: https://lkml.kernel.org/r/20170922062440.23701-2-paul.burton@imgtec.com
parent 2827a418
Loading
Loading
Loading
Loading
+3 −3
Original line number Original line Diff line number Diff line
@@ -645,7 +645,7 @@ static int __init gic_of_init(struct device_node *node,


	/* Find the first available CPU vector. */
	/* Find the first available CPU vector. */
	i = 0;
	i = 0;
	reserved = (C_SW0 | C_SW1) >> __fls(C_SW0);
	reserved = (C_SW0 | C_SW1) >> __ffs(C_SW0);
	while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors",
	while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors",
					   i++, &cpu_vec))
					   i++, &cpu_vec))
		reserved |= BIT(cpu_vec);
		reserved |= BIT(cpu_vec);
@@ -684,11 +684,11 @@ static int __init gic_of_init(struct device_node *node,


	gicconfig = read_gic_config();
	gicconfig = read_gic_config();
	gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS;
	gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS;
	gic_shared_intrs >>= __fls(GIC_CONFIG_NUMINTERRUPTS);
	gic_shared_intrs >>= __ffs(GIC_CONFIG_NUMINTERRUPTS);
	gic_shared_intrs = (gic_shared_intrs + 1) * 8;
	gic_shared_intrs = (gic_shared_intrs + 1) * 8;


	gic_vpes = gicconfig & GIC_CONFIG_PVPS;
	gic_vpes = gicconfig & GIC_CONFIG_PVPS;
	gic_vpes >>= __fls(GIC_CONFIG_PVPS);
	gic_vpes >>= __ffs(GIC_CONFIG_PVPS);
	gic_vpes = gic_vpes + 1;
	gic_vpes = gic_vpes + 1;


	if (cpu_has_veic) {
	if (cpu_has_veic) {