linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] bus/fsl-mc: Extend mc-bus driver functionalities in preparation for mc-bus VFIO support
@ 2020-03-19 15:40 Diana Craciun
  2020-03-19 15:40 ` [PATCH 01/10] bus/fsl-mc: Do no longer export the total number of irqs outside dprc_scan_objects Diana Craciun
                   ` (9 more replies)
  0 siblings, 10 replies; 19+ messages in thread
From: Diana Craciun @ 2020-03-19 15:40 UTC (permalink / raw)
  To: linux-kernel, laurentiu.tudor, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Diana Craciun

The vfio-mc bus driver needs some additional services to be exported by the
mc-bus driver like:
- a way to reset the DPRC container
- support for driver_override such taht the objects within a DPRC to be
bind to the VFIO driver
- functions to setup/tear dowan a DPRC
- functions for allocating the pool of interrupts. In case of VFIO the
interrupts are not configured at probe time, but later, when the userspace
configures the interrupts.

Bharat Bhushan (3):
  bus/fsl-mc: add support for 'driver_override' in the mc-bus
  bus/fsl-mc: Propagate driver_override for a child DPRC's children
  bus/fsl-mc: Add dprc-reset-container support

Diana Craciun (7):
  bus/fsl-mc: Do no longer export the total number of irqs outside dprc_scan_objects
  bus/fsl-mc: Add a new parameter to dprc_scan_objects function
  bus/fsl-mc: Set the QMAN/BMAN region flags
  bus/fsl-mc: Export a dprc scan function to be used by multiple
    entities
  bus/fsl-mc: Export a cleanup function for DPRC
  bus/fsl-mc: Add a container setup function
  bus/fsl-mc: Export IRQ pool handling functions to be used by VFIO

 drivers/bus/fsl-mc/dprc-driver.c      | 184 ++++++++++++++++----------
 drivers/bus/fsl-mc/dprc.c             |  41 ++++++
 drivers/bus/fsl-mc/fsl-mc-allocator.c |  12 +-
 drivers/bus/fsl-mc/fsl-mc-bus.c       |  81 +++++++++++-
 drivers/bus/fsl-mc/fsl-mc-private.h   |  23 +---
 drivers/bus/fsl-mc/mc-io.c            |   7 +-
 include/linux/fsl/mc.h                |  27 ++++
 7 files changed, 279 insertions(+), 96 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 01/10] bus/fsl-mc: Do no longer export the total number of irqs outside dprc_scan_objects
  2020-03-19 15:40 [PATCH 00/10] bus/fsl-mc: Extend mc-bus driver functionalities in preparation for mc-bus VFIO support Diana Craciun
@ 2020-03-19 15:40 ` Diana Craciun
  2020-04-06 14:46   ` Diana Craciun OSS
  2020-03-19 15:40 ` [PATCH 02/10] bus/fsl-mc: Add a new parameter to dprc_scan_objects function Diana Craciun
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Diana Craciun @ 2020-03-19 15:40 UTC (permalink / raw)
  To: linux-kernel, laurentiu.tudor, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Diana Craciun

The total number of interrupts is only used for some checks
outside the dprc_scan_objects function. Furthermore, in some
situations the check is made twice. Move the bounds check inside
the function for all situations.

Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
---
 drivers/bus/fsl-mc/dprc-driver.c | 30 ++++++++++--------------------
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
index c8b1c3842c1a..035b220779d0 100644
--- a/drivers/bus/fsl-mc/dprc-driver.c
+++ b/drivers/bus/fsl-mc/dprc-driver.c
@@ -3,6 +3,7 @@
  * Freescale data path resource container (DPRC) driver
  *
  * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2019-2020 NXP
  * Author: German Rivera <German.Rivera@freescale.com>
  *
  */
@@ -197,8 +198,6 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
  * dprc_scan_objects - Discover objects in a DPRC
  *
  * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
- * @total_irq_count: If argument is provided the function populates the
- * total number of IRQs created by objects in the DPRC.
  *
  * Detects objects added and removed from a DPRC and synchronizes the
  * state of the Linux bus driver, MC by adding and removing
@@ -212,8 +211,7 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
  * populated before they can get allocation requests from probe callbacks
  * of the device drivers for the non-allocatable devices.
  */
-static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
-			     unsigned int *total_irq_count)
+static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
 {
 	int num_child_objects;
 	int dprc_get_obj_failures;
@@ -294,22 +292,21 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
 	 * Allocate IRQ's before binding the scanned devices with their
 	 * respective drivers.
 	 */
-	if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) {
+	if (dev_get_msi_domain(&mc_bus_dev->dev)) {
 		if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
 			dev_warn(&mc_bus_dev->dev,
 				 "IRQs needed (%u) exceed IRQs preallocated (%u)\n",
 				 irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
 		}
 
-		error = fsl_mc_populate_irq_pool(mc_bus,
+		if (!mc_bus->irq_resources) {
+			error = fsl_mc_populate_irq_pool(mc_bus,
 				FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
-		if (error < 0)
-			return error;
+			if (error < 0)
+				return error;
+		}
 	}
 
-	if (total_irq_count)
-		*total_irq_count = irq_count;
-
 	dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
 			    num_child_objects);
 
@@ -342,7 +339,7 @@ static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 	 * Discover objects in the DPRC:
 	 */
 	mutex_lock(&mc_bus->scan_mutex);
-	error = dprc_scan_objects(mc_bus_dev, NULL);
+	error = dprc_scan_objects(mc_bus_dev);
 	mutex_unlock(&mc_bus->scan_mutex);
 	if (error < 0) {
 		fsl_mc_cleanup_all_resource_pools(mc_bus_dev);
@@ -411,9 +408,8 @@ static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
 		      DPRC_IRQ_EVENT_CONTAINER_DESTROYED |
 		      DPRC_IRQ_EVENT_OBJ_DESTROYED |
 		      DPRC_IRQ_EVENT_OBJ_CREATED)) {
-		unsigned int irq_count;
 
-		error = dprc_scan_objects(mc_dev, &irq_count);
+		error = dprc_scan_objects(mc_dev);
 		if (error < 0) {
 			/*
 			 * If the error is -ENXIO, we ignore it, as it indicates
@@ -428,12 +424,6 @@ static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
 
 			goto out;
 		}
-
-		if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
-			dev_warn(dev,
-				 "IRQs needed (%u) exceed IRQs preallocated (%u)\n",
-				 irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
-		}
 	}
 
 out:
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 02/10] bus/fsl-mc: Add a new parameter to dprc_scan_objects function
  2020-03-19 15:40 [PATCH 00/10] bus/fsl-mc: Extend mc-bus driver functionalities in preparation for mc-bus VFIO support Diana Craciun
  2020-03-19 15:40 ` [PATCH 01/10] bus/fsl-mc: Do no longer export the total number of irqs outside dprc_scan_objects Diana Craciun
@ 2020-03-19 15:40 ` Diana Craciun
  2020-03-23 12:04   ` Laurentiu Tudor
  2020-03-19 15:40 ` [PATCH 03/10] bus/fsl-mc: add support for 'driver_override' in the mc-bus Diana Craciun
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Diana Craciun @ 2020-03-19 15:40 UTC (permalink / raw)
  To: linux-kernel, laurentiu.tudor, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Diana Craciun

Prepare the dprc_scan_objects function to be used by
the VFIO mc driver code. The function is used to scan the mc
objects by the bus driver. The same functionality is
needed by the VFIO mc driver, but in this case the
interrupt configuration is delayed until the userspace
configures the interrupts. In order to use the same function
in both drivers add a new parameter.

Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
---
 drivers/bus/fsl-mc/dprc-driver.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
index 035b220779d0..d373b28abe2d 100644
--- a/drivers/bus/fsl-mc/dprc-driver.c
+++ b/drivers/bus/fsl-mc/dprc-driver.c
@@ -198,7 +198,9 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
  * dprc_scan_objects - Discover objects in a DPRC
  *
  * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
- *
+ * @alloc_interrupts: if true the function allocates the interrupt pool,
+ * otherwise the interrupt allocation is delayed
+
  * Detects objects added and removed from a DPRC and synchronizes the
  * state of the Linux bus driver, MC by adding and removing
  * devices accordingly.
@@ -211,7 +213,8 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
  * populated before they can get allocation requests from probe callbacks
  * of the device drivers for the non-allocatable devices.
  */
-static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
+static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+			    bool alloc_interrupts)
 {
 	int num_child_objects;
 	int dprc_get_obj_failures;
@@ -299,7 +302,7 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
 				 irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
 		}
 
-		if (!mc_bus->irq_resources) {
+		if (alloc_interrupts && !mc_bus->irq_resources) {
 			error = fsl_mc_populate_irq_pool(mc_bus,
 				FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
 			if (error < 0)
@@ -339,7 +342,7 @@ static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 	 * Discover objects in the DPRC:
 	 */
 	mutex_lock(&mc_bus->scan_mutex);
-	error = dprc_scan_objects(mc_bus_dev);
+	error = dprc_scan_objects(mc_bus_dev, true);
 	mutex_unlock(&mc_bus->scan_mutex);
 	if (error < 0) {
 		fsl_mc_cleanup_all_resource_pools(mc_bus_dev);
@@ -409,7 +412,7 @@ static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
 		      DPRC_IRQ_EVENT_OBJ_DESTROYED |
 		      DPRC_IRQ_EVENT_OBJ_CREATED)) {
 
-		error = dprc_scan_objects(mc_dev);
+		error = dprc_scan_objects(mc_dev, true);
 		if (error < 0) {
 			/*
 			 * If the error is -ENXIO, we ignore it, as it indicates
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 03/10] bus/fsl-mc: add support for 'driver_override' in the mc-bus
  2020-03-19 15:40 [PATCH 00/10] bus/fsl-mc: Extend mc-bus driver functionalities in preparation for mc-bus VFIO support Diana Craciun
  2020-03-19 15:40 ` [PATCH 01/10] bus/fsl-mc: Do no longer export the total number of irqs outside dprc_scan_objects Diana Craciun
  2020-03-19 15:40 ` [PATCH 02/10] bus/fsl-mc: Add a new parameter to dprc_scan_objects function Diana Craciun
@ 2020-03-19 15:40 ` Diana Craciun
  2020-03-23 12:30   ` Laurentiu Tudor
  2020-03-19 15:40 ` [PATCH 04/10] bus/fsl-mc: Propagate driver_override for a child DPRC's children Diana Craciun
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Diana Craciun @ 2020-03-19 15:40 UTC (permalink / raw)
  To: linux-kernel, laurentiu.tudor, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Bharat Bhushan, Diana Craciun

From: Bharat Bhushan <Bharat.Bhushan@nxp.com>

This patch is required for vfio-fsl-mc meta driver to successfully bind
layerscape container devices for device passthrough. This patch adds
a mechanism to allow a layerscape device to specify a driver rather than
a layerscape driver provide a device match.

Example to allow a device (dprc.1) to specifically bind
with driver (vfio-fsl-mc):-
 - echo vfio-fsl-mc > /sys/bus/fsl-mc/devices/dprc.1/driver_override
 - echo dprc.1 > /sys/bus/fsl-mc/drivers/fsl_mc_dprc/unbind
 - echo dprc.1 > /sys/bus/fsl-mc/drivers/vfio-fsl-mc/bind

Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
---
 drivers/bus/fsl-mc/fsl-mc-bus.c | 54 +++++++++++++++++++++++++++++++++
 include/linux/fsl/mc.h          |  1 +
 2 files changed, 55 insertions(+)

diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index c78d10ea641f..baf8259262a9 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -3,6 +3,7 @@
  * Freescale Management Complex (MC) bus driver
  *
  * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2019-2020 NXP
  * Author: German Rivera <German.Rivera@freescale.com>
  *
  */
