i3c: mipi-i3c-hci: Allow for Multi-Bus Instances
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>
This commit is contained in:
parent
35c0bfe8fd
commit
b8460480f6
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Loading…
Reference in New Issue