mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
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 <adrian.hunter@intel.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20260106164416.67074-10-adrian.hunter@intel.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
This commit is contained in:
parent
9a4d56b42f
commit
0590fe32f9
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/idr.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_data/mipi-i3c-hci.h>
|
||||
|
|
@ -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;
|
||||
return ret;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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[] = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user