Browse Source

Merge branch 'topic/4.19/pruss' of git://git.ti.com/rpmsg/remoteproc into rproc-linux-4.19.y

Merge in the PRUSS topic branch into the base remoteproc feature branch
that pulls in a fix for properly clearing and configuring the PRUSS INTC
event-to-channel and channel-to-host interrupt mapping.

* 'topic/4.19/pruss' of git://git.ti.com/rpmsg/remoteproc:
  irqchip/irq-pruss-intc: Fix incorrect macro replacement
  irqchip/irq-pruss-intc: Fix erroneous channel/host mapping logic
  irqchip/irq-pruss-intc: Use macros for operations on CMR and HMR
  TEMP: irqchip/irq-pruss-intc: Allow setting irq affinity for PRU events
  irqchip/irq-pruss-intc: Reset chained handlers during cleanup

Signed-off-by: Suman Anna <s-anna@ti.com>
Suman Anna 6 years ago
parent
commit
80e8ce38b7
1 changed files with 25 additions and 10 deletions
  1. 25 10
      drivers/irqchip/irq-pruss-intc.c

+ 25 - 10
drivers/irqchip/irq-pruss-intc.c

@@ -52,6 +52,16 @@
 #define PRU_INTC_HINLR(x)	(0x1100 + (x) * 4)
 #define PRU_INTC_HIER		0x1500
 
+/* CMR register bit-field macros */
+#define CMR_EVT_MAP_MASK	0xf
+#define CMR_EVT_MAP_BITS	8
+#define CMR_EVT_PER_REG		4
+
+/* HMR register bit-field macros */
+#define HMR_CH_MAP_MASK		0xf
+#define HMR_CH_MAP_BITS		8
+#define HMR_CH_PER_REG		4
+
 /* HIPIR register bit-fields */
 #define INTC_HIPIR_NONE_HINT	0x80000000
 
@@ -189,9 +199,11 @@ int pruss_intc_configure(struct pruss *pruss,
 
 		intc->config_map.sysev_to_ch[i] = ch;
 
-		idx = i / 4;
+		idx = i / CMR_EVT_PER_REG;
 		val = pruss_intc_read_reg(intc, PRU_INTC_CMR(idx));
-		val |= ch << ((i & 3) * 8);
+		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);
 		ch_mask |= BIT(ch);
@@ -228,10 +240,12 @@ int pruss_intc_configure(struct pruss *pruss,
 
 		intc->config_map.ch_to_host[i] = host;
 
-		idx = i / 4;
+		idx = i / HMR_CH_PER_REG;
 
 		val = pruss_intc_read_reg(intc, PRU_INTC_HMR(idx));
-		val |= host << ((i & 3) * 8);
+		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);
 
 		ch_mask |= BIT(i);
@@ -427,14 +441,15 @@ static int pruss_intc_irq_set_affinity(struct irq_data *data,
 	}
 
 	/* find programmed channel */
-	ch = pruss_intc_read_reg(intc, PRU_INTC_CMR(data->hwirq / 4));
-	ch >>= (data->hwirq % 4) * 8;
-	ch &= 0xf;
+	ch = pruss_intc_read_reg(intc,
+				 PRU_INTC_CMR(data->hwirq / CMR_EVT_PER_REG));
+	ch >>= (data->hwirq % CMR_EVT_PER_REG) * CMR_EVT_MAP_BITS;
+	ch &= CMR_EVT_MAP_MASK;
 
 	/* find programmed host interrupt */
-	host = pruss_intc_read_reg(intc, PRU_INTC_HMR(ch / 4));
-	host >>= (ch % 4) * 8;
-	host &= 0xf;
+	host = pruss_intc_read_reg(intc, PRU_INTC_HMR(ch / HMR_CH_PER_REG));
+	host >>= (ch % HMR_CH_PER_REG) * HMR_CH_MAP_BITS;
+	host &= HMR_CH_MAP_MASK;
 
 	/* check programmed configuration for sanity */
 	if (ch != sch || host != shost) {