i3c: mipi-i3c-hci: Handle interrupts according to current specifications
authorJarkko Nikula <jarkko.nikula@linux.intel.com>
Fri, 20 Sep 2024 14:44:32 +0000 (17:44 +0300)
committerAlexandre Belloni <alexandre.belloni@bootlin.com>
Thu, 31 Oct 2024 23:06:14 +0000 (00:06 +0100)
Current MIPI I3C HCI specification versions pre-1.0, 1.0. 1.1 and 1.2
don't have cascaded interrupt bits for the PIO and DMA (ring headers) in
the INTR_STATUS register as implemented currently in the code. Instead
bits 9:0 are marked as reserved with unspecified reset value.

To my understanding they were planned to be introduced in the version 2
and the original commit 9ad9a52cce28 ("i3c/master: introduce the
mipi-i3c-hci driver") was coding ahead according to a draft. With
remarks though.

This is causing that the DMA handler is not called until at least one
reserved bit 7:0 is set in the INTR_STATUS.

Since it looks that idea was dropped in later official versions and to
make able to handle DMA interrupts on an HW that is implemented
according to current specifications call assigned PIO or DMA IO handler
unconditionally.

While doing so remove cascaded interrupt bit definitions and the mask
argument passed to the handler functions.

Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Link: https://lore.kernel.org/r/20240920144432.62370-3-jarkko.nikula@linux.intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
drivers/i3c/master/mipi-i3c-hci/core.c
drivers/i3c/master/mipi-i3c-hci/dma.c
drivers/i3c/master/mipi-i3c-hci/hci.h
drivers/i3c/master/mipi-i3c-hci/pio.c

index a82c47c..b190401 100644 (file)
@@ -80,8 +80,6 @@
 #define INTR_HC_CMD_SEQ_UFLOW_STAT     BIT(12) /* Cmd Sequence Underflow */
 #define INTR_HC_RESET_CANCEL           BIT(11) /* HC Cancelled Reset */
 #define INTR_HC_INTERNAL_ERR           BIT(10) /* HC Internal Error */
-#define INTR_HC_PIO                    BIT(8)  /* cascaded PIO interrupt */
-#define INTR_HC_RINGS                  GENMASK(7, 0)
 
 #define DAT_SECTION                    0x30    /* Device Address Table */
 #define DAT_ENTRY_SIZE                 GENMASK(31, 28)
@@ -597,9 +595,6 @@ static irqreturn_t i3c_hci_irq_handler(int irq, void *dev_id)
 
        if (val) {
                reg_write(INTR_STATUS, val);
-       } else {
-               /* v1.0 does not have PIO cascaded notification bits */
-               val |= INTR_HC_PIO;
        }
 
        if (val & INTR_HC_RESET_CANCEL) {
@@ -610,14 +605,9 @@ static irqreturn_t i3c_hci_irq_handler(int irq, void *dev_id)
                dev_err(&hci->master.dev, "Host Controller Internal Error\n");
                val &= ~INTR_HC_INTERNAL_ERR;
        }
-       if (val & INTR_HC_PIO) {
-               hci->io->irq_handler(hci, 0);
-               val &= ~INTR_HC_PIO;
-       }
-       if (val & INTR_HC_RINGS) {
-               hci->io->irq_handler(hci, val & INTR_HC_RINGS);
-               val &= ~INTR_HC_RINGS;
-       }
+
+       hci->io->irq_handler(hci);
+
        if (val)
                dev_err(&hci->master.dev, "unexpected INTR_STATUS %#x\n", val);
        else
index 13adc58..e8e56a8 100644 (file)
@@ -733,20 +733,16 @@ done:
        rh_reg_write(CHUNK_CONTROL, rh_reg_read(CHUNK_CONTROL) + ibi_chunks);
 }
 
-static bool hci_dma_irq_handler(struct i3c_hci *hci, unsigned int mask)
+static bool hci_dma_irq_handler(struct i3c_hci *hci)
 {
        struct hci_rings_data *rings = hci->io_data;
        unsigned int i;
        bool handled = false;
 
-       for (i = 0; mask && i < rings->total; i++) {
+       for (i = 0; i < rings->total; i++) {
                struct hci_rh_data *rh;
                u32 status;
 
-               if (!(mask & BIT(i)))
-                       continue;
-               mask &= ~BIT(i);
-
                rh = &rings->headers[i];
                status = rh_reg_read(INTR_STATUS);
                DBG("rh%d status: %#x", i, status);
index aaa47ac..69ea1d1 100644 (file)
@@ -115,7 +115,7 @@ static inline void hci_free_xfer(struct hci_xfer *xfer, unsigned int n)
 
 /* This abstracts PIO vs DMA operations */
 struct hci_io_ops {
-       bool (*irq_handler)(struct i3c_hci *hci, unsigned int mask);
+       bool (*irq_handler)(struct i3c_hci *hci);
        int (*queue_xfer)(struct i3c_hci *hci, struct hci_xfer *xfer, int n);
        bool (*dequeue_xfer)(struct i3c_hci *hci, struct hci_xfer *xfer, int n);
        int (*request_ibi)(struct i3c_hci *hci, struct i3c_dev_desc *dev,
index d0272aa..2fc71e6 100644 (file)
@@ -979,7 +979,7 @@ static void hci_pio_recycle_ibi_slot(struct i3c_hci *hci,
        i3c_generic_ibi_recycle_slot(dev_ibi->pool, slot);
 }
 
-static bool hci_pio_irq_handler(struct i3c_hci *hci, unsigned int unused)
+static bool hci_pio_irq_handler(struct i3c_hci *hci)
 {
        struct hci_pio_data *pio = hci->io_data;
        u32 status;