Re: [PATCH v4 2/8] irqchip: Add Realtek RTD1295 mux driver

From: Marc Zyngier
Date: Wed Nov 20 2019 - 05:19:02 EST


On 2019-11-19 23:25, Andreas FÃrber wrote:
Am 19.11.19 um 13:01 schrieb Marc Zyngier:
On 2019-11-19 02:19, Andreas FÃrber wrote:
diff --git a/drivers/irqchip/irq-rtd1195-mux.c
b/drivers/irqchip/irq-rtd1195-mux.c
new file mode 100644
index 000000000000..e6b08438b23c
--- /dev/null
+++ b/drivers/irqchip/irq-rtd1195-mux.c
[...]
+static void rtd1195_mux_irq_handle(struct irq_desc *desc)
+{
+ÂÂÂ struct rtd1195_irq_mux_data *data = irq_desc_get_handler_data(desc);
+ÂÂÂ struct irq_chip *chip = irq_desc_get_chip(desc);
+ÂÂÂ u32 isr, mask;
+ÂÂÂ int i;
+
+ÂÂÂ chained_irq_enter(chip, desc);
+
+ÂÂÂ isr = readl_relaxed(data->reg_isr);
+
+ÂÂÂ while (isr) {
+ÂÂÂÂÂÂÂ i = __ffs(isr);
+ÂÂÂÂÂÂÂ isr &= ~BIT(i);
+
+ÂÂÂÂÂÂÂ mask = data->info->isr_to_int_en_mask[i];
+ÂÂÂÂÂÂÂ if (mask && !(data->scpu_int_en & mask))
+ÂÂÂÂÂÂÂÂÂÂÂ continue;
+
+ÂÂÂÂÂÂÂ if (!generic_handle_irq(irq_find_mapping(data->domain, i)))
+ÂÂÂÂÂÂÂÂÂÂÂ writel_relaxed(BIT(i), data->reg_isr);

What does this write do exactly? It is the same thing as a 'mask',
which is pretty odd. So either:

- this is not doing anything and your 'mask' callback is bogus
 (otherwise you'd never have more than a single interrupt)

- or this is an ACK operation, and this should be described as
 such (and then fix the mask/unmask/enable/disable mess that
 results from it).

This is supposed to be an ACK, i.e. clear-1-bits operation.

If it is an ACK, model it as such, and do not open-code it.


The BSP had extended various drivers, such as 8250 UART, to do this ack
in their interrupt handler through an additional DT reg region. I tried
to clean that up by handling it centrally here in the irqchip driver.


as I can't see how the same register can be used for both purposes.
You should be able to verify this experimentally, even without
documentation.

There are three registers here:

MIS_UMSK_ISR - MISC unmasked interrupt status register
MIS_ISR - MISC masked interrupt status register
MIS_SCPU_INT_EN - MISC SCPU interrupt enable register

The latter is a regular R/W register; the former two have a write_data
field as BIT(0), with 1 indicating a write vs. 0 indicating clear, RAZ.

By enabling/disabling in _SCPU_INT_EN we mask/unmask them in _ISR but
not in _UMSK_ISR.

Does that shed any more light?

None whatsoever. Your mask callback doesn't make any sense, since it
actually acks the interrupt. My gut feeling is that your enable/disable
should really be mask/unmask.


So given that we're iterating over reg_isr above, we could probably drop
the mask check here...

In addition there are MIS_[UMSK_]ISR_SWC and MIS_SETTING_SWC registers
for Secure World, and MIS_FAST_INT_EN_* and MIS_FAST_ISR as well as
various GPIO interrupt registers.

This doesn't seem relevant to the discussion here.

M.
--
Jazz is not dead. It just smells funny...