From: Adrian Hunter Date: Tue, 6 Jan 2026 16:44:14 +0000 (+0200) Subject: i3c: mipi-i3c-hci-pci: Convert to MFD driver X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0590fe32f9040bccb5481915b32bba1595946b16;p=thirdparty%2Fkernel%2Flinux.git i3c: mipi-i3c-hci-pci: Convert to MFD driver Prepare for Multi-Bus instance support. Convert to MFD driver but still support only 1 instance. Signed-off-by: Adrian Hunter Reviewed-by: Frank Li Link: https://patch.msgid.link/20260106164416.67074-10-adrian.hunter@intel.com Signed-off-by: Alexandre Belloni --- diff --git a/drivers/i3c/master/Kconfig b/drivers/i3c/master/Kconfig index 82cf330778d5a..2609f2b18e0a3 100644 --- a/drivers/i3c/master/Kconfig +++ b/drivers/i3c/master/Kconfig @@ -69,6 +69,7 @@ config MIPI_I3C_HCI_PCI tristate "MIPI I3C Host Controller Interface PCI support" depends on MIPI_I3C_HCI depends on PCI + select MFD_CORE help Support for MIPI I3C Host Controller Interface compatible hardware on the PCI bus. diff --git a/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c b/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c index ca562a5634e8b..7ef17255c3122 100644 --- a/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c +++ b/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -20,7 +21,6 @@ struct mipi_i3c_hci_pci { struct pci_dev *pci; - struct platform_device *pdev; void __iomem *base; const struct mipi_i3c_hci_pci_info *info; void *private; @@ -187,12 +187,45 @@ static const struct mipi_i3c_hci_pci_info intel_2_info = { .id = 2, }; +struct mipi_i3c_hci_pci_cell_data { + struct mipi_i3c_hci_platform_data pdata; + struct resource res; +}; + +static void mipi_i3c_hci_pci_setup_cell(struct mipi_i3c_hci_pci *hci, + struct mipi_i3c_hci_pci_cell_data *data, + struct mfd_cell *cell) +{ + data->pdata.base_regs = hci->base; + + data->res = DEFINE_RES_IRQ(0); + + cell->name = hci->info->name; + cell->id = hci->info->id; + cell->platform_data = &data->pdata; + cell->pdata_size = sizeof(data->pdata); + cell->num_resources = 1; + cell->resources = &data->res; +} + +static int mipi_i3c_hci_pci_add_instances(struct mipi_i3c_hci_pci *hci) +{ + struct mipi_i3c_hci_pci_cell_data *data __free(kfree) = kzalloc(sizeof(*data), GFP_KERNEL); + struct mfd_cell *cells __free(kfree) = kzalloc(sizeof(*cells), GFP_KERNEL); + int irq = pci_irq_vector(hci->pci, 0); + + if (!cells || !data) + return -ENOMEM; + + mipi_i3c_hci_pci_setup_cell(hci, data, cells); + + return mfd_add_devices(&hci->pci->dev, 0, cells, 1, NULL, irq, NULL); +} + static int mipi_i3c_hci_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) { - struct mipi_i3c_hci_platform_data pdata = {}; struct mipi_i3c_hci_pci *hci; - struct resource res; int ret; hci = devm_kzalloc(&pci->dev, sizeof(*hci), GFP_KERNEL); @@ -215,38 +248,13 @@ static int mipi_i3c_hci_pci_probe(struct pci_dev *pci, if (ret < 0) return ret; - memset(&res, 0, sizeof(res)); - - res.flags = IORESOURCE_IRQ; - res.start = pci_irq_vector(hci->pci, 0); - res.end = res.start; - hci->info = (const struct mipi_i3c_hci_pci_info *)id->driver_data; - hci->pdev = platform_device_alloc(hci->info->name, hci->info->id); - if (!hci->pdev) - return -ENOMEM; - - hci->pdev->dev.parent = &pci->dev; - device_set_node(&hci->pdev->dev, dev_fwnode(&pci->dev)); - - ret = platform_device_add_resources(hci->pdev, &res, 1); + ret = hci->info->init ? hci->info->init(hci) : 0; if (ret) - goto err; - - pdata.base_regs = hci->base; - - ret = platform_device_add_data(hci->pdev, &pdata, sizeof(pdata)); - if (ret) - goto err; - - if (hci->info->init) { - ret = hci->info->init(hci); - if (ret) - goto err; - } + return ret; - ret = platform_device_add(hci->pdev); + ret = mipi_i3c_hci_pci_add_instances(hci); if (ret) goto err_exit; @@ -257,20 +265,17 @@ static int mipi_i3c_hci_pci_probe(struct pci_dev *pci, err_exit: if (hci->info->exit) hci->info->exit(hci); -err: - platform_device_put(hci->pdev); return ret; } static void mipi_i3c_hci_pci_remove(struct pci_dev *pci) { struct mipi_i3c_hci_pci *hci = pci_get_drvdata(pci); - struct platform_device *pdev = hci->pdev; if (hci->info->exit) hci->info->exit(hci); - platform_device_unregister(pdev); + mfd_remove_devices(&pci->dev); } static const struct pci_device_id mipi_i3c_hci_pci_devices[] = {