[PATCH 4/7] staging: fsl-mc: Upgraded MC bus driver to match MC fw 7.0.0

J. German Rivera German.Rivera at freescale.com
Tue Apr 28 17:39:07 UTC 2015


- Migrated MC bus driver to use DPRC flib 0.6.
- Changed IRQ setup infrastructure to be able to program MSIs
  for MC objects in an object-independent way.

Signed-off-by: J. German Rivera <German.Rivera at freescale.com>
---
 drivers/staging/fsl-mc/bus/dpmcp-cmd.h      |  79 ------------
 drivers/staging/fsl-mc/bus/dprc-cmd.h       |   6 +-
 drivers/staging/fsl-mc/bus/dprc-driver.c    | 106 +++++++++++++---
 drivers/staging/fsl-mc/bus/dprc.c           | 179 +++++++++++++++++++++++-----
 drivers/staging/fsl-mc/bus/mc-allocator.c   |  26 ++--
 drivers/staging/fsl-mc/bus/mc-bus.c         | 125 ++++++++-----------
 drivers/staging/fsl-mc/bus/mc-sys.c         |   6 +-
 drivers/staging/fsl-mc/include/dpmng.h      |   4 +-
 drivers/staging/fsl-mc/include/dprc.h       | 114 +++++++++++++-----
 drivers/staging/fsl-mc/include/mc-private.h |  29 ++++-
 drivers/staging/fsl-mc/include/mc.h         |   4 +
 11 files changed, 431 insertions(+), 247 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h
index 57f326b..62bdc18 100644
--- a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h
+++ b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h
@@ -54,83 +54,4 @@
 #define DPMCP_CMDID_GET_IRQ_STATUS			0x016
 #define DPMCP_CMDID_CLEAR_IRQ_STATUS			0x017
 
-/*                cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_CREATE(cmd, cfg) \
-	MC_CMD_OP(cmd, 0, 0,  32, int,      cfg->portal_id)
-
-/*                cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_SET_IRQ(cmd, irq_index, irq_addr, irq_val, user_irq_id) \
-do { \
-	MC_CMD_OP(cmd, 0, 0,  8,  uint8_t,  irq_index);\
-	MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_val);\
-	MC_CMD_OP(cmd, 1, 0,  64, uint64_t, irq_addr); \
-	MC_CMD_OP(cmd, 2, 0,  32, int,	    user_irq_id); \
-} while (0)
-
-/*                cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_GET_IRQ(cmd, irq_index) \
-	MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index)
-
-/*                cmd, param, offset, width, type, arg_name */
-#define DPMCP_RSP_GET_IRQ(cmd, type, irq_addr, irq_val, user_irq_id) \
-do { \
-	MC_RSP_OP(cmd, 0, 0,  32, uint32_t, irq_val); \
-	MC_RSP_OP(cmd, 1, 0,  64, uint64_t, irq_addr); \
-	MC_RSP_OP(cmd, 2, 0,  32, int,	    user_irq_id); \
-	MC_RSP_OP(cmd, 2, 32, 32, int,	    type); \
-} while (0)
-
-/*                cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_SET_IRQ_ENABLE(cmd, irq_index, en) \
-do { \
-	MC_CMD_OP(cmd, 0, 0,  8,  uint8_t,  en); \
-	MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index);\
-} while (0)
-
-/*                cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_GET_IRQ_ENABLE(cmd, irq_index) \
-	MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index)
-
-/*                cmd, param, offset, width, type, arg_name */
-#define DPMCP_RSP_GET_IRQ_ENABLE(cmd, en) \
-	MC_RSP_OP(cmd, 0, 0,  8,  uint8_t,  en)
-
-/*                cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \
-do { \
-	MC_CMD_OP(cmd, 0, 0,  32, uint32_t, mask);\
-	MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index);\
-} while (0)
-
-/*                cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_GET_IRQ_MASK(cmd, irq_index) \
-	MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index)
-
-/*                cmd, param, offset, width, type, arg_name */
-#define DPMCP_RSP_GET_IRQ_MASK(cmd, mask) \
-	MC_RSP_OP(cmd, 0, 0,  32, uint32_t, mask)
-
-/*                cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_GET_IRQ_STATUS(cmd, irq_index) \
-	MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index)
-
-/*                cmd, param, offset, width, type, arg_name */
-#define DPMCP_RSP_GET_IRQ_STATUS(cmd, status) \
-	MC_RSP_OP(cmd, 0, 0,  32, uint32_t, status)
-
-/*                cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \
-do { \
-	MC_CMD_OP(cmd, 0, 0,  32, uint32_t, status); \
-	MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index);\
-} while (0)
-
-/*                cmd, param, offset, width, type,	arg_name */
-#define DPMCP_RSP_GET_ATTRIBUTES(cmd, attr) \
-do { \
-	MC_RSP_OP(cmd, 0, 32, 32, int,	    attr->id);\
-	MC_RSP_OP(cmd, 1, 0,  16, uint16_t, attr->version.major);\
-	MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->version.minor);\
-} while (0)
-
 #endif /* _FSL_DPMCP_CMD_H */
diff --git a/drivers/staging/fsl-mc/bus/dprc-cmd.h b/drivers/staging/fsl-mc/bus/dprc-cmd.h
index 0920248..df5ad5f 100644
--- a/drivers/staging/fsl-mc/bus/dprc-cmd.h
+++ b/drivers/staging/fsl-mc/bus/dprc-cmd.h
@@ -41,7 +41,7 @@
 #define _FSL_DPRC_CMD_H
 
 /* DPRC Version */
-#define DPRC_VER_MAJOR				3
+#define DPRC_VER_MAJOR				4
 #define DPRC_VER_MINOR				0
 
 /* Command IDs */
@@ -72,12 +72,14 @@
 #define DPRC_CMDID_GET_RES_COUNT		0x15B
 #define DPRC_CMDID_GET_RES_IDS			0x15C
 #define DPRC_CMDID_GET_OBJ_REG			0x15E
+#define DPRC_CMDID_OBJ_SET_IRQ			0x15F
+#define DPRC_CMDID_OBJ_GET_IRQ			0x160
+#define DPRC_CMDID_SET_OBJ_LABEL		0x161
 
 #define DPRC_CMDID_CONNECT			0x167
 #define DPRC_CMDID_DISCONNECT			0x168
 #define DPRC_CMDID_GET_POOL			0x169
 #define DPRC_CMDID_GET_POOL_COUNT		0x16A
-#define DPRC_CMDID_GET_PORTAL_PADDR		0x16B
 
 #define DPRC_CMDID_GET_CONNECTION		0x16C
 
diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c b/drivers/staging/fsl-mc/bus/dprc-driver.c
index ce88859..b84cca3 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -233,12 +233,17 @@ static void dprc_cleanup_resource_pool(struct fsl_mc_device *mc_bus_dev,
 	WARN_ON(free_count != res_pool->free_count);
 }
 
