diff --git a/drivers/i3c/master/mipi-i3c-hci/core.c b/drivers/i3c/master/mipi-i3c-hci/core.c index cfe9b5390b56..f95da427d7a9 100644 --- a/drivers/i3c/master/mipi-i3c-hci/core.c +++ b/drivers/i3c/master/mipi-i3c-hci/core.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -117,6 +118,21 @@ static inline struct i3c_hci *to_i3c_hci(struct i3c_master_controller *m) return container_of(m, struct i3c_hci, master); } +/** + * i3c_hci_sysdev() - Get the device to use for DMA + * @dev: Device the HCI controller is bound to + * + * When an IOMMU is enabled, DMA API calls must use the device that IOMMU + * setup was done for. Under PCI enumeration that is the PCI device, not + * the "mipi-i3c-hci" platform device below it. + * + * Return: @dev's parent if it is a PCI device, otherwise @dev. + */ +struct device *i3c_hci_sysdev(struct device *dev) +{ + return dev->parent && dev_is_pci(dev->parent) ? dev->parent : dev; +} + static void i3c_hci_set_master_dyn_addr(struct i3c_hci *hci) { reg_write(MASTER_DEVICE_ADDR, diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c index 0672ed1132f8..7c2b20474130 100644 --- a/drivers/i3c/master/mipi-i3c-hci/dma.c +++ b/drivers/i3c/master/mipi-i3c-hci/dma.c @@ -15,7 +15,6 @@ #include #include #include -#include #include "hci.h" #include "cmd.h" @@ -301,23 +300,11 @@ static int hci_dma_init(struct i3c_hci *hci) { struct hci_rings_data *rings; struct hci_rh_data *rh; - struct device *sysdev; u32 regval; unsigned int i, nr_rings, xfers_sz, resps_sz; unsigned int ibi_status_ring_sz, ibi_data_ring_sz; int ret; - /* - * Set pointer to a physical device that does DMA and has IOMMU setup - * done for it in case of enabled IOMMU and use it with the DMA API. - * Here such device is either - * "mipi-i3c-hci" platform device (OF/ACPI enumeration) parent or - * grandparent (PCI enumeration). - */ - sysdev = hci->master.dev.parent; - if (sysdev->parent && dev_is_pci(sysdev->parent)) - sysdev = sysdev->parent; - regval = rhs_reg_read(CONTROL); nr_rings = FIELD_GET(MAX_HEADER_COUNT_CAP, regval); dev_dbg(&hci->master.dev, "%d DMA rings available\n", nr_rings); @@ -332,7 +319,7 @@ static int hci_dma_init(struct i3c_hci *hci) return -ENOMEM; hci->io_data = rings; rings->total = nr_rings; - rings->sysdev = sysdev; + rings->sysdev = i3c_hci_sysdev(hci->master.dev.parent); for (i = 0; i < rings->total; i++) { u32 offset = rhs_reg_read(RHn_OFFSET(i)); diff --git a/drivers/i3c/master/mipi-i3c-hci/hci.h b/drivers/i3c/master/mipi-i3c-hci/hci.h index b3d9803b1968..b8d2a3d680f8 100644 --- a/drivers/i3c/master/mipi-i3c-hci/hci.h +++ b/drivers/i3c/master/mipi-i3c-hci/hci.h @@ -184,6 +184,8 @@ void amd_set_resp_buf_thld(struct i3c_hci *hci); void i3c_hci_sync_irq_inactive(struct i3c_hci *hci); int i3c_hci_process_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n); +struct device *i3c_hci_sysdev(struct device *dev); + #define DEFAULT_AUTOSUSPEND_DELAY_MS 1000 int i3c_hci_rpm_suspend(struct device *dev);