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.
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?
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.