@@ -83,6 +84,12 @@ static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv)
 	struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
 	bool found = false;
 
+	/* When driver_override is set, only bind to the matching driver */
+	if (mc_dev->driver_override) {
+		found = !strcmp(mc_dev->driver_override, mc_drv->driver.name);
+		goto out;
+	}
+
 	if (!mc_drv->match_id_table)
 		goto out;
 
@@ -147,8 +154,52 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR_RO(modalias);
 
+static ssize_t driver_override_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+	const char *driver_override, *old = mc_dev->driver_override;
+	char *cp;
+
+	if (WARN_ON(dev->bus != &fsl_mc_bus_type))
+		return -EINVAL;
+
+	if (count >= (PAGE_SIZE - 1))
+		return -EINVAL;
+
+	driver_override = kstrndup(buf, count, GFP_KERNEL);
+	if (!driver_override)
+		return -ENOMEM;
+
+	cp = strchr(driver_override, '\n');
+	if (cp)
+		*cp = '\0';
+
+	if (strlen(driver_override)) {
+		mc_dev->driver_override = driver_override;
+	} else {
+		kfree(driver_override);
+		mc_dev->driver_override = NULL;
+	}
+
+	kfree(old);
+
+	return count;
+}
+
+static ssize_t driver_override_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", mc_dev->driver_override);
+}
+static DEVICE_ATTR_RW(driver_override);
+
 static struct attribute *fsl_mc_dev_attrs[] = {
 	&dev_attr_modalias.attr,
+	&dev_attr_driver_override.attr,
 	NULL,
 };
 
@@ -704,6 +755,9 @@ EXPORT_SYMBOL_GPL(fsl_mc_device_add);
  */
 void fsl_mc_device_remove(struct fsl_mc_device *mc_dev)
 {
+	kfree(mc_dev->driver_override);
+	mc_dev->driver_override = NULL;
+
 	/*
 	 * The device-specific remove callback will get invoked by device_del()
 	 */
diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
index 54d9436600c7..88095fd30c80 100644
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -194,6 +194,7 @@ struct fsl_mc_device {
 	struct fsl_mc_device_irq **irqs;
 	struct fsl_mc_resource *resource;
 	struct device_link *consumer_link;
+	const char *driver_override;
 };
 
 #define to_fsl_mc_device(_dev) \
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 04/10] bus/fsl-mc: Propagate driver_override for a child DPRC's children
  2020-03-19 15:40 [PATCH 00/10] bus/fsl-mc: Extend mc-bus driver functionalities in preparation for mc-bus VFIO support Diana Craciun
                   ` (2 preceding siblings ...)
  2020-03-19 15:40 ` [PATCH 03/10] bus/fsl-mc: add support for 'driver_override' in the mc-bus Diana Craciun
@ 2020-03-19 15:40 ` Diana Craciun
  2020-03-23 12:35   ` Laurentiu Tudor
  2020-03-19 15:40 ` [PATCH 05/10] bus/fsl-mc: Set the QMAN/BMAN region flags Diana Craciun
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Diana Craciun @ 2020-03-19 15:40 UTC (permalink / raw)
  To: linux-kernel, laurentiu.tudor, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Bharat Bhushan, J . German Rivera, Stuart Yoder, Diana Craciun

From: Bharat Bhushan <Bharat.Bhushan@nxp.com>

When a child DPRC is bound to the vfio_fsl_mc driver via
driver_override, its own children should not be bound to corresponding
host kernel drivers, but instead should be bound to the vfio_fsl_mc
driver as well.

Currently, when a child container is scanned by the vfio_fsl_mc
driver, child devices found are automatically bound to corresponding
host kernel drivers (e.g., DPMCP and DPBP objects are bound to the
fsl_mc_allocator driver, DPNI objects are bound to the ldpaa_eth
driver, etc), Then, the user has to manually unbind these child
devices from their drivers, set the driver_override sysfs attribute
to vfio_fsl_mc driver, for each of them and rebind them.

Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
---
 drivers/bus/fsl-mc/dprc-driver.c    | 12 ++++++++----
 drivers/bus/fsl-mc/fsl-mc-bus.c     | 18 +++++++++++++++++-
 drivers/bus/fsl-mc/fsl-mc-private.h |  2 ++
 include/linux/fsl/mc.h              |  2 ++
 4 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
index d373b28abe2d..7eaf78900dfc 100644
--- a/drivers/bus/fsl-mc/dprc-driver.c
+++ b/drivers/bus/fsl-mc/dprc-driver.c
@@ -155,6 +155,8 @@ static void check_plugged_state_change(struct fsl_mc_device *mc_dev,
  * dprc_add_new_devices - Adds devices to the logical bus for a DPRC
  *
  * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
+ * @driver_override: driver override to apply to new objects found in the
+ * DPRC, or NULL, if none.
  * @obj_desc_array: array of device descriptors for child devices currently
  * present in the physical DPRC.
  * @num_child_objects_in_mc: number of entries in obj_desc_array
@@ -164,6 +166,7 @@ static void check_plugged_state_change(struct fsl_mc_device *mc_dev,
  * in the physical DPRC.
  */
 static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
+				 const char *driver_override,
 				 struct fsl_mc_obj_desc *obj_desc_array,
 				 int num_child_objects_in_mc)
 {
@@ -188,7 +191,7 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
 		}
 
 		error = fsl_mc_device_add(obj_desc, NULL, &mc_bus_dev->dev,
-					  &child_dev);
+					  driver_override, &child_dev);
 		if (error < 0)
 			continue;
 	}
@@ -214,6 +217,7 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
  * of the device drivers for the non-allocatable devices.
  */
 static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+			    const char *driver_override,
 			    bool alloc_interrupts)
 {
 	int num_child_objects;
@@ -313,7 +317,7 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
 	dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
 			    num_child_objects);
 
-	dprc_add_new_devices(mc_bus_dev, child_obj_desc_array,
+	dprc_add_new_devices(mc_bus_dev, driver_override, child_obj_desc_array,
 			     num_child_objects);
 
 	if (child_obj_desc_array)
@@ -342,7 +346,7 @@ static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 	 * Discover objects in the DPRC:
 	 */
 	mutex_lock(&mc_bus->scan_mutex);
-	error = dprc_scan_objects(mc_bus_dev, true);
+	error = dprc_scan_objects(mc_bus_dev, NULL, true);
 	mutex_unlock(&mc_bus->scan_mutex);
 	if (error < 0) {
 		fsl_mc_cleanup_all_resource_pools(mc_bus_dev);
@@ -412,7 +416,7 @@ static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
 		      DPRC_IRQ_EVENT_OBJ_DESTROYED |
 		      DPRC_IRQ_EVENT_OBJ_CREATED)) {
 
-		error = dprc_scan_objects(mc_dev, true);
+		error = dprc_scan_objects(mc_dev, NULL, true);
 		if (error < 0) {
 			/*
 			 * If the error is -ENXIO, we ignore it, as it indicates
diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index baf8259262a9..b9ccac9862b7 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -617,6 +617,7 @@ static void fsl_mc_device_release(struct device *dev)
 int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
 		      struct fsl_mc_io *mc_io,
 		      struct device *parent_dev,
+		      const char *driver_override,
 		      struct fsl_mc_device **new_mc_dev)
 {
 	int error;
@@ -649,6 +650,19 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
 
 	mc_dev->obj_desc = *obj_desc;
 	mc_dev->mc_io = mc_io;
+
+	if (driver_override) {
+		/*
+		 * We trust driver_override, so we don't need to use
+		 * kstrndup() here
+		 */
+		mc_dev->driver_override = kstrdup(driver_override, GFP_KERNEL);
+		if (!mc_dev->driver_override) {
+			error = -ENOMEM;
+			goto error_cleanup_dev;
+		}
+	}
+
 	device_initialize(&mc_dev->dev);
 	mc_dev->dev.parent = parent_dev;
 	mc_dev->dev.bus = &fsl_mc_bus_type;
@@ -740,6 +754,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
 
 error_cleanup_dev:
 	kfree(mc_dev->regions);
+	kfree(mc_dev->driver_override);
 	kfree(mc_bus);
 	kfree(mc_dev);
 
@@ -980,7 +995,8 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
 	obj_desc.irq_count = 1;
 	obj_desc.region_count = 0;
 
-	error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, &mc_bus_dev);
+	error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, NULL,
+				 &mc_bus_dev);
 	if (error < 0)
 		goto error_cleanup_mc_io;
 
diff --git a/drivers/bus/fsl-mc/fsl-mc-private.h b/drivers/bus/fsl-mc/fsl-mc-private.h
index 21ca8c756ee7..be6bb0fb4603 100644
--- a/drivers/bus/fsl-mc/fsl-mc-private.h
+++ b/drivers/bus/fsl-mc/fsl-mc-private.h
@@ -3,6 +3,7 @@
  * Freescale Management Complex (MC) bus private declarations
  *
  * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2019-2020 NXP
  *
  */
 #ifndef _FSL_MC_PRIVATE_H_
@@ -567,6 +568,7 @@ struct fsl_mc_bus {
 int __must_check fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
 				   struct fsl_mc_io *mc_io,
 				   struct device *parent_dev,
+				   const char *driver_override,
 				   struct fsl_mc_device **new_mc_dev);
 
 void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);
diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
index 88095fd30c80..f997f8091408 100644
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -3,6 +3,7 @@
  * Freescale Management Complex (MC) bus public interface
  *
  * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2019-2020 NXP
  * Author: German Rivera <German.Rivera@freescale.com>
  *
  */
@@ -161,6 +162,7 @@ struct fsl_mc_obj_desc {
  * @regions: pointer to array of MMIO region entries
  * @irqs: pointer to array of pointers to interrupts allocated to this device
  * @resource: generic resource associated with this MC object device, if any.
+ * @driver_override: Driver name to force a match
  *
  * Generic device object for MC object devices that are "attached" to a
  * MC bus.
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 05/10] bus/fsl-mc: Set the QMAN/BMAN region flags
  2020-03-19 15:40 [PATCH 00/10] bus/fsl-mc: Extend mc-bus driver functionalities in preparation for mc-bus VFIO support Diana Craciun
                   ` (3 preceding siblings ...)
  2020-03-19 15:40 ` [PATCH 04/10] bus/fsl-mc: Propagate driver_override for a child DPRC's children Diana Craciun
@ 2020-03-19 15:40 ` Diana Craciun
  2020-03-19 15:40 ` [PATCH 06/10] bus/fsl-mc: Add dprc-reset-container support Diana Craciun
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Diana Craciun @ 2020-03-19 15:40 UTC (permalink / raw)
  To: linux-kernel, laurentiu.tudor, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Diana Craciun

The QMAN region is memory mapped, so it should be of type
IORESOURCE_MEM. The region flags bits were wrongly used to
pass additional information. Use the bus specific bits for
this purpose.

Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
---
 drivers/bus/fsl-mc/fsl-mc-bus.c     | 7 ++-----
 drivers/bus/fsl-mc/fsl-mc-private.h | 6 ------
 2 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index b9ccac9862b7..a99a0edef252 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -571,11 +571,8 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev,
 
 		regions[i].end = regions[i].start + region_desc.size - 1;
 		regions[i].name = "fsl-mc object MMIO region";
-		regions[i].flags = IORESOURCE_IO;
-		if (region_desc.flags & DPRC_REGION_CACHEABLE)
-			regions[i].flags |= IORESOURCE_CACHEABLE;
-		if (region_desc.flags & DPRC_REGION_SHAREABLE)
-			regions[i].flags |= IORESOURCE_MEM;
+		regions[i].flags = region_desc.flags & IORESOURCE_BITS;
+		regions[i].flags |= IORESOURCE_MEM;
 	}
 
 	mc_dev->regions = regions;
diff --git a/drivers/bus/fsl-mc/fsl-mc-private.h b/drivers/bus/fsl-mc/fsl-mc-private.h
index be6bb0fb4603..81b9a9b16698 100644
--- a/drivers/bus/fsl-mc/fsl-mc-private.h
+++ b/drivers/bus/fsl-mc/fsl-mc-private.h
@@ -359,12 +359,6 @@ int dprc_set_obj_irq(struct fsl_mc_io *mc_io,
 		     int obj_id,
 		     u8 irq_index,
 		     struct dprc_irq_cfg *irq_cfg);
-
-/* Region flags */
-/* Cacheable - Indicates that region should be mapped as cacheable */
-#define DPRC_REGION_CACHEABLE	0x00000001
-#define DPRC_REGION_SHAREABLE	0x00000002
-
 /**
  * enum dprc_region_type - Region type
  * @DPRC_REGION_TYPE_MC_PORTAL: MC portal region
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 06/10] bus/fsl-mc: Add dprc-reset-container support
  2020-03-19 15:40 [PATCH 00/10] bus/fsl-mc: Extend mc-bus driver functionalities in preparation for mc-bus VFIO support Diana Craciun
                   ` (4 preceding siblings ...)
  2020-03-19 15:40 ` [PATCH 05/10] bus/fsl-mc: Set the QMAN/BMAN region flags Diana Craciun
@ 2020-03-19 15:40 ` Diana Craciun
  2020-03-19 15:40 ` [PATCH 07/10] bus/fsl-mc: Export a dprc scan function to be used by multiple entities Diana Craciun
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Diana Craciun @ 2020-03-19 15:40 UTC (permalink / raw)
  To: linux-kernel, laurentiu.tudor, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Bharat Bhushan, Diana Craciun

From: Bharat Bhushan <Bharat.Bhushan@nxp.com>

DPRC reset is required by VFIO-mc in order to stop a device
to further generate DMA transactions.

Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
---
 drivers/bus/fsl-mc/dprc.c           | 41 +++++++++++++++++++++++++++++
 drivers/bus/fsl-mc/fsl-mc-private.h |  5 ++++
 include/linux/fsl/mc.h              |  5 ++++
 3 files changed, 51 insertions(+)

diff --git a/drivers/bus/fsl-mc/dprc.c b/drivers/bus/fsl-mc/dprc.c
index 602f030d84eb..5ae17fd957ba 100644
--- a/drivers/bus/fsl-mc/dprc.c
+++ b/drivers/bus/fsl-mc/dprc.c
@@ -72,6 +72,47 @@ int dprc_close(struct fsl_mc_io *mc_io,
 }
 EXPORT_SYMBOL_GPL(dprc_close);
 
+/**
+ * dprc_reset_container - Reset child container.
+ * @mc_io:	Pointer to MC portal's I/O object
+ * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token:	Token of DPRC object
+ * @child_container_id:	ID of the container to reset
+ *
+ * In case a software context crashes or becomes non-responsive, the parent
+ * may wish to reset its resources container before the software context is
+ * restarted.
+ *
+ * This routine informs all objects assigned to the child container that the
+ * container is being reset, so they may perform any cleanup operations that are
+ * needed. All objects handles that were owned by the child container shall be
+ * closed.
+ *
+ * Note that such request may be submitted even if the child software context
+ * has not crashed, but the resulting object cleanup operations will not be
+ * aware of that.
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dprc_reset_container(struct fsl_mc_io *mc_io,
+			 u32 cmd_flags,
+			 u16 token,
+			 int child_container_id)
+{
+	struct fsl_mc_command cmd = { 0 };
+	struct dprc_cmd_reset_container *cmd_params;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_RESET_CONT,
+					  cmd_flags, token);
+	cmd_params = (struct dprc_cmd_reset_container *)cmd.params;
+	cmd_params->child_container_id = cpu_to_le32(child_container_id);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+EXPORT_SYMBOL_GPL(dprc_reset_container);
+
 /**
  * dprc_set_irq() - Set IRQ information for the DPRC to trigger an interrupt.
  * @mc_io:	Pointer to MC portal's I/O object
diff --git a/drivers/bus/fsl-mc/fsl-mc-private.h b/drivers/bus/fsl-mc/fsl-mc-private.h
index 81b9a9b16698..66ccf7fb34af 100644
--- a/drivers/bus/fsl-mc/fsl-mc-private.h
+++ b/drivers/bus/fsl-mc/fsl-mc-private.h
@@ -92,6 +92,7 @@ int dpmcp_reset(struct fsl_mc_io *mc_io,
 #define DPRC_CMDID_GET_API_VERSION              DPRC_CMD(0xa05)
 
 #define DPRC_CMDID_GET_ATTR                     DPRC_CMD(0x004)
+#define DPRC_CMDID_RESET_CONT                   DPRC_CMD(0x005)
 
 #define DPRC_CMDID_SET_IRQ                      DPRC_CMD(0x010)
 #define DPRC_CMDID_SET_IRQ_ENABLE               DPRC_CMD(0x012)
@@ -112,6 +113,10 @@ struct dprc_cmd_open {
 	__le32 container_id;
 };
 
+struct dprc_cmd_reset_container {
+	__le32 child_container_id;
+};
+
 struct dprc_cmd_set_irq {
 	/* cmd word 0 */
 	__le32 irq_val;
diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
index f997f8091408..b9d5e5955adb 100644
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -471,6 +471,11 @@ static inline bool is_fsl_mc_bus_dpseci(const struct fsl_mc_device *mc_dev)
 	return mc_dev->dev.type == &fsl_mc_bus_dpseci_type;
 }
 
+int dprc_reset_container(struct fsl_mc_io *mc_io,
+			 u32 cmd_flags,
+			 u16 token,
+			 int child_container_id);
+
 /*
  * Data Path Buffer Pool (DPBP) API
  * Contains initialization APIs and runtime control APIs for DPBP
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 07/10] bus/fsl-mc: Export a dprc scan function to be used by multiple entities
  2020-03-19 15:40 [PATCH 00/10] bus/fsl-mc: Extend mc-bus driver functionalities in preparation for mc-bus VFIO support Diana Craciun
                   ` (5 preceding siblings ...)
  2020-03-19 15:40 ` [PATCH 06/10] bus/fsl-mc: Add dprc-reset-container support Diana Craciun
@ 2020-03-19 15:40 ` Diana Craciun
  2020-03-23 12:48   ` Laurentiu Tudor
  2020-03-19 15:40 ` [PATCH 08/10] bus/fsl-mc: Export a cleanup function for DPRC Diana Craciun
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Diana Craciun @ 2020-03-19 15:40 UTC (permalink / raw)
  To: linux-kernel, laurentiu.tudor, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Diana Craciun