+/*
+ * Clean up all resource pools other than the IRQ pool
+ */
 static void dprc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev)
 {
 	int pool_type;
 
-	for (pool_type = 0; pool_type < FSL_MC_NUM_POOL_TYPES; pool_type++)
-		dprc_cleanup_resource_pool(mc_bus_dev, pool_type);
+	for (pool_type = 0; pool_type < FSL_MC_NUM_POOL_TYPES; pool_type++) {
+		if (pool_type != FSL_MC_POOL_IRQ)
+			dprc_cleanup_resource_pool(mc_bus_dev, pool_type);
+	}
 }
 
 /**
@@ -343,6 +348,57 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
 EXPORT_SYMBOL_GPL(dprc_scan_objects);
 
 /**
+ * dprc_lookup_object - Finds a given MC object in a DPRC and returns
+ * the index of the object in the DPRC
+ *
+ * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
+ * @child_dev: pointer to the fsl-mc device to be looked up
+ * @child_obj_index: output parameter to hold the index of the object
+ */
+int dprc_lookup_object(struct fsl_mc_device *mc_bus_dev,
+		       struct fsl_mc_device *child_dev,
+		       uint32_t *child_obj_index)
+{
+	int i;
+	int num_child_objects;
+	int error;
+
+	error = dprc_get_obj_count(mc_bus_dev->mc_io,
+				   mc_bus_dev->mc_handle,
+				   &num_child_objects);
+	if (error < 0) {
+		dev_err(&mc_bus_dev->dev, "dprc_get_obj_count() failed: %d\n",
+			error);
+		return error;
+	}
+
+	for (i = 0; i < num_child_objects; i++) {
+		struct dprc_obj_desc obj_desc;
+
+		error = dprc_get_obj(mc_bus_dev->mc_io,
+				     mc_bus_dev->mc_handle,
+				     i, &obj_desc);
+		if (error < 0) {
+			dev_err(&mc_bus_dev->dev,
+				"dprc_get_obj(i=%d) failed: %d\n",
+				i, error);
+			return error;
+		}
+
+		if (strcmp(obj_desc.type, child_dev->obj_desc.type) == 0 &&
+		    obj_desc.id == child_dev->obj_desc.id) {
+			*child_obj_index = i;
+			return 0;
+		}
+	}
+
+	dev_err(&mc_bus_dev->dev, "%s.%u not found\n",
+		child_dev->obj_desc.type, child_dev->obj_desc.id);
+
+	return -ENODEV;
+}
+
+/**
  * dprc_scan_container - Scans a physical DPRC and synchronizes Linux bus state
  *
  * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
@@ -377,6 +433,7 @@ static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 
 	return 0;
 error:
+	device_for_each_child(&mc_bus_dev->dev, NULL, __fsl_mc_device_remove);
 	dprc_cleanup_all_resource_pools(mc_bus_dev);
 	return error;
 }
@@ -552,6 +609,22 @@ static int register_dprc_irq_handlers(struct fsl_mc_device *mc_dev)
 
 	for (i = 0; i < ARRAY_SIZE(irq_handlers); i++) {
 		irq = mc_dev->irqs[i];
+
+		if (WARN_ON(irq->dev_irq_index != i)) {
+			error = -EINVAL;
+			goto error_unregister_irq_handlers;
+		}
+
+		/*
+		 * NOTE: Normally, devm_request_threaded_irq() programs the MSI
+		 * physically in the device (by invoking a device-specific
+		 * callback). However, for MC IRQs, we have to program the MSI
+		 * outside of this callback, because this callback is invoked
+		 * with interrupts disabled, and we don't have a reliable
+		 * way of sending commands to the MC from atomic context.
+		 * The MC callback just set the msi_paddr and msi_value
+		 * fields of the irq structure.
+		 */
 		error = devm_request_threaded_irq(&mc_dev->dev,
 						  irq->irq_number,
 						  irq_handlers[i].irq_handler,
@@ -568,24 +641,19 @@ static int register_dprc_irq_handlers(struct fsl_mc_device *mc_dev)
 			goto error_unregister_irq_handlers;
 		}
 
-		/*
-		 * Program the MSI (paddr, value) pair in the device:
-		 *
-		 * TODO: This needs to be moved to mc_bus_msi_domain_write_msg()
-		 * when the MC object-independent dprc_set_irq() flib API
-		 * becomes available
-		 */
-		error = dprc_set_irq(mc_dev->mc_io, mc_dev->mc_handle,
-				     i, irq->msi_paddr,
+		num_irq_handlers_registered++;
+		error = dprc_set_irq(mc_dev->mc_io,
+				     mc_dev->mc_handle,
+				     i,
+				     irq->msi_paddr,
 				     irq->msi_value,
 				     irq->irq_number);
 		if (error < 0) {
 			dev_err(&mc_dev->dev,
-				"mc_set_irq() failed: %d\n", error);
+				"dprc_set_irq() failed for IRQ %u: %d\n",
+				i, error);
 			goto error_unregister_irq_handlers;
 		}
-
-		num_irq_handlers_registered++;
 	}
 
 	return 0;
@@ -729,15 +797,17 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 	 */
 	error = dprc_setup_irqs(mc_dev);
 	if (error < 0)
-		goto error_cleanup_open;
+		goto error_cleanup_dprc_scan;
 
 	dev_info(&mc_dev->dev, "DPRC device bound to driver");
 	return 0;
 
-error_cleanup_open:
-	if (mc_bus->irq_resources)
-		fsl_mc_cleanup_irq_pool(mc_bus);
+error_cleanup_dprc_scan:
+	device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove);
+	dprc_cleanup_all_resource_pools(mc_dev);
+	fsl_mc_cleanup_irq_pool(mc_bus);
 
+error_cleanup_open:
 	(void)dprc_close(mc_dev->mc_io, mc_dev->mc_handle);
 
 error_cleanup_mc_io:
diff --git a/drivers/staging/fsl-mc/bus/dprc.c b/drivers/staging/fsl-mc/bus/dprc.c
index 19b26e6..7a37d2d 100644
--- a/drivers/staging/fsl-mc/bus/dprc.c
+++ b/drivers/staging/fsl-mc/bus/dprc.c
@@ -73,7 +73,7 @@ int dprc_create_container(struct fsl_mc_io *mc_io,
 			  uint16_t token,
 			  struct dprc_cfg *cfg,
 			  int *child_container_id,
-			  uint64_t *child_portal_paddr)
+			  uint64_t *child_portal_offset)
 {
 	struct mc_command cmd = { 0 };
 	int err;
@@ -82,6 +82,22 @@ int dprc_create_container(struct fsl_mc_io *mc_io,
 	cmd.params[0] |= mc_enc(32, 16, cfg->icid);
 	cmd.params[0] |= mc_enc(0, 32, cfg->options);
 	cmd.params[1] |= mc_enc(32, 32, cfg->portal_id);
+	cmd.params[2] |= mc_enc(0, 8, cfg->label[0]);
+	cmd.params[2] |= mc_enc(8, 8, cfg->label[1]);
+	cmd.params[2] |= mc_enc(16, 8, cfg->label[2]);
+	cmd.params[2] |= mc_enc(24, 8, cfg->label[3]);
+	cmd.params[2] |= mc_enc(32, 8, cfg->label[4]);
+	cmd.params[2] |= mc_enc(40, 8, cfg->label[5]);
+	cmd.params[2] |= mc_enc(48, 8, cfg->label[6]);
+	cmd.params[2] |= mc_enc(56, 8, cfg->label[7]);
+	cmd.params[3] |= mc_enc(0, 8, cfg->label[8]);
+	cmd.params[3] |= mc_enc(8, 8, cfg->label[9]);
+	cmd.params[3] |= mc_enc(16, 8, cfg->label[10]);
+	cmd.params[3] |= mc_enc(24, 8, cfg->label[11]);
+	cmd.params[3] |= mc_enc(32, 8, cfg->label[12]);
+	cmd.params[3] |= mc_enc(40, 8, cfg->label[13]);
+	cmd.params[3] |= mc_enc(48, 8, cfg->label[14]);
+	cmd.params[3] |= mc_enc(56, 8, cfg->label[15]);
 
 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_CREATE_CONT,
 					  MC_CMD_PRI_LOW, token);
@@ -93,10 +109,11 @@ int dprc_create_container(struct fsl_mc_io *mc_io,
 
 	/* retrieve response parameters */
 	*child_container_id = mc_dec(cmd.params[1], 0, 32);
-	*child_portal_paddr = mc_dec(cmd.params[2], 0, 64);
+	*child_portal_offset = mc_dec(cmd.params[2], 0, 64);
 
 	return 0;
 }
+EXPORT_SYMBOL(dprc_create_container);
 
 int dprc_destroy_container(struct fsl_mc_io *mc_io,
 			   uint16_t token,
@@ -112,6 +129,7 @@ int dprc_destroy_container(struct fsl_mc_io *mc_io,
 	/* send command to mc*/
 	return mc_send_command(mc_io, &cmd);
 }
+EXPORT_SYMBOL(dprc_destroy_container);
 
 int dprc_reset_container(struct fsl_mc_io *mc_io,
 			 uint16_t token,
@@ -127,6 +145,7 @@ int dprc_reset_container(struct fsl_mc_io *mc_io,
 	/* send command to mc*/
 	return mc_send_command(mc_io, &cmd);
 }
+EXPORT_SYMBOL(dprc_reset_container);
 
 int dprc_get_irq(struct fsl_mc_io *mc_io,
 		 uint16_t token,
@@ -158,6 +177,41 @@ int dprc_get_irq(struct fsl_mc_io *mc_io,
 
 	return 0;
 }
+EXPORT_SYMBOL(dprc_get_irq);
+
+int dprc_obj_get_irq(struct fsl_mc_io *mc_io,
+		     uint16_t token,
+		     int obj_index,
+		     uint8_t irq_index,
+		     int *type,
+		     uint64_t *irq_addr,
+		     uint32_t *irq_val,
+		     int *user_irq_id)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_OBJ_GET_IRQ,
+					  MC_CMD_PRI_LOW,
+					  token);
+
+	cmd.params[0] |= mc_enc(0, 32, obj_index);
+	cmd.params[0] |= mc_enc(32, 8, irq_index);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	*irq_val = mc_dec(cmd.params[0], 0, 32);
+	*irq_addr = mc_dec(cmd.params[1], 0, 64);
+	*user_irq_id = mc_dec(cmd.params[2], 0, 32);
+	*type = mc_dec(cmd.params[2], 32, 32);
+	return 0;
+}
+EXPORT_SYMBOL(dprc_obj_get_irq);
 
 int dprc_set_irq(struct fsl_mc_io *mc_io,
 		 uint16_t token,
@@ -180,6 +234,33 @@ int dprc_set_irq(struct fsl_mc_io *mc_io,
 	/* send command to mc*/
 	return mc_send_command(mc_io, &cmd);
 }
+EXPORT_SYMBOL(dprc_set_irq);
+
+int dprc_obj_set_irq(struct fsl_mc_io *mc_io,
+		     uint16_t token,
+		     int obj_index,
+		     uint8_t irq_index,
+		     uint64_t irq_addr,
+		     uint32_t irq_val,
+		     int user_irq_id)
+{
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_OBJ_SET_IRQ,
+					  MC_CMD_PRI_LOW,
+					  token);
+
+	cmd.params[0] |= mc_enc(32, 8, irq_index);
+	cmd.params[0] |= mc_enc(0, 32, irq_val);
+	cmd.params[1] |= mc_enc(0, 64, irq_addr);
+	cmd.params[2] |= mc_enc(0, 32, user_irq_id);
+	cmd.params[2] |= mc_enc(32, 32, obj_index);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+EXPORT_SYMBOL(dprc_obj_set_irq);
 
 int dprc_get_irq_enable(struct fsl_mc_io *mc_io,
 			uint16_t token,
@@ -204,6 +285,7 @@ int dprc_get_irq_enable(struct fsl_mc_io *mc_io,
 
 	return 0;
 }
+EXPORT_SYMBOL(dprc_get_irq_enable);
 
 int dprc_set_irq_enable(struct fsl_mc_io *mc_io,
 			uint16_t token,
@@ -221,6 +303,7 @@ int dprc_set_irq_enable(struct fsl_mc_io *mc_io,
 	/* send command to mc*/
 	return mc_send_command(mc_io, &cmd);
 }
+EXPORT_SYMBOL(dprc_set_irq_enable);
 
 int dprc_get_irq_mask(struct fsl_mc_io *mc_io,
 		      uint16_t token,
@@ -245,6 +328,7 @@ int dprc_get_irq_mask(struct fsl_mc_io *mc_io,
 
 	return 0;
 }
+EXPORT_SYMBOL(dprc_get_irq_mask);
 
 int dprc_set_irq_mask(struct fsl_mc_io *mc_io,
 		      uint16_t token,
@@ -262,6 +346,7 @@ int dprc_set_irq_mask(struct fsl_mc_io *mc_io,
 	/* send command to mc*/
 	return mc_send_command(mc_io, &cmd);
 }
+EXPORT_SYMBOL(dprc_set_irq_mask);
 
 int dprc_get_irq_status(struct fsl_mc_io *mc_io,
 			uint16_t token,
@@ -286,6 +371,7 @@ int dprc_get_irq_status(struct fsl_mc_io *mc_io,
 
 	return 0;
 }
+EXPORT_SYMBOL(dprc_get_irq_status);
 
 int dprc_clear_irq_status(struct fsl_mc_io *mc_io,
 			  uint16_t token,
@@ -303,6 +389,7 @@ int dprc_clear_irq_status(struct fsl_mc_io *mc_io,
 	/* send command to mc*/
 	return mc_send_command(mc_io, &cmd);
 }
+EXPORT_SYMBOL(dprc_clear_irq_status);
 
 int dprc_get_attributes(struct fsl_mc_io *mc_io,
 			uint16_t token,
@@ -331,6 +418,7 @@ int dprc_get_attributes(struct fsl_mc_io *mc_io,
 
 	return 0;
 }
+EXPORT_SYMBOL(dprc_get_attributes);
 
 int dprc_set_res_quota(struct fsl_mc_io *mc_io,
 		       uint16_t token,
@@ -365,6 +453,7 @@ int dprc_set_res_quota(struct fsl_mc_io *mc_io,
 	/* send command to mc*/
 	return mc_send_command(mc_io, &cmd);
 }
+EXPORT_SYMBOL(dprc_set_res_quota);
 
 int dprc_get_res_quota(struct fsl_mc_io *mc_io,
 		       uint16_t token,
@@ -406,6 +495,7 @@ int dprc_get_res_quota(struct fsl_mc_io *mc_io,
 
 	return 0;
 }
+EXPORT_SYMBOL(dprc_get_res_quota);
 
 int dprc_assign(struct fsl_mc_io *mc_io,
 		uint16_t token,
@@ -441,6 +531,7 @@ int dprc_assign(struct fsl_mc_io *mc_io,
 	/* send command to mc*/
 	return mc_send_command(mc_io, &cmd);
 }
+EXPORT_SYMBOL(dprc_assign);
 
 int dprc_unassign(struct fsl_mc_io *mc_io,
 		  uint16_t token,
@@ -477,6 +568,7 @@ int dprc_unassign(struct fsl_mc_io *mc_io,
 	/* send command to mc*/
 	return mc_send_command(mc_io, &cmd);
 }
+EXPORT_SYMBOL(dprc_unassign);
 
 int dprc_get_pool_count(struct fsl_mc_io *mc_io,
 			uint16_t token,
@@ -499,6 +591,7 @@ int dprc_get_pool_count(struct fsl_mc_io *mc_io,
 
 	return 0;
 }
+EXPORT_SYMBOL(dprc_get_pool_count);
 
 int dprc_get_pool(struct fsl_mc_io *mc_io,
 		  uint16_t token,
@@ -539,6 +632,7 @@ int dprc_get_pool(struct fsl_mc_io *mc_io,
 
 	return 0;
 }
+EXPORT_SYMBOL(dprc_get_pool);
 
 int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count)
 {
@@ -604,7 +698,22 @@ int dprc_get_obj(struct fsl_mc_io *mc_io,
 	obj_desc->type[13] = mc_dec(cmd.params[4], 40, 8);
 	obj_desc->type[14] = mc_dec(cmd.params[4], 48, 8);
 	obj_desc->type[15] = '\0';
-
+	obj_desc->label[0] = mc_dec(cmd.params[5], 0, 8);
+	obj_desc->label[1] = mc_dec(cmd.params[5], 8, 8);
+	obj_desc->label[2] = mc_dec(cmd.params[5], 16, 8);
+	obj_desc->label[3] = mc_dec(cmd.params[5], 24, 8);
+	obj_desc->label[4] = mc_dec(cmd.params[5], 32, 8);
+	obj_desc->label[5] = mc_dec(cmd.params[5], 40, 8);
+	obj_desc->label[6] = mc_dec(cmd.params[5], 48, 8);
+	obj_desc->label[7] = mc_dec(cmd.params[5], 56, 8);
+	obj_desc->label[8] = mc_dec(cmd.params[6], 0, 8);
+	obj_desc->label[9] = mc_dec(cmd.params[6], 8, 8);
+	obj_desc->label[10] = mc_dec(cmd.params[6], 16, 8);
+	obj_desc->label[11] = mc_dec(cmd.params[6], 24, 8);
+	obj_desc->label[12] = mc_dec(cmd.params[6], 32, 8);
+	obj_desc->label[13] = mc_dec(cmd.params[6], 40, 8);
+	obj_desc->label[14] = mc_dec(cmd.params[6], 48, 8);
+	obj_desc->label[15] = '\0';
 	return 0;
 }
 EXPORT_SYMBOL(dprc_get_obj);
@@ -696,31 +805,6 @@ int dprc_get_res_ids(struct fsl_mc_io *mc_io,
 }
 EXPORT_SYMBOL(dprc_get_res_ids);
 
-int dprc_get_portal_paddr(struct fsl_mc_io *mc_io,
-			  uint16_t token,
-			  int portal_id,
-			  uint64_t *portal_addr)
-{
-	struct mc_command cmd = { 0 };
-	int err;
-
-	/* prepare command */
-	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_PORTAL_PADDR,
-					  MC_CMD_PRI_LOW, token);
-	cmd.params[0] |= mc_enc(0, 32, portal_id);
-
-	/* send command to mc*/
-	err = mc_send_command(mc_io, &cmd);
-	if (err)
-		return err;
-
-	/* retrieve response parameters */
-	*portal_addr = mc_dec(cmd.params[1], 0, 64);
-
-	return 0;
-}
-EXPORT_SYMBOL(dprc_get_portal_paddr);
-
 int dprc_get_obj_region(struct fsl_mc_io *mc_io,
 			uint16_t token,
 			char *obj_type,
@@ -759,13 +843,47 @@ int dprc_get_obj_region(struct fsl_mc_io *mc_io,
 		return err;
 
 	/* retrieve response parameters */
-	region_desc->base_paddr = mc_dec(cmd.params[1], 0, 64);
+	region_desc->base_offset = mc_dec(cmd.params[1], 0, 64);
 	region_desc->size = mc_dec(cmd.params[2], 0, 32);
 
 	return 0;
 }
 EXPORT_SYMBOL(dprc_get_obj_region);
 
+int dprc_set_obj_label(struct fsl_mc_io *mc_io,
+		       uint16_t  token,
+		       int  obj_index,
+		       char *label)
+{
+	struct mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_OBJ_LABEL,
+					  MC_CMD_PRI_LOW, token);
+
+	cmd.params[0] |= mc_enc(0, 32, obj_index);
+	cmd.params[1] |= mc_enc(0, 8, label[0]);
+	cmd.params[1] |= mc_enc(8, 8, label[1]);
+	cmd.params[1] |= mc_enc(16, 8, label[2]);
+	cmd.params[1] |= mc_enc(24, 8, label[3]);
+	cmd.params[1] |= mc_enc(32, 8, label[4]);
+	cmd.params[1] |= mc_enc(40, 8, label[5]);
+	cmd.params[1] |= mc_enc(48, 8, label[6]);
+	cmd.params[1] |= mc_enc(56, 8, label[7]);
+	cmd.params[2] |= mc_enc(0, 8, label[8]);
+	cmd.params[2] |= mc_enc(8, 8, label[9]);
+	cmd.params[2] |= mc_enc(16, 8, label[10]);
+	cmd.params[2] |= mc_enc(24, 8, label[11]);
+	cmd.params[2] |= mc_enc(32, 8, label[12]);
+	cmd.params[2] |= mc_enc(40, 8, label[13]);
+	cmd.params[2] |= mc_enc(48, 8, label[14]);
+	cmd.params[2] |= mc_enc(56, 8, label[15]);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+EXPORT_SYMBOL(dprc_set_obj_label);
+
 int dprc_connect(struct fsl_mc_io *mc_io,
 		 uint16_t token,
 		 const struct dprc_endpoint *endpoint1,
@@ -817,6 +935,7 @@ int dprc_connect(struct fsl_mc_io *mc_io,
 	/* send command to mc*/
 	return mc_send_command(mc_io, &cmd);
 }
+EXPORT_SYMBOL(dprc_connect);
 
 int dprc_disconnect(struct fsl_mc_io *mc_io,
 		    uint16_t token,
@@ -850,6 +969,7 @@ int dprc_disconnect(struct fsl_mc_io *mc_io,
 	/* send command to mc*/
 	return mc_send_command(mc_io, &cmd);
 }
+EXPORT_SYMBOL(dprc_disconnect);
 
 int dprc_get_connection(struct fsl_mc_io *mc_io,
 			uint16_t token,
@@ -911,3 +1031,4 @@ int dprc_get_connection(struct fsl_mc_io *mc_io,
 
 	return 0;
 }
+EXPORT_SYMBOL(dprc_get_connection);
diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c b/drivers/staging/fsl-mc/bus/mc-allocator.c
index 27497e7..0c5fad0 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -531,13 +531,19 @@ int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev)
 
 		irqs[i] = to_fsl_mc_irq(resource);
 		res_allocated_count++;
+
+		WARN_ON(irqs[i]->mc_dev);
+		irqs[i]->mc_dev = mc_dev;
+		irqs[i]->dev_irq_index = i;
 	}
 
 	mc_dev->irqs = irqs;
 	return 0;
 error:
-	for (i = 0; i < res_allocated_count; i++)
+	for (i = 0; i < res_allocated_count; i++) {
+		irqs[i]->mc_dev = NULL;
 		fsl_mc_resource_free(&irqs[i]->resource);
+	}
 
 	if (irqs)
 		devm_kfree(&mc_dev->dev, irqs);
@@ -555,8 +561,9 @@ void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev)
 	int i;
 	int irq_count;
 	struct fsl_mc_bus *mc_bus;
+	struct fsl_mc_device_irq **irqs = mc_dev->irqs;
 
-	if (WARN_ON(!mc_dev->irqs))
+	if (WARN_ON(!irqs))
 		return;
 
 	irq_count = mc_dev->obj_desc.irq_count;
@@ -569,8 +576,11 @@ void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev)
 	if (WARN_ON(!mc_bus->irq_resources))
 		return;
 
-	for (i = 0; i < irq_count; i++)
-		fsl_mc_resource_free(&mc_dev->irqs[i]->resource);
+	for (i = 0; i < irq_count; i++) {
+		WARN_ON(!irqs[i]->mc_dev);
+		irqs[i]->mc_dev = NULL;
+		fsl_mc_resource_free(&irqs[i]->resource);
+	}
 
 	devm_kfree(&mc_dev->dev, mc_dev->irqs);
 	mc_dev->irqs = NULL;
@@ -604,8 +614,8 @@ static int fsl_mc_allocator_probe(struct fsl_mc_device *mc_dev)
 	if (error < 0)
 		goto error;
 
-	dev_info(&mc_dev->dev,
-		 "Allocatable MC object device bound to fsl_mc_allocator driver");
+	dev_dbg(&mc_dev->dev,
+		"Allocatable MC object device bound to fsl_mc_allocator driver");
 	return 0;
 error:
 
@@ -627,8 +637,8 @@ static int fsl_mc_allocator_remove(struct fsl_mc_device *mc_dev)
 	if (error < 0)
 		goto out;
 
-	dev_info(&mc_dev->dev,
-		 "Allocatable MC object device unbound from fsl_mc_allocator driver");
+	dev_dbg(&mc_dev->dev,
+		"Allocatable MC object device unbound from fsl_mc_allocator driver");
 	error = 0;
 out:
 	return error;
diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c b/drivers/staging/fsl-mc/bus/mc-bus.c
index 08fd559..55a8b86 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -315,7 +315,8 @@ common_cleanup:
 	return error;
 }
 
-static int translate_mc_addr(uint64_t mc_addr, phys_addr_t *phys_addr)
+static int translate_mc_addr(enum fsl_mc_region_types mc_region_type,
+			     uint64_t mc_offset, phys_addr_t *phys_addr)
 {
 	int i;
 	struct fsl_mc *mc = dev_get_drvdata(fsl_mc_bus_type.dev_root->parent);
@@ -324,7 +325,7 @@ static int translate_mc_addr(uint64_t mc_addr, phys_addr_t *phys_addr)
 		/*
 		 * Do identity mapping:
 		 */
-		*phys_addr = mc_addr;
+		*phys_addr = mc_offset;
 		return 0;
 	}
 
@@ -332,10 +333,11 @@ static int translate_mc_addr(uint64_t mc_addr, phys_addr_t *phys_addr)
 		struct fsl_mc_addr_translation_range *range =
 			&mc->translation_ranges[i];
 
-		if (mc_addr >= range->start_mc_addr &&
-		    mc_addr < range->end_mc_addr) {
+		if (mc_region_type == range->mc_region_type &&
+		    mc_offset >= range->start_mc_offset &&
+		    mc_offset < range->end_mc_offset) {
 			*phys_addr = range->start_phys_addr +
-				     (mc_addr - range->start_mc_addr);
+				     (mc_offset - range->start_mc_offset);
 			return 0;
 		}
 	}
@@ -351,6 +353,22 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev,
 	struct resource *regions;
 	struct dprc_obj_desc *obj_desc = &mc_dev->obj_desc;
 	struct device *parent_dev = mc_dev->dev.parent;
+	enum fsl_mc_region_types mc_region_type;
+
+	if (strcmp(obj_desc->type, "dprc") == 0 ||
+	    strcmp(obj_desc->type, "dpmcp") == 0) {
+		mc_region_type = FSL_MC_PORTAL;
+	} else if (strcmp(obj_desc->type, "dpio") == 0) {
+		mc_region_type = FSL_QBMAN_PORTAL;
+	} else {
+		/*
+		 * This function should not have been called for this MC object
+		 * type, as this object type is not supposed to have MMIO
+		 * regions
+		 */
+		WARN_ON(true);
+		return -EINVAL;
+	}
 
 	regions = kmalloc_array(obj_desc->region_count,
 				sizeof(regions[0]), GFP_KERNEL);
@@ -370,14 +388,14 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev,
 			goto error_cleanup_regions;
 		}
 
-		WARN_ON(region_desc.base_paddr == 0x0);
 		WARN_ON(region_desc.size == 0);
-		error = translate_mc_addr(region_desc.base_paddr,
+		error = translate_mc_addr(mc_region_type,
+					  region_desc.base_offset,
 					  &regions[i].start);
 		if (error < 0) {
 			dev_err(parent_dev,
-				"Invalid MC address: %#llx (for %s.%d\'s region %d)\n",
-				region_desc.base_paddr,
+				"Invalid MC offset: %#llx (for %s.%d\'s region %d)\n",
+				region_desc.base_offset,
 				obj_desc->type, obj_desc->id, i);
 			goto error_cleanup_regions;
 		}
@@ -447,13 +465,7 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
 	}
 
 	device_initialize(&mc_dev->dev);
-
-	/*
-	 * FIXME: Enable this code when the GIC-ITS MC support patch is merged
-	 */
-#ifdef GIC_ITS_MC_SUPPORT
 	INIT_LIST_HEAD(&mc_dev->dev.msi_list);
-#endif
 	mc_dev->dev.parent = parent_dev;
 	mc_dev->dev.bus = &fsl_mc_bus_type;
 	dev_set_name(&mc_dev->dev, "%s.%d", obj_desc->type, obj_desc->id);
@@ -586,10 +598,6 @@ void fsl_mc_device_remove(struct fsl_mc_device *mc_dev)
 }
 EXPORT_SYMBOL_GPL(fsl_mc_device_remove);
 
-/*
- * FIXME: Enable this code when the GIC-ITS MC support patch is merged
- */
-#ifdef GIC_ITS_MC_SUPPORT
 static int mc_bus_msi_prepare(struct irq_domain *domain, struct device *dev,
 			      int nvec, msi_alloc_info_t *info)
 {
@@ -641,6 +649,10 @@ static void mc_bus_unmask_msi_irq(struct irq_data *d)
 	irq_chip_unmask_parent(d);
 }
 
+/*
+ * This function is invoked from devm_request_irq(),
+ * devm_request_threaded_irq(), dev_free_irq()
+ */
 static void mc_bus_msi_domain_write_msg(struct irq_data *irq_data,
 					struct msi_msg *msg)
 {
@@ -657,6 +669,13 @@ static void mc_bus_msi_domain_write_msg(struct irq_data *irq_data,
 		irq_res->msi_paddr =
 			((u64)msg->address_hi << 32) | msg->address_lo;
 		irq_res->msi_value = msg->data;
+
+		/*
+		 * NOTE: We cannot do the actual programming of the MSI
+		 * in the MC, as this function is invoked in atomic context
+		 * (interrupts disabled) and we cannot reliably send MC commands
+		 * in atomic context.
+		 */
 	}
 }
 
@@ -706,10 +725,6 @@ static int create_mc_irq_domain(struct platform_device *mc_pdev,
 		goto cleanup_its_of_node;
 	}
 
-	/*
-	 * FIXME: Enable this code when the GIC-ITS MC support patch is merged
-	 */
-#ifdef GIC_ITS_MC_SUPPORT
 	irq_domain = msi_create_irq_domain(mc_of_node, &mc_bus_msi_domain_info,
 					   its_domain->parent);
 	if (!irq_domain) {
@@ -719,9 +734,6 @@ static int create_mc_irq_domain(struct platform_device *mc_pdev,
 	}
 
 	dev_dbg(&mc_pdev->dev, "Allocated MSI domain\n");
-#else
-	irq_domain = NULL;
-#endif
 	*new_irq_domain = irq_domain;
 	return 0;
 
@@ -729,7 +741,6 @@ cleanup_its_of_node:
 	of_node_put(its_of_node);
 	return error;
 }
-#endif /* GIC_ITS_MC_SUPPORT */
 
 /*
  * Initialize the interrupt pool associated with a MC bus.
@@ -739,26 +750,21 @@ int __must_check fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
 					  unsigned int irq_count)
 {
 	unsigned int i;
+	struct msi_desc *msi_entry;
+	struct msi_desc *next_msi_entry;
 	struct fsl_mc_device_irq *irq_resources;
 	struct fsl_mc_device_irq *irq_res;
+	int error;
 	struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+	struct fsl_mc *mc = dev_get_drvdata(fsl_mc_bus_type.dev_root->parent);
 	struct fsl_mc_resource_pool *res_pool =
 			&mc_bus->resource_pools[FSL_MC_POOL_IRQ];
-	/*
-	 * FIXME: Enable this code when the GIC-ITS MC support patch is merged
-	 */
-#ifdef GIC_ITS_MC_SUPPORT
-	int error;
-	struct msi_desc *msi_entry;
-	struct msi_desc *next_msi_entry;
-	struct fsl_mc *mc = dev_get_drvdata(fsl_mc_bus_type.dev_root->parent);
 
 	/*
 	 * Detect duplicate invocations of this function:
 	 */
 	if (WARN_ON(!list_empty(&mc_bus_dev->dev.msi_list)))
 		return -EINVAL;
-#endif
 
 	if (WARN_ON(irq_count == 0 ||
 		    irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS))
@@ -773,10 +779,6 @@ int __must_check fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
 
 	for (i = 0; i < irq_count; i++) {
 		irq_res = &irq_resources[i];
-	/*
-	 * FIXME: Enable this code when the GIC-ITS MC support patch is merged
-	 */
-#ifdef GIC_ITS_MC_SUPPORT
 		msi_entry = alloc_msi_entry(&mc_bus_dev->dev);
 		if (!msi_entry) {
 			dev_err(&mc_bus_dev->dev, "Failed to allocate msi entry\n");
@@ -789,7 +791,6 @@ int __must_check fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
 		msi_entry->msi_attrib.entry_nr = i;
 		msi_entry->nvec_used = 1;
 		list_add_tail(&msi_entry->list, &mc_bus_dev->dev.msi_list);
-#endif
 
 		/*
 		 * NOTE: irq_res->msi_paddr will be set by the
@@ -803,10 +804,6 @@ int __must_check fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
 	}
 
 	/*
-	 * FIXME: Enable this code when the GIC-ITS MC support patch is merged
-	 */
-#ifdef GIC_ITS_MC_SUPPORT
-	/*
 	 * NOTE: Calling this function will trigger the invocation of the
 	 * mc_bus_msi_prepare() callback
 	 */
@@ -817,12 +814,7 @@ int __must_check fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
 		dev_err(&mc_bus_dev->dev, "Failed to allocate IRQs\n");
 		goto cleanup_msi_entries;
 	}
-#endif
 
-	/*
-	 * FIXME: Enable this code when the GIC-ITS MC support patch is merged
-	 */
-#ifdef GIC_ITS_MC_SUPPORT
 	for_each_msi_entry(msi_entry, &mc_bus_dev->dev) {
 		u32 irq_num = msi_entry->irq;
 
@@ -830,17 +822,12 @@ int __must_check fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
 		irq_res->irq_number = irq_num;
 		irq_res->resource.id = irq_num;
 	}
-#endif
 
 	res_pool->max_count = irq_count;
 	res_pool->free_count = irq_count;
 	mc_bus->irq_resources = irq_resources;
 	return 0;
 
-	/*
-	 * FIXME: Enable this code when the GIC-ITS MC support patch is merged
-	 */
-#ifdef GIC_ITS_MC_SUPPORT
 cleanup_msi_entries:
 	list_for_each_entry_safe(msi_entry, next_msi_entry,
 				 &mc_bus_dev->dev.msi_list, list)
@@ -848,7 +835,6 @@ cleanup_msi_entries:
 
 	devm_kfree(&mc_bus_dev->dev, irq_resources);
 	return error;
-#endif
 }
 EXPORT_SYMBOL_GPL(fsl_mc_populate_irq_pool);
 
@@ -858,32 +844,25 @@ EXPORT_SYMBOL_GPL(fsl_mc_populate_irq_pool);
  */
 void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus)
 {
-	/*
-	 * FIXME: Enable this code when the GIC-ITS MC support patch is merged
-	 */
-#ifdef GIC_ITS_MC_SUPPORT
 	struct msi_desc *msi_entry;
 	struct msi_desc *next_msi_entry;
 	struct fsl_mc *mc = dev_get_drvdata(fsl_mc_bus_type.dev_root->parent);
-#endif
 	struct fsl_mc_resource_pool *res_pool =
 			&mc_bus->resource_pools[FSL_MC_POOL_IRQ];
 
+	if (WARN_ON(!mc_bus->irq_resources))
+		return;
+
 	if (WARN_ON(res_pool->max_count == 0))
 		return;
 
 	if (WARN_ON(res_pool->free_count != res_pool->max_count))
 		return;
 
-	/*
-	 * FIXME: Enable this code when the GIC-ITS MC support patch is merged
-	 */
-#ifdef GIC_ITS_MC_SUPPORT
 	msi_domain_free_irqs(mc->irq_domain, &mc_bus->mc_dev.dev);
 	list_for_each_entry_safe(msi_entry, next_msi_entry,
 				 &mc_bus->mc_dev.dev.msi_list, list)
 		kfree(msi_entry);
-#endif
 
 	devm_kfree(&mc_bus->mc_dev.dev, mc_bus->irq_resources);
 	res_pool->max_count = 0;
@@ -984,12 +963,14 @@ static int get_mc_addr_translation_ranges(struct device *dev,
 	for (i = 0; i < *num_ranges; ++i) {
 		struct fsl_mc_addr_translation_range *range = &(*ranges)[i];
 
-		range->start_mc_addr = of_read_number(cell, mc_addr_cells);
+		range->mc_region_type = of_read_number(cell, 1);
+		range->start_mc_offset = of_read_number(cell + 1,
+							mc_addr_cells - 1);
 		cell += mc_addr_cells;
 		range->start_phys_addr = of_read_number(cell, paddr_cells);
 		cell += paddr_cells;
-		range->end_mc_addr = range->start_mc_addr +
-				     of_read_number(cell, mc_size_cells);
+		range->end_mc_offset = range->start_mc_offset +
+				       of_read_number(cell, mc_size_cells);
 
 		cell += mc_size_cells;
 	}
@@ -1021,15 +1002,9 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	platform_set_drvdata(pdev, mc);
-
-	/*
-	 * FIXME: Enable this code when the GIC-ITS MC support patch is merged
-	 */
-#ifdef GIC_ITS_MC_SUPPORT
 	error = create_mc_irq_domain(pdev, &mc->irq_domain);
 	if (error < 0)
 		return error;
-#endif
 
 	/*
 	 * Get physical address of MC portal for the root DPRC:
diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c b/drivers/staging/fsl-mc/bus/mc-sys.c
index 5737f59..9ae000c 100644
--- a/drivers/staging/fsl-mc/bus/mc-sys.c
+++ b/drivers/staging/fsl-mc/bus/mc-sys.c
@@ -256,8 +256,10 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
 		 * TODO: When MC command completion interrupts are supported
 		 * call wait function here instead of usleep_range()
 		 */
-		usleep_range(MC_CMD_COMPLETION_POLLING_MIN_SLEEP_USECS,
-			     MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS);
+		if (preemptible()) {
+			usleep_range(MC_CMD_COMPLETION_POLLING_MIN_SLEEP_USECS,
+				     MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS);
+		}
 
 		if (time_after_eq(jiffies, jiffies_until_timeout)) {
 			pr_debug("MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n",
diff --git a/drivers/staging/fsl-mc/include/dpmng.h b/drivers/staging/fsl-mc/include/dpmng.h
index 1b052b8..a38eb1a 100644
--- a/drivers/staging/fsl-mc/include/dpmng.h
+++ b/drivers/staging/fsl-mc/include/dpmng.h
@@ -41,11 +41,11 @@ struct fsl_mc_io;
 /**
  * Management Complex firmware version information
  */
-#define MC_VER_MAJOR 6
+#define MC_VER_MAJOR 7
 #define MC_VER_MINOR 0
 
 /**
- * struct mc_versoin
+ * struct mc_version
  * @major: Major version number: incremented on API compatibility changes
  * @minor: Minor version number: incremented on API additions (that are
  *		backward compatible); reset when major version is incremented
diff --git a/drivers/staging/fsl-mc/include/dprc.h b/drivers/staging/fsl-mc/include/dprc.h
index f1862a7..610ea31 100644
--- a/drivers/staging/fsl-mc/include/dprc.h
+++ b/drivers/staging/fsl-mc/include/dprc.h
@@ -99,7 +99,7 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token);
 /* Object initialization allowed - software context associated with this
  * container is allowed to invoke object initialization operations.
  */
-#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED	0x00000004
+#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED         0x00000004
 
 /* Topology change allowed - software context associated with this
  * container is allowed to invoke topology operations, such as attach/detach
@@ -115,6 +115,9 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token);
 /* AIOP - Indicates that container belongs to AIOP.  */
 #define DPRC_CFG_OPT_AIOP			0x00000020
 
+/* IRQ Config - Indicates that the container allowed to configure its IRQs.  */
+#define DPRC_CFG_OPT_IRQ_CFG_ALLOWED		0x00000040
+
 /**
  * struct dprc_cfg - Container configuration options
  * @icid: Container's ICID; if set to 'DPRC_GET_ICID_FROM_POOL', a free
@@ -122,11 +125,13 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token);
  * @portal_id: Portal ID; if set to 'DPRC_GET_PORTAL_ID_FROM_POOL', a free
  *		portal ID is allocated by the DPRC
  * @options: Combination of 'DPRC_CFG_OPT_<X>' options
+ * @label: Object's label
  */
 struct dprc_cfg {
 	uint16_t icid;
 	int portal_id;
 	uint64_t options;
+	char label[16];
 };
 
 /**
@@ -135,8 +140,7 @@ struct dprc_cfg {
  * @token:	Token of DPRC object
  * @cfg:	Child container configuration
  * @child_container_id:	Returned child container ID
- * @child_portal_paddr:	Returned base physical address of the
- *					child portal
+ * @child_portal_offset: Returned child portal offset from MC portal base
  *
  * Return:	'0' on Success; Error code otherwise.
  */
@@ -144,7 +148,7 @@ int dprc_create_container(struct fsl_mc_io	*mc_io,
 			  uint16_t		token,
 			  struct dprc_cfg	*cfg,
 			  int			*child_container_id,
-			  uint64_t		*child_portal_paddr);
+			  uint64_t		*child_portal_offset);
 
 /**
  * dprc_destroy_container() - Destroy child container.
@@ -201,16 +205,20 @@ int dprc_reset_container(struct fsl_mc_io *mc_io,
 /* Number of dprc's IRQs */
 #define DPRC_NUM_OF_IRQS		1
 
-/* Object irq events */
+/* DPRC IRQ events */
 
-/* IRQ event - Indicates that a new object assigned to the container */
+/* IRQ event - Indicates that a new object added to the container */
 #define DPRC_IRQ_EVENT_OBJ_ADDED		0x00000001
-/* IRQ event - Indicates that an object was unassigned from the container */
+
+/* IRQ event - Indicates that an object was removed from the container */
 #define DPRC_IRQ_EVENT_OBJ_REMOVED		0x00000002
-/* IRQ event - Indicates that resources assigned to the container */
+
+/* IRQ event - Indicates that resources added to the container */
 #define DPRC_IRQ_EVENT_RES_ADDED		0x00000004
-/* IRQ event - Indicates that resources unassigned from the container */
+
+/* IRQ event - Indicates that resources removed from the container */
 #define DPRC_IRQ_EVENT_RES_REMOVED		0x00000008
+
 /* IRQ event - Indicates that one of the descendant containers that opened by
  * this container is destroyed
  */
@@ -610,6 +618,7 @@ int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count);
  * @irq_count: Number of interrupts supported by the object
  * @region_count: Number of mappable regions supported by the object
  * @state: Object state: combination of DPRC_OBJ_STATE_ states
+ * @label: Object label
  */
 struct dprc_obj_desc {
 	char type[16];
@@ -620,6 +629,7 @@ struct dprc_obj_desc {
 	uint8_t irq_count;
 	uint8_t region_count;
 	uint32_t state;
+	char label[16];
 };
 
 /**
@@ -642,6 +652,53 @@ int dprc_get_obj(struct fsl_mc_io	*mc_io,
 		 struct dprc_obj_desc	*obj_desc);
 
 /**
+ * dprc_obj_set_irq() - Set IRQ information for object to trigger an interrupt.
+ * @mc_io:	Pointer to MC portal's I/O object
+ * @token:	Token of DPRC object
+ * @obj_index:  Index of the object to set its IRQ (< obj_count returned from
+ *		dprc_get_obj_count())
+ * @irq_index:	Identifies the interrupt index to configure
+ * @irq_addr:	Address that must be written to
+ *			signal a message-based interrupt
+ * @irq_val:	Value to write into irq_addr address
+ * @user_irq_id: Returned a user defined number associated with this IRQ
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dprc_obj_set_irq(struct fsl_mc_io	*mc_io,
+		     uint16_t		token,
+		     int		obj_index,
+		     uint8_t		irq_index,
+		     uint64_t		irq_addr,
+		     uint32_t		irq_val,
+		     int		user_irq_id);
+
+/**
+ * dprc_obj_get_irq() - Get IRQ information from object.
+ * @mc_io:	Pointer to MC portal's I/O object
+ * @token:	Token of DPRC object
+ * @obj_index:  Index of the object to get its IRQ (< obj_count returned from
+ *		dprc_get_obj_count())
+ * @irq_index:	The interrupt index to configure
+ * @type:	Returned interrupt type: 0 represents message interrupt
+ *			type (both irq_addr and irq_val are valid)
+ * @irq_addr:	Returned address that must be written to
+ *			signal the message-based interrupt
+ * @irq_val:	Value to write into irq_addr address
+ * @user_irq_id: A user defined number associated with this IRQ
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dprc_obj_get_irq(struct fsl_mc_io	*mc_io,
+		     uint16_t		token,
+		     int		obj_index,
+		     uint8_t		irq_index,
+		     int		*type,
+		     uint64_t		*irq_addr,
+		     uint32_t		*irq_val,
+		     int		*user_irq_id);
+
+/**
  * dprc_get_res_count() - Obtains the number of free resources that are assigned
  *		to this container, by pool type
  * @mc_io:	Pointer to MC portal's I/O object
@@ -699,26 +756,15 @@ int dprc_get_res_ids(struct fsl_mc_io			*mc_io,
 		     struct dprc_res_ids_range_desc	*range_desc);
 
 /**
- * dprc_get_portal_paddr() - Get the physical address of MC portals
- * @mc_io:	Pointer to MC portal's I/O object
- * @token:	Token of DPRC object
- * @portal_id:	MC portal ID
- * @portal_addr: The physical address of the MC portal ID
- *
- * Return:	'0' on Success; Error code otherwise.
- */
-int dprc_get_portal_paddr(struct fsl_mc_io	*mc_io,
-			  uint16_t		token,
-			  int			portal_id,
-			  uint64_t		*portal_addr);
-
-/**
  * struct dprc_region_desc - Mappable region descriptor
- * @base_paddr: Region base physical address
+ * @base_offset: Region offset from region's base address.
+ *	For DPMCP and DPRC objects, region base is offset from SoC MC portals
+ *	base address; For DPIO, region base is offset from SoC QMan portals
+ *	base address
  * @size: Region size (in bytes)
  */
 struct dprc_region_desc {
-	uint64_t base_paddr;
+	uint64_t base_offset;
 	uint32_t size;
 };
 
@@ -741,6 +787,20 @@ int dprc_get_obj_region(struct fsl_mc_io	*mc_io,
 			struct dprc_region_desc	*region_desc);
 
 /**
+ * dprc_set_obj_label() - Set object label.
+ * @mc_io:	Pointer to MC portal's I/O object
+ * @token:	Token of DPRC object
+ * @obj_index;	Object index
+ * @label:	The required label. The maximum length is 16 chars.
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dprc_set_obj_label(struct fsl_mc_io *mc_io,
+		       uint16_t  token,
+		       int obj_index,
+		       char *label);
+
+/**
  * struct dprc_endpoint - Endpoint description for link connect/disconnect
  *			operations
  * @type: Endpoint object type: NULL terminated string
@@ -783,8 +843,8 @@ int dprc_disconnect(struct fsl_mc_io		*mc_io,
 /**
 * dprc_get_connection() - Get connected endpoint and link status if connection
 *			exists.
-* @mc_io		Pointer to MC portal's I/O object
-* @token		Token of DPRC object
+* @mc_io	Pointer to MC portal's I/O object
+* @token	Token of DPRC object
 * @endpoint1	Endpoint 1 configuration parameters
 * @endpoint2	Returned endpoint 2 configuration parameters
 * @state:	Returned link state: 1 - link is up, 0 - link is down
diff --git a/drivers/staging/fsl-mc/include/mc-private.h b/drivers/staging/fsl-mc/include/mc-private.h
index 5b9c8f2..67ba488 100644
--- a/drivers/staging/fsl-mc/include/mc-private.h
+++ b/drivers/staging/fsl-mc/include/mc-private.h
@@ -52,16 +52,31 @@ struct fsl_mc {
 };
 
 /**
+ * enum mc_region_types - Types of MC MMIO regions
+ */
+enum fsl_mc_region_types {
+	FSL_MC_PORTAL = 0x0,
+	FSL_QBMAN_PORTAL,
+
+	/*
+	 * New offset types must be added above this entry
+	 */
+	FSL_NUM_MC_OFFSET_TYPES
+};
+
+/**
  * struct fsl_mc_addr_translation_range - bus to system address translation
  * range
- * @start_mc_addr: Start MC address of the range being translated
- * @end_mc_addr: MC address of the first byte after the range (last MC
- * address of the range is end_mc_addr - 1)
+ * @mc_region_type: Type of MC region for the range being translated
+ * @start_mc_offset: Start MC offset of the range being translated
+ * @end_mc_offset: MC offset of the first byte after the range (last MC
+ * offset of the range is end_mc_offset - 1)
  * @start_phys_addr: system physical address corresponding to start_mc_addr
  */
 struct fsl_mc_addr_translation_range {
-	uint64_t start_mc_addr;
-	uint64_t end_mc_addr;
+	enum fsl_mc_region_types mc_region_type;
+	uint64_t start_mc_offset;
+	uint64_t end_mc_offset;
 	phys_addr_t start_phys_addr;
 };
 
@@ -115,6 +130,10 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
 		      const char *driver_override,
 		      unsigned int *total_irq_count);
 
+int dprc_lookup_object(struct fsl_mc_device *mc_bus_dev,
+		       struct fsl_mc_device *child_dev,
+		       uint32_t *child_obj_index);
+
 int __init dprc_driver_init(void);
 
 void __exit dprc_driver_exit(void);
diff --git a/drivers/staging/fsl-mc/include/mc.h b/drivers/staging/fsl-mc/include/mc.h
index f965c4d..0a2f381d 100644
--- a/drivers/staging/fsl-mc/include/mc.h
+++ b/drivers/staging/fsl-mc/include/mc.h
@@ -110,12 +110,16 @@ struct fsl_mc_resource {
  * @msi_paddr: message-based interrupt physical address
  * @msi_value: message-based interrupt data value
  * @irq_number: Linux IRQ number assigned to the interrupt
+ * @mc_dev: MC object device that owns this interrupt
+ * @dev_irq_index: device-relative IRQ index
  * @resource: MC generic resource associated with the interrupt
  */
 struct fsl_mc_device_irq {
 	phys_addr_t msi_paddr;
 	uint32_t msi_value;
 	uint32_t irq_number;
+	struct fsl_mc_device *mc_dev;
+	uint8_t dev_irq_index;
 	struct fsl_mc_resource resource;
 };
 
-- 
2.3.3



More information about the devel mailing list