]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - rpmsg/rpmsg.git/commitdiff
irqchip/irq-pruss-intc: Fix erroneous channel/host mapping logic
authorSuman Anna <s-anna@ti.com>
Sat, 29 Jun 2019 01:52:09 +0000 (01:52 +0000)
committerSuman Anna <s-anna@ti.com>
Mon, 1 Jul 2019 16:48:05 +0000 (11:48 -0500)
The PRUSS INTC uses two-levels of many-to-one mappings to route various
PRU System Events to a limited number of output interrupt lines connected
to various processors on the SoC. This event mapping configuration logic
is optimized to program the associated Channel Map Registers (CMRx) and
Host Interrupt Map Registers (HMRx) only when a new program is being
loaded/started and simply disables the same events and interrupt channels
without zeroing out the corresponding map registers when stopping a PRU.

The map logic currently does not zero out the previous field value before
programming the new value, and thereby potentially mapping a completely
different value in the CMR and HMR registers (if previous values are not
zero) and resulting in non-functional interrupts. Fix this erroneous
bitwise logic.

Reported-by: Nick Saulnier <nsaulnier@ti.com>
Signed-off-by: Suman Anna <s-anna@ti.com>
Acked-by: Roger Quadros <rogerq@ti.com>

index 2bd2498ac3898c805e83f7df6542eeda2e1f4192..fe4dc776fb2af991bd05df3e262e1a9a056d310f 100644 (file)
@@ -201,6 +201,8 @@ int pruss_intc_configure(struct pruss *pruss,
                idx = i / CMR_EVT_PER_REG;
                val = pruss_intc_read_reg(intc, PRU_INTC_CMR(idx));
+               val &= ~(CMR_EVT_MAP_MASK <<
+                        ((i % CMR_EVT_PER_REG) * CMR_EVT_MAP_BITS));
                val |= ch << ((i % CMR_EVT_PER_REG) * CMR_EVT_MAP_BITS);
                pruss_intc_write_reg(intc, PRU_INTC_CMR(idx), val);
                sysevt_mask |= BIT_ULL(i);
@@ -241,6 +243,8 @@ int pruss_intc_configure(struct pruss *pruss,
                idx = i / HMR_CH_PER_REG;
                val = pruss_intc_read_reg(intc, PRU_INTC_HMR(idx));
+               val &= ~(HMR_CH_MAP_MASK <<
+                        ((i % HMR_CH_PER_REG) * HMR_CH_MAP_BITS));
                val |= host << ((i % HMR_CH_PER_REG) * HMR_CH_MAP_BITS);
                pruss_intc_write_reg(intc, PRU_INTC_HMR(idx), val);