diff options
author | Paul Burton <paul.burton@imgtec.com> | 2017-09-22 02:24:39 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-09-25 15:23:43 -0400 |
commit | a08588ea486a5590b50c36f437dc86350271b250 (patch) | |
tree | 18db0b04b2255a4e2f40cd3769a028fc966b61b8 | |
parent | 2827a418ca1b23e432e62c9b3d0e7cf3255dfe88 (diff) |
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 3680746abd87
("irqchip: mips-gic: Convert remaining shared reg access to new
accessors") and commit b2b2e584ceab ("irqchip: mips-gic: Clean up mti,
reserved-cpu-vectors handling") managed to work correctly despite this
issue, but not all systems do...
Fixes: 3680746abd87 ("irqchip: mips-gic: Convert remaining shared reg access to new accessors")
Fixes: b2b2e584ceab ("irqchip: mips-gic: Clean up mti, reserved-cpu-vectors handling")
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Signed-off-by: Thomas 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
-rw-r--r-- | drivers/irqchip/irq-mips-gic.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 40159ac12ac8..0022b31ad2c5 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c | |||
@@ -645,7 +645,7 @@ static int __init gic_of_init(struct device_node *node, | |||
645 | 645 | ||
646 | /* Find the first available CPU vector. */ | 646 | /* Find the first available CPU vector. */ |
647 | i = 0; | 647 | i = 0; |
648 | reserved = (C_SW0 | C_SW1) >> __fls(C_SW0); | 648 | reserved = (C_SW0 | C_SW1) >> __ffs(C_SW0); |
649 | while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors", | 649 | while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors", |
650 | i++, &cpu_vec)) | 650 | i++, &cpu_vec)) |
651 | reserved |= BIT(cpu_vec); | 651 | reserved |= BIT(cpu_vec); |
@@ -684,11 +684,11 @@ static int __init gic_of_init(struct device_node *node, | |||
684 | 684 | ||
685 | gicconfig = read_gic_config(); | 685 | gicconfig = read_gic_config(); |
686 | gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS; | 686 | gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS; |
687 | gic_shared_intrs >>= __fls(GIC_CONFIG_NUMINTERRUPTS); | 687 | gic_shared_intrs >>= __ffs(GIC_CONFIG_NUMINTERRUPTS); |
688 | gic_shared_intrs = (gic_shared_intrs + 1) * 8; | 688 | gic_shared_intrs = (gic_shared_intrs + 1) * 8; |
689 | 689 | ||
690 | gic_vpes = gicconfig & GIC_CONFIG_PVPS; | 690 | gic_vpes = gicconfig & GIC_CONFIG_PVPS; |
691 | gic_vpes >>= __fls(GIC_CONFIG_PVPS); | 691 | gic_vpes >>= __ffs(GIC_CONFIG_PVPS); |
692 | gic_vpes = gic_vpes + 1; | 692 | gic_vpes = gic_vpes + 1; |
693 | 693 | ||
694 | if (cpu_has_veic) { | 694 | if (cpu_has_veic) { |