+++ /dev/null
-From 0af25541e1ad7a10527ef8dbdd461d4b91753a64 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 22 Nov 2024 15:30:24 -0800
-Subject: dmaengine: idxd: Add idxd_pci_probe_alloc() helper
-
-From: Fenghua Yu <fenghua.yu@intel.com>
-
-[ Upstream commit 087e89b69b5fe5529a8809a06b4b4680e54f87e2 ]
-
-Add the idxd_pci_probe_alloc() helper to probe IDXD PCI device with or
-without allocating and setting idxd software values.
-
-The idxd_pci_probe() function is refactored to call this helper and
-always probe the IDXD device with allocating and setting the software
-values.
-
-This helper will be called later in the Function Level Reset (FLR)
-process without modifying the idxd software data.
-
-Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
-Reviewed-by: Dave Jiang <dave.jiang@intel.com>
-Link: https://lore.kernel.org/r/20241122233028.2762809-2-fenghua.yu@intel.com
-Signed-off-by: Vinod Koul <vkoul@kernel.org>
-Stable-dep-of: ee66bc295783 ("dmaengine: idxd: Fix leaking event log memory")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/dma/idxd/idxd.h | 2 +
- drivers/dma/idxd/init.c | 102 ++++++++++++++++++++++++----------------
- 2 files changed, 64 insertions(+), 40 deletions(-)
-
-diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
-index d84e21daa9912..1f93dd6db28f0 100644
---- a/drivers/dma/idxd/idxd.h
-+++ b/drivers/dma/idxd/idxd.h
-@@ -742,6 +742,8 @@ void idxd_unmask_error_interrupts(struct idxd_device *idxd);
-
- /* device control */
- int idxd_device_drv_probe(struct idxd_dev *idxd_dev);
-+int idxd_pci_probe_alloc(struct idxd_device *idxd, struct pci_dev *pdev,
-+ const struct pci_device_id *id);
- void idxd_device_drv_remove(struct idxd_dev *idxd_dev);
- int idxd_drv_enable_wq(struct idxd_wq *wq);
- void idxd_drv_disable_wq(struct idxd_wq *wq);
-diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
-index e55136bb525e2..c3073518d1db4 100644
---- a/drivers/dma/idxd/init.c
-+++ b/drivers/dma/idxd/init.c
-@@ -800,67 +800,84 @@ static void idxd_cleanup(struct idxd_device *idxd)
- idxd_disable_sva(idxd->pdev);
- }
-
--static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-+/*
-+ * Probe idxd PCI device.
-+ * If idxd is not given, need to allocate idxd and set up its data.
-+ *
-+ * If idxd is given, idxd was allocated and setup already. Just need to
-+ * configure device without re-allocating and re-configuring idxd data.
-+ * This is useful for recovering from FLR.
-+ */
-+int idxd_pci_probe_alloc(struct idxd_device *idxd, struct pci_dev *pdev,
-+ const struct pci_device_id *id)
- {
-- struct device *dev = &pdev->dev;
-- struct idxd_device *idxd;
-- struct idxd_driver_data *data = (struct idxd_driver_data *)id->driver_data;
-+ bool alloc_idxd = idxd ? false : true;
-+ struct idxd_driver_data *data;
-+ struct device *dev;
- int rc;
-
-+ pdev = idxd ? idxd->pdev : pdev;
-+ dev = &pdev->dev;
-+ data = id ? (struct idxd_driver_data *)id->driver_data : NULL;
- rc = pci_enable_device(pdev);
- if (rc)
- return rc;
-
-- dev_dbg(dev, "Alloc IDXD context\n");
-- idxd = idxd_alloc(pdev, data);
-- if (!idxd) {
-- rc = -ENOMEM;
-- goto err_idxd_alloc;
-- }
-+ if (alloc_idxd) {
-+ dev_dbg(dev, "Alloc IDXD context\n");
-+ idxd = idxd_alloc(pdev, data);
-+ if (!idxd) {
-+ rc = -ENOMEM;
-+ goto err_idxd_alloc;
-+ }
-
-- dev_dbg(dev, "Mapping BARs\n");
-- idxd->reg_base = pci_iomap(pdev, IDXD_MMIO_BAR, 0);
-- if (!idxd->reg_base) {
-- rc = -ENOMEM;
-- goto err_iomap;
-- }
-+ dev_dbg(dev, "Mapping BARs\n");
-+ idxd->reg_base = pci_iomap(pdev, IDXD_MMIO_BAR, 0);
-+ if (!idxd->reg_base) {
-+ rc = -ENOMEM;
-+ goto err_iomap;
-+ }
-
-- dev_dbg(dev, "Set DMA masks\n");
-- rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
-- if (rc)
-- goto err;
-+ dev_dbg(dev, "Set DMA masks\n");
-+ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
-+ if (rc)
-+ goto err;
-+ }
-
- dev_dbg(dev, "Set PCI master\n");
- pci_set_master(pdev);
- pci_set_drvdata(pdev, idxd);
-
-- idxd->hw.version = ioread32(idxd->reg_base + IDXD_VER_OFFSET);
-- rc = idxd_probe(idxd);
-- if (rc) {
-- dev_err(dev, "Intel(R) IDXD DMA Engine init failed\n");
-- goto err;
-- }
-+ if (alloc_idxd) {
-+ idxd->hw.version = ioread32(idxd->reg_base + IDXD_VER_OFFSET);
-+ rc = idxd_probe(idxd);
-+ if (rc) {
-+ dev_err(dev, "Intel(R) IDXD DMA Engine init failed\n");
-+ goto err;
-+ }
-
-- if (data->load_device_defaults) {
-- rc = data->load_device_defaults(idxd);
-- if (rc)
-- dev_warn(dev, "IDXD loading device defaults failed\n");
-- }
-+ if (data->load_device_defaults) {
-+ rc = data->load_device_defaults(idxd);
-+ if (rc)
-+ dev_warn(dev, "IDXD loading device defaults failed\n");
-+ }
-
-- rc = idxd_register_devices(idxd);
-- if (rc) {
-- dev_err(dev, "IDXD sysfs setup failed\n");
-- goto err_dev_register;
-- }
-+ rc = idxd_register_devices(idxd);
-+ if (rc) {
-+ dev_err(dev, "IDXD sysfs setup failed\n");
-+ goto err_dev_register;
-+ }
-
-- rc = idxd_device_init_debugfs(idxd);
-- if (rc)
-- dev_warn(dev, "IDXD debugfs failed to setup\n");
-+ rc = idxd_device_init_debugfs(idxd);
-+ if (rc)
-+ dev_warn(dev, "IDXD debugfs failed to setup\n");
-+ }
-
- dev_info(&pdev->dev, "Intel(R) Accelerator Device (v%x)\n",
- idxd->hw.version);
-
-- idxd->user_submission_safe = data->user_submission_safe;
-+ if (data)
-+ idxd->user_submission_safe = data->user_submission_safe;
-
- return 0;
-
-@@ -875,6 +892,11 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
- return rc;
- }
-
-+static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-+{
-+ return idxd_pci_probe_alloc(NULL, pdev, id);
-+}
-+
- void idxd_wqs_quiesce(struct idxd_device *idxd)
- {
- struct idxd_wq *wq;
---
-2.53.0
-