Currently the DPRC scan function is used only by the bus driver.
But the same functionality will be needed by the VFIO driver.
To support this, the dprc scan function was exported and a little
bit adjusted to fit both scenarios.

Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
---
 drivers/bus/fsl-mc/dprc-driver.c | 15 ++++++---------
 drivers/bus/fsl-mc/fsl-mc-bus.c  |  2 ++
 include/linux/fsl/mc.h           |  4 ++++
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
index 7eaf78900dfc..789220f0372a 100644
--- a/drivers/bus/fsl-mc/dprc-driver.c
+++ b/drivers/bus/fsl-mc/dprc-driver.c
@@ -335,7 +335,9 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
  * bus driver with the actual state of the MC by adding and removing
  * devices as appropriate.
  */
-static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
+int dprc_scan_container(struct fsl_mc_device *mc_bus_dev,
+		   const char *driver_override,
+		   bool alloc_interrupts)
 {
 	int error;
 	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
@@ -346,15 +348,12 @@ static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 	 * Discover objects in the DPRC:
 	 */
 	mutex_lock(&mc_bus->scan_mutex);
-	error = dprc_scan_objects(mc_bus_dev, NULL, true);
+	error = dprc_scan_objects(mc_bus_dev, driver_override, alloc_interrupts);
 	mutex_unlock(&mc_bus->scan_mutex);
-	if (error < 0) {
-		fsl_mc_cleanup_all_resource_pools(mc_bus_dev);
-		return error;
-	}
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dprc_scan_container);
 
 /**
  * dprc_irq0_handler - Regular ISR for DPRC interrupt 0
@@ -679,12 +678,10 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 		goto error_cleanup_open;
 	}
 
-	mutex_init(&mc_bus->scan_mutex);
-
 	/*
 	 * Discover MC objects in DPRC object:
 	 */
-	error = dprc_scan_container(mc_dev);
+	error = dprc_scan_container(mc_dev, NULL, true);
 	if (error < 0)
 		goto error_cleanup_open;
 
diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index a99a0edef252..1865221bb12d 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -635,7 +635,9 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
 		if (!mc_bus)
 			return -ENOMEM;
 
+		mutex_init(&mc_bus->scan_mutex);
 		mc_dev = &mc_bus->mc_dev;
+
 	} else {
 		/*
 		 * Allocate a regular fsl_mc_device object:
diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
index b9d5e5955adb..2bdd96a482fb 100644
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -476,6 +476,10 @@ int dprc_reset_container(struct fsl_mc_io *mc_io,
 			 u16 token,
 			 int child_container_id);
 
+int dprc_scan_container(struct fsl_mc_device *mc_bus_dev,
+		   const char *driver_override,
+		   bool alloc_interrupts);
+
 /*
  * Data Path Buffer Pool (DPBP) API
  * Contains initialization APIs and runtime control APIs for DPBP
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 08/10] bus/fsl-mc: Export a cleanup function for DPRC
  2020-03-19 15:40 [PATCH 00/10] bus/fsl-mc: Extend mc-bus driver functionalities in preparation for mc-bus VFIO support Diana Craciun
                   ` (6 preceding siblings ...)
  2020-03-19 15:40 ` [PATCH 07/10] bus/fsl-mc: Export a dprc scan function to be used by multiple entities Diana Craciun
@ 2020-03-19 15:40 ` Diana Craciun
  2020-03-23 12:52   ` Laurentiu Tudor
  2020-03-19 15:40 ` [PATCH 09/10] bus/fsl-mc: Add a container setup function Diana Craciun
  2020-03-19 15:40 ` [PATCH 10/10] bus/fsl-mc: Export IRQ pool handling functions to be used by VFIO Diana Craciun
  9 siblings, 1 reply; 19+ messages in thread
From: Diana Craciun @ 2020-03-19 15:40 UTC (permalink / raw)
  To: linux-kernel, laurentiu.tudor, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Diana Craciun

Create and export a cleanup function for DPRC. The function
is used by the DPRC driver, but it will be used by the VFIO
driver as well.

Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
---
 drivers/bus/fsl-mc/dprc-driver.c | 52 ++++++++++++++++++++++++--------
 include/linux/fsl/mc.h           |  2 ++
 2 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
index 789220f0372a..a655e3fee291 100644
--- a/drivers/bus/fsl-mc/dprc-driver.c
+++ b/drivers/bus/fsl-mc/dprc-driver.c
@@ -725,33 +725,25 @@ static void dprc_teardown_irq(struct fsl_mc_device *mc_dev)
 }
 
 /**
- * dprc_remove - callback invoked when a DPRC is being unbound from this driver
+ * dprc_cleanup - function that cleanups a DPRC
  *
  * @mc_dev: Pointer to fsl-mc device representing the DPRC
  *
- * It removes the DPRC's child objects from Linux (not from the MC) and
- * closes the DPRC device in the MC.
- * It tears down the interrupts that were configured for the DPRC device.
+ * It closes the DPRC device in the MC.
  * It destroys the interrupt pool associated with this MC bus.
  */
-static int dprc_remove(struct fsl_mc_device *mc_dev)
+
+int dprc_cleanup(struct fsl_mc_device *mc_dev)
 {
 	int error;
 	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
 
 	if (!is_fsl_mc_bus_dprc(mc_dev))
 		return -EINVAL;
-	if (!mc_dev->mc_io)
-		return -EINVAL;
 
-	if (!mc_bus->irq_resources)
+	if (!mc_dev->mc_io)
 		return -EINVAL;
 
-	if (dev_get_msi_domain(&mc_dev->dev))
-		dprc_teardown_irq(mc_dev);
-
-	device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove);
-
 	if (dev_get_msi_domain(&mc_dev->dev)) {
 		fsl_mc_cleanup_irq_pool(mc_bus);
 		dev_set_msi_domain(&mc_dev->dev, NULL);
@@ -768,6 +760,40 @@ static int dprc_remove(struct fsl_mc_device *mc_dev)
 		mc_dev->mc_io = NULL;
 	}
 
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dprc_cleanup);
+
+/**
+ * dprc_remove - callback invoked when a DPRC is being unbound from this driver
+ *
+ * @mc_dev: Pointer to fsl-mc device representing the DPRC
+ *
+ * It removes the DPRC's child objects from Linux (not from the MC) and
+ * closes the DPRC device in the MC.
+ * It tears down the interrupts that were configured for the DPRC device.
+ * It destroys the interrupt pool associated with this MC bus.
+ */
+static int dprc_remove(struct fsl_mc_device *mc_dev)
+{
+	int error;
+	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+
+	if (!is_fsl_mc_bus_dprc(mc_dev))
+		return -EINVAL;
+
+	if (!mc_bus->irq_resources)
+		return -EINVAL;
+
+	if (dev_get_msi_domain(&mc_dev->dev))
+		dprc_teardown_irq(mc_dev);
+
+	device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove);
+
+	error = dprc_cleanup(mc_dev);
+	if (error < 0)
+		dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);
+
 	dev_info(&mc_dev->dev, "DPRC device unbound from driver");
 	return 0;
 }
diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
index 2bdd96a482fb..e3ba273a1122 100644
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -480,6 +480,8 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev,
 		   const char *driver_override,
 		   bool alloc_interrupts);
 
+int dprc_cleanup(struct fsl_mc_device *mc_dev);
+
 /*
  * Data Path Buffer Pool (DPBP) API
  * Contains initialization APIs and runtime control APIs for DPBP
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 09/10] bus/fsl-mc: Add a container setup function
  2020-03-19 15:40 [PATCH 00/10] bus/fsl-mc: Extend mc-bus driver functionalities in preparation for mc-bus VFIO support Diana Craciun
                   ` (7 preceding siblings ...)
  2020-03-19 15:40 ` [PATCH 08/10] bus/fsl-mc: Export a cleanup function for DPRC Diana Craciun
@ 2020-03-19 15:40 ` Diana Craciun
  2020-03-23 13:06   ` Laurentiu Tudor
  2020-03-19 15:40 ` [PATCH 10/10] bus/fsl-mc: Export IRQ pool handling functions to be used by VFIO Diana Craciun
  9 siblings, 1 reply; 19+ messages in thread
From: Diana Craciun @ 2020-03-19 15:40 UTC (permalink / raw)
  To: linux-kernel, laurentiu.tudor, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Diana Craciun

Both DPRC driver and VFIO driver use a initialization code
for the DPRC. Introduced a new function which groups this
initialization code. The function is exported and may be
used by VFIO as well.

Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
---
 drivers/bus/fsl-mc/dprc-driver.c | 77 +++++++++++++++++++++-----------
 drivers/bus/fsl-mc/mc-io.c       |  7 ++-
 include/linux/fsl/mc.h           |  2 +
 3 files changed, 60 insertions(+), 26 deletions(-)

diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
index a655e3fee291..0fe45c301858 100644
--- a/drivers/bus/fsl-mc/dprc-driver.c
+++ b/drivers/bus/fsl-mc/dprc-driver.c
@@ -570,16 +570,15 @@ static int dprc_setup_irq(struct fsl_mc_device *mc_dev)
 }
 
 /**
- * dprc_probe - callback invoked when a DPRC is being bound to this driver
+ * dprc_setup - opens and creates a mc_io for DPRC
  *
  * @mc_dev: Pointer to fsl-mc device representing a DPRC
  *
  * It opens the physical DPRC in the MC.
- * It scans the DPRC to discover the MC objects contained in it.
- * It creates the interrupt pool for the MC bus associated with the DPRC.
- * It configures the interrupts for the DPRC device itself.
+ * It configures the DPRC portal used to communicate with MC
  */
