]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
i3c: mipi-i3c-hci: Allow for Multi-Bus Instances
authorAdrian Hunter <adrian.hunter@intel.com>
Tue, 6 Jan 2026 16:44:12 +0000 (18:44 +0200)
committerAlexandre Belloni <alexandre.belloni@bootlin.com>
Wed, 14 Jan 2026 14:53:34 +0000 (15:53 +0100)
Add support for MIPI I3C Host Controllers with the Multi-Bus Instance
capability.  These controllers can host multiple I3C buses (up to 15)
within a single hardware function (e.g., PCIe B/D/F), providing one
indepedent HCI register set and corresponding I3C bus controller logic
per bus.

A separate platform device will represent each instance, but it is
necessary to allow for shared resources.

Multi-bus instances share the same MMIO address space, but the ranges are
not guaranteed to be contiguous. To avoid overlapping mappings, pass
base_regs from the parent mapping to child devices.

Allow the IRQ to be shared among instances.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260106164416.67074-8-adrian.hunter@intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
drivers/i3c/master/mipi-i3c-hci/core.c
include/linux/platform_data/mipi-i3c-hci.h [new file with mode: 0644]

index 3d6544a64188716d68e8d88032d10f5ac0448a38..6da5daf18166ff63fe4d74a6b5aa2fe0ef44cf37 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/iopoll.h>
 #include <linux/module.h>
+#include <linux/platform_data/mipi-i3c-hci.h>
 #include <linux/platform_device.h>
 
 #include "hci.h"
@@ -737,15 +738,27 @@ static int i3c_hci_init(struct i3c_hci *hci)
 
 static int i3c_hci_probe(struct platform_device *pdev)
 {
+       const struct mipi_i3c_hci_platform_data *pdata = pdev->dev.platform_data;
        struct i3c_hci *hci;
        int irq, ret;
 
        hci = devm_kzalloc(&pdev->dev, sizeof(*hci), GFP_KERNEL);
        if (!hci)
                return -ENOMEM;
-       hci->base_regs = devm_platform_ioremap_resource(pdev, 0);
-       if (IS_ERR(hci->base_regs))
-               return PTR_ERR(hci->base_regs);
+
+       /*
+        * Multi-bus instances share the same MMIO address range, but not
+        * necessarily in separate contiguous sub-ranges. To avoid overlapping
+        * mappings, provide base_regs from the parent mapping.
+        */
+       if (pdata)
+               hci->base_regs = pdata->base_regs;
+
+       if (!hci->base_regs) {
+               hci->base_regs = devm_platform_ioremap_resource(pdev, 0);
+               if (IS_ERR(hci->base_regs))
+                       return PTR_ERR(hci->base_regs);
+       }
 
        platform_set_drvdata(pdev, hci);
        /* temporary for dev_printk's, to be replaced in i3c_master_register */
@@ -759,7 +772,7 @@ static int i3c_hci_probe(struct platform_device *pdev)
 
        irq = platform_get_irq(pdev, 0);
        ret = devm_request_irq(&pdev->dev, irq, i3c_hci_irq_handler,
-                              0, NULL, hci);
+                              IRQF_SHARED, NULL, hci);
        if (ret)
                return ret;
 
diff --git a/include/linux/platform_data/mipi-i3c-hci.h b/include/linux/platform_data/mipi-i3c-hci.h
new file mode 100644 (file)
index 0000000..ab7395f
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef INCLUDE_PLATFORM_DATA_MIPI_I3C_HCI_H
+#define INCLUDE_PLATFORM_DATA_MIPI_I3C_HCI_H
+
+#include <linux/compiler_types.h>
+
+/**
+ * struct mipi_i3c_hci_platform_data - Platform-dependent data for mipi_i3c_hci
+ * @base_regs: Register set base address (to support multi-bus instances)
+ */
+struct mipi_i3c_hci_platform_data {
+       void __iomem *base_regs;
+};
+
+#endif