diff --git a/drivers/virtualization/virt_ivshmem.c b/drivers/virtualization/virt_ivshmem.c index 8e34d0d00d9..f4b780a4345 100644 --- a/drivers/virtualization/virt_ivshmem.c +++ b/drivers/virtualization/virt_ivshmem.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define DT_DRV_COMPAT qemu_ivshmem + #define LOG_LEVEL CONFIG_IVSHMEM_LOG_LEVEL #include LOG_MODULE_REGISTER(ivshmem); @@ -223,25 +225,42 @@ static const struct ivshmem_driver_api ivshmem_api = { static int ivshmem_init(const struct device *dev) { struct ivshmem *data = dev->data; + static bool bdf_lookup_done; - data->bdf = pcie_bdf_lookup(PCIE_ID(IVSHMEM_VENDOR_ID, - IVSHMEM_DEVICE_ID)); - if (data->bdf == PCIE_BDF_NONE) { - LOG_WRN("ivshmem device not found"); + if ((data->bdf == PCIE_BDF_NONE) && bdf_lookup_done) { + LOG_ERR("One instance of ivshmem with pcie_bdf_lookup() already initialized.\n" + "Using more than one with PCIE_BDF_NONE parameter might conflict\n" + "with already initialized instances."); return -ENOTSUP; } - + if ((data->bdf == PCIE_BDF_NONE) && !bdf_lookup_done) { + if (data->dev_ven_id) { + data->bdf = pcie_bdf_lookup(data->dev_ven_id); + } else { + data->bdf = pcie_bdf_lookup(PCIE_ID(IVSHMEM_VENDOR_ID, IVSHMEM_DEVICE_ID)); + } + if (data->bdf == PCIE_BDF_NONE) { + LOG_WRN("ivshmem device not found"); + return -ENOTSUP; + } + } LOG_DBG("ivshmem found at bdf 0x%x", data->bdf); + bdf_lookup_done = true; if (!ivshmem_configure(dev)) { return -EIO; } - return 0; } -static struct ivshmem ivshmem_data; +#define IVSHMEM_DEVICE_INIT(n) \ + static struct ivshmem ivshmem_data_##n = { \ + .bdf = DT_INST_REG_ADDR_BY_IDX(n, 0), \ + .dev_ven_id = DT_INST_REG_SIZE_BY_IDX(n, 0) \ + }; \ + DEVICE_DT_INST_DEFINE(n, &ivshmem_init, NULL, \ + &ivshmem_data_##n, NULL, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &ivshmem_api); -DEVICE_DEFINE(ivshmem, CONFIG_IVSHMEM_DEV_NAME, - ivshmem_init, NULL, &ivshmem_data, NULL, - POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &ivshmem_api); +DT_INST_FOREACH_STATUS_OKAY(IVSHMEM_DEVICE_INIT) diff --git a/drivers/virtualization/virt_ivshmem.h b/drivers/virtualization/virt_ivshmem.h index 4298e83af6f..b3e2b935086 100644 --- a/drivers/virtualization/virt_ivshmem.h +++ b/drivers/virtualization/virt_ivshmem.h @@ -25,6 +25,7 @@ struct ivshmem_param { struct ivshmem { DEVICE_MMIO_RAM; pcie_bdf_t bdf; + uint32_t dev_ven_id; uintptr_t shmem; size_t size; #ifdef CONFIG_IVSHMEM_DOORBELL diff --git a/dts/bindings/virtualization/qemu,ivshmem.yaml b/dts/bindings/virtualization/qemu,ivshmem.yaml new file mode 100644 index 00000000000..22095389a9b --- /dev/null +++ b/dts/bindings/virtualization/qemu,ivshmem.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: ivShMem device properties + +compatible: "qemu,ivshmem" + +include: base.yaml diff --git a/tests/drivers/virtualization/ivshmem/app.overlay b/tests/drivers/virtualization/ivshmem/app.overlay new file mode 100644 index 00000000000..763109cf807 --- /dev/null +++ b/tests/drivers/virtualization/ivshmem/app.overlay @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +/ { + pcie0 { + label = "PCIE_0"; + #address-cells = <1>; + #size-cells = <1>; + compatible = "intel,pcie"; + ranges; + + ivshmem0: ivshmem@800 { + compatible = "qemu,ivshmem"; + + reg = ; + label = "IVSHMEM"; + status = "okay"; + }; + }; +};