-static int dprc_probe(struct fsl_mc_device *mc_dev)
+
+int dprc_setup(struct fsl_mc_device *mc_dev)
 {
 	int error;
 	size_t region_size;
@@ -589,12 +588,6 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 	bool msi_domain_set = false;
 	u16 major_ver, minor_ver;
 
-	if (!is_fsl_mc_bus_dprc(mc_dev))
-		return -EINVAL;
-
-	if (dev_get_msi_domain(&mc_dev->dev))
-		return -EINVAL;
-
 	if (!mc_dev->mc_io) {
 		/*
 		 * This is a child DPRC:
@@ -678,35 +671,69 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 		goto error_cleanup_open;
 	}
 
+	return 0;
+
+error_cleanup_open:
+	(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
+
+error_cleanup_msi_domain:
+	if (msi_domain_set)
+		dev_set_msi_domain(&mc_dev->dev, NULL);
+
+	if (mc_io_created) {
+		fsl_destroy_mc_io(mc_dev->mc_io);
+		mc_dev->mc_io = NULL;
+	}
+
+	return error;
+}
+EXPORT_SYMBOL_GPL(dprc_setup);
+
+/**
+ * dprc_probe - callback invoked when a DPRC is being bound to this driver
+ *
+ * @mc_dev: Pointer to fsl-mc device representing a DPRC
+ *
+ * It opens the physical DPRC in the MC.
+ * It scans the DPRC to discover the MC objects contained in it.
+ * It creates the interrupt pool for the MC bus associated with the DPRC.
+ * It configures the interrupts for the DPRC device itself.
+ */
+static int dprc_probe(struct fsl_mc_device *mc_dev)
+{
+	int error;
+
+	if (!is_fsl_mc_bus_dprc(mc_dev))
+		return -EINVAL;
+
+	if (dev_get_msi_domain(&mc_dev->dev))
+		return -EINVAL;
+
+	error = dprc_setup(mc_dev);
+	if (error < 0)
+		return error;
+
 	/*
 	 * Discover MC objects in DPRC object:
 	 */
 	error = dprc_scan_container(mc_dev, NULL, true);
 	if (error < 0)
-		goto error_cleanup_open;
+		goto dprc_cleanup;
 
 	/*
 	 * Configure interrupt for the DPRC object associated with this MC bus:
 	 */
 	error = dprc_setup_irq(mc_dev);
 	if (error < 0)
-		goto error_cleanup_open;
+		goto scan_cleanup;
 
 	dev_info(&mc_dev->dev, "DPRC device bound to driver");
 	return 0;
 
-error_cleanup_open:
-	(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
-
-error_cleanup_msi_domain:
-	if (msi_domain_set)
-		dev_set_msi_domain(&mc_dev->dev, NULL);
-
-	if (mc_io_created) {
-		fsl_destroy_mc_io(mc_dev->mc_io);
-		mc_dev->mc_io = NULL;
-	}
-
+scan_cleanup:
+	device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove);
+dprc_cleanup:
+	dprc_cleanup(mc_dev);
 	return error;
 }
 
diff --git a/drivers/bus/fsl-mc/mc-io.c b/drivers/bus/fsl-mc/mc-io.c
index 6ae48ad80409..e1dfe4a76519 100644
--- a/drivers/bus/fsl-mc/mc-io.c
+++ b/drivers/bus/fsl-mc/mc-io.c
@@ -129,7 +129,12 @@ int __must_check fsl_create_mc_io(struct device *dev,
  */
 void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
 {
-	struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
+	struct fsl_mc_device *dpmcp_dev;
+
+	if (!mc_io)
+		return;
+
+	dpmcp_dev = mc_io->dpmcp_dev;
 
 	if (dpmcp_dev)
 		fsl_mc_io_unset_dpmcp(mc_io);
diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
index e3ba273a1122..59b39c635ec9 100644
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -480,6 +480,8 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev,
 		   const char *driver_override,
 		   bool alloc_interrupts);
 
+int dprc_setup(struct fsl_mc_device *mc_dev);
+
 int dprc_cleanup(struct fsl_mc_device *mc_dev);
 
 /*
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 10/10] bus/fsl-mc: Export IRQ pool handling functions to be used by VFIO
  2020-03-19 15:40 [PATCH 00/10] bus/fsl-mc: Extend mc-bus driver functionalities in preparation for mc-bus VFIO support Diana Craciun
                   ` (8 preceding siblings ...)
  2020-03-19 15:40 ` [PATCH 09/10] bus/fsl-mc: Add a container setup function Diana Craciun
@ 2020-03-19 15:40 ` Diana Craciun
  9 siblings, 0 replies; 19+ messages in thread
From: Diana Craciun @ 2020-03-19 15:40 UTC (permalink / raw)
  To: linux-kernel, laurentiu.tudor, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Diana Craciun

The IRQ pool handling functions can be used by both DPRC
driver and VFIO. Adapt and export those functions.

Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
---
 drivers/bus/fsl-mc/dprc-driver.c      |  5 ++---
 drivers/bus/fsl-mc/fsl-mc-allocator.c | 12 ++++++++----
 drivers/bus/fsl-mc/fsl-mc-private.h   | 10 ----------
 include/linux/fsl/mc.h                | 11 +++++++++++
 4 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
index 0fe45c301858..2a64172c0101 100644
--- a/drivers/bus/fsl-mc/dprc-driver.c
+++ b/drivers/bus/fsl-mc/dprc-driver.c
@@ -307,7 +307,7 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
 		}
 
 		if (alloc_interrupts && !mc_bus->irq_resources) {
-			error = fsl_mc_populate_irq_pool(mc_bus,
+			error = fsl_mc_populate_irq_pool(mc_bus_dev,
 				FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
 			if (error < 0)
 				return error;
@@ -763,7 +763,6 @@ static void dprc_teardown_irq(struct fsl_mc_device *mc_dev)
 int dprc_cleanup(struct fsl_mc_device *mc_dev)
 {
 	int error;
-	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
 
 	if (!is_fsl_mc_bus_dprc(mc_dev))
 		return -EINVAL;
@@ -772,7 +771,7 @@ int dprc_cleanup(struct fsl_mc_device *mc_dev)
 		return -EINVAL;
 
 	if (dev_get_msi_domain(&mc_dev->dev)) {
-		fsl_mc_cleanup_irq_pool(mc_bus);
+		fsl_mc_cleanup_irq_pool(mc_dev);
 		dev_set_msi_domain(&mc_dev->dev, NULL);
 	}
 
diff --git a/drivers/bus/fsl-mc/fsl-mc-allocator.c b/drivers/bus/fsl-mc/fsl-mc-allocator.c
index cc7bb900f524..e71a6f52ea0c 100644
--- a/drivers/bus/fsl-mc/fsl-mc-allocator.c
+++ b/drivers/bus/fsl-mc/fsl-mc-allocator.c
@@ -344,7 +344,7 @@ EXPORT_SYMBOL_GPL(fsl_mc_object_free);
  * Initialize the interrupt pool associated with an fsl-mc bus.
  * It allocates a block of IRQs from the GIC-ITS.
  */
-int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
+int fsl_mc_populate_irq_pool(struct fsl_mc_device *mc_bus_dev,
 			     unsigned int irq_count)
 {
 	unsigned int i;
@@ -352,10 +352,14 @@ int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
 	struct fsl_mc_device_irq *irq_resources;
 	struct fsl_mc_device_irq *mc_dev_irq;
 	int error;
-	struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
 	struct fsl_mc_resource_pool *res_pool =
 			&mc_bus->resource_pools[FSL_MC_POOL_IRQ];
 
+	/* do nothing if the IRQ pool is already populated */
+	if (mc_bus->irq_resources)
+		return 0;
+
 	if (irq_count == 0 ||
 	    irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS)
 		return -EINVAL;
@@ -407,9 +411,9 @@ EXPORT_SYMBOL_GPL(fsl_mc_populate_irq_pool);
  * Teardown the interrupt pool associated with an fsl-mc bus.
  * It frees the IRQs that were allocated to the pool, back to the GIC-ITS.
  */
-void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus)
+void fsl_mc_cleanup_irq_pool(struct fsl_mc_device *mc_bus_dev)
 {
-	struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
 	struct fsl_mc_resource_pool *res_pool =
 			&mc_bus->resource_pools[FSL_MC_POOL_IRQ];
 
diff --git a/drivers/bus/fsl-mc/fsl-mc-private.h b/drivers/bus/fsl-mc/fsl-mc-private.h
index 66ccf7fb34af..2762e9ecb098 100644
--- a/drivers/bus/fsl-mc/fsl-mc-private.h
+++ b/drivers/bus/fsl-mc/fsl-mc-private.h
@@ -518,11 +518,6 @@ struct dpcon_cmd_set_notification {
 	__le64 user_ctx;
 };
 
-/**
- * Maximum number of total IRQs that can be pre-allocated for an MC bus'
- * IRQ pool
- */
-#define FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS	256
 
 /**
  * struct fsl_mc_resource_pool - Pool of MC resources of a given
@@ -599,11 +594,6 @@ void fsl_mc_msi_domain_free_irqs(struct device *dev);
 int fsl_mc_find_msi_domain(struct device *mc_platform_dev,
 			   struct irq_domain **mc_msi_domain);
 
-int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
-			     unsigned int irq_count);
-
-void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus);
-
 int __must_check fsl_create_mc_io(struct device *dev,
 				  phys_addr_t mc_portal_phys_addr,
 				  u32 mc_portal_size,
diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
index 59b39c635ec9..ad918b99be42 100644
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -484,6 +484,17 @@ int dprc_setup(struct fsl_mc_device *mc_dev);
 
 int dprc_cleanup(struct fsl_mc_device *mc_dev);
 
+/**
+ * Maximum number of total IRQs that can be pre-allocated for an MC bus'
+ * IRQ pool
+ */
+#define FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS	256
+
+int fsl_mc_populate_irq_pool(struct fsl_mc_device *mc_bus_dev,
+			     unsigned int irq_count);
+
+void fsl_mc_cleanup_irq_pool(struct fsl_mc_device *mc_bus_dev);
+
 /*
  * Data Path Buffer Pool (DPBP) API
  * Contains initialization APIs and runtime control APIs for DPBP
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH 02/10] bus/fsl-mc: Add a new parameter to dprc_scan_objects function
  2020-03-19 15:40 ` [PATCH 02/10] bus/fsl-mc: Add a new parameter to dprc_scan_objects function Diana Craciun
@ 2020-03-23 12:04   ` Laurentiu Tudor
  0 siblings, 0 replies; 19+ messages in thread
From: Laurentiu Tudor @ 2020-03-23 12:04 UTC (permalink / raw)
  To: Diana Craciun, linux-kernel, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav



On 3/19/2020 5:40 PM, Diana Craciun wrote:
> Prepare the dprc_scan_objects function to be used by
> the VFIO mc driver code. The function is used to scan the mc
> objects by the bus driver. The same functionality is
> needed by the VFIO mc driver, but in this case the
> interrupt configuration is delayed until the userspace
> configures the interrupts. In order to use the same function
> in both drivers add a new parameter.
> 
> Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
> ---
>  drivers/bus/fsl-mc/dprc-driver.c | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
> index 035b220779d0..d373b28abe2d 100644
> --- a/drivers/bus/fsl-mc/dprc-driver.c
> +++ b/drivers/bus/fsl-mc/dprc-driver.c
> @@ -198,7 +198,9 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
>   * dprc_scan_objects - Discover objects in a DPRC
>   *
>   * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
> - *
> + * @alloc_interrupts: if true the function allocates the interrupt pool,
> + * otherwise the interrupt allocation is delayed
> +

nit: missing * here.

---
Best Regards, Laurentiu

>   * Detects objects added and removed from a DPRC and synchronizes the
>   * state of the Linux bus driver, MC by adding and removing
>   * devices accordingly.
> @@ -211,7 +213,8 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
>   * populated before they can get allocation requests from probe callbacks
>   * of the device drivers for the non-allocatable devices.
>   */
> -static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
> +static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
> +			    bool alloc_interrupts)
>  {
>  	int num_child_objects;
>  	int dprc_get_obj_failures;
> @@ -299,7 +302,7 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
>  				 irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
>  		}
>  
> -		if (!mc_bus->irq_resources) {
> +		if (alloc_interrupts && !mc_bus->irq_resources) {
>  			error = fsl_mc_populate_irq_pool(mc_bus,
>  				FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
>  			if (error < 0)
> @@ -339,7 +342,7 @@ static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
>  	 * Discover objects in the DPRC:
>  	 */
>  	mutex_lock(&mc_bus->scan_mutex);
> -	error = dprc_scan_objects(mc_bus_dev);
> +	error = dprc_scan_objects(mc_bus_dev, true);
>  	mutex_unlock(&mc_bus->scan_mutex);
>  	if (error < 0) {
>  		fsl_mc_cleanup_all_resource_pools(mc_bus_dev);
> @@ -409,7 +412,7 @@ static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
>  		      DPRC_IRQ_EVENT_OBJ_DESTROYED |
>  		      DPRC_IRQ_EVENT_OBJ_CREATED)) {
>  
> -		error = dprc_scan_objects(mc_dev);
> +		error = dprc_scan_objects(mc_dev, true);
>  		if (error < 0) {
>  			/*
>  			 * If the error is -ENXIO, we ignore it, as it indicates
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 03/10] bus/fsl-mc: add support for 'driver_override' in the mc-bus
  2020-03-19 15:40 ` [PATCH 03/10] bus/fsl-mc: add support for 'driver_override' in the mc-bus Diana Craciun
@ 2020-03-23 12:30   ` Laurentiu Tudor
  2020-04-09 11:14     ` Diana Craciun OSS
  0 siblings, 1 reply; 19+ messages in thread
From: Laurentiu Tudor @ 2020-03-23 12:30 UTC (permalink / raw)
  To: Diana Craciun, linux-kernel, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Bharat Bhushan



On 3/19/2020 5:40 PM, Diana Craciun wrote:
> From: Bharat Bhushan <Bharat.Bhushan@nxp.com>
> 
> This patch is required for vfio-fsl-mc meta driver to successfully bind
> layerscape container devices for device passthrough. This patch adds
> a mechanism to allow a layerscape device to specify a driver rather than
> a layerscape driver provide a device match.
> 
> Example to allow a device (dprc.1) to specifically bind
> with driver (vfio-fsl-mc):-
>  - echo vfio-fsl-mc > /sys/bus/fsl-mc/devices/dprc.1/driver_override
>  - echo dprc.1 > /sys/bus/fsl-mc/drivers/fsl_mc_dprc/unbind
>  - echo dprc.1 > /sys/bus/fsl-mc/drivers/vfio-fsl-mc/bind
> 
> Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
> ---
>  drivers/bus/fsl-mc/fsl-mc-bus.c | 54 +++++++++++++++++++++++++++++++++
>  include/linux/fsl/mc.h          |  1 +
>  2 files changed, 55 insertions(+)
> 
> diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
> index c78d10ea641f..baf8259262a9 100644
> --- a/drivers/bus/fsl-mc/fsl-mc-bus.c
> +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
> @@ -3,6 +3,7 @@
>   * Freescale Management Complex (MC) bus driver
>   *
>   * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
> + * Copyright 2019-2020 NXP
>   * Author: German Rivera <German.Rivera@freescale.com>
>   *
>   */
> @@ -83,6 +84,12 @@ static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv)
>  	struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
>  	bool found = false;
>  
> +	/* When driver_override is set, only bind to the matching driver */
> +	if (mc_dev->driver_override) {
> +		found = !strcmp(mc_dev->driver_override, mc_drv->driver.name);

I think we can use sysfs_streq() here and ...


> +		goto out;
> +	}
> +
>  	if (!mc_drv->match_id_table)
>  		goto out;
>  
> @@ -147,8 +154,52 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
>  }
>  static DEVICE_ATTR_RO(modalias);
>  
> +static ssize_t driver_override_store(struct device *dev,
> +				     struct device_attribute *attr,
> +				     const char *buf, size_t count)
> +{
> +	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
> +	const char *driver_override, *old = mc_dev->driver_override;
> +	char *cp;
> +
> +	if (WARN_ON(dev->bus != &fsl_mc_bus_type))
> +		return -EINVAL;
> +
> +	if (count >= (PAGE_SIZE - 1))
> +		return -EINVAL;
> +
> +	driver_override = kstrndup(buf, count, GFP_KERNEL);
> +	if (!driver_override)
> +		return -ENOMEM;
> +
> +	cp = strchr(driver_override, '\n');
> +	if (cp)
> +		*cp = '\0';

drop this strchr() ...

> +	if (strlen(driver_override)) {
> +		mc_dev->driver_override = driver_override;
> +	} else {
> +		kfree(driver_override);
> +		mc_dev->driver_override = NULL;
> +	}
> +
> +	kfree(old);
> +
> +	return count;
> +}
> +
> +static ssize_t driver_override_show(struct device *dev,
> +				    struct device_attribute *attr, char *buf)
> +{
> +	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
> +
> +	return snprintf(buf, PAGE_SIZE, "%s\n", mc_dev->driver_override);

and also the terminating '\n' here.

> +}
> +static DEVICE_ATTR_RW(driver_override);
> +
>  static struct attribute *fsl_mc_dev_attrs[] = {
>  	&dev_attr_modalias.attr,
> +	&dev_attr_driver_override.attr,
>  	NULL,
>  };
>  
> @@ -704,6 +755,9 @@ EXPORT_SYMBOL_GPL(fsl_mc_device_add);
>   */
>  void fsl_mc_device_remove(struct fsl_mc_device *mc_dev)
>  {
> +	kfree(mc_dev->driver_override);
> +	mc_dev->driver_override = NULL;
> +
>  	/*
>  	 * The device-specific remove callback will get invoked by device_del()
>  	 */
> diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
> index 54d9436600c7..88095fd30c80 100644
> --- a/include/linux/fsl/mc.h
> +++ b/include/linux/fsl/mc.h
> @@ -194,6 +194,7 @@ struct fsl_mc_device {
>  	struct fsl_mc_device_irq **irqs;
>  	struct fsl_mc_resource *resource;
>  	struct device_link *consumer_link;
> +	const char *driver_override;

We probably don't want const here.

---
Best Regards, Laurentiu

>  };
>  
>  #define to_fsl_mc_device(_dev) \
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 04/10] bus/fsl-mc: Propagate driver_override for a child DPRC's children
  2020-03-19 15:40 ` [PATCH 04/10] bus/fsl-mc: Propagate driver_override for a child DPRC's children Diana Craciun
@ 2020-03-23 12:35   ` Laurentiu Tudor
  0 siblings, 0 replies; 19+ messages in thread
From: Laurentiu Tudor @ 2020-03-23 12:35 UTC (permalink / raw)
  To: Diana Craciun, linux-kernel, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Bharat Bhushan, J . German Rivera, Stuart Yoder



On 3/19/2020 5:40 PM, Diana Craciun wrote:
> From: Bharat Bhushan <Bharat.Bhushan@nxp.com>
> 
> When a child DPRC is bound to the vfio_fsl_mc driver via
> driver_override, its own children should not be bound to corresponding
> host kernel drivers, but instead should be bound to the vfio_fsl_mc
> driver as well.
> 
> Currently, when a child container is scanned by the vfio_fsl_mc
> driver, child devices found are automatically bound to corresponding
> host kernel drivers (e.g., DPMCP and DPBP objects are bound to the
> fsl_mc_allocator driver, DPNI objects are bound to the ldpaa_eth
> driver, etc), Then, the user has to manually unbind these child
> devices from their drivers, set the driver_override sysfs attribute
> to vfio_fsl_mc driver, for each of them and rebind them.
> 
> Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
> Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
> Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
> ---
>  drivers/bus/fsl-mc/dprc-driver.c    | 12 ++++++++----
>  drivers/bus/fsl-mc/fsl-mc-bus.c     | 18 +++++++++++++++++-
>  drivers/bus/fsl-mc/fsl-mc-private.h |  2 ++
>  include/linux/fsl/mc.h              |  2 ++
>  4 files changed, 29 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
> index d373b28abe2d..7eaf78900dfc 100644
> --- a/drivers/bus/fsl-mc/dprc-driver.c
> +++ b/drivers/bus/fsl-mc/dprc-driver.c
> @@ -155,6 +155,8 @@ static void check_plugged_state_change(struct fsl_mc_device *mc_dev,
>   * dprc_add_new_devices - Adds devices to the logical bus for a DPRC
>   *
>   * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
> + * @driver_override: driver override to apply to new objects found in the
> + * DPRC, or NULL, if none.
>   * @obj_desc_array: array of device descriptors for child devices currently
>   * present in the physical DPRC.
>   * @num_child_objects_in_mc: number of entries in obj_desc_array
> @@ -164,6 +166,7 @@ static void check_plugged_state_change(struct fsl_mc_device *mc_dev,
>   * in the physical DPRC.
>   */
>  static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
> +				 const char *driver_override,
>  				 struct fsl_mc_obj_desc *obj_desc_array,
>  				 int num_child_objects_in_mc)
>  {
> @@ -188,7 +191,7 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
>  		}
>  
>  		error = fsl_mc_device_add(obj_desc, NULL, &mc_bus_dev->dev,
> -					  &child_dev);
> +					  driver_override, &child_dev);
>  		if (error < 0)
>  			continue;
>  	}
> @@ -214,6 +217,7 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
>   * of the device drivers for the non-allocatable devices.
>   */
>  static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
> +			    const char *driver_override,
>  			    bool alloc_interrupts)
>  {
>  	int num_child_objects;
> @@ -313,7 +317,7 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
>  	dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
>  			    num_child_objects);
>  
> -	dprc_add_new_devices(mc_bus_dev, child_obj_desc_array,
> +	dprc_add_new_devices(mc_bus_dev, driver_override, child_obj_desc_array,
>  			     num_child_objects);
>  
>  	if (child_obj_desc_array)
> @@ -342,7 +346,7 @@ static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
>  	 * Discover objects in the DPRC:
>  	 */
>  	mutex_lock(&mc_bus->scan_mutex);
> -	error = dprc_scan_objects(mc_bus_dev, true);
> +	error = dprc_scan_objects(mc_bus_dev, NULL, true);
>  	mutex_unlock(&mc_bus->scan_mutex);
>  	if (error < 0) {
>  		fsl_mc_cleanup_all_resource_pools(mc_bus_dev);
> @@ -412,7 +416,7 @@ static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
>  		      DPRC_IRQ_EVENT_OBJ_DESTROYED |
>  		      DPRC_IRQ_EVENT_OBJ_CREATED)) {
>  
> -		error = dprc_scan_objects(mc_dev, true);
> +		error = dprc_scan_objects(mc_dev, NULL, true);
>  		if (error < 0) {
>  			/*
>  			 * If the error is -ENXIO, we ignore it, as it indicates
> diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
> index baf8259262a9..b9ccac9862b7 100644
> --- a/drivers/bus/fsl-mc/fsl-mc-bus.c
> +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
> @@ -617,6 +617,7 @@ static void fsl_mc_device_release(struct device *dev)
>  int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
>  		      struct fsl_mc_io *mc_io,
>  		      struct device *parent_dev,
> +		      const char *driver_override,
>  		      struct fsl_mc_device **new_mc_dev)
>  {
>  	int error;
> @@ -649,6 +650,19 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
>  
>  	mc_dev->obj_desc = *obj_desc;
>  	mc_dev->mc_io = mc_io;
> +
> +	if (driver_override) {
> +		/*
> +		 * We trust driver_override, so we don't need to use
> +		 * kstrndup() here
> +		 */
> +		mc_dev->driver_override = kstrdup(driver_override, GFP_KERNEL);
> +		if (!mc_dev->driver_override) {
> +			error = -ENOMEM;
> +			goto error_cleanup_dev;
> +		}
> +	}
> +
>  	device_initialize(&mc_dev->dev);
>  	mc_dev->dev.parent = parent_dev;
>  	mc_dev->dev.bus = &fsl_mc_bus_type;
> @@ -740,6 +754,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
>  
>  error_cleanup_dev:
>  	kfree(mc_dev->regions);
> +	kfree(mc_dev->driver_override);
>  	kfree(mc_bus);
>  	kfree(mc_dev);
>  
> @@ -980,7 +995,8 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
>  	obj_desc.irq_count = 1;
>  	obj_desc.region_count = 0;
>  
> -	error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, &mc_bus_dev);
> +	error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, NULL,
> +				 &mc_bus_dev);
>  	if (error < 0)
>  		goto error_cleanup_mc_io;
>  
> diff --git a/drivers/bus/fsl-mc/fsl-mc-private.h b/drivers/bus/fsl-mc/fsl-mc-private.h
> index 21ca8c756ee7..be6bb0fb4603 100644
> --- a/drivers/bus/fsl-mc/fsl-mc-private.h
> +++ b/drivers/bus/fsl-mc/fsl-mc-private.h
> @@ -3,6 +3,7 @@
>   * Freescale Management Complex (MC) bus private declarations
>   *
>   * Copyright (C) 2016 Freescale Semiconductor, Inc.
> + * Copyright 2019-2020 NXP
>   *
>   */
>  #ifndef _FSL_MC_PRIVATE_H_
> @@ -567,6 +568,7 @@ struct fsl_mc_bus {
>  int __must_check fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
>  				   struct fsl_mc_io *mc_io,
>  				   struct device *parent_dev,
> +				   const char *driver_override,
>  				   struct fsl_mc_device **new_mc_dev);
>  
>  void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);
> diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
> index 88095fd30c80..f997f8091408 100644
> --- a/include/linux/fsl/mc.h
> +++ b/include/linux/fsl/mc.h
> @@ -3,6 +3,7 @@
>   * Freescale Management Complex (MC) bus public interface
>   *
>   * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
> + * Copyright 2019-2020 NXP
>   * Author: German Rivera <German.Rivera@freescale.com>
>   *
>   */
> @@ -161,6 +162,7 @@ struct fsl_mc_obj_desc {
>   * @regions: pointer to array of MMIO region entries
>   * @irqs: pointer to array of pointers to interrupts allocated to this device
>   * @resource: generic resource associated with this MC object device, if any.
> + * @driver_override: Driver name to force a match

This was probably meant to go in the previous patch.

---
Best Regards, Laurentiu

>   *
>   * Generic device object for MC object devices that are "attached" to a
>   * MC bus.
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 07/10] bus/fsl-mc: Export a dprc scan function to be used by multiple entities
  2020-03-19 15:40 ` [PATCH 07/10] bus/fsl-mc: Export a dprc scan function to be used by multiple entities Diana Craciun
@ 2020-03-23 12:48   ` Laurentiu Tudor
  0 siblings, 0 replies; 19+ messages in thread
From: Laurentiu Tudor @ 2020-03-23 12:48 UTC (permalink / raw)
  To: Diana Craciun, linux-kernel, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav



On 3/19/2020 5:40 PM, Diana Craciun wrote:
> Currently the DPRC scan function is used only by the bus driver.
> But the same functionality will be needed by the VFIO driver.
> To support this, the dprc scan function was exported and a little
> bit adjusted to fit both scenarios.
> 
> Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
> ---
>  drivers/bus/fsl-mc/dprc-driver.c | 15 ++++++---------
>  drivers/bus/fsl-mc/fsl-mc-bus.c  |  2 ++
>  include/linux/fsl/mc.h           |  4 ++++
>  3 files changed, 12 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
> index 7eaf78900dfc..789220f0372a 100644
> --- a/drivers/bus/fsl-mc/dprc-driver.c
> +++ b/drivers/bus/fsl-mc/dprc-driver.c
> @@ -335,7 +335,9 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
>   * bus driver with the actual state of the MC by adding and removing
>   * devices as appropriate.
>   */
> -static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
> +int dprc_scan_container(struct fsl_mc_device *mc_bus_dev,
> +		   const char *driver_override,
> +		   bool alloc_interrupts)
>  {
>  	int error;
>  	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
> @@ -346,15 +348,12 @@ static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
>  	 * Discover objects in the DPRC:
>  	 */
>  	mutex_lock(&mc_bus->scan_mutex);
> -	error = dprc_scan_objects(mc_bus_dev, NULL, true);
> +	error = dprc_scan_objects(mc_bus_dev, driver_override, alloc_interrupts);
>  	mutex_unlock(&mc_bus->scan_mutex);
> -	if (error < 0) {
> -		fsl_mc_cleanup_all_resource_pools(mc_bus_dev);
> -		return error;
> -	}
>  
>  	return 0;
>  }
> +EXPORT_SYMBOL_GPL(dprc_scan_container);
>  
>  /**
>   * dprc_irq0_handler - Regular ISR for DPRC interrupt 0
> @@ -679,12 +678,10 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
>  		goto error_cleanup_open;
>  	}
>  
> -	mutex_init(&mc_bus->scan_mutex);
> -

It's not obvious that this is related, maybe it should be mentioned in
the commit message.

>  	/*
>  	 * Discover MC objects in DPRC object:
>  	 */
> -	error = dprc_scan_container(mc_dev);
> +	error = dprc_scan_container(mc_dev, NULL, true);
>  	if (error < 0)
>  		goto error_cleanup_open;
>  
> diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
> index a99a0edef252..1865221bb12d 100644
> --- a/drivers/bus/fsl-mc/fsl-mc-bus.c
> +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
> @@ -635,7 +635,9 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
>  		if (!mc_bus)
>  			return -ENOMEM;
>  
> +		mutex_init(&mc_bus->scan_mutex);
>  		mc_dev = &mc_bus->mc_dev;
> +

nit: extra white space.

---
Best Regards, Laurentiu

>  	} else {
>  		/*
>  		 * Allocate a regular fsl_mc_device object:
> diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
> index b9d5e5955adb..2bdd96a482fb 100644
> --- a/include/linux/fsl/mc.h
> +++ b/include/linux/fsl/mc.h
> @@ -476,6 +476,10 @@ int dprc_reset_container(struct fsl_mc_io *mc_io,
>  			 u16 token,
>  			 int child_container_id);
>  
> +int dprc_scan_container(struct fsl_mc_device *mc_bus_dev,
> +		   const char *driver_override,
> +		   bool alloc_interrupts);
> +
>  /*
>   * Data Path Buffer Pool (DPBP) API
>   * Contains initialization APIs and runtime control APIs for DPBP
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 08/10] bus/fsl-mc: Export a cleanup function for DPRC
  2020-03-19 15:40 ` [PATCH 08/10] bus/fsl-mc: Export a cleanup function for DPRC Diana Craciun
@ 2020-03-23 12:52   ` Laurentiu Tudor
  0 siblings, 0 replies; 19+ messages in thread
From: Laurentiu Tudor @ 2020-03-23 12:52 UTC (permalink / raw)
  To: Diana Craciun, linux-kernel, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav



On 3/19/2020 5:40 PM, Diana Craciun wrote:
> Create and export a cleanup function for DPRC. The function
> is used by the DPRC driver, but it will be used by the VFIO
> driver as well.
> 
> Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
> ---
>  drivers/bus/fsl-mc/dprc-driver.c | 52 ++++++++++++++++++++++++--------
>  include/linux/fsl/mc.h           |  2 ++
>  2 files changed, 41 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
> index 789220f0372a..a655e3fee291 100644
> --- a/drivers/bus/fsl-mc/dprc-driver.c
> +++ b/drivers/bus/fsl-mc/dprc-driver.c
> @@ -725,33 +725,25 @@ static void dprc_teardown_irq(struct fsl_mc_device *mc_dev)
>  }
>  
>  /**
> - * dprc_remove - callback invoked when a DPRC is being unbound from this driver
> + * dprc_cleanup - function that cleanups a DPRC
>   *
>   * @mc_dev: Pointer to fsl-mc device representing the DPRC
>   *
> - * It removes the DPRC's child objects from Linux (not from the MC) and
> - * closes the DPRC device in the MC.
> - * It tears down the interrupts that were configured for the DPRC device.
> + * It closes the DPRC device in the MC.
>   * It destroys the interrupt pool associated with this MC bus.
>   */
> -static int dprc_remove(struct fsl_mc_device *mc_dev)
> +

nit: extra white space?

---
Best Regards, Laurentiu

> +int dprc_cleanup(struct fsl_mc_device *mc_dev)
>  {
>  	int error;
>  	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
>  
>  	if (!is_fsl_mc_bus_dprc(mc_dev))
>  		return -EINVAL;
> -	if (!mc_dev->mc_io)
> -		return -EINVAL;
>  
> -	if (!mc_bus->irq_resources)
> +	if (!mc_dev->mc_io)
>  		return -EINVAL;
>  
> -	if (dev_get_msi_domain(&mc_dev->dev))
> -		dprc_teardown_irq(mc_dev);
> -
> -	device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove);
> -
>  	if (dev_get_msi_domain(&mc_dev->dev)) {
>  		fsl_mc_cleanup_irq_pool(mc_bus);
>  		dev_set_msi_domain(&mc_dev->dev, NULL);
> @@ -768,6 +760,40 @@ static int dprc_remove(struct fsl_mc_device *mc_dev)
>  		mc_dev->mc_io = NULL;
>  	}
>  
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(dprc_cleanup);
> +
> +/**
> + * dprc_remove - callback invoked when a DPRC is being unbound from this driver
> + *
> + * @mc_dev: Pointer to fsl-mc device representing the DPRC
> + *
> + * It removes the DPRC's child objects from Linux (not from the MC) and
> + * closes the DPRC device in the MC.
> + * It tears down the interrupts that were configured for the DPRC device.
> + * It destroys the interrupt pool associated with this MC bus.
> + */
> +static int dprc_remove(struct fsl_mc_device *mc_dev)
> +{
> +	int error;
> +	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
> +
> +	if (!is_fsl_mc_bus_dprc(mc_dev))
> +		return -EINVAL;
> +
> +	if (!mc_bus->irq_resources)
> +		return -EINVAL;
> +
> +	if (dev_get_msi_domain(&mc_dev->dev))
> +		dprc_teardown_irq(mc_dev);
> +
> +	device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove);
> +
> +	error = dprc_cleanup(mc_dev);
> +	if (error < 0)
> +		dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);
> +
>  	dev_info(&mc_dev->dev, "DPRC device unbound from driver");
>  	return 0;
>  }
> diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
> index 2bdd96a482fb..e3ba273a1122 100644
> --- a/include/linux/fsl/mc.h
> +++ b/include/linux/fsl/mc.h
> @@ -480,6 +480,8 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev,
>  		   const char *driver_override,
>  		   bool alloc_interrupts);
>  
> +int dprc_cleanup(struct fsl_mc_device *mc_dev);
> +
>  /*
>   * Data Path Buffer Pool (DPBP) API
>   * Contains initialization APIs and runtime control APIs for DPBP
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 09/10] bus/fsl-mc: Add a container setup function
  2020-03-19 15:40 ` [PATCH 09/10] bus/fsl-mc: Add a container setup function Diana Craciun
@ 2020-03-23 13:06   ` Laurentiu Tudor
  0 siblings, 0 replies; 19+ messages in thread
From: Laurentiu Tudor @ 2020-03-23 13:06 UTC (permalink / raw)
  To: Diana Craciun, linux-kernel, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav



On 3/19/2020 5:40 PM, Diana Craciun wrote:
> Both DPRC driver and VFIO driver use a initialization code
> for the DPRC. Introduced a new function which groups this
> initialization code. The function is exported and may be
> used by VFIO as well.
> 
> Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
> ---
>  drivers/bus/fsl-mc/dprc-driver.c | 77 +++++++++++++++++++++-----------
>  drivers/bus/fsl-mc/mc-io.c       |  7 ++-
>  include/linux/fsl/mc.h           |  2 +
>  3 files changed, 60 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
> index a655e3fee291..0fe45c301858 100644
> --- a/drivers/bus/fsl-mc/dprc-driver.c
> +++ b/drivers/bus/fsl-mc/dprc-driver.c
> @@ -570,16 +570,15 @@ static int dprc_setup_irq(struct fsl_mc_device *mc_dev)
>  }
>  
>  /**
> - * dprc_probe - callback invoked when a DPRC is being bound to this driver
> + * dprc_setup - opens and creates a mc_io for DPRC
>   *
>   * @mc_dev: Pointer to fsl-mc device representing a DPRC
>   *
>   * It opens the physical DPRC in the MC.
> - * It scans the DPRC to discover the MC objects contained in it.
> - * It creates the interrupt pool for the MC bus associated with the DPRC.
> - * It configures the interrupts for the DPRC device itself.
> + * It configures the DPRC portal used to communicate with MC
>   */
> -static int dprc_probe(struct fsl_mc_device *mc_dev)
> +
> +int dprc_setup(struct fsl_mc_device *mc_dev)
>  {
>  	int error;
>  	size_t region_size;
> @@ -589,12 +588,6 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
>  	bool msi_domain_set = false;
>  	u16 major_ver, minor_ver;
>  
> -	if (!is_fsl_mc_bus_dprc(mc_dev))
> -		return -EINVAL;
> -
> -	if (dev_get_msi_domain(&mc_dev->dev))
> -		return -EINVAL;
> -
>  	if (!mc_dev->mc_io) {
>  		/*
>  		 * This is a child DPRC:
> @@ -678,35 +671,69 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
>  		goto error_cleanup_open;
>  	}
>  
> +	return 0;
> +
> +error_cleanup_open:
> +	(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
> +
> +error_cleanup_msi_domain:
> +	if (msi_domain_set)
> +		dev_set_msi_domain(&mc_dev->dev, NULL);
> +
> +	if (mc_io_created) {
> +		fsl_destroy_mc_io(mc_dev->mc_io);
> +		mc_dev->mc_io = NULL;
> +	}
> +
> +	return error;
> +}
> +EXPORT_SYMBOL_GPL(dprc_setup);
> +
> +/**
> + * dprc_probe - callback invoked when a DPRC is being bound to this driver
> + *
> + * @mc_dev: Pointer to fsl-mc device representing a DPRC
> + *
> + * It opens the physical DPRC in the MC.
> + * It scans the DPRC to discover the MC objects contained in it.
> + * It creates the interrupt pool for the MC bus associated with the DPRC.
> + * It configures the interrupts for the DPRC device itself.
> + */
> +static int dprc_probe(struct fsl_mc_device *mc_dev)
> +{
> +	int error;
> +
> +	if (!is_fsl_mc_bus_dprc(mc_dev))
> +		return -EINVAL;
> +
> +	if (dev_get_msi_domain(&mc_dev->dev))
> +		return -EINVAL;
> +
> +	error = dprc_setup(mc_dev);
> +	if (error < 0)
> +		return error;
> +
>  	/*
>  	 * Discover MC objects in DPRC object:
>  	 */
>  	error = dprc_scan_container(mc_dev, NULL, true);
>  	if (error < 0)
> -		goto error_cleanup_open;
> +		goto dprc_cleanup;
>  
>  	/*
>  	 * Configure interrupt for the DPRC object associated with this MC bus:
>  	 */
>  	error = dprc_setup_irq(mc_dev);
>  	if (error < 0)
> -		goto error_cleanup_open;
> +		goto scan_cleanup;
>  
>  	dev_info(&mc_dev->dev, "DPRC device bound to driver");
>  	return 0;
>  
> -error_cleanup_open:
> -	(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
> -
> -error_cleanup_msi_domain:
> -	if (msi_domain_set)
> -		dev_set_msi_domain(&mc_dev->dev, NULL);
> -
> -	if (mc_io_created) {
> -		fsl_destroy_mc_io(mc_dev->mc_io);
> -		mc_dev->mc_io = NULL;
> -	}
> -
> +scan_cleanup:
> +	device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove);
> +dprc_cleanup:
> +	dprc_cleanup(mc_dev);
>  	return error;
>  }
>  
> diff --git a/drivers/bus/fsl-mc/mc-io.c b/drivers/bus/fsl-mc/mc-io.c
> index 6ae48ad80409..e1dfe4a76519 100644
> --- a/drivers/bus/fsl-mc/mc-io.c
> +++ b/drivers/bus/fsl-mc/mc-io.c
> @@ -129,7 +129,12 @@ int __must_check fsl_create_mc_io(struct device *dev,
>   */
>  void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
>  {
> -	struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
> +	struct fsl_mc_device *dpmcp_dev;
> +
> +	if (!mc_io)
> +		return;
> +
> +	dpmcp_dev = mc_io->dpmcp_dev;

Is this change related to the patch?

---
Best Regards, Laurentiu

>  	if (dpmcp_dev)
>  		fsl_mc_io_unset_dpmcp(mc_io);
> diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
> index e3ba273a1122..59b39c635ec9 100644
> --- a/include/linux/fsl/mc.h
> +++ b/include/linux/fsl/mc.h
> @@ -480,6 +480,8 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev,
>  		   const char *driver_override,
>  		   bool alloc_interrupts);
>  
> +int dprc_setup(struct fsl_mc_device *mc_dev);
> +
>  int dprc_cleanup(struct fsl_mc_device *mc_dev);
>  
>  /*
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 01/10] bus/fsl-mc: Do no longer export the total number of irqs outside dprc_scan_objects
  2020-03-19 15:40 ` [PATCH 01/10] bus/fsl-mc: Do no longer export the total number of irqs outside dprc_scan_objects Diana Craciun
@ 2020-04-06 14:46   ` Diana Craciun OSS
  0 siblings, 0 replies; 19+ messages in thread
From: Diana Craciun OSS @ 2020-04-06 14:46 UTC (permalink / raw)
  To: linux-kernel, Laurentiu Tudor, stuyoder, Leo Li,
	linux-arm-kernel, bharatb.yadav

Please ignore these patches. I have sent them again by mistake. I apologize!

Diana

On 4/6/2020 5:27 PM, Diana Craciun wrote:
> The total number of interrupts is only used for some checks
> outside the dprc_scan_objects function. Furthermore, in some
> situations the check is made twice. Move the bounds check inside
> the function for all situations.
>
> Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
> ---
>   drivers/bus/fsl-mc/dprc-driver.c | 30 ++++++++++--------------------
>   1 file changed, 10 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
> index c8b1c3842c1a..035b220779d0 100644
> --- a/drivers/bus/fsl-mc/dprc-driver.c
> +++ b/drivers/bus/fsl-mc/dprc-driver.c
> @@ -3,6 +3,7 @@
>    * Freescale data path resource container (DPRC) driver
>    *
>    * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
> + * Copyright 2019-2020 NXP
>    * Author: German Rivera <German.Rivera@freescale.com>
>    *
>    */
> @@ -197,8 +198,6 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
>    * dprc_scan_objects - Discover objects in a DPRC
>    *
>    * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
> - * @total_irq_count: If argument is provided the function populates the
> - * total number of IRQs created by objects in the DPRC.
>    *
>    * Detects objects added and removed from a DPRC and synchronizes the
>    * state of the Linux bus driver, MC by adding and removing
> @@ -212,8 +211,7 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
>    * populated before they can get allocation requests from probe callbacks
>    * of the device drivers for the non-allocatable devices.
>    */
> -static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
> -			     unsigned int *total_irq_count)
> +static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
>   {
>   	int num_child_objects;
>   	int dprc_get_obj_failures;
> @@ -294,22 +292,21 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
>   	 * Allocate IRQ's before binding the scanned devices with their
>   	 * respective drivers.
>   	 */
> -	if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) {
> +	if (dev_get_msi_domain(&mc_bus_dev->dev)) {
>   		if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
>   			dev_warn(&mc_bus_dev->dev,
>   				 "IRQs needed (%u) exceed IRQs preallocated (%u)\n",
>   				 irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
>   		}
>   
> -		error = fsl_mc_populate_irq_pool(mc_bus,
> +		if (!mc_bus->irq_resources) {
> +			error = fsl_mc_populate_irq_pool(mc_bus,
>   				FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
> -		if (error < 0)
> -			return error;
> +			if (error < 0)
> +				return error;
> +		}
>   	}
>   
> -	if (total_irq_count)
> -		*total_irq_count = irq_count;
> -
>   	dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
>   			    num_child_objects);
>   
> @@ -342,7 +339,7 @@ static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
>   	 * Discover objects in the DPRC:
>   	 */
>   	mutex_lock(&mc_bus->scan_mutex);
> -	error = dprc_scan_objects(mc_bus_dev, NULL);
> +	error = dprc_scan_objects(mc_bus_dev);
>   	mutex_unlock(&mc_bus->scan_mutex);
>   	if (error < 0) {
>   		fsl_mc_cleanup_all_resource_pools(mc_bus_dev);
> @@ -411,9 +408,8 @@ static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
>   		      DPRC_IRQ_EVENT_CONTAINER_DESTROYED |
>   		      DPRC_IRQ_EVENT_OBJ_DESTROYED |
>   		      DPRC_IRQ_EVENT_OBJ_CREATED)) {
> -		unsigned int irq_count;
>   
> -		error = dprc_scan_objects(mc_dev, &irq_count);
> +		error = dprc_scan_objects(mc_dev);
>   		if (error < 0) {
>   			/*
>   			 * If the error is -ENXIO, we ignore it, as it indicates
> @@ -428,12 +424,6 @@ static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
>   
>   			goto out;
>   		}
> -
> -		if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
> -			dev_warn(dev,
> -				 "IRQs needed (%u) exceed IRQs preallocated (%u)\n",
> -				 irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
> -		}
>   	}
>   
>   out:


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 03/10] bus/fsl-mc: add support for 'driver_override' in the mc-bus
  2020-03-23 12:30   ` Laurentiu Tudor
@ 2020-04-09 11:14     ` Diana Craciun OSS
  0 siblings, 0 replies; 19+ messages in thread
From: Diana Craciun OSS @ 2020-04-09 11:14 UTC (permalink / raw)
  To: Laurentiu Tudor, linux-kernel, stuyoder, leoyang.li,
	linux-arm-kernel, bharatb.yadav
  Cc: Bharat Bhushan

On 3/23/2020 2:30 PM, Laurentiu Tudor wrote:
>
> On 3/19/2020 5:40 PM, Diana Craciun wrote:
>> From: Bharat Bhushan <Bharat.Bhushan@nxp.com>
>>
>> This patch is required for vfio-fsl-mc meta driver to successfully bind
>> layerscape container devices for device passthrough. This patch adds
>> a mechanism to allow a layerscape device to specify a driver rather than
>> a layerscape driver provide a device match.
>>
>> Example to allow a device (dprc.1) to specifically bind
>> with driver (vfio-fsl-mc):-
>>   - echo vfio-fsl-mc > /sys/bus/fsl-mc/devices/dprc.1/driver_override
>>   - echo dprc.1 > /sys/bus/fsl-mc/drivers/fsl_mc_dprc/unbind
>>   - echo dprc.1 > /sys/bus/fsl-mc/drivers/vfio-fsl-mc/bind
>>
>> Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
>> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
>> Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
>> ---
>>   drivers/bus/fsl-mc/fsl-mc-bus.c | 54 +++++++++++++++++++++++++++++++++
>>   include/linux/fsl/mc.h          |  1 +
>>   2 files changed, 55 insertions(+)
>>
>> diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
>> index c78d10ea641f..baf8259262a9 100644
>> --- a/drivers/bus/fsl-mc/fsl-mc-bus.c
>> +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
>> @@ -3,6 +3,7 @@
>>    * Freescale Management Complex (MC) bus driver
>>    *
>>    * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
>> + * Copyright 2019-2020 NXP
>>    * Author: German Rivera <German.Rivera@freescale.com>
>>    *
>>    */
>> @@ -83,6 +84,12 @@ static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv)
>>   	struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
>>   	bool found = false;
>>   
>> +	/* When driver_override is set, only bind to the matching driver */
>> +	if (mc_dev->driver_override) {
>> +		found = !strcmp(mc_dev->driver_override, mc_drv->driver.name);
> I think we can use sysfs_streq() here and ...

I would prefer to maintain consistency with other buses and store the 
driver_override string without the terminating newline.

>
>
>> +		goto out;
>> +	}
>> +
>>   	if (!mc_drv->match_id_table)
>>   		goto out;
>>   
>> @@ -147,8 +154,52 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
>>   }
>>   static DEVICE_ATTR_RO(modalias);
>>   
>> +static ssize_t driver_override_store(struct device *dev,
>> +				     struct device_attribute *attr,
>> +				     const char *buf, size_t count)
>> +{
>> +	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
>> +	const char *driver_override, *old = mc_dev->driver_override;
>> +	char *cp;
>> +
>> +	if (WARN_ON(dev->bus != &fsl_mc_bus_type))
>> +		return -EINVAL;
>> +
>> +	if (count >= (PAGE_SIZE - 1))
>> +		return -EINVAL;
>> +
>> +	driver_override = kstrndup(buf, count, GFP_KERNEL);
>> +	if (!driver_override)
>> +		return -ENOMEM;
>> +
>> +	cp = strchr(driver_override, '\n');
>> +	if (cp)
>> +		*cp = '\0';
> drop this strchr() ...
>
>> +	if (strlen(driver_override)) {
>> +		mc_dev->driver_override = driver_override;
>> +	} else {
>> +		kfree(driver_override);
>> +		mc_dev->driver_override = NULL;
>> +	}
>> +
>> +	kfree(old);
>> +
>> +	return count;
>> +}
>> +
>> +static ssize_t driver_override_show(struct device *dev,
>> +				    struct device_attribute *attr, char *buf)
>> +{
>> +	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
>> +
>> +	return snprintf(buf, PAGE_SIZE, "%s\n", mc_dev->driver_override);
> and also the terminating '\n' here.
>
>> +}
>> +static DEVICE_ATTR_RW(driver_override);
>> +
>>   static struct attribute *fsl_mc_dev_attrs[] = {
>>   	&dev_attr_modalias.attr,
>> +	&dev_attr_driver_override.attr,
>>   	NULL,
>>   };
>>   
>> @@ -704,6 +755,9 @@ EXPORT_SYMBOL_GPL(fsl_mc_device_add);
>>    */
>>   void fsl_mc_device_remove(struct fsl_mc_device *mc_dev)
>>   {
>> +	kfree(mc_dev->driver_override);
>> +	mc_dev->driver_override = NULL;
>> +
>>   	/*
>>   	 * The device-specific remove callback will get invoked by device_del()
>>   	 */
>> diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
>> index 54d9436600c7..88095fd30c80 100644
>> --- a/include/linux/fsl/mc.h
>> +++ b/include/linux/fsl/mc.h
>> @@ -194,6 +194,7 @@ struct fsl_mc_device {
>>   	struct fsl_mc_device_irq **irqs;
>>   	struct fsl_mc_resource *resource;
>>   	struct device_link *consumer_link;
>> +	const char *driver_override;
> We probably don't want const here.

OK

>
> ---
> Best Regards, Laurentiu
>
>>   };
>>   
>>   #define to_fsl_mc_device(_dev) \
>>

Diana

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2020-04-09 11:14 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-19 15:40 [PATCH 00/10] bus/fsl-mc: Extend mc-bus driver functionalities in preparation for mc-bus VFIO support Diana Craciun
2020-03-19 15:40 ` [PATCH 01/10] bus/fsl-mc: Do no longer export the total number of irqs outside dprc_scan_objects Diana Craciun
2020-04-06 14:46   ` Diana Craciun OSS
2020-03-19 15:40 ` [PATCH 02/10] bus/fsl-mc: Add a new parameter to dprc_scan_objects function Diana Craciun
2020-03-23 12:04   ` Laurentiu Tudor
2020-03-19 15:40 ` [PATCH 03/10] bus/fsl-mc: add support for 'driver_override' in the mc-bus Diana Craciun
2020-03-23 12:30   ` Laurentiu Tudor
2020-04-09 11:14     ` Diana Craciun OSS
2020-03-19 15:40 ` [PATCH 04/10] bus/fsl-mc: Propagate driver_override for a child DPRC's children Diana Craciun
2020-03-23 12:35   ` Laurentiu Tudor
2020-03-19 15:40 ` [PATCH 05/10] bus/fsl-mc: Set the QMAN/BMAN region flags Diana Craciun
2020-03-19 15:40 ` [PATCH 06/10] bus/fsl-mc: Add dprc-reset-container support Diana Craciun
2020-03-19 15:40 ` [PATCH 07/10] bus/fsl-mc: Export a dprc scan function to be used by multiple entities Diana Craciun
2020-03-23 12:48   ` Laurentiu Tudor
2020-03-19 15:40 ` [PATCH 08/10] bus/fsl-mc: Export a cleanup function for DPRC Diana Craciun
2020-03-23 12:52   ` Laurentiu Tudor
2020-03-19 15:40 ` [PATCH 09/10] bus/fsl-mc: Add a container setup function Diana Craciun
2020-03-23 13:06   ` Laurentiu Tudor
2020-03-19 15:40 ` [PATCH 10/10] bus/fsl-mc: Export IRQ pool handling functions to be used by VFIO Diana Craciun

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).