drivers/irqchip: xtensa-mx: fix mask and unmask
authorMax Filippov <jcmvbkbc@gmail.com>
Thu, 24 Jan 2019 22:06:49 +0000 (14:06 -0800)
committerMax Filippov <jcmvbkbc@gmail.com>
Sat, 26 Jan 2019 10:02:15 +0000 (02:02 -0800)
xtensa_irq_mask and xtensa_irq_unmask don't do the right thing when
called for the first two external IRQs. Treat these IRQs as per-CPU
IRQs.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
drivers/irqchip/irq-xtensa-mx.c

index 0bd3fe3..2793333 100644 (file)
@@ -71,14 +71,17 @@ static void xtensa_mx_irq_mask(struct irq_data *d)
        unsigned int mask = 1u << d->hwirq;
 
        if (mask & (XCHAL_INTTYPE_MASK_EXTERN_EDGE |
-                               XCHAL_INTTYPE_MASK_EXTERN_LEVEL)) {
-               set_er(1u << (xtensa_get_ext_irq_no(d->hwirq) -
-                                       HW_IRQ_MX_BASE), MIENG);
-       } else {
-               mask = __this_cpu_read(cached_irq_mask) & ~mask;
-               __this_cpu_write(cached_irq_mask, mask);
-               xtensa_set_sr(mask, intenable);
+                   XCHAL_INTTYPE_MASK_EXTERN_LEVEL)) {
+               unsigned int ext_irq = xtensa_get_ext_irq_no(d->hwirq);
+
+               if (ext_irq >= HW_IRQ_MX_BASE) {
+                       set_er(1u << (ext_irq - HW_IRQ_MX_BASE), MIENG);
+                       return;
+               }
        }
+       mask = __this_cpu_read(cached_irq_mask) & ~mask;
+       __this_cpu_write(cached_irq_mask, mask);
+       xtensa_set_sr(mask, intenable);
 }
 
 static void xtensa_mx_irq_unmask(struct irq_data *d)
@@ -86,14 +89,17 @@ static void xtensa_mx_irq_unmask(struct irq_data *d)
        unsigned int mask = 1u << d->hwirq;
 
        if (mask & (XCHAL_INTTYPE_MASK_EXTERN_EDGE |
-                               XCHAL_INTTYPE_MASK_EXTERN_LEVEL)) {
-               set_er(1u << (xtensa_get_ext_irq_no(d->hwirq) -
-                                       HW_IRQ_MX_BASE), MIENGSET);
-       } else {
-               mask |= __this_cpu_read(cached_irq_mask);
-               __this_cpu_write(cached_irq_mask, mask);
-               xtensa_set_sr(mask, intenable);
+                   XCHAL_INTTYPE_MASK_EXTERN_LEVEL)) {
+               unsigned int ext_irq = xtensa_get_ext_irq_no(d->hwirq);
+
+               if (ext_irq >= HW_IRQ_MX_BASE) {
+                       set_er(1u << (ext_irq - HW_IRQ_MX_BASE), MIENGSET);
+                       return;
+               }
        }
+       mask |= __this_cpu_read(cached_irq_mask);
+       __this_cpu_write(cached_irq_mask, mask);
+       xtensa_set_sr(mask, intenable);
 }
 
 static void xtensa_mx_irq_enable(struct irq_data *d)