linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series
@ 2014-09-11 17:34 J. German Rivera
  2014-09-11 17:34 ` [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs J. German Rivera
                   ` (4 more replies)
  0 siblings, 5 replies; 43+ messages in thread
From: J. German Rivera @ 2014-09-11 17:34 UTC (permalink / raw)
  To: gregkh, arnd, linux-kernel
  Cc: stuart.yoder, Kim.Phillips, scottwood, agraf, linuxppc-release

This patch series introduces Linux support for the Freescale
Management Complex (fsl-mc) hardware.

The fsl-mc is a hardware resource manager that manages specialized
hardware objects used in network-oriented packet processing
applications.  After the fsl-mc block is enabled, pools of hardware
resources are available, such as queues, buffer poools, I/O
interfaces.  These resources are building blocks that can be
used to create functional hardware objects such as network
interfaces, crypto accelerator instances, or L2 switches.

All the fsl-mc managed hardware resources/objects are represented in
a physical grouping mechanism called a 'container' or DPRC (data
path resource container).

>From the point of view of an OS, a DPRC functions similar to a plug
and play bus.  Using fsl-mc commands software can enumerate the
contents of the DPRC discovering the hardware objects present
and binding them to drivers.  Hardware objects can be created
and removed dynamically, providing hot pluggability of the hardware
objects.

Software contexts interact with the fsl-mc by sending commands through
a memory mapped hardware interface called an "MC portal". Every
fsl-mc object type has a command set to manage the objects. Key
DPRC commands include:
   -create/destroy a DPRC
   -enumerate objects and resource pools in the DPRC, including
    identifying mappable regions and the number of IRQs an object
    may have
   -IRQ configuration
   -move objects/resources between DPRCs
   -connecting objects (e.g. connecting a network interface to
    an L2 switch port)
   -reset

Patch 1 contains a minimal set of low level functions to send an
d receive commands to the fsl-mc. It includes support for basic
management commands and commands to manipulate DPRC objects.

Patch 2 contains a platform device driver that sets up and registers
the basic bus infrastructure including support for adding/removing
devices, register/unregister of drivers, and bus match support
to bind devices to drivers.

Patch 3 contains an driver that manages DPRC objects (the
container that holds the hardware resources). This driver
functions as a bus controller and handles enumeration
of the objects in the container and hotplug events.

Patch 4 contains the update to the MAINTAINERS file.

CHANGE HISTORY

No changes since RFC v4

Changes in RFC v4:
- Fixed parameter mismatch for device_find_child() call in fsl_mc_dprc.c
- Added back the dma_mask field to struct fsl_mc_device as it is needed
  by some MC child device drivers. However, the default DMA mask now
  does not have the 32-bit limitation of the original patch series (v1).

Changes in RFC v3:
Rework to address comments from Arnd Bergmann:
- Removed per-bus list of children, and instead use device_for_each_child()
- Use the same structure (struct fsl_mc_device) to represent both
  bus devices and their children.
http://www.mail-archive.com/linux-kernel%40vger.kernel.org/msg711301.html

Changes in RFC v2:
Rework to address comments from Arnd Bergmann:
- Removed fsl_mc_bus structure and global variable
- Removed the 'magic' fields from all structs
- Removed NULL initializers
- Replaced all occurrences of EXPORT_SYMBOL() with EXPORT_SYMBOL_GPL()
- Removed function dprc_parse_dt_node(), and replaced its call by a
  direct call to of_address_to_resource()
- Removed struct fsl_mc_device_region and use standard 'struct resource'
  instead.
- Removed dma_mask field from 'struct fsl_mc_device' as it is not currently
  being used.
- Removed redundant 'driver' field from struct fsl_mc_device
- Removed the container field. We can get the parent DPRC of a given dev,
  from its dev.parent field.
http://www.mail-archive.com/linux-kernel%40vger.kernel.org/msg708858.html


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

* [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-11 17:34 [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series J. German Rivera
@ 2014-09-11 17:34 ` J. German Rivera
  2014-09-11 18:45   ` Joe Perches
  2014-09-15 23:44   ` Kim Phillips
  2014-09-11 17:34 ` [PATCH 2/4] drivers/bus: Freescale Management Complex (fsl-mc) bus driver J. German Rivera
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 43+ messages in thread
From: J. German Rivera @ 2014-09-11 17:34 UTC (permalink / raw)
  To: gregkh, arnd, linux-kernel
  Cc: stuart.yoder, Kim.Phillips, scottwood, agraf, linuxppc-release,
	J. German Rivera

From: "J. German Rivera" <German.Rivera@freescale.com>

APIs to access the Management Complex (MC) hardware
module of Freescale LS2 SoCs. This patch includes
APIs to check the MC firmware version and to manipulate
DPRC objects in the MC.

Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
---
 drivers/bus/fsl-mc/dpmng.c         |   93 +++++
 drivers/bus/fsl-mc/dprc.c          |  504 +++++++++++++++++++++++
 drivers/bus/fsl-mc/fsl_dpmng_cmd.h |   83 ++++
 drivers/bus/fsl-mc/fsl_dprc_cmd.h  |  545 +++++++++++++++++++++++++
 drivers/bus/fsl-mc/fsl_mc_sys.c    |  237 +++++++++++
 include/linux/fsl_dpmng.h          |  120 ++++++
 include/linux/fsl_dprc.h           |  790 ++++++++++++++++++++++++++++++++++++
 include/linux/fsl_mc_cmd.h         |  182 +++++++++
 include/linux/fsl_mc_sys.h         |   81 ++++
 9 files changed, 2635 insertions(+)
 create mode 100644 drivers/bus/fsl-mc/dpmng.c
 create mode 100644 drivers/bus/fsl-mc/dprc.c
 create mode 100644 drivers/bus/fsl-mc/fsl_dpmng_cmd.h
 create mode 100644 drivers/bus/fsl-mc/fsl_dprc_cmd.h
 create mode 100644 drivers/bus/fsl-mc/fsl_mc_sys.c
 create mode 100644 include/linux/fsl_dpmng.h
 create mode 100644 include/linux/fsl_dprc.h
 create mode 100644 include/linux/fsl_mc_cmd.h
 create mode 100644 include/linux/fsl_mc_sys.h

diff --git a/drivers/bus/fsl-mc/dpmng.c b/drivers/bus/fsl-mc/dpmng.c
new file mode 100644
index 0000000..c6ed27c
--- /dev/null
+++ b/drivers/bus/fsl-mc/dpmng.c
@@ -0,0 +1,93 @@
+/* Copyright 2013-2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/fsl_mc_sys.h>
+#include <linux/fsl_mc_cmd.h>
+#include <linux/fsl_dpmng.h>
+#include "fsl_dpmng_cmd.h"
+
+int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION,
+					  DPMNG_CMDSZ_GET_VERSION,
+					  MC_CMD_PRI_LOW, 0);
+
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPMNG_RSP_GET_VERSION(cmd, mc_ver_info);
+
+	return err;
+}
+
+int dpmng_reset_aiop(struct fsl_mc_io *mc_io, int aiop_tile_id)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_AIOP,
+					  DPMNG_CMDSZ_RESET_AIOP,
+					  MC_CMD_PRI_LOW, 0);
+
+	DPMNG_CMD_RESET_AIOP(cmd, aiop_tile_id);
+
+	return mc_send_command(mc_io, &cmd);
+}
+
+int dpmng_load_aiop(struct fsl_mc_io *mc_io,
+		    int aiop_tile_id, uint8_t *img_addr, int img_size)
+{
+	struct mc_command cmd = { 0 };
+	uint64_t img_paddr = virt_to_phys(img_addr);
+
+	cmd.header = mc_encode_cmd_header(DPMNG_CMDID_LOAD_AIOP,
+					  DPMNG_CMDSZ_LOAD_AIOP,
+					  MC_CMD_PRI_LOW, 0);
+
+	DPMNG_CMD_LOAD_AIOP(cmd, aiop_tile_id, img_size, img_paddr);
+
+	return mc_send_command(mc_io, &cmd);
+}
+
+int dpmng_run_aiop(struct fsl_mc_io *mc_io,
+		   int aiop_tile_id, uint32_t cores_mask, uint64_t options)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RUN_AIOP,
+					  DPMNG_CMDSZ_RUN_AIOP,
+					  MC_CMD_PRI_LOW, 0);
+
+	DPMNG_CMD_RUN_AIOP(cmd, aiop_tile_id, cores_mask, options);
+
+	return mc_send_command(mc_io, &cmd);
+}
diff --git a/drivers/bus/fsl-mc/dprc.c b/drivers/bus/fsl-mc/dprc.c
new file mode 100644
index 0000000..5c80bab
--- /dev/null
+++ b/drivers/bus/fsl-mc/dprc.c
@@ -0,0 +1,504 @@
+/* Copyright 2013-2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/fsl_mc_sys.h>
+#include <linux/fsl_mc_cmd.h>
+#include <linux/fsl_dprc.h>
+#include "fsl_dprc_cmd.h"
+
+int dprc_get_container_id(struct fsl_mc_io *mc_io, int *container_id)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID,
+					  DPRC_CMDSZ_GET_CONT_ID,
+					  MC_CMD_PRI_LOW, 0);
+
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_CONTAINER_ID(cmd, *container_id);
+
+	return err;
+}
+
+int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *dprc_handle)
+{
+	int err;
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(MC_DPRC_CMDID_OPEN,
+					  MC_CMD_OPEN_SIZE, MC_CMD_PRI_LOW, 0);
+
+	DPRC_CMD_OPEN(cmd, container_id);
+
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		*dprc_handle = MC_CMD_HDR_READ_AUTHID(cmd.header);
+
+	return err;
+}
+
+int dprc_close(struct fsl_mc_io *mc_io, uint16_t dprc_handle)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(MC_CMDID_CLOSE,
+					  MC_CMD_CLOSE_SIZE,
+					  MC_CMD_PRI_HIGH, dprc_handle);
+
+	return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_create_container(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			  struct dprc_cfg *cfg,
+			  int *child_container_id,
+			  uint64_t *child_portal_paddr)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_CREATE_CONT,
+					  DPRC_CMDSZ_CREATE_CONT,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_CREATE_CONTAINER(cmd, cfg);
+
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_CREATE_CONTAINER(cmd, *child_container_id,
+					  *child_portal_paddr);
+
+	return err;
+}
+
+int dprc_destroy_container(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			   int child_container_id)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_DESTROY_CONT,
+					  DPRC_CMDSZ_DESTROY_CONT,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_DESTROY_CONTAINER(cmd, child_container_id);
+	return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_reset_container(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			 int child_container_id)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_RESET_CONT,
+					  DPRC_CMDSZ_RESET_CONT,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_RESET_CONTAINER(cmd, child_container_id);
+	return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_set_res_quota(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		       int child_container_id, char *type, uint16_t quota)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_RES_QUOTA,
+					  DPRC_CMDSZ_SET_RES_QUOTA,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_SET_RES_QUOTA(cmd, child_container_id, type, quota);
+	return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_get_res_quota(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		       int child_container_id, char *type, uint16_t *quota)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_QUOTA,
+					  DPRC_CMDSZ_GET_RES_QUOTA,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_GET_RES_QUOTA(cmd, child_container_id, type);
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_RES_QUOTA(cmd, *quota);
+
+	return err;
+}
+
+int dprc_assign(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		int container_id, struct dprc_res_req *res_req)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_ASSIGN,
+					  DPRC_CMDSZ_ASSIGN,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_ASSIGN(cmd, container_id, res_req);
+	return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_unassign(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		  int child_container_id, struct dprc_res_req *res_req)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_UNASSIGN,
+					  DPRC_CMDSZ_UNASSIGN,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_UNASSIGN(cmd, child_container_id, res_req);
+	return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		       int *obj_count)
+{
+	int err;
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_COUNT,
+					  DPRC_CMDSZ_GET_OBJ_COUNT,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_OBJ_COUNT(cmd, *obj_count);
+
+	return err;
+}
+
+int dprc_get_obj(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		 int obj_index, struct dprc_obj_desc *obj_desc)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJECT,
+					  DPRC_CMDSZ_GET_OBJECT,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_GET_OBJECT(cmd, obj_index);
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_OBJECT(cmd, obj_desc);
+
+	return err;
+}
+
+int dprc_get_res_count(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		       char *type, int *res_count)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	*res_count = 0;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_COUNT,
+					  DPRC_CMDSZ_GET_RES_COUNT,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_GET_RES_COUNT(cmd, type);
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_RES_COUNT(cmd, *res_count);
+
+	return err;
+}
+
+int dprc_get_res_ids(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		     char *type, struct dprc_res_ids_range_desc *range_desc)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_IDS,
+					  DPRC_CMDSZ_GET_RES_IDS,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_GET_RES_IDS(cmd, type, range_desc);
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_RES_IDS(cmd, range_desc);
+
+	return err;
+}
+
+int dprc_get_attributes(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			struct dprc_attributes *attr)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_ATTR,
+					  DPRC_CMDSZ_GET_ATTR,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_ATTRIBUTES(cmd, attr);
+
+	return err;
+}
+
+int dprc_get_obj_region(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			char *obj_type,
+			int obj_id,
+			uint8_t region_index,
+			struct dprc_region_desc *region_desc)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG,
+					  DPRC_CMDSZ_GET_OBJ_REG,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_GET_OBJ_REGION(cmd, obj_id, region_index, obj_type);
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_OBJ_REGION(cmd, region_desc);
+
+	return err;
+}
+
+int dprc_get_irq(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		 uint8_t irq_index,
+		 int *type,
+		 uint64_t *irq_paddr, uint32_t *irq_val, int *user_irq_id)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ,
+					  DPRC_CMDSZ_GET_IRQ,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_GET_IRQ(cmd, irq_index);
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_IRQ(cmd, *irq_val, *irq_paddr, *user_irq_id,
+				 *type);
+
+	return err;
+}
+
+int dprc_set_irq(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		 uint8_t irq_index,
+		 uint64_t irq_paddr, uint32_t irq_val, int user_irq_id)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ,
+					  DPRC_CMDSZ_SET_IRQ,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_SET_IRQ(cmd, irq_index, irq_val, irq_paddr, user_irq_id);
+	return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_get_irq_enable(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			uint8_t irq_index, uint8_t *enable_state)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_ENABLE,
+					  DPRC_CMDSZ_GET_IRQ_ENABLE,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_GET_IRQ_ENABLE(cmd, irq_index);
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_IRQ_ENABLE(cmd, *enable_state);
+
+	return err;
+}
+
+int dprc_set_irq_enable(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			uint8_t irq_index, uint8_t enable_state)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_ENABLE,
+					  DPRC_CMDSZ_SET_IRQ_ENABLE,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_SET_IRQ_ENABLE(cmd, enable_state, irq_index);
+	return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_get_irq_mask(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		      uint8_t irq_index, uint32_t *mask)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_MASK,
+					  DPRC_CMDSZ_GET_IRQ_MASK,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_GET_IRQ_MASK(cmd, irq_index);
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_IRQ_MASK(cmd, *mask);
+
+	return err;
+}
+
+int dprc_set_irq_mask(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		      uint8_t irq_index, uint32_t mask)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_MASK,
+					  DPRC_CMDSZ_SET_IRQ_MASK,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_SET_IRQ_MASK(cmd, mask, irq_index);
+	return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_get_irq_status(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			uint8_t irq_index, uint32_t *status)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_STATUS,
+					  DPRC_CMDSZ_GET_IRQ_STATUS,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_GET_IRQ_STATUS(cmd, irq_index);
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_IRQ_STATUS(cmd, *status);
+
+	return err;
+}
+
+int dprc_clear_irq_status(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			  uint8_t irq_index, uint32_t status)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLEAR_IRQ_STATUS,
+					  DPRC_CMDSZ_CLEAR_IRQ_STATUS,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_CLEAR_IRQ_STATUS(cmd, status, irq_index);
+	return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_get_pool_count(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			int *pool_count)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_POOL_COUNT,
+					  DPRC_CMDSZ_GET_POOL_COUNT,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_POOL_COUNT(cmd, *pool_count);
+
+	return err;
+}
+
+int dprc_get_pool(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		  int pool_index, char *type)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_POOL,
+					  DPRC_CMDSZ_GET_POOL,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_GET_POOL(cmd, pool_index);
+
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_POOL(cmd, type);
+
+	return err;
+}
+
+int dprc_get_portal_paddr(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			  int portal_id, uint64_t *portal_addr)
+{
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_PORTAL_PADDR,
+					  DPRC_CMDSZ_GET_PORTAL_PADDR,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_GET_PORTAL_PADDR(cmd, portal_id);
+	err = mc_send_command(mc_io, &cmd);
+	if (!err)
+		DPRC_RSP_GET_PORTAL_PADDR(cmd, *portal_addr);
+
+	return err;
+}
+
+int dprc_connect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		 struct dprc_endpoint *endpoint1,
+		 struct dprc_endpoint *endpoint2)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_CONNECT,
+					  DPRC_CMDSZ_CONNECT,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_CONNECT(cmd, endpoint1, endpoint2);
+	return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_disconnect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		    struct dprc_endpoint *endpoint)
+{
+	struct mc_command cmd = { 0 };
+
+	cmd.header = mc_encode_cmd_header(DPRC_CMDID_DISCONNECT,
+					  DPRC_CMDSZ_DISCONNECT,
+					  MC_CMD_PRI_LOW, dprc_handle);
+
+	DPRC_CMD_DISCONNECT(cmd, endpoint);
+	return mc_send_command(mc_io, &cmd);
+}
diff --git a/drivers/bus/fsl-mc/fsl_dpmng_cmd.h b/drivers/bus/fsl-mc/fsl_dpmng_cmd.h
new file mode 100644
index 0000000..5445455
--- /dev/null
+++ b/drivers/bus/fsl-mc/fsl_dpmng_cmd.h
@@ -0,0 +1,83 @@
+/* Copyright 2013-2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//*
+ @File          fsl_dpmng_cmd.h
+
+ @Description   defines portal commands
+
+ @Cautions      None.
+ *//***************************************************************************/
+
+#ifndef __FSL_DPMNG_CMD_H
+#define __FSL_DPMNG_CMD_H
+
+/* Command IDs */
+#define DPMNG_CMDID_GET_VERSION			0x831
+#define DPMNG_CMDID_RESET_AIOP			0x832
+#define DPMNG_CMDID_LOAD_AIOP			0x833
+#define DPMNG_CMDID_RUN_AIOP			0x834
+
+/* Command sizes */
+#define DPMNG_CMDSZ_GET_VERSION			(8 * 2)
+#define DPMNG_CMDSZ_RESET_AIOP			8
+#define DPMNG_CMDSZ_LOAD_AIOP			(8 * 2)
+#define DPMNG_CMDSZ_RUN_AIOP			(8 * 2)
+
+/*	param, offset, width,	type,		arg_name */
+#define DPMNG_RSP_GET_VERSION(cmd, mc_ver_info) \
+do { \
+	MC_RSP_PARAM_OP(cmd, 0,	0,	32, uint32_t,	mc_ver_info->revision);\
+	MC_RSP_PARAM_OP(cmd, 0,	32,	32, uint32_t,	mc_ver_info->major); \
+	MC_RSP_PARAM_OP(cmd, 1,	0,	8,  uint32_t,	mc_ver_info->minor); \
+} while (0)
+
+/*	param, offset, width,	type,		arg_name */
+#define DPMNG_CMD_RESET_AIOP(cmd, aiop_tile_id) \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32,	int,	aiop_tile_id)
+
+/*	param, offset, width,	type,		arg_name */
+#define DPMNG_CMD_LOAD_AIOP(cmd, aiop_tile_id, img_size, img_paddr) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32, int,	aiop_tile_id); \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	32, int,	img_size); \
+	MC_CMD_PARAM_OP(cmd, 1,	0,	64, uint64_t,	img_paddr); \
+} while (0)
+
+/*	param, offset, width,	type,		arg_name */
+#define DPMNG_CMD_RUN_AIOP(cmd, aiop_tile_id, cores_mask, options) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32,	int,		aiop_tile_id); \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	32,	uint32_t,	cores_mask); \
+	MC_CMD_PARAM_OP(cmd, 1,	0,	64,	uint64_t,	options); \
+} while (0)
+
+#endif /* __FSL_DPMNG_CMD_H */
diff --git a/drivers/bus/fsl-mc/fsl_dprc_cmd.h b/drivers/bus/fsl-mc/fsl_dprc_cmd.h
new file mode 100644
index 0000000..e4d1fdc
--- /dev/null
+++ b/drivers/bus/fsl-mc/fsl_dprc_cmd.h
@@ -0,0 +1,545 @@
+/* Copyright 2013-2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//*
+ @File          fsl_dprc_cmd.h
+
+ @Description   defines dprc portal commands
+
+ @Cautions      None.
+ *//***************************************************************************/
+
+#ifndef _FSL_DPRC_CMD_H
+#define _FSL_DPRC_CMD_H
+
+/* DPRC Version */
+#define DPRC_VER_MAJOR				1
+#define DPRC_VER_MINOR				0
+
+/* Command IDs */
+#define MC_CMDID_CLOSE				0x800
+#define MC_DPRC_CMDID_OPEN			0x805
+#define MC_DPRC_CMDID_CREATE			0x905
+
+#define DPRC_CMDID_CREATE_CONT			0x151
+#define DPRC_CMDID_DESTROY_CONT			0x152
+#define DPRC_CMDID_GET_CONT_ID			0x830
+#define DPRC_CMDID_RESET_CONT			0x154
+#define DPRC_CMDID_SET_RES_QUOTA		0x155
+#define DPRC_CMDID_GET_RES_QUOTA		0x156
+#define DPRC_CMDID_ASSIGN			0x157
+#define DPRC_CMDID_UNASSIGN			0x158
+#define DPRC_CMDID_GET_OBJ_COUNT		0x159
+#define DPRC_CMDID_GET_OBJECT			0x15A
+#define DPRC_CMDID_GET_RES_COUNT		0x15B
+#define DPRC_CMDID_GET_RES_IDS			0x15C
+#define DPRC_CMDID_GET_ATTR			0x15D
+#define DPRC_CMDID_GET_OBJ_REG			0x15E
+#define DPRC_CMDID_SET_IRQ			0x15F
+#define DPRC_CMDID_GET_IRQ			0x160
+#define DPRC_CMDID_SET_IRQ_ENABLE		0x161
+#define DPRC_CMDID_GET_IRQ_ENABLE		0x162
+#define DPRC_CMDID_SET_IRQ_MASK			0x163
+#define DPRC_CMDID_GET_IRQ_MASK			0x164
+#define DPRC_CMDID_GET_IRQ_STATUS		0x165
+#define DPRC_CMDID_CLEAR_IRQ_STATUS		0x166
+#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
+
+/* Command sizes */
+#define MC_CMD_OPEN_SIZE			8
+#define MC_CMD_CLOSE_SIZE			0
+#define DPRC_CMDSZ_CREATE_CONT			(8 * 2)
+#define DPRC_CMDSZ_DESTROY_CONT			8
+#define DPRC_CMDSZ_GET_CONT_ID			8
+#define DPRC_CMDSZ_RESET_CONT			8
+#define DPRC_CMDSZ_SET_RES_QUOTA		(8 * 3)
+#define DPRC_CMDSZ_GET_RES_QUOTA		(8 * 3)
+#define DPRC_CMDSZ_ASSIGN			(8 * 4)
+#define DPRC_CMDSZ_UNASSIGN			(8 * 4)
+#define DPRC_CMDSZ_GET_OBJ_COUNT		0
+#define DPRC_CMDSZ_GET_OBJECT			(8 * 5)
+#define DPRC_CMDSZ_GET_RES_COUNT		8
+#define DPRC_CMDSZ_GET_RES_IDS			(8 * 4)
+#define DPRC_CMDSZ_GET_ATTR			(8 * 3)
+#define DPRC_CMDSZ_GET_OBJ_REG			(8 * 5)
+#define DPRC_CMDSZ_SET_IRQ			(8 * 3)
+#define DPRC_CMDSZ_GET_IRQ			(8 * 3)
+#define DPRC_CMDSZ_SET_IRQ_ENABLE		8
+#define DPRC_CMDSZ_GET_IRQ_ENABLE		8
+#define DPRC_CMDSZ_SET_IRQ_MASK			8
+#define DPRC_CMDSZ_GET_IRQ_MASK			8
+#define DPRC_CMDSZ_GET_IRQ_STATUS		8
+#define DPRC_CMDSZ_CLEAR_IRQ_STATUS		8
+#define DPRC_CMDSZ_CONNECT			(8 * 7)
+#define DPRC_CMDSZ_DISCONNECT			(8 * 3)
+#define DPRC_CMDSZ_GET_POOL			(8 * 3)
+#define DPRC_CMDSZ_GET_POOL_COUNT		8
+#define DPRC_CMDSZ_GET_PORTAL_PADDR		(8 * 2)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_OPEN(cmd, container_id) \
+	MC_CMD_PARAM_OP(cmd, 0, 0, 32,	int, container_id)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_GET_CONTAINER_ID(cmd, container_id) \
+	MC_RSP_PARAM_OP(cmd, 0,  0, 32, int, container_id)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_CREATE_CONTAINER(cmd, cfg) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0, 32, 16, uint16_t, cfg->icid); \
+	MC_CMD_PARAM_OP(cmd, 0, 0,  32, uint32_t, cfg->options); \
+	MC_CMD_PARAM_OP(cmd, 1, 32, 32, int,	  cfg->portal_id); \
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_CREATE_CONTAINER(cmd, child_container_id, child_portal_paddr) \
+do { \
+	MC_RSP_PARAM_OP(cmd, 1, 0, 32,	int,	  child_container_id); \
+	MC_RSP_PARAM_OP(cmd, 2, 0, 64,	uint64_t, child_portal_paddr); \
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_DESTROY_CONTAINER(cmd, child_container_id) \
+	MC_CMD_PARAM_OP(cmd, 0,	0, 32, int, child_container_id)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_RESET_CONTAINER(cmd, child_container_id) \
+	MC_CMD_PARAM_OP(cmd, 0,	0, 32, int, child_container_id)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_SET_RES_QUOTA(cmd, child_container_id, type, quota) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	 0,	32,	int,	  child_container_id); \
+	MC_CMD_PARAM_OP(cmd, 0,  32,	16,	uint16_t, quota);\
+	MC_CMD_PARAM_OP(cmd, 1,  0,	8,	char,	  type[0]);\
+	MC_CMD_PARAM_OP(cmd, 1,  8,	8,	char,	  type[1]);\
+	MC_CMD_PARAM_OP(cmd, 1,  16,	8,	char,	  type[2]);\
+	MC_CMD_PARAM_OP(cmd, 1,  24,	8,	char,	  type[3]);\
+	MC_CMD_PARAM_OP(cmd, 1,  32,	8,	char,	  type[4]);\
+	MC_CMD_PARAM_OP(cmd, 1,  40,	8,	char,	  type[5]);\
+	MC_CMD_PARAM_OP(cmd, 1,  48,	8,	char,	  type[6]);\
+	MC_CMD_PARAM_OP(cmd, 1,  56,	8,	char,	  type[7]);\
+	MC_CMD_PARAM_OP(cmd, 2,  0,	8,	char,	  type[8]);\
+	MC_CMD_PARAM_OP(cmd, 2,  8,	8,	char,	  type[9]);\
+	MC_CMD_PARAM_OP(cmd, 2,  16,	8,	char,	  type[10]);\
+	MC_CMD_PARAM_OP(cmd, 2,  24,	8,	char,	  type[11]);\
+	MC_CMD_PARAM_OP(cmd, 2,  32,	8,	char,	  type[12]);\
+	MC_CMD_PARAM_OP(cmd, 2,  40,	8,	char,	  type[13]);\
+	MC_CMD_PARAM_OP(cmd, 2,  48,	8,	char,	  type[14]);\
+	MC_CMD_PARAM_OP(cmd, 2,  56,	8,	char,	  type[15]);\
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_GET_RES_QUOTA(cmd, child_container_id, type) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32,	int,	child_container_id); \
+	MC_CMD_PARAM_OP(cmd, 1,  0,	8,	char,	type[0]);\
+	MC_CMD_PARAM_OP(cmd, 1,  8,	8,	char,	type[1]);\
+	MC_CMD_PARAM_OP(cmd, 1,  16,	8,	char,	type[2]);\
+	MC_CMD_PARAM_OP(cmd, 1,  24,	8,	char,	type[3]);\
+	MC_CMD_PARAM_OP(cmd, 1,  32,	8,	char,	type[4]);\
+	MC_CMD_PARAM_OP(cmd, 1,  40,	8,	char,	type[5]);\
+	MC_CMD_PARAM_OP(cmd, 1,  48,	8,	char,	type[6]);\
+	MC_CMD_PARAM_OP(cmd, 1,  56,	8,	char,	type[7]);\
+	MC_CMD_PARAM_OP(cmd, 2,  0,	8,	char,	type[8]);\
+	MC_CMD_PARAM_OP(cmd, 2,  8,	8,	char,	type[9]);\
+	MC_CMD_PARAM_OP(cmd, 2,  16,	8,	char,	type[10]);\
+	MC_CMD_PARAM_OP(cmd, 2,  24,	8,	char,	type[11]);\
+	MC_CMD_PARAM_OP(cmd, 2,  32,	8,	char,	type[12]);\
+	MC_CMD_PARAM_OP(cmd, 2,  40,	8,	char,	type[13]);\
+	MC_CMD_PARAM_OP(cmd, 2,  48,	8,	char,	type[14]);\
+	MC_CMD_PARAM_OP(cmd, 2,  56,	8,	char,	type[15]);\
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_GET_RES_QUOTA(cmd, quota) \
+	MC_RSP_PARAM_OP(cmd, 0,	32,	16,	uint16_t,	quota)
+
+/*	param, offset, width,	type,		arg_name */
+#define DPRC_CMD_ASSIGN(cmd, container_id, res_req) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32, int,      container_id); \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	32, uint32_t, res_req->options);\
+	MC_CMD_PARAM_OP(cmd, 1,	0,	32, uint32_t, res_req->num); \
+	MC_CMD_PARAM_OP(cmd, 1,	32,	32, int,      res_req->id_base_align); \
+	MC_CMD_PARAM_OP(cmd, 2,	0,	8,  char,     res_req->type[0]);\
+	MC_CMD_PARAM_OP(cmd, 2,	8,	8,  char,     res_req->type[1]);\
+	MC_CMD_PARAM_OP(cmd, 2,	16,	8,  char,     res_req->type[2]);\
+	MC_CMD_PARAM_OP(cmd, 2,	24,	8,  char,     res_req->type[3]);\
+	MC_CMD_PARAM_OP(cmd, 2,	32,	8,  char,     res_req->type[4]);\
+	MC_CMD_PARAM_OP(cmd, 2,	40,	8,  char,     res_req->type[5]);\
+	MC_CMD_PARAM_OP(cmd, 2,	48,	8,  char,     res_req->type[6]);\
+	MC_CMD_PARAM_OP(cmd, 2,	56,	8,  char,     res_req->type[7]);\
+	MC_CMD_PARAM_OP(cmd, 3,	0,	8,  char,     res_req->type[8]);\
+	MC_CMD_PARAM_OP(cmd, 3,	8,	8,  char,     res_req->type[9]);\
+	MC_CMD_PARAM_OP(cmd, 3,	16,	8,  char,     res_req->type[10]);\
+	MC_CMD_PARAM_OP(cmd, 3,	24,	8,  char,     res_req->type[11]);\
+	MC_CMD_PARAM_OP(cmd, 3,	32,	8,  char,     res_req->type[12]);\
+	MC_CMD_PARAM_OP(cmd, 3,	40,	8,  char,     res_req->type[13]);\
+	MC_CMD_PARAM_OP(cmd, 3,	48,	8,  char,     res_req->type[14]);\
+	MC_CMD_PARAM_OP(cmd, 3,	56,	8,  char,     res_req->type[15]);\
+} while (0)
+
+/*	param, offset, width,	type,		arg_name */
+#define DPRC_CMD_UNASSIGN(cmd, child_container_id, res_req) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32, int,     child_container_id); \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	32, uint32_t, res_req->options);\
+	MC_CMD_PARAM_OP(cmd, 1,	0,	32, uint32_t, res_req->num); \
+	MC_CMD_PARAM_OP(cmd, 1,	32,	32, int,      res_req->id_base_align); \
+	MC_CMD_PARAM_OP(cmd, 2,	0,	8,  char,     res_req->type[0]);\
+	MC_CMD_PARAM_OP(cmd, 2,	8,	8,  char,     res_req->type[1]);\
+	MC_CMD_PARAM_OP(cmd, 2,	16,	8,  char,     res_req->type[2]);\
+	MC_CMD_PARAM_OP(cmd, 2,	24,	8,  char,     res_req->type[3]);\
+	MC_CMD_PARAM_OP(cmd, 2,	32,	8,  char,     res_req->type[4]);\
+	MC_CMD_PARAM_OP(cmd, 2,	40,	8,  char,     res_req->type[5]);\
+	MC_CMD_PARAM_OP(cmd, 2,	48,	8,  char,     res_req->type[6]);\
+	MC_CMD_PARAM_OP(cmd, 2,	56,	8,  char,     res_req->type[7]);\
+	MC_CMD_PARAM_OP(cmd, 3,	0,	8,  char,     res_req->type[8]);\
+	MC_CMD_PARAM_OP(cmd, 3,	8,	8,  char,     res_req->type[9]);\
+	MC_CMD_PARAM_OP(cmd, 3,	16,	8,  char,     res_req->type[10]);\
+	MC_CMD_PARAM_OP(cmd, 3,	24,	8,  char,     res_req->type[11]);\
+	MC_CMD_PARAM_OP(cmd, 3,	32,	8,  char,     res_req->type[12]);\
+	MC_CMD_PARAM_OP(cmd, 3,	40,	8,  char,     res_req->type[13]);\
+	MC_CMD_PARAM_OP(cmd, 3,	48,	8,  char,     res_req->type[14]);\
+	MC_CMD_PARAM_OP(cmd, 3,	56,	8,  char,     res_req->type[15]);\
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_GET_OBJ_COUNT(cmd, obj_count) \
+	MC_RSP_PARAM_OP(cmd, 0,	32,	32,	int,	obj_count)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_GET_OBJECT(cmd, obj_index) \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32,	int,	obj_index)
+
+/*	param, offset, width,	type,		arg_name */
+#define DPRC_RSP_GET_OBJECT(cmd, obj_desc) \
+do { \
+	MC_RSP_PARAM_OP(cmd, 0,	32,	32, int,      obj_desc->id); \
+	MC_RSP_PARAM_OP(cmd, 1,	0,	16, uint16_t, obj_desc->vendor); \
+	MC_RSP_PARAM_OP(cmd, 1,	16,	8,  uint8_t,  obj_desc->irq_count); \
+	MC_RSP_PARAM_OP(cmd, 1,	24,	8,  uint8_t,  obj_desc->region_count); \
+	MC_RSP_PARAM_OP(cmd, 1,	32,	32, uint32_t, obj_desc->state);\
+	MC_RSP_PARAM_OP(cmd, 2,	0,	32, uint32_t, obj_desc->ver_minor); \
+	MC_RSP_PARAM_OP(cmd, 2,	32,	32, uint32_t, obj_desc->ver_major); \
+	MC_RSP_PARAM_OP(cmd, 3,  0,	8,  char,     obj_desc->type[0]);\
+	MC_RSP_PARAM_OP(cmd, 3,  8,	8,  char,     obj_desc->type[1]);\
+	MC_RSP_PARAM_OP(cmd, 3,  16,	8,  char,     obj_desc->type[2]);\
+	MC_RSP_PARAM_OP(cmd, 3,  24,	8,  char,     obj_desc->type[3]);\
+	MC_RSP_PARAM_OP(cmd, 3,  32,	8,  char,     obj_desc->type[4]);\
+	MC_RSP_PARAM_OP(cmd, 3,  40,	8,  char,     obj_desc->type[5]);\
+	MC_RSP_PARAM_OP(cmd, 3,  48,	8,  char,     obj_desc->type[6]);\
+	MC_RSP_PARAM_OP(cmd, 3,  56,	8,  char,     obj_desc->type[7]);\
+	MC_RSP_PARAM_OP(cmd, 4,  0,	8,  char,     obj_desc->type[8]);\
+	MC_RSP_PARAM_OP(cmd, 4,  8,	8,  char,     obj_desc->type[9]);\
+	MC_RSP_PARAM_OP(cmd, 4,  16,	8,  char,     obj_desc->type[10]);\
+	MC_RSP_PARAM_OP(cmd, 4,  24,	8,  char,     obj_desc->type[11]);\
+	MC_RSP_PARAM_OP(cmd, 4,  32,	8,  char,     obj_desc->type[12]);\
+	MC_RSP_PARAM_OP(cmd, 4,  40,	8,  char,     obj_desc->type[13]);\
+	MC_RSP_PARAM_OP(cmd, 4,  48,	8,  char,     obj_desc->type[14]);\
+	MC_RSP_PARAM_OP(cmd, 4,  56,	8,  char,     obj_desc->type[15]);\
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_GET_RES_COUNT(cmd, type) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 1,  0,	8,	char,		type[0]);\
+	MC_CMD_PARAM_OP(cmd, 1,  8,	8,	char,		type[1]);\
+	MC_CMD_PARAM_OP(cmd, 1,  16,	8,	char,		type[2]);\
+	MC_CMD_PARAM_OP(cmd, 1,  24,	8,	char,		type[3]);\
+	MC_CMD_PARAM_OP(cmd, 1,  32,	8,	char,		type[4]);\
+	MC_CMD_PARAM_OP(cmd, 1,  40,	8,	char,		type[5]);\
+	MC_CMD_PARAM_OP(cmd, 1,  48,	8,	char,		type[6]);\
+	MC_CMD_PARAM_OP(cmd, 1,  56,	8,	char,		type[7]);\
+	MC_CMD_PARAM_OP(cmd, 2,  0,	8,	char,		type[8]);\
+	MC_CMD_PARAM_OP(cmd, 2,  8,	8,	char,		type[9]);\
+	MC_CMD_PARAM_OP(cmd, 2,  16,	8,	char,		type[10]);\
+	MC_CMD_PARAM_OP(cmd, 2,  24,	8,	char,		type[11]);\
+	MC_CMD_PARAM_OP(cmd, 2,  32,	8,	char,		type[12]);\
+	MC_CMD_PARAM_OP(cmd, 2,  40,	8,	char,		type[13]);\
+	MC_CMD_PARAM_OP(cmd, 2,  48,	8,	char,		type[14]);\
+	MC_CMD_PARAM_OP(cmd, 2,  56,	8,	char,		type[15]);\
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_GET_RES_COUNT(cmd, res_count) \
+	MC_RSP_PARAM_OP(cmd, 0,	0,	32,	int,		res_count)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_GET_RES_IDS(cmd, type, range_desc) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	42,	7,	enum dprc_iter_status,	\
+						      range_desc->iter_status);\
+	MC_CMD_PARAM_OP(cmd, 1,	0,	32,	int,  range_desc->base_id); \
+	MC_CMD_PARAM_OP(cmd, 1,	32,	32,	int,  range_desc->last_id);\
+	MC_CMD_PARAM_OP(cmd, 2,  0,	8,	char, type[0]);\
+	MC_CMD_PARAM_OP(cmd, 2,  8,	8,	char, type[1]);\
+	MC_CMD_PARAM_OP(cmd, 2,  16,	8,	char, type[2]);\
+	MC_CMD_PARAM_OP(cmd, 2,  24,	8,	char, type[3]);\
+	MC_CMD_PARAM_OP(cmd, 2,  32,	8,	char, type[4]);\
+	MC_CMD_PARAM_OP(cmd, 2,  40,	8,	char, type[5]);\
+	MC_CMD_PARAM_OP(cmd, 2,  48,	8,	char, type[6]);\
+	MC_CMD_PARAM_OP(cmd, 2,  56,	8,	char, type[7]);\
+	MC_CMD_PARAM_OP(cmd, 3,  0,	8,	char, type[8]);\
+	MC_CMD_PARAM_OP(cmd, 3,  8,	8,	char, type[9]);\
+	MC_CMD_PARAM_OP(cmd, 3,  16,	8,	char, type[10]);\
+	MC_CMD_PARAM_OP(cmd, 3,  24,	8,	char, type[11]);\
+	MC_CMD_PARAM_OP(cmd, 3,  32,	8,	char, type[12]);\
+	MC_CMD_PARAM_OP(cmd, 3,  40,	8,	char, type[13]);\
+	MC_CMD_PARAM_OP(cmd, 3,  48,	8,	char, type[14]);\
+	MC_CMD_PARAM_OP(cmd, 3,  56,	8,	char, type[15]);\
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_GET_RES_IDS(cmd, range_desc) \
+do { \
+	MC_RSP_PARAM_OP(cmd, 0,	42,	7,	enum dprc_iter_status,	\
+						     range_desc->iter_status);\
+	MC_RSP_PARAM_OP(cmd, 1,	0,	32,	int, range_desc->base_id); \
+	MC_RSP_PARAM_OP(cmd, 1,	32,	32,	int, range_desc->last_id);\
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_GET_ATTRIBUTES(cmd, attr) \
+do { \
+	MC_RSP_PARAM_OP(cmd, 0,	0,	32,	int,	  attr->container_id); \
+	MC_RSP_PARAM_OP(cmd, 0,	32,	16,	uint16_t, attr->icid); \
+	MC_RSP_PARAM_OP(cmd, 0,	48,	16,	uint16_t, attr->portal_id); \
+	MC_RSP_PARAM_OP(cmd, 1,	0,	32,	uint32_t, attr->options);\
+	MC_RSP_PARAM_OP(cmd, 2,  0,	32,	uint32_t, attr->version.major);\
+	MC_RSP_PARAM_OP(cmd, 2,  32,	32,	uint32_t, attr->version.minor);\
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_GET_OBJ_REGION(cmd, obj_id, region_index, obj_type) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32,	int,		obj_id); \
+	MC_CMD_PARAM_OP(cmd, 0,	48,	8,	uint8_t,	region_index);\
+	MC_CMD_PARAM_OP(cmd, 3,  0,	8,	char,		obj_type[0]);\
+	MC_CMD_PARAM_OP(cmd, 3,  8,	8,	char,		obj_type[1]);\
+	MC_CMD_PARAM_OP(cmd, 3,  16,	8,	char,		obj_type[2]);\
+	MC_CMD_PARAM_OP(cmd, 3,  24,	8,	char,		obj_type[3]);\
+	MC_CMD_PARAM_OP(cmd, 3,  32,	8,	char,		obj_type[4]);\
+	MC_CMD_PARAM_OP(cmd, 3,  40,	8,	char,		obj_type[5]);\
+	MC_CMD_PARAM_OP(cmd, 3,  48,	8,	char,		obj_type[6]);\
+	MC_CMD_PARAM_OP(cmd, 3,  56,	8,	char,		obj_type[7]);\
+	MC_CMD_PARAM_OP(cmd, 4,  0,	8,	char,		obj_type[8]);\
+	MC_CMD_PARAM_OP(cmd, 4,  8,	8,	char,		obj_type[9]);\
+	MC_CMD_PARAM_OP(cmd, 4,  16,	8,	char,		obj_type[10]);\
+	MC_CMD_PARAM_OP(cmd, 4,  24,	8,	char,		obj_type[11]);\
+	MC_CMD_PARAM_OP(cmd, 4,  32,	8,	char,		obj_type[12]);\
+	MC_CMD_PARAM_OP(cmd, 4,  40,	8,	char,		obj_type[13]);\
+	MC_CMD_PARAM_OP(cmd, 4,  48,	8,	char,		obj_type[14]);\
+	MC_CMD_PARAM_OP(cmd, 4,  56,	8,	char,		obj_type[15]);\
+} while (0)
+
+/*	param, offset, width,	type,		arg_name */
+#define DPRC_RSP_GET_OBJ_REGION(cmd, region_desc) \
+do { \
+	MC_RSP_PARAM_OP(cmd, 1,	0,	64, uint64_t, region_desc->base_paddr);\
+	MC_RSP_PARAM_OP(cmd, 2,	0,	32, uint32_t, region_desc->size); \
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_SET_IRQ(cmd, irq_index, irq_val, irq_paddr, user_irq_id) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	8,	uint8_t,    irq_index); \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32,	uint32_t,   irq_val); \
+	MC_CMD_PARAM_OP(cmd, 1,	0,	64,	uint64_t,   irq_paddr);\
+	MC_CMD_PARAM_OP(cmd, 2,  0,	32,	int,	    user_irq_id); \
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_GET_IRQ(cmd, irq_index) \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	8,	uint8_t,	irq_index)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_GET_IRQ(cmd, irq_val, irq_paddr, user_irq_id, type) \
+do { \
+	MC_RSP_PARAM_OP(cmd, 0,	0,	32,	uint32_t,   irq_val); \
+	MC_RSP_PARAM_OP(cmd, 1,	0,	64,	uint64_t,   irq_paddr);\
+	MC_RSP_PARAM_OP(cmd, 2,  0,	32,	int,	    user_irq_id); \
+	MC_RSP_PARAM_OP(cmd, 2,	32,	32,	int,	    type); \
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_SET_IRQ_ENABLE(cmd, enable_state, irq_index) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	8,	uint8_t,    enable_state); \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	8,	uint8_t,    irq_index);\
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_GET_IRQ_ENABLE(cmd, irq_index) \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	8,	uint8_t,	irq_index)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_GET_IRQ_ENABLE(cmd, enable_state) \
+	MC_RSP_PARAM_OP(cmd, 0,	0,	8,	uint8_t,	enable_state)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_SET_IRQ_MASK(cmd, mask, irq_index) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32,	uint32_t,	mask); \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	8,	uint8_t,	irq_index);\
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_GET_IRQ_MASK(cmd, irq_index) \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	8,	uint8_t,	irq_index)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_GET_IRQ_MASK(cmd, mask) \
+	MC_RSP_PARAM_OP(cmd, 0,	0,	32,	uint32_t,	mask)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_GET_IRQ_STATUS(cmd, irq_index) \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	8,	uint8_t,	irq_index)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_GET_IRQ_STATUS(cmd, status) \
+	MC_RSP_PARAM_OP(cmd, 0,	0,	32,	uint32_t,	status)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_CLEAR_IRQ_STATUS(cmd, status, irq_index) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32,	uint32_t,	status); \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	8,	uint8_t,	irq_index);\
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_CONNECT(cmd, endpoint1, endpoint2) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32, int,    endpoint1->id); \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	32, int,    endpoint1->interface_id); \
+	MC_CMD_PARAM_OP(cmd, 1,	0,	32, int,    endpoint2->id); \
+	MC_CMD_PARAM_OP(cmd, 1,	32,	32, int,    endpoint2->interface_id); \
+	MC_CMD_PARAM_OP(cmd, 2,	0,	8,  char,   endpoint1->type[0]); \
+	MC_CMD_PARAM_OP(cmd, 2,	8,	8,  char,   endpoint1->type[1]); \
+	MC_CMD_PARAM_OP(cmd, 2,	16,	8,  char,   endpoint1->type[2]); \
+	MC_CMD_PARAM_OP(cmd, 2,	24,	8,  char,   endpoint1->type[3]); \
+	MC_CMD_PARAM_OP(cmd, 2,	32,	8,  char,   endpoint1->type[4]); \
+	MC_CMD_PARAM_OP(cmd, 2,	40,	8,  char,   endpoint1->type[5]); \
+	MC_CMD_PARAM_OP(cmd, 2,	48,	8,  char,   endpoint1->type[6]); \
+	MC_CMD_PARAM_OP(cmd, 2,	56,	8,  char,   endpoint1->type[7]); \
+	MC_CMD_PARAM_OP(cmd, 3,	0,	8,  char,   endpoint1->type[8]); \
+	MC_CMD_PARAM_OP(cmd, 3,	8,	8,  char,   endpoint1->type[9]); \
+	MC_CMD_PARAM_OP(cmd, 3,	16,	8,  char,   endpoint1->type[10]); \
+	MC_CMD_PARAM_OP(cmd, 3,	24,	8,  char,   endpoint1->type[11]); \
+	MC_CMD_PARAM_OP(cmd, 3,	32,	8,  char,   endpoint1->type[12]); \
+	MC_CMD_PARAM_OP(cmd, 3,	40,	8,  char,   endpoint1->type[13]); \
+	MC_CMD_PARAM_OP(cmd, 3,	48,	8,  char,   endpoint1->type[14]); \
+	MC_CMD_PARAM_OP(cmd, 3,	56,	8,  char,   endpoint1->type[15]); \
+	MC_CMD_PARAM_OP(cmd, 5,	0,	8,  char,   endpoint2->type[0]); \
+	MC_CMD_PARAM_OP(cmd, 5,	8,	8,  char,   endpoint2->type[1]); \
+	MC_CMD_PARAM_OP(cmd, 5,	16,	8,  char,   endpoint2->type[2]); \
+	MC_CMD_PARAM_OP(cmd, 5,	24,	8,  char,   endpoint2->type[3]); \
+	MC_CMD_PARAM_OP(cmd, 5,	32,	8,  char,   endpoint2->type[4]); \
+	MC_CMD_PARAM_OP(cmd, 5,	40,	8,  char,   endpoint2->type[5]); \
+	MC_CMD_PARAM_OP(cmd, 5,	48,	8,  char,   endpoint2->type[6]); \
+	MC_CMD_PARAM_OP(cmd, 5,	56,	8,  char,   endpoint2->type[7]); \
+	MC_CMD_PARAM_OP(cmd, 6,	0,	8,  char,   endpoint2->type[8]); \
+	MC_CMD_PARAM_OP(cmd, 6,	8,	8,  char,   endpoint2->type[9]); \
+	MC_CMD_PARAM_OP(cmd, 6,	16,	8,  char,   endpoint2->type[10]); \
+	MC_CMD_PARAM_OP(cmd, 6,	24,	8,  char,   endpoint2->type[11]); \
+	MC_CMD_PARAM_OP(cmd, 6,	32,	8,  char,   endpoint2->type[12]); \
+	MC_CMD_PARAM_OP(cmd, 6,	40,	8,  char,   endpoint2->type[13]); \
+	MC_CMD_PARAM_OP(cmd, 6,	48,	8,  char,   endpoint2->type[14]); \
+	MC_CMD_PARAM_OP(cmd, 6,	56,	8,  char,   endpoint2->type[15]); \
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_DISCONNECT(cmd, endpoint) \
+do { \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32,	int,  endpoint->id); \
+	MC_CMD_PARAM_OP(cmd, 0,	32,	32,	int,  endpoint->interface_id); \
+	MC_CMD_PARAM_OP(cmd, 1,	0,	8,	char, endpoint->type[0]); \
+	MC_CMD_PARAM_OP(cmd, 1,	8,	8,	char, endpoint->type[1]); \
+	MC_CMD_PARAM_OP(cmd, 1,	16,	8,	char, endpoint->type[2]); \
+	MC_CMD_PARAM_OP(cmd, 1,	24,	8,	char, endpoint->type[3]); \
+	MC_CMD_PARAM_OP(cmd, 1,	32,	8,	char, endpoint->type[4]); \
+	MC_CMD_PARAM_OP(cmd, 1,	40,	8,	char, endpoint->type[5]); \
+	MC_CMD_PARAM_OP(cmd, 1,	48,	8,	char, endpoint->type[6]); \
+	MC_CMD_PARAM_OP(cmd, 1,	56,	8,	char, endpoint->type[7]); \
+	MC_CMD_PARAM_OP(cmd, 2,	0,	8,	char, endpoint->type[8]); \
+	MC_CMD_PARAM_OP(cmd, 2,	8,	8,	char, endpoint->type[9]); \
+	MC_CMD_PARAM_OP(cmd, 2,	16,	8,	char, endpoint->type[10]); \
+	MC_CMD_PARAM_OP(cmd, 2,	24,	8,	char, endpoint->type[11]); \
+	MC_CMD_PARAM_OP(cmd, 2,	32,	8,	char, endpoint->type[12]); \
+	MC_CMD_PARAM_OP(cmd, 2,	40,	8,	char, endpoint->type[13]); \
+	MC_CMD_PARAM_OP(cmd, 2,	48,	8,	char, endpoint->type[14]); \
+	MC_CMD_PARAM_OP(cmd, 2,	56,	8,	char, endpoint->type[15]); \
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_GET_POOL(cmd, pool_index) \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32,	int,	pool_index)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_GET_POOL(cmd, type) \
+do { \
+	MC_RSP_PARAM_OP(cmd, 1,	0,	8,	char,		type[0]);\
+	MC_RSP_PARAM_OP(cmd, 1,	8,	8,	char,		type[1]);\
+	MC_RSP_PARAM_OP(cmd, 1,	16,	8,	char,		type[2]);\
+	MC_RSP_PARAM_OP(cmd, 1,	24,	8,	char,		type[3]);\
+	MC_RSP_PARAM_OP(cmd, 1,	32,	8,	char,		type[4]);\
+	MC_RSP_PARAM_OP(cmd, 1,	40,	8,	char,		type[5]);\
+	MC_RSP_PARAM_OP(cmd, 1,	48,	8,	char,		type[6]);\
+	MC_RSP_PARAM_OP(cmd, 1,	56,	8,	char,		type[7]);\
+	MC_RSP_PARAM_OP(cmd, 2,	0,	8,	char,		type[8]);\
+	MC_RSP_PARAM_OP(cmd, 2,	8,	8,	char,		type[9]);\
+	MC_RSP_PARAM_OP(cmd, 2,	16,	8,	char,		type[10]);\
+	MC_RSP_PARAM_OP(cmd, 2,	24,	8,	char,		type[11]);\
+	MC_RSP_PARAM_OP(cmd, 2,	32,	8,	char,		type[12]);\
+	MC_RSP_PARAM_OP(cmd, 2,	40,	8,	char,		type[13]);\
+	MC_RSP_PARAM_OP(cmd, 2,	48,	8,	char,		type[14]);\
+	MC_RSP_PARAM_OP(cmd, 2,	56,	8,	char,		type[15]);\
+} while (0)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_GET_POOL_COUNT(cmd, pool_count) \
+	MC_RSP_PARAM_OP(cmd, 0,	0,	32,	int,		pool_count)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_CMD_GET_PORTAL_PADDR(cmd, portal_id) \
+	MC_CMD_PARAM_OP(cmd, 0,	0,	32,	int,	portal_id)
+
+/*	param, offset, width,	type,			arg_name */
+#define DPRC_RSP_GET_PORTAL_PADDR(cmd, portal_addr) \
+	MC_RSP_PARAM_OP(cmd, 1,	0,	64,	uint64_t,	portal_addr)
+
+#endif /* _FSL_DPRC_CMD_H */
diff --git a/drivers/bus/fsl-mc/fsl_mc_sys.c b/drivers/bus/fsl-mc/fsl_mc_sys.c
new file mode 100644
index 0000000..2a7adef
--- /dev/null
+++ b/drivers/bus/fsl-mc/fsl_mc_sys.c
@@ -0,0 +1,237 @@
+/* Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <linux/fsl_mc_sys.h>
+#include <linux/fsl_mc_cmd.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+
+/**
+ * Timeout in jiffies to wait for the completion of an MC command
+ */
+#define MC_CMD_COMPLETION_TIMEOUT   100
+
+/**
+ * Delay in microseconds between polling iterations while
+ * waiting for MC command completion
+ */
+#define MC_CMD_COMPLETION_POLLING_INTERVAL  500
+
+/**
+ * Map an MC portal in the kernel virtual address space
+ */
+static int map_mc_portal(phys_addr_t mc_portal_phys_addr,
+			 uint32_t mc_portal_size,
+			 void __iomem **new_mc_portal_virt_addr)
+{
+	void __iomem *mc_portal_virt_addr = NULL;
+	struct resource *res = NULL;
+	int error = -EINVAL;
+
+	res =
+	    request_mem_region(mc_portal_phys_addr, mc_portal_size,
+			       "mc_portal");
+	if (res == NULL) {
+		pr_err("request_mem_region() failed for MC portal %#llx\n",
+		       mc_portal_phys_addr);
+		error = -EBUSY;
+		goto error;
+	}
+
+	mc_portal_virt_addr = ioremap_nocache(mc_portal_phys_addr,
+					      mc_portal_size);
+	if (mc_portal_virt_addr == NULL) {
+		pr_err("ioremap_nocache() failed for MC portal %#llx\n",
+		       mc_portal_phys_addr);
+		error = -EFAULT;
+		goto error;
+	}
+
+	*new_mc_portal_virt_addr = mc_portal_virt_addr;
+	return 0;
+error:
+	if (mc_portal_virt_addr != NULL)
+		iounmap(mc_portal_virt_addr);
+
+	if (res != NULL)
+		release_mem_region(mc_portal_phys_addr, mc_portal_size);
+
+	return error;
+}
+
+/**
+ * Unmap an MC portal from the kernel virtual address space
+ */
+static void unmap_mc_portal(phys_addr_t mc_portal_phys_addr,
+			    uint16_t mc_portal_size,
+			    void __iomem *mc_portal_virt_addr)
+{
+	if (WARN_ON(mc_portal_virt_addr == NULL))
+		return;
+
+	iounmap(mc_portal_virt_addr);
+	release_mem_region(mc_portal_phys_addr, mc_portal_size);
+}
+
+int __must_check fsl_create_mc_io(phys_addr_t mc_portal_phys_addr,
+				  uint32_t mc_portal_size,
+				  uint32_t flags, struct fsl_mc_io **new_mc_io)
+{
+	int error = -EINVAL;
+	struct fsl_mc_io *mc_io = NULL;
+
+	mc_io = kzalloc(sizeof(*mc_io), GFP_KERNEL);
+	if (mc_io == NULL) {
+		error = -ENOMEM;
+		pr_err("No memory to allocate mc_io\n");
+		goto error;
+	}
+
+	mc_io->magic = FSL_MC_IO_MAGIC;
+	mc_io->flags = flags;
+	mc_io->portal_phys_addr = mc_portal_phys_addr;
+	mc_io->portal_size = mc_portal_size;
+	spin_lock_init(&mc_io->spinlock);
+	error = map_mc_portal(mc_portal_phys_addr,
+			      mc_portal_size, &mc_io->portal_virt_addr);
+	if (error < 0)
+		goto error;
+
+	*new_mc_io = mc_io;
+	return 0;
+error:
+	if (mc_io != NULL) {
+		if (mc_io->portal_virt_addr != NULL) {
+			unmap_mc_portal(mc_portal_phys_addr,
+					mc_portal_size,
+					mc_io->portal_virt_addr);
+		}
+
+		kfree(mc_io);
+	}
+
+	return error;
+}
+EXPORT_SYMBOL_GPL(fsl_create_mc_io);
+
+void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
+{
+	if (WARN_ON(mc_io->magic != FSL_MC_IO_MAGIC))
+		return;
+
+	if (mc_io->portal_virt_addr != NULL) {
+		unmap_mc_portal(mc_io->portal_phys_addr,
+				mc_io->portal_size, mc_io->portal_virt_addr);
+
+		mc_io->portal_virt_addr = NULL;
+	}
+
+	mc_io->magic = 0x0;
+	kfree(mc_io);
+}
+EXPORT_SYMBOL_GPL(fsl_destroy_mc_io);
+
+static int mc_status_to_error(enum mc_cmd_status status)
+{
+	switch (status) {
+	case MC_CMD_STATUS_OK:
+		return 0;
+	case MC_CMD_STATUS_AUTH_ERR:
+		return -EACCES;
+	case MC_CMD_STATUS_NO_PRIVILEGE:
+		return -EPERM;
+	case MC_CMD_STATUS_DMA_ERR:
+		return -EIO;
+	case MC_CMD_STATUS_CONFIG_ERR:
+		return -EINVAL;
+	case MC_CMD_STATUS_TIMEOUT:
+		return -ETIMEDOUT;
+	case MC_CMD_STATUS_NO_RESOURCE:
+		return -ENAVAIL;
+	case MC_CMD_STATUS_NO_MEMORY:
+		return -ENOMEM;
+	case MC_CMD_STATUS_BUSY:
+		return -EBUSY;
+	case MC_CMD_STATUS_UNSUPPORTED_OP:
+		return -ENOTSUP;
+	case MC_CMD_STATUS_INVALID_STATE:
+		return -ENODEV;
+	default:
+		break;
+	}
+
+	/* Not expected to reach here */
+	return -EINVAL;
+}
+
+int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
+{
+	enum mc_cmd_status status;
+	unsigned long irqsave_flags = 0;
+	int error = -EINVAL;
+	bool lock_acquired = false;
+	unsigned long jiffies_until_timeout =
+	    jiffies + MC_CMD_COMPLETION_TIMEOUT;
+
+	if (WARN_ON(mc_io->magic != FSL_MC_IO_MAGIC))
+		goto out;
+
+	if (mc_io->flags & FSL_MC_IO_PORTAL_SHARED) {
+		spin_lock_irqsave(&mc_io->spinlock, irqsave_flags);
+		lock_acquired = true;
+	}
+
+	mc_write_command(mc_io->portal_virt_addr, cmd);
+
+	for (;;) {
+		status = mc_read_response(mc_io->portal_virt_addr, cmd);
+		if (status != MC_CMD_STATUS_READY)
+			break;
+
+		/*
+		 * TODO: When MC command completion interrupts are supported
+		 * call wait function here instead of udelay()
+		 */
+		udelay(MC_CMD_COMPLETION_POLLING_INTERVAL);
+		if (time_after_eq(jiffies, jiffies_until_timeout)) {
+			error = -ETIMEDOUT;
+			goto out;
+		}
+	}
+
+	error = mc_status_to_error(status);
+out:
+	if (lock_acquired)
+		spin_unlock_irqrestore(&mc_io->spinlock, irqsave_flags);
+
+	return error;
+}
+EXPORT_SYMBOL(mc_send_command);
diff --git a/include/linux/fsl_dpmng.h b/include/linux/fsl_dpmng.h
new file mode 100644
index 0000000..68af9de
--- /dev/null
+++ b/include/linux/fsl_dpmng.h
@@ -0,0 +1,120 @@
+/* Copyright 2013-2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*!
+ *  @file    fsl_dpmng.h
+ *  @brief   Management Complex General API
+ */
+
+#ifndef __FSL_DPMNG_H
+#define __FSL_DPMNG_H
+
+/*!
+ * @Group grp_dpmng	Management Complex General API
+ *
+ * @brief	Contains general API for the Management Complex firmware
+ * @{
+ */
+
+struct fsl_mc_io;
+
+/**
+ * @brief	Management Complex firmware version information
+ */
+#define MC_VER_MAJOR 2
+#define MC_VER_MINOR 0
+
+struct mc_version {
+	uint32_t major;
+	/*!<
+	 * Major version number: incremented on API compatibility changes
+	 */
+	uint32_t minor;
+	/*!<
+	 * Minor version number: incremented on API additions (backward
+	 * compatible); reset when major version is incremented.
+	 */
+	uint32_t revision;
+	/*!<
+	 * Internal revision number: incremented on implementation changes
+	 * and/or bug fixes that have no impact on API
+	 */
+};
+
+/**
+ * @brief	Retrieves the Management Complex firmware version information
+ *
+ * @param[in]   mc_io - Pointer to opaque I/O object
+ * @param[out]	mc_ver_info - Pointer to version information structure
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info);
+
+/**
+ * @brief	Resets an AIOP tile
+ *
+ * @param[in]   mc_io - Pointer to opaque I/O object
+ * @param[in]	aiop_tile_id - AIOP tile ID to reset
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dpmng_reset_aiop(struct fsl_mc_io *mc_io, int aiop_tile_id);
+
+/**
+ * @brief	Loads an image to AIOP tile
+ *
+ * @param[in]   mc_io - Pointer to opaque I/O object
+ * @param[in]	aiop_tile_id - AIOP tile ID
+ * @param[in]	img_addr - Pointer to AIOP ELF image in memory
+ * @param[in]	img_size - Size in bytes of AIOP ELF image in memory
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dpmng_load_aiop(struct fsl_mc_io *mc_io,
+		    int aiop_tile_id, uint8_t *img_addr, int img_size);
+
+/**
+ * @brief	Starts AIOP tile execution
+ *
+ * @param[in]   mc_io - Pointer to opaque I/O object
+ * @param[in]	aiop_tile_id - AIOP tile ID to run
+ * @param[in]	cores_mask - Mask of AIOP cores to run (core 0 in msb)
+ * @param[in]	options - Execution options (currently none defined)
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dpmng_run_aiop(struct fsl_mc_io *mc_io,
+		   int aiop_tile_id, uint32_t cores_mask, uint64_t options);
+
+/** @} */
+
+#endif /* __FSL_DPMNG_H */
diff --git a/include/linux/fsl_dprc.h b/include/linux/fsl_dprc.h
new file mode 100644
index 0000000..8bd753e
--- /dev/null
+++ b/include/linux/fsl_dprc.h
@@ -0,0 +1,790 @@
+/* Copyright 2013-2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*!
+ *  @file    fsl_dprc.h
+ *  @brief   Data Path Resource Container API
+ */
+
+#ifndef _FSL_DPRC_H
+#define _FSL_DPRC_H
+
+/*!
+ * @Group grp_dprc	Data Path Resource Container API
+ *
+ * @brief	Contains DPRC API for managing and querying LDPAA resources
+ * @{
+ */
+
+struct fsl_mc_io;
+
+/*!
+ * Set this value as the icid value in dprc_cfg structure when creating a
+ * container, in case the ICID is not selected by the user and should be
+ * allocated by the DPRC from the pool of ICIDs.
+ */
+#define DPRC_GET_ICID_FROM_POOL			(uint16_t)(~(0))
+/*!
+ * Set this value as the portal_id value in dprc_cfg structure when creating a
+ * container, in case the portal id is not specifically selected by the
+ * user and should be allocated by the DPRC from the pool of portal ids.
+ */
+#define DPRC_GET_PORTAL_ID_FROM_POOL	(int)(~(0))
+
+/*!
+ * @name Resource request options
+ */
+#define DPRC_RES_REQ_OPT_EXPLICIT		0x00000001
+/*!< Explicit resource id request - The requested objects/resources
+ * are explicit and sequential (in case of resources).
+ * The base ID is given at res_req at base_align field */
+#define DPRC_RES_REQ_OPT_ALIGNED		0x00000002
+/*!< Aligned resources request - Relevant only for resources
+ * request (and not objects). Indicates that resources base id should be
+ * sequential and aligned to the value given at dprc_res_req base_align field*/
+#define DPRC_RES_REQ_OPT_PLUGGED		0x00000004
+/*!< Plugged Flag - Relevant only for object assignment request.
+ * Indicates that after all objects assigned. An interrupt will be invoked at
+ * the relevant GPP. The assigned object will be marked as plugged.
+ * plugged objects can't be assigned from their container */
+/* @} */
+
+/*!
+ * @name Container general options
+ *
+ * These options may be selected at container creation by the container creator
+ * and can be retrieved using dprc_get_attributes()
+ */
+#define DPRC_CFG_OPT_SPAWN_ALLOWED		0x00000001
+/*!< Spawn Policy Option allowed - Indicates that the new container is allowed
+ * to spawn and have its own child containers. */
+#define DPRC_CFG_OPT_ALLOC_ALLOWED		0x00000002
+/*!< General Container allocation policy - Indicates that the new container is
+ * allowed to allocate requested resources from its parent container; if not
+ * set, the container is only allowed to use resources in its own pools; Note
+ * that this is a container's global policy, but the parent container may
+ * override it and set specific quota per resource type. */
+#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED	0x00000004
+/*!< Object initialization allowed - software context associated with this
+ * container is allowed to invoke object initialization operations. */
+#define DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED	0x00000008
+/*!< Topology change allowed - software context associated with this
+ * container is allowed to invoke topology operations, such as attach/detach
+ * of network objects. */
+#define DPRC_CFG_OPT_IOMMU_BYPASS		0x00000010
+/*!<IOMMU bypass - indicates whether objects of this container are permitted
+ * to bypass the IOMMU.  */
+#define DPRC_CFG_OPT_AIOP			0x00000020
+/*!<AIOP -Indicates that container belongs to aiop.  */
+/* @} */
+
+/*!
+ * @name Objects Attributes Flags
+ */
+#define DPRC_OBJ_STATE_OPEN		0x00000001
+/*!< Opened state - Indicates that an object is open by at least one owner */
+#define DPRC_OBJ_STATE_PLUGGED		0x00000002
+/*!< Plugged state - Indicates that the object is plugged */
+/* @} */
+
+/*!
+ * @name Irq
+ */
+#define DPRC_NUM_OF_IRQS		1
+/*!< Number of dprc's IRQs */
+/* @} */
+
+/*!
+ * @name Object irq events
+ */
+#define DPRC_IRQ_EVENT_OBJ_ASSIGNED			0x00000001
+/*!< Irq event - Indicates that a new object assigned to the container */
+#define DPRC_IRQ_EVENT_OBJ_UNASSIGNED		0x00000002
+/*!< Irq event - Indicates that an object was unassigned from the container */
+#define DPRC_IRQ_EVENT_RES_ASSIGNED			0x00000004
+/*!< Irq event - Indicates that resources assigned to the container */
+#define DPRC_IRQ_EVENT_RES_UNASSIGNED		0x00000008
+/*!< Irq event - Indicates that resources unassigned from the container */
+#define DPRC_IRQ_EVENT_CONTAINER_DESTROYED	0x00000010
+/*!< Irq event - Indicates that one of the descendant containers that opened by
+ * this container is destroyed */
+#define DPRC_IRQ_EVENT_OBJ_DESTROYED		0x00000011
+/*!< Irq event - Indicates that on one of the container's opened object is
+ destroyed */
+/* @} */
+
+/**
+ * @brief	Resource request descriptor, to be used in assignment or
+ *		un-assignment of resources and objects.
+ */
+struct dprc_res_req {
+	char type[16];
+	/*!<
+	 * Resource/object type: Represent as a NULL terminated string.
+	 * This string may received by using dprc_get_pool() to get resource
+	 * type and dprc_get_obj() to get object type.
+	 * Note: it is not possible to assign/unassign DP_OBJ_DPRC objects
+	 */
+	uint32_t num;
+	/*!< Number of resources */
+	uint32_t options;
+	/*!< Request options: combination of DPRC_RES_REQ_OPT_ options */
+	int id_base_align;
+	/*!<
+	 * In case of explicit assignment (DPRC_RES_REQ_OPT_EXPLICIT is set at
+	 * option), this field represents the required base ID for resource
+	 * allocation;
+	 * In case of aligned assignment (DPRC_RES_REQ_OPT_ALIGNED is set at
+	 * option), this field indicates the required alignment for the
+	 * resource ID(s) - use 0 if there is no alignment or explicit id
+	 * requirements.
+	 */
+};
+
+/**
+ * @brief	Object descriptor, returned from dprc_get_obj()
+ */
+struct dprc_obj_desc {
+	uint16_t vendor;
+	/*!< Object vendor identifier */
+	char type[16];
+	/*!< Type of object: NULL terminated string */
+	int id;
+	/*!< ID of logical object resource */
+	uint32_t ver_major;
+	/*!< Major version number */
+	uint32_t ver_minor;
+	/*!< Minor version number */
+	uint8_t irq_count;
+	/*!< Number of interrupts supported by the object */
+	uint8_t region_count;
+	/*!< Number of mappable regions supported by the object */
+	uint32_t state;
+	/*!< Object state: combination of DPRC_OBJ_STATE_ states */
+};
+
+/**
+ * @brief	Mappable region descriptor, returned by dprc_get_obj_region()
+ */
+struct dprc_region_desc {
+	uint64_t base_paddr;
+	/*!< Region base physical address */
+	uint32_t size;
+	/*!< Region size (in bytes) */
+};
+
+/**
+ * @brief	Iteration status, for use with dprc_get_res_ids() function
+ *
+ */
+enum dprc_iter_status {
+	DPRC_ITER_STATUS_FIRST = 0,
+	/*!< Perform first iteration */
+	DPRC_ITER_STATUS_MORE = 1,
+	/*!< Indicates more/next iteration is needed */
+	DPRC_ITER_STATUS_LAST = 2
+	    /*!< Indicates last iteration */
+};
+
+/**
+ * @brief	Resource Id range descriptor, Used at dprc_get_res_ids() and
+ *		contains one range details.
+ */
+struct dprc_res_ids_range_desc {
+	int base_id;
+	/*!< Base resource ID of this range */
+	int last_id;
+	/*!< Last resource ID of this range */
+	enum dprc_iter_status iter_status;
+	/*!<
+	 * Iteration status - should be set to DPRC_ITER_STATUS_FIRST at
+	 * first iteration; while the returned marker is DPRC_ITER_STATUS_MORE,
+	 * additional iterations are needed, until the returned marker is
+	 * DPRC_ITER_STATUS_LAST
+	 */
+};
+
+/**
+ * @brief	Container attributes, returned by dprc_get_attributes()
+ */
+struct dprc_attributes {
+	int container_id;
+	/*!< Container's ID */
+	uint16_t icid;
+	/*!< Container's ICID */
+	int portal_id;
+	/*!< Container's portal ID */
+	uint64_t options;
+	/*!< Container's options as set at container's creation */
+	struct {
+		uint32_t major;	/*!< DPRC major version */
+		uint32_t minor;	/*!< DPRC minor version */
+	} version;
+	/*!< DPRC version */
+};
+
+/**
+ * @brief	Container configuration options, used in dprc_create_container()
+ */
+struct dprc_cfg {
+	uint16_t icid;
+	/*!< Container's ICID; if set to DPRC_GET_ICID_FROM_POOL, a free ICID
+	 * will be allocated by the DPRC */
+	int portal_id;
+	/*!< portal id; if set to DPRC_GET_PORTAL_ID_FROM_POOL, a free portal id
+	 * will be allocated by the DPRC */
+	uint64_t options;
+	/*!< Combination of DPRC_CFG_OPT_ options */
+};
+
+/**
+ * @brief	Endpoint description for link connect/disconnect operations
+ */
+struct dprc_endpoint {
+	char type[16];
+	/*!< Endpoint object type: NULL terminated string */
+	int id;
+	/*!< Endpoint object id */
+	int interface_id;
+	/*!<
+	 * Interface id; should be set for endpoints with multiple interfaces
+	 * (DP_OBJ_DPSW, DP_OBJ_DPDMUX); for others, always set to 0.
+	 */
+};
+
+/**
+ * @brief	Obtains the container id associated with a given portal.
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[out]	container_id	Requested container ID
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_get_container_id(struct fsl_mc_io *mc_io, int *container_id);
+
+/**
+ * @brief	Opens a DPRC object for use
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	container_id	Container ID to open
+ * @param[out]	dprc_handle	Handle to the DPRC object
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ *
+ * @warning	Required before any operation on the object.
+ */
+int dprc_open(struct fsl_mc_io *mc_io, int container_id,
+	      uint16_t *dprc_handle);
+
+/**
+ * @brief	Closes the DPRC object handle
+ *
+ * No further operations on the object are allowed after this call without
+ * re-opening the object.
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_close(struct fsl_mc_io *mc_io, uint16_t dprc_handle);
+
+/**
+ * @brief	Creates a child container
+ *
+ * @param[in]   mc_io			Pointer to opaque I/O object
+ * @param[in]	dprc_handle		Handle to the DPRC object
+ * @param[in]	cfg			Child container configuration
+ * @param[out]	child_container_id	Child container ID
+ * @param[out]	child_portal_paddr	Base physical address of the
+ *				child portal
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_create_container(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			  struct dprc_cfg *cfg,
+			  int *child_container_id,
+			  uint64_t *child_portal_paddr);
+
+/**
+ * @brief	Destroys a child container.
+ *
+ * This function terminates the child container, so following this call the
+ * child container ID becomes invalid.
+ *
+ * Notes:
+ * - All resources and objects of the destroyed container are returned to the
+ * parent container or destroyed if were created be the destroyed container.
+ * - This function destroy all the child containers of the specified
+ *   container prior to destroying the container itself.
+ *
+ * @param[in]   mc_io			Pointer to opaque I/O object
+ * @param[in]	dprc_handle		Handle to the DPRC object
+ * @param[in]	child_container_id	ID of the container to destroy
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ *
+ * @warning	Only the parent container is allowed to destroy a child policy
+ *		Container 0 can't be destroyed
+ */
+int dprc_destroy_container(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			   int child_container_id);
+
+/**
+ * @brief	Sets allocation policy for a specific resource/object type in a
+ * child container
+ *
+ * Allocation policy determines whether or not a container may allocate
+ * resources from its parent. Each container has a 'global' allocation policy
+ * that is set when the container is created.
+ *
+ * This function sets allocation policy for a specific resource type.
+ * The default policy for all resource types matches the container's 'global'
+ * allocation policy.
+ *
+ * @param[in]   mc_io		    Pointer to opaque I/O object
+ * @param[in]	dprc_handle	    Handle to the DPRC object
+ * @param[in]	child_container_id  ID of the child container
+ * @param[in]	type		    resource/object type
+ * @param[in]	quota		    Sets the maximum number of resources of
+ *				    the selected type that the child
+ *				    container is allowed to allocate
+ *				    from its parent;
+ *				    when quota is set to -1, the policy is
+ *				    the same as container's general policy.
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ *
+ * @warning	Only the parent container is allowed to change a child policy.
+ */
+int dprc_set_res_quota(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		       int child_container_id, char *type, uint16_t quota);
+
+/**
+ * @brief	Gets the allocation policy of a specific resource/object type
+ *		in a child container
+ *
+ * @param[in]   mc_io			Pointer to opaque I/O object
+ * @param[in]	dprc_handle		Handle to the DPRC object
+ * @param[in]	child_container_id	ID of the child container
+ * @param[in]	type			resource/object type
+ * @param[out]	quota			Holds the maximum number of resources of
+ *					the selected type that the child
+ *					container is allowed to allocate from
+ *					the parent;
+ *					when quota is set to -1, the policy is
+ *					the same as container's general policy.
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_get_res_quota(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		       int child_container_id, char *type, uint16_t *quota);
+
+/**
+ * @brief	Resets a child container.
+ *
+ * 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.
+ *
+ * @param[in]   mc_io			Pointer to opaque I/O object
+ * @param[in]	dprc_handle		Handle to the DPRC object
+ * @param[in]	child_container_id	ID of the container to reset
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_reset_container(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			 int child_container_id);
+
+/**
+ * @brief	Assigns objects or resource to a child container.
+ *
+ * Assignment is usually done by a parent (this DPRC) to one of its child
+ * containers.
+ *
+ * According to the DPRC allocation policy, the assigned resources may be taken
+ * (allocated) from the container's ancestors, if not enough resources are
+ * available in the container itself.
+ *
+ * The type of assignment depends on the dprc_res_req options, as follows:
+ * - DPRC_RES_REQ_OPT_EXPLICIT: indicates that assigned resources should have
+ *   the explicit base ID specified at the id_base_align field of res_req.
+ * - DPRC_RES_REQ_OPT_ALIGNED: indicates that the assigned resources should be
+ *   aligned to the value given at id_base_align field of res_req.
+ * - DPRC_RES_REQ_OPT_PLUGGED: Relevant only for object assignment,
+ *   and indicates that the object must be set to the plugged state.
+ *
+ * A container may use this function with its own ID in order to change a
+ * object state to plugged or unplugged.
+ *
+ * If IRQ information has been set in the child DPRC, it will signal an
+ * interrupt following every change in its object assignment.
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]	container_id	ID of the child container
+ * @param[in]	res_req		Describes the type and amount of resources to
+ *				assign to the given container.
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_assign(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		int container_id, struct dprc_res_req *res_req);
+
+/**
+ * @brief	Un-assigns objects or resources from a child container
+ *		and moves them into this (parent) DPRC.
+ *
+ * Un-assignment of objects can succeed only if the object is not in the
+ * plugged or opened state.
+ *
+ * @param[in]   mc_io			Pointer to opaque I/O object
+ * @param[in]	dprc_handle		Handle to the DPRC object
+ * @param[in]	child_container_id	ID of the child container
+ * @param[in]	res_req			Describes the type and amount of
+ *					resources to un-assign from the child
+ *					container
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_unassign(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		  int child_container_id, struct dprc_res_req *res_req);
+
+/**
+ * @brief	Get the number of dprc's pools
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[out]  pool_count	Number of resource pools in the dprc.
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ * */
+int dprc_get_pool_count(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			int *pool_count);
+
+/**
+ * @brief	Get the type (string) of a certain dprc's pool
+ *
+ * The pool types retrieved one by one by incrementing
+ * pool_index up to (not including) the value of pool_count returned
+ * from dprc_get_pool_count(). dprc_get_pool_count() must
+ * be called prior to dprc_get_pool().
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]   pool_index	Index of the pool to be queried (< pool_count)
+ * @param[out]  type		The type of the pool.
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ * */
+int dprc_get_pool(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		  int pool_index, char *type);
+
+/**
+ * @brief	Obtains the number of objects in the DPRC
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[out]	obj_count	Number of objects assigned to the DPRC
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		       int *obj_count);
+
+/**
+ * @brief	Obtains general information on an object
+ *
+ * The object descriptors are retrieved one by one by incrementing
+ * obj_index up to (not including) the value of obj_count returned
+ * from dprc_get_obj_count(). dprc_get_obj_count() must
+ * be called prior to dprc_get_obj().
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]	obj_index	Index of the object to be queried (< obj_count)
+ * @param[out]	obj_desc	Returns the requested object descriptor
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_get_obj(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		 int obj_index, struct dprc_obj_desc *obj_desc);
+
+/**
+ * @brief	Obtains the number of free resources that are assigned
+ *		to this container, by pool type
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]	type		pool type
+ * @param[out]	res_count	Number of free resources of the given
+ *				resource type that are assigned to this DPRC
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_get_res_count(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		       char *type, int *res_count);
+
+/**
+ * @brief	Obtains IDs of free resources in the container
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]	type		pool type
+ * @param[in,out] range_desc	range descriptor
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_get_res_ids(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		     char *type, struct dprc_res_ids_range_desc *range_desc);
+
+/**
+ * @brief	Obtains the physical address of MC portals
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]	portal_id	MC portal id
+ * @param[out]  portal_addr	The physical address of the MC portal id
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_get_portal_paddr(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			  int portal_id, uint64_t *portal_addr);
+
+/**
+ * @brief	Obtains container attributes
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[out]	attributes	Container attributes
+ *
+ * @returns     '0' on Success; Error code otherwise.
+ */
+int dprc_get_attributes(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			struct dprc_attributes *attributes);
+
+/**
+ * @brief	Returns region information for a specified object.
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]	obj_type	Object type as returned in dprc_get_obj()
+ * @param[in]	obj_id		Unique object instance as returned in
+ *				dprc_get_obj()
+ * @param[in]	region_index	The specific region to query
+ * @param[out]	region_desc	Returns the requested region descriptor
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_get_obj_region(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			char *obj_type,
+			int obj_id,
+			uint8_t region_index,
+			struct dprc_region_desc *region_desc);
+
+/**
+ * @brief	Sets IRQ information for the DPRC to trigger an interrupt.
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]	irq_index	Identifies the interrupt index to configure
+ *				DPRC supports only irq_index 0 - this interrupt
+ *				will be signaled on every change to
+ *				resource/object assignment in this DPRC.
+ * @param[in]	irq_paddr	Physical IRQ address that must be written to
+ *				signal a message-based interrupt
+ * @param[in]	irq_val		Value to write into irq_paddr address
+ * @param[in]	user_irq_id	A user defined number associated with this IRQ;
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_set_irq(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		 uint8_t irq_index,
+		 uint64_t irq_paddr, uint32_t irq_val, int user_irq_id);
+
+/**
+ * @brief	Gets IRQ information from the DPRC.
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]   irq_index	The interrupt index to configure;
+ *				DPRC supports only irq_index 0 - this interrupt
+ *				will be signaled on every change to
+ *				resource/object assignment in this DPRC.
+ * @param[out]  type		Interrupt type: 0 represents message interrupt
+ *				type (both irq_paddr and irq_val are valid);
+ * @param[out]	irq_paddr	Physical address that must be written in order
+ *				to signal the message-based interrupt
+ * @param[out]	irq_val		Value to write in order to signal the
+ *				message-based interrupt
+ * @param[out]	user_irq_id	A user defined number associated with this IRQ;
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_get_irq(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		 uint8_t irq_index,
+		 int *type,
+		 uint64_t *irq_paddr, uint32_t *irq_val, int *user_irq_id);
+
+/**
+ * @brief	Sets overall interrupt state.
+ *
+ * Allows GPP software to control when interrupts are generated.
+ * Each interrupt can have up to 32 causes.  The enable/disable control's the
+ * overall interrupt state. if the interrupt is disabled no causes will cause an
+ * interrupt.
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]   irq_index	The interrupt index to configure
+ * @param[in]	enable_state	Interrupt state - enable = 1, disable = 0.
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_set_irq_enable(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			uint8_t irq_index, uint8_t enable_state);
+
+/**
+ * @brief	Gets overall interrupt state
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]   irq_index	The interrupt index to configure
+ * @param[out]	enable_state	Interrupt state - enable = 1, disable = 0.
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_get_irq_enable(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			uint8_t irq_index, uint8_t *enable_state);
+
+/**
+ * @brief	Sets interrupt mask.
+ *
+ * Every interrupt can have up to 32 causes and the interrupt model supports
+ * masking/unmasking each cause independently
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]   irq_index	The interrupt index to configure
+ * @param[in]	mask		Event mask to trigger interrupt.
+ *				each bit:
+ *					0 = ignore event
+ *					1 = consider event for asserting irq
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_set_irq_mask(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		      uint8_t irq_index, uint32_t mask);
+
+/**
+ * @brief	Gets interrupt mask.
+ *
+ * Every interrupt can have up to 32 causes and the interrupt model supports
+ * masking/unmasking each cause independently
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]   irq_index	The interrupt index to configure
+ * @param[out]	mask		Event mask to trigger interrupt
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ */
+int dprc_get_irq_mask(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		      uint8_t irq_index, uint32_t *mask);
+
+/**
+ * @brief	Gets the current status of any pending interrupts.
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]   irq_index	The interrupt index to configure
+ * @param[out]	 status		Interrupts status - one bit per cause
+ *					0 = no interrupt pending
+ *					1 = interrupt pending
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ * */
+int dprc_get_irq_status(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			uint8_t irq_index, uint32_t *status);
+
+/**
+ * @brief	Clears a pending interrupt's status
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]   irq_index	The interrupt index to configure
+ * @param[out]	status		Bits to clear (W1C) - one bit per cause
+ *					0 = don't change
+ *					1 = clear status bit
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ * */
+int dprc_clear_irq_status(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+			  uint8_t irq_index, uint32_t status);
+
+/**
+ * @brief	Connects two endpoints to create a network link between them
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]   endpoint1	Endpoint 1 configuration parameters.
+ * @param[in]	endpoint2	Endpoint 2 configuration parameters.
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ * */
+int dprc_connect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		 struct dprc_endpoint *endpoint1,
+		 struct dprc_endpoint *endpoint2);
+
+/**
+ * @brief	Disconnects one endpoint to remove its network link
+ *
+ * @param[in]   mc_io		Pointer to opaque I/O object
+ * @param[in]	dprc_handle	Handle to the DPRC object
+ * @param[in]   endpoint	Endpoint configuration parameters.
+ *
+ * @returns	'0' on Success; Error code otherwise.
+ * */
+int dprc_disconnect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
+		    struct dprc_endpoint *endpoint);
+
+/*! @} */
+
+#endif /* _FSL_DPRC_H */
diff --git a/include/linux/fsl_mc_cmd.h b/include/linux/fsl_mc_cmd.h
new file mode 100644
index 0000000..945c5a1
--- /dev/null
+++ b/include/linux/fsl_mc_cmd.h
@@ -0,0 +1,182 @@
+/* Copyright 2013-2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __FSL_MC_CMD_H
+#define __FSL_MC_CMD_H
+
+#include <linux/fsl_mc_sys.h>
+
+#ifdef FSL_MC_FIRMWARE
+/*
+ * MC firmware decodes MC command parameters and encodes MC response parameters
+ */
+
+#define MC_CMD_PARAM_OP(_cmd, _param, _offset, _width, _type, _arg) \
+	((_arg) = (_type)u64_dec((_cmd).params[_param], (_offset), (_width)))
+
+#define MC_RSP_PARAM_OP(_cmd, _param, _offset, _width, _type, _arg) \
+	((_cmd).params[_param] |= u64_enc((_offset), (_width), (_type)(_arg)))
+
+#else
+/*
+ * MC clients (GPP side) encode MC command parameters and decode MC response
+ * parameters
+ */
+
+#define MC_CMD_PARAM_OP(_cmd, _param, _offset, _width, _type, _arg) \
+	((_cmd).params[_param] |= u64_enc((_offset), (_width), (_type)(_arg)))
+
+#define MC_RSP_PARAM_OP(_cmd, _param, _offset, _width, _type, _arg) \
+	((_arg) = (_type)u64_dec((_cmd).params[_param], (_offset), (_width)))
+
+#endif /* FSL_MC_FIRMWARE */
+
+#define MAKE_UMASK64(_width) \
+	((uint64_t)((_width) < 64 ? ((uint64_t)1 << (_width)) - 1 : -1))
+
+static inline uint64_t u64_enc(int lsoffset, int width, uint64_t val)
+{
+	return (uint64_t)(((uint64_t)val & MAKE_UMASK64(width)) << lsoffset);
+}
+
+static inline uint64_t u64_dec(uint64_t val, int lsoffset, int width)
+{
+	return (uint64_t)((val >> lsoffset) & MAKE_UMASK64(width));
+}
+
+#define MC_CMD_NUM_OF_PARAMS	7
+
+struct mc_command {
+	uint64_t header;
+	uint64_t params[MC_CMD_NUM_OF_PARAMS];
+};
+
+enum mc_cmd_status {
+	MC_CMD_STATUS_OK = 0x0,	/*!< Completed successfully */
+	MC_CMD_STATUS_READY = 0x1,	/*!< Ready to be processed */
+	MC_CMD_STATUS_AUTH_ERR = 0x3,	/*!< Authentication error */
+	MC_CMD_STATUS_NO_PRIVILEGE = 0x4,	/*!< No privilege */
+	MC_CMD_STATUS_DMA_ERR = 0x5,	/*!< DMA or I/O error */
+	MC_CMD_STATUS_CONFIG_ERR = 0x6,	/*!< Configuration error */
+	MC_CMD_STATUS_TIMEOUT = 0x7,	/*!< Operation timed out */
+	MC_CMD_STATUS_NO_RESOURCE = 0x8,	/*!< No resources */
+	MC_CMD_STATUS_NO_MEMORY = 0x9,	/*!< No memory available */
+	MC_CMD_STATUS_BUSY = 0xA,	/*!< Device is busy */
+	MC_CMD_STATUS_UNSUPPORTED_OP = 0xB,	/*!< Unsupported operation */
+	MC_CMD_STATUS_INVALID_STATE = 0xC	/*!< Invalid state */
+};
+
+#define MC_CMD_HDR_CMDID_O	52	/* Command ID field offset */
+#define MC_CMD_HDR_CMDID_S	12	/* Command ID field size */
+#define MC_CMD_HDR_AUTHID_O	38	/* Authentication ID field offset */
+#define MC_CMD_HDR_AUTHID_S	10	/* Authentication ID field size */
+#define MC_CMD_HDR_SIZE_O	31	/* Size field offset */
+#define MC_CMD_HDR_SIZE_S	6	/* Size field size */
+#define MC_CMD_HDR_STATUS_O	16	/* Status field offset */
+#define MC_CMD_HDR_STATUS_S	8	/* Status field size */
+#define MC_CMD_HDR_PRI_O	15	/* Priority field offset */
+#define MC_CMD_HDR_PRI_S	1	/* Priority field size */
+
+#define MC_CMD_HDR_READ_STATUS(_hdr) \
+	((enum mc_cmd_status)u64_dec((_hdr), \
+		MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S))
+
+#define MC_CMD_HDR_READ_AUTHID(_hdr) \
+	((uint16_t)u64_dec((_hdr), MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S))
+
+#define MC_CMD_PRI_LOW		0	/*!< Low Priority command indication */
+#define MC_CMD_PRI_HIGH		1	/*!< High Priority command indication */
+
+static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id,
+					    uint8_t cmd_size,
+					    uint8_t priority, uint16_t auth_id)
+{
+	uint64_t hdr;
+
+	hdr = u64_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id);
+	hdr |= u64_enc(MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S, auth_id);
+	hdr |= u64_enc(MC_CMD_HDR_SIZE_O, MC_CMD_HDR_SIZE_S, cmd_size);
+	hdr |= u64_enc(MC_CMD_HDR_PRI_O, MC_CMD_HDR_PRI_S, priority);
+	hdr |= u64_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S,
+		       MC_CMD_STATUS_READY);
+
+	return hdr;
+}
+
+/**
+ * mc_write_command - writes a command to a Management Complex (MC) portal
+ *
+ * @portal: pointer to an MC portal
+ * @cmd: pointer to a filled command
+ */
+static inline void mc_write_command(struct mc_command __iomem *portal,
+				    struct mc_command *cmd)
+{
+	int i;
+
+	/* copy command parameters into the portal */
+	for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
+		iowrite64(cmd->params[i], &portal->params[i]);
+
+	/* submit the command by writing the header */
+	iowrite64(cmd->header, &portal->header);
+}
+
+/**
+ * mc_read_response - reads the response for the last MC command from a
+ * Management Complex (MC) portal
+ *
+ * @portal: pointer to an MC portal
+ * @resp: pointer to command response buffer
+ *
+ * Returns MC_CMD_STATUS_OK on Success; Error code otherwise.
+ */
+static inline enum mc_cmd_status mc_read_response(struct mc_command __iomem *
+						  portal,
+						  struct mc_command *resp)
+{
+	int i;
+	enum mc_cmd_status status;
+
+	/* Copy command response header from MC portal: */
+	resp->header = ioread64(&portal->header);
+	status = MC_CMD_HDR_READ_STATUS(resp->header);
+	if (status != MC_CMD_STATUS_OK)
+		return status;
+
+	/* Copy command response data from MC portal: */
+	for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
+		resp->params[i] = ioread64(&portal->params[i]);
+
+	return status;
+}
+
+#endif /* __FSL_MC_CMD_H */
diff --git a/include/linux/fsl_mc_sys.h b/include/linux/fsl_mc_sys.h
new file mode 100644
index 0000000..3233fdb
--- /dev/null
+++ b/include/linux/fsl_mc_sys.h
@@ -0,0 +1,81 @@
+/* Copyright 2013-2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _FSL_MC_SYS_H
+#define _FSL_MC_SYS_H
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/spinlock_types.h>
+
+#ifndef ENOTSUP
+#define ENOTSUP		95
+#endif
+
+#define ioread64(_p)	    readq(_p)
+#define iowrite64(_v, _p)   writeq(_v, _p)
+
+/**
+ * Bit masks for a MC I/O object (struct fsl_mc_io) flags
+ */
+#define FSL_MC_IO_PORTAL_SHARED	0x0001
+
+struct mc_command;
+
+/**
+ * struct fsl_mc_io - MC I/O object to be passed-in to mc_send_command()
+ * @magic: marker to verify identity of this structure
+ * @flags: flags for mc_send_command()
+ * @portal_size: MC command portal size in bytes
+ * @portal_phys_addr: MC command portal physical address
+ * @portal_virt_addr: MC command portal virtual address
+ * @spinlock: spin lock to serialize access to the MC command portal
+ */
+struct fsl_mc_io {
+#	define FSL_MC_IO_MAGIC	0x434d4f49
+	uint32_t magic;
+	uint32_t flags;
+	uint32_t portal_size;
+	phys_addr_t portal_phys_addr;
+	void __iomem *portal_virt_addr;
+	spinlock_t spinlock;	/* serializes commands on the same MC portal */
+};
+
+int __must_check fsl_create_mc_io(phys_addr_t mc_portal_phys_addr,
+				  uint32_t mc_portal_size,
+				  uint32_t flags, struct fsl_mc_io **new_mc_io);
+
+void fsl_destroy_mc_io(struct fsl_mc_io *mc_io);
+
+int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd);
+
+#endif /* _FSL_MC_SYS_H */
-- 
1.7.9.7


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

* [PATCH 2/4] drivers/bus: Freescale Management Complex (fsl-mc) bus driver
  2014-09-11 17:34 [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series J. German Rivera
  2014-09-11 17:34 ` [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs J. German Rivera
@ 2014-09-11 17:34 ` J. German Rivera
  2014-09-11 18:49   ` Joe Perches
  2014-09-11 17:34 ` [PATCH 3/4] drivers/bus: Device driver for FSL-MC DPRC devices J. German Rivera
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 43+ messages in thread
From: J. German Rivera @ 2014-09-11 17:34 UTC (permalink / raw)
  To: gregkh, arnd, linux-kernel
  Cc: stuart.yoder, Kim.Phillips, scottwood, agraf, linuxppc-release,
	J. German Rivera

From: "J. German Rivera" <German.Rivera@freescale.com>

Platform device driver that sets up the basic bus infrastructure
for the fsl-mc bus type, including support for adding/removing
fsl-mc devices, register/unregister of fsl-mc drivers, and bus
match support to bind devices to drivers.

Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
---
Changes in RFC v4:
- Added back the dma_mask field to struct fsl_mc_device as it is needed
  by some MC child device drivers. However, the default DMA mask now
  does not have the 32-bit limitation of the original patch series (v1).

Changes in RFC v3:
- Removed per-bus list of children, and instead use device_for_each_child()
- Use the same structure (struct fsl_mc_device) to represent both
  bus devices and their children.

Changes in RFC v2:
- Removed fsl_mc_bus structure and global variable
- Removed the 'magic' fields from all structs
- Removed NULL initializers
- Replaced all occurrences of EXPORT_SYMBOL() with EXPORT_SYMBOL_GPL()
- Removed function dprc_parse_dt_node(), and replaced its call by a
  direct call to of_address_to_resource()
- Removed struct fsl_mc_device_region and use standard 'struct resource'
  instead.
- Removed dma_mask field from 'struct fsl_mc_device' as it is not currently
  being used.
- Removed redundant 'driver' field from struct fsl_mc_device
- Removed the container field. We can get the parent DPRC of a given dev,
  from its dev.parent field.

 drivers/bus/Kconfig             |    3 +
 drivers/bus/Makefile            |    3 +
 drivers/bus/fsl-mc/Kconfig      |   13 +
 drivers/bus/fsl-mc/Makefile     |   14 +
 drivers/bus/fsl-mc/fsl_mc_bus.c |  602 +++++++++++++++++++++++++++++++++++++++
 include/linux/fsl_mc.h          |  137 +++++++++
 include/linux/fsl_mc_private.h  |   33 +++
 7 files changed, 805 insertions(+)
 create mode 100644 drivers/bus/fsl-mc/Kconfig
 create mode 100644 drivers/bus/fsl-mc/Makefile
 create mode 100644 drivers/bus/fsl-mc/fsl_mc_bus.c
 create mode 100644 include/linux/fsl_mc.h
 create mode 100644 include/linux/fsl_mc_private.h

diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 603eb1b..2fbb1fd 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -67,4 +67,7 @@ config VEXPRESS_CONFIG
 	help
 	  Platform configuration infrastructure for the ARM Ltd.
 	  Versatile Express.
+
+source "drivers/bus/fsl-mc/Kconfig"
+
 endmenu
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 2973c18..6abcab1 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -15,3 +15,6 @@ obj-$(CONFIG_ARM_CCI)		+= arm-cci.o
 obj-$(CONFIG_ARM_CCN)		+= arm-ccn.o

 obj-$(CONFIG_VEXPRESS_CONFIG)	+= vexpress-config.o
+
+# Freescale Management Complex (MC) bus drivers
+obj-$(CONFIG_FSL_MC_BUS)	+= fsl-mc/
diff --git a/drivers/bus/fsl-mc/Kconfig b/drivers/bus/fsl-mc/Kconfig
new file mode 100644
index 0000000..e3226f9
--- /dev/null
+++ b/drivers/bus/fsl-mc/Kconfig
@@ -0,0 +1,13 @@
+#
+# Freescale Management Complex (MC) bus drivers
+#
+# Copyright (C) 2014 Freescale Semiconductor, Inc.
+#
+# This file is released under the GPLv2
+#
+
+config FSL_MC_BUS
+	tristate "Freescale Management Complex (MC) bus driver"
+	help
+	  Driver to enable the bus infrastructure for the Freescale
+          QorIQ Management Complex.
diff --git a/drivers/bus/fsl-mc/Makefile b/drivers/bus/fsl-mc/Makefile
new file mode 100644
index 0000000..2981d70
--- /dev/null
+++ b/drivers/bus/fsl-mc/Makefile
@@ -0,0 +1,14 @@
+#
+# Freescale Management Complex (MC) bus drivers
+#
+# Copyright (C) 2014 Freescale Semiconductor, Inc.
+#
+# This file is released under the GPLv2
+#
+obj-$(CONFIG_FSL_MC_BUS) += fsl_mc_bus_driver.o
+
+fsl_mc_bus_driver-objs := fsl_mc_bus.o \
+			      fsl_mc_sys.o \
+			      dprc.o \
+			      dpmng.o
+
diff --git a/drivers/bus/fsl-mc/fsl_mc_bus.c b/drivers/bus/fsl-mc/fsl_mc_bus.c
new file mode 100644
index 0000000..3f59c31
--- /dev/null
+++ b/drivers/bus/fsl-mc/fsl_mc_bus.c
@@ -0,0 +1,602 @@
+/*
+ * Freescale Management Complex (MC) bus driver
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/fsl_mc_private.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/limits.h>
+#include <linux/fsl_dpmng.h>
+#include <linux/fsl_mc_sys.h>
+#include "fsl_dprc_cmd.h"
+
+static struct kmem_cache *mc_dev_cache;
+
+/**
+ * fsl_mc_bus_match - device to driver matching callback
+ * @dev: the MC object device structure to match against
+ * @drv: the device driver to search for matching MC object device id
+ * structures
+ *
+ * Returns 1 on success, 0 otherwise.
+ */
+static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv)
+{
+	const struct fsl_mc_device_match_id *id;
+	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+	struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
+	bool found = false;
+
+	if (mc_drv->match_id_table == NULL)
+		goto out;
+
+	/*
+	 * If the object is not 'plugged' don't match.
+	 * Only exception is the root DPRC, which is a special case.
+	 */
+	if ((mc_dev->obj_desc.state & DPRC_OBJ_STATE_PLUGGED) == 0 &&
+	    &mc_dev->dev != fsl_mc_bus_type.dev_root)
+		goto out;
+
+	/*
+	 * Traverse the match_id table of the given driver, trying to find
+	 * a matching for the given MC object device.
+	 */
+	for (id = mc_drv->match_id_table; id->vendor != 0x0; id++) {
+		if (id->vendor == mc_dev->obj_desc.vendor &&
+		    strcmp(id->obj_type, mc_dev->obj_desc.type) == 0 &&
+		    id->ver_major == mc_dev->obj_desc.ver_major &&
+		    id->ver_minor == mc_dev->obj_desc.ver_minor) {
+			found = true;
+			break;
+		}
+	}
+
+out:
+	pr_debug("%s: %s %s\n", __func__, dev_name(dev),
+		 found ? "matched" : "not matched");
+
+	return found;
+}
+
+/**
+ * fsl_mc_bus_uevent - callback invoked when a device is added
+ */
+static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	pr_debug("%s invoked\n", __func__);
+	return 0;
+}
+
+struct bus_type fsl_mc_bus_type = {
+	.name = "fsl-mc",
+	.match = fsl_mc_bus_match,
+	.uevent = fsl_mc_bus_uevent,
+};
+EXPORT_SYMBOL_GPL(fsl_mc_bus_type);
+
+static int fsl_mc_driver_probe(struct device *dev)
+{
+	struct fsl_mc_driver *mc_drv;
+	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+	int error = -EINVAL;
+
+	if (WARN_ON(dev->driver == NULL))
+		goto error;
+
+	mc_drv = to_fsl_mc_driver(dev->driver);
+	if (WARN_ON(mc_drv->probe == NULL))
+		goto error;
+
+	error = mc_drv->probe(mc_dev);
+	if (error < 0) {
+		dev_err(dev, "MC object device probe callback failed: %d\n",
+			error);
+		goto error;
+	}
+
+	return 0;
+error:
+	return error;
+}
+
+static int fsl_mc_driver_remove(struct device *dev)
+{
+	struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
+	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+	int error = -EINVAL;
+
+	if (WARN_ON(dev->driver == NULL))
+		goto error;
+
+	error = mc_drv->remove(mc_dev);
+	if (error < 0) {
+		dev_err(dev,
+			"MC object device remove callback failed: %d\n",
+			error);
+		goto error;
+	}
+
+	return 0;
+error:
+	return error;
+}
+
+static void fsl_mc_driver_shutdown(struct device *dev)
+{
+	struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
+	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+
+	mc_drv->shutdown(mc_dev);
+}
+
+/**
+ * __fsl_mc_driver_register - registers a child device driver with the
+ * MC bus
+ *
+ * This function is implicitly invoked from the registration function of
+ * fsl_mc device drivers, which is generated by the
+ * module_fsl_mc_driver() macro.
+ */
+int __fsl_mc_driver_register(struct fsl_mc_driver *mc_driver,
+			     struct module *owner)
+{
+	int error = -EINVAL;
+
+	mc_driver->driver.owner = owner;
+	mc_driver->driver.bus = &fsl_mc_bus_type;
+
+	/*
+	 * Set default driver callbacks, if not set by the child driver:
+	 */
+	if (mc_driver->probe != NULL)
+		mc_driver->driver.probe = fsl_mc_driver_probe;
+
+	if (mc_driver->remove != NULL)
+		mc_driver->driver.remove = fsl_mc_driver_remove;
+
+	if (mc_driver->shutdown != NULL)
+		mc_driver->driver.shutdown = fsl_mc_driver_shutdown;
+
+	error = driver_register(&mc_driver->driver);
+	if (error < 0) {
+		pr_err("driver_register() failed for %s: %d\n",
+		       mc_driver->driver.name, error);
+		goto error;
+	}
+
+	pr_info("MC object device driver %s registered\n",
+		mc_driver->driver.name);
+	return 0;
+error:
+	return error;
+}
+EXPORT_SYMBOL_GPL(__fsl_mc_driver_register);
+
+/**
+ * fsl_mc_driver_unregister - unregisters a device driver from the
+ * MC bus
+ */
+void fsl_mc_driver_unregister(struct fsl_mc_driver *mc_driver)
+{
+	driver_unregister(&mc_driver->driver);
+}
+EXPORT_SYMBOL_GPL(fsl_mc_driver_unregister);
+
+static int get_dprc_icid(struct fsl_mc_io *mc_io,
+			 int container_id, uint16_t *icid)
+{
+	uint16_t dprc_handle;
+	struct dprc_attributes attr;
+	bool dprc_opened = false;
+	int error = -EINVAL;
+
+	error = dprc_open(mc_io, container_id, &dprc_handle);
+	if (error < 0) {
+		pr_err("dprc_open() failed: %d\n", error);
+		goto out;
+	}
+
+	dprc_opened = true;
+	memset(&attr, 0, sizeof(attr));
+	error = dprc_get_attributes(mc_io, dprc_handle, &attr);
+	if (error < 0) {
+		pr_err("dprc_get_attributes() failed: %d\n", error);
+		goto out;
+	}
+
+	*icid = attr.icid;
+	error = 0;
+out:
+	if (dprc_opened)
+		(void)dprc_close(mc_io, dprc_handle);
+
+	return error;
+}
+
+static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev,
+					  struct fsl_mc_device *mc_bus_dev)
+{
+	int i;
+	int error;
+	struct resource *regions;
+	struct dprc_obj_desc *obj_desc = &mc_dev->obj_desc;
+	struct device *parent_dev = mc_dev->dev.parent;
+
+	regions = kmalloc_array(obj_desc->region_count,
+				sizeof(regions[0]), GFP_KERNEL);
+	if (regions == NULL) {
+		error = -ENOMEM;
+		dev_err(parent_dev, "No memory to allocate regions[]\n");
+		goto error;
+	}
+
+	for (i = 0; i < obj_desc->region_count; i++) {
+		struct dprc_region_desc region_desc;
+
+		error = dprc_get_obj_region(mc_bus_dev->mc_io,
+					    mc_bus_dev->mc_handle,
+					    obj_desc->type,
+					    obj_desc->id, i, &region_desc);
+		if (error < 0) {
+			dev_err(parent_dev,
+				"dprc_get_obj_region() failed: %d\n", error);
+			goto error;
+		}
+
+		WARN_ON(region_desc.base_paddr == 0x0);
+		WARN_ON(region_desc.size == 0);
+		regions[i].start = region_desc.base_paddr;
+		regions[i].end = region_desc.base_paddr + region_desc.size - 1;
+		regions[i].name = "fsl-mc object MMIO region";
+		regions[i].flags = IORESOURCE_IO;
+	}
+
+	mc_dev->regions = regions;
+	return 0;
+error:
+	kfree(regions);
+	return error;
+}
+
+/**
+ * Add a newly discovered MC object device to be visible in Linux
+ */
+int fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
+		      struct fsl_mc_io *mc_io,
+		      struct device *parent_dev,
+		      struct fsl_mc_device **new_mc_dev)
+{
+	int error = -EINVAL;
+	struct fsl_mc_device *mc_dev = NULL;
+	bool device_added = false;
+	struct fsl_mc_device *parent_mc_dev;
+
+	if (parent_dev->bus == &fsl_mc_bus_type)
+		parent_mc_dev = to_fsl_mc_device(parent_dev);
+	else
+		parent_mc_dev = NULL;
+
+	/*
+	 * DPRC devices must have a dedicated MC portal
+	 */
+	if (WARN_ON(strcmp(obj_desc->type, "dprc") == 0 && mc_io == NULL))
+		goto error;
+
+	mc_dev = kmem_cache_zalloc(mc_dev_cache, GFP_KERNEL);
+	if (mc_dev == NULL) {
+		error = -ENOMEM;
+		dev_err(parent_dev,
+			"No memory to allocate fsl_mc_device\n");
+		goto error;
+	}
+
+	mc_dev->obj_desc = *obj_desc;
+	mc_dev->mc_io = mc_io;
+	device_initialize(&mc_dev->dev);
+	mc_dev->dev.parent = parent_dev;
+	mc_dev->dev.bus = &fsl_mc_bus_type;
+	dev_set_name(&mc_dev->dev, "%s.%x", obj_desc->type, obj_desc->id);
+
+	if (strcmp(obj_desc->type, "dprc") == 0) {
+		struct fsl_mc_io *mc_io2;
+
+		mc_dev->flags |= FSL_MC_IS_DPRC;
+
+		/*
+		 * To get the DPRC's ICID, we need to open the DPRC
+		 * in get_dprc_icid(). For child DPRCs, we do so using the
+		 * parent DPRC's MC portal instead of the child DPRC's MC
+		 * portal, in case the child DPRC is already opened with
+		 * its own portal (e.g., the DPRC used by AIOP).
+		 *
+		 * NOTE: There cannot be more than one active open for a
+		 * given MC object, using the same MC portal.
+		 */
+		if (parent_mc_dev != NULL) {
+			/*
+			 * device being added is a child DPRC device
+			 */
+			mc_io2 = parent_mc_dev->mc_io;
+		} else {
+			/*
+			 * device being added is the root DPRC device
+			 */
+			mc_io2 = mc_io;
+		}
+
+		error = get_dprc_icid(mc_io2, obj_desc->id, &mc_dev->icid);
+		if (error < 0)
+			goto error;
+	} else {
+		/*
+		 * A non-DPRC MC object device has to be a child of another
+		 * MC object (specifically a DPRC object)
+		 */
+		mc_dev->icid = parent_mc_dev->icid;
+		mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK;
+		mc_dev->dev.dma_mask = &mc_dev->dma_mask;
+		if (obj_desc->region_count != 0) {
+			error = fsl_mc_device_get_mmio_regions(mc_dev,
+							       parent_mc_dev);
+			if (error < 0)
+				goto error;
+		}
+	}
+
+	/*
+	 * The device-specific probe callback will get invoked by device_add()
+	 */
+	error = device_add(&mc_dev->dev);
+	if (error < 0) {
+		dev_err(parent_dev,
+			"device_add() failed for device %s: %d\n",
+			dev_name(&mc_dev->dev), error);
+		goto error;
+	}
+
+	get_device(&mc_dev->dev);
+	device_added = true;
+	dev_dbg(parent_dev, "Added MC object device %s\n",
+		dev_name(&mc_dev->dev));
+
+	*new_mc_dev = mc_dev;
+	return 0;
+error:
+	if (device_added) {
+		device_del(&mc_dev->dev);
+		put_device(&mc_dev->dev);
+	}
+
+	if (mc_dev != NULL) {
+		if (mc_dev->regions != NULL)
+			kfree(mc_dev->regions);
+
+		kmem_cache_free(mc_dev_cache, mc_dev);
+	}
+
+	return error;
+}
+EXPORT_SYMBOL_GPL(fsl_mc_device_add);
+
+/**
+ * fsl_mc_device_remove - Remove a MC object device from being visible to
+ * Linux
+ *
+ * @mc_dev: Pointer to a MC object device object
+ */
+void fsl_mc_device_remove(struct fsl_mc_device *mc_dev)
+{
+	struct fsl_mc_device *parent_mc_dev;
+
+	if (mc_dev->dev.parent->bus == &fsl_mc_bus_type)
+		parent_mc_dev = to_fsl_mc_device(mc_dev->dev.parent);
+	else
+		parent_mc_dev = NULL;
+
+	if (mc_dev->regions != NULL)
+		kfree(mc_dev->regions);
+
+	/*
+	 * The device-specific remove callback will get invoked by device_del()
+	 */
+	device_del(&mc_dev->dev);
+	put_device(&mc_dev->dev);
+
+	if (strcmp(mc_dev->obj_desc.type, "dprc") == 0)
+		fsl_destroy_mc_io(mc_dev->mc_io);
+
+	mc_dev->mc_io = NULL;
+	kmem_cache_free(mc_dev_cache, mc_dev);
+}
+EXPORT_SYMBOL_GPL(fsl_mc_device_remove);
+
+/**
+ * fsl_mc_bus_probe - callback invoked when the root MC bus is being
+ * added
+ */
+static int fsl_mc_bus_probe(struct platform_device *pdev)
+{
+	struct dprc_obj_desc obj_desc;
+	int error = -EINVAL;
+	struct fsl_mc_device *mc_bus_dev = NULL;
+	struct fsl_mc_io *mc_io = NULL;
+	int container_id;
+	phys_addr_t mc_portal_phys_addr;
+	uint32_t mc_portal_size;
+	struct mc_version mc_version;
+	struct resource res;
+
+	dev_info(&pdev->dev, "Root MC bus device probed");
+	error = of_address_to_resource(pdev->dev.of_node, 0, &res);
+	if (error < 0) {
+		dev_err(&pdev->dev,
+			"of_address_to_resource() failed for %s\n",
+			pdev->dev.of_node->full_name);
+		goto error;
+	}
+
+	mc_portal_phys_addr = res.start;
+	mc_portal_size = resource_size(&res);
+	error = fsl_create_mc_io(mc_portal_phys_addr,
+				 mc_portal_size, 0, &mc_io);
+	if (error < 0)
+		goto error;
+
+	error = mc_get_version(mc_io, &mc_version);
+	if (error != 0) {
+		dev_err(&pdev->dev,
+			"mc_get_version() failed with error %d\n", error);
+		goto error;
+	}
+
+	dev_info(&pdev->dev,
+		 "Freescale Management Complex Firmware version: %u.%u.%u\n",
+		 mc_version.major, mc_version.minor, mc_version.revision);
+
+	if (mc_version.major != MC_VER_MAJOR) {
+		dev_err(&pdev->dev,
+			"ERROR: Firmware major version mismatch (found: %d, expected: %d)\n",
+			mc_version.major, MC_VER_MAJOR);
+	}
+
+	if (mc_version.minor != MC_VER_MINOR) {
+		dev_err(&pdev->dev,
+			"WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n",
+			mc_version.minor, MC_VER_MINOR);
+	}
+
+	error = dprc_get_container_id(mc_io, &container_id);
+	if (error < 0) {
+		dev_err(&pdev->dev,
+			"dprc_get_container_id() failed: %d\n", error);
+		goto error;
+	}
+
+	obj_desc.vendor = FSL_MC_VENDOR_FREESCALE;
+	strcpy(obj_desc.type, "dprc");
+	obj_desc.id = container_id;
+	obj_desc.ver_major = DPRC_VER_MAJOR;
+	obj_desc.ver_minor = DPRC_VER_MINOR;
+	obj_desc.region_count = 0;
+
+	error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, &mc_bus_dev);
+	if (error < 0)
+		goto error;
+
+	platform_set_drvdata(pdev, mc_bus_dev);
+	fsl_mc_bus_type.dev_root = &mc_bus_dev->dev;
+	return 0;
+error:
+	if (mc_io != NULL)
+		fsl_destroy_mc_io(mc_io);
+
+	return error;
+}
+
+/**
+ * fsl_mc_bus_remove - callback invoked when the root MC bus is being
+ * removed
+ */
+static int fsl_mc_bus_remove(struct platform_device *pdev)
+{
+	int error = -EINVAL;
+	struct fsl_mc_device *mc_bus_dev = platform_get_drvdata(pdev);
+
+	if (WARN_ON(&mc_bus_dev->dev != fsl_mc_bus_type.dev_root))
+		goto error;
+
+	fsl_mc_device_remove(mc_bus_dev);
+	fsl_mc_bus_type.dev_root = NULL;
+	dev_info(&pdev->dev, "Root MC bus device removed");
+	return 0;
+error:
+	return error;
+}
+
+static const struct of_device_id fsl_mc_bus_match_table[] = {
+	{.compatible = "fsl,qoriq-mc",},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table);
+
+static struct platform_driver fsl_mc_bus_driver = {
+	.driver = {
+		   .name = "fsl_mc_bus",
+		   .owner = THIS_MODULE,
+		   .pm = NULL,
+		   .of_match_table = fsl_mc_bus_match_table,
+		   },
+	.probe = fsl_mc_bus_probe,
+	.remove = fsl_mc_bus_remove,
+};
+
+static int __init fsl_mc_bus_driver_init(void)
+{
+	int error = -EINVAL;
+	bool bus_registered = false;
+
+	mc_dev_cache = kmem_cache_create("fsl_mc_device",
+					 sizeof(struct fsl_mc_device), 0, 0,
+					 NULL);
+	if (mc_dev_cache == NULL) {
+		error = -ENOMEM;
+		pr_err("Could not create fsl_mc_device cache\n");
+		goto error;
+	}
+
+	error = bus_register(&fsl_mc_bus_type);
+	if (error < 0) {
+		pr_err("fsl-mc bus type registration failed: %d\n", error);
+		goto error;
+	}
+
+	bus_registered = true;
+	pr_info("fsl-mc bus type registered\n");
+
+	error = platform_driver_register(&fsl_mc_bus_driver);
+	if (error < 0) {
+		pr_err("platform_driver_register() failed: %d\n", error);
+		goto error;
+	}
+
+	return 0;
+error:
+	if (bus_registered)
+		bus_unregister(&fsl_mc_bus_type);
+
+	if (mc_dev_cache != NULL)
+		kmem_cache_destroy(mc_dev_cache);
+
+	return error;
+}
+
+postcore_initcall(fsl_mc_bus_driver_init);
+
+static void __exit fsl_mc_bus_driver_exit(void)
+{
+	if (WARN_ON(mc_dev_cache == NULL))
+		return;
+
+	platform_driver_unregister(&fsl_mc_bus_driver);
+	bus_unregister(&fsl_mc_bus_type);
+	kmem_cache_destroy(mc_dev_cache);
+	pr_info("MC bus unregistered\n");
+}
+
+module_exit(fsl_mc_bus_driver_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor Inc.");
+MODULE_DESCRIPTION("Freescale Management Complex (MC) bus driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/fsl_mc.h b/include/linux/fsl_mc.h
new file mode 100644
index 0000000..b291eba
--- /dev/null
+++ b/include/linux/fsl_mc.h
@@ -0,0 +1,137 @@
+/*
+ * Freescale Management Complex (MC) bus public interface
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#ifndef _FSL_MC_H_
+#define _FSL_MC_H_
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/fsl_dprc.h>
+
+#define FSL_MC_VENDOR_FREESCALE	0x1957
+
+struct fsl_mc_device;
+struct fsl_mc_io;
+
+/**
+ * struct fsl_mc_driver - MC object device driver object
+ * @driver: Generic device driver
+ * @match_id_table: table of supported device matching Ids
+ * @probe: Function called when a device is added
+ * @remove: Function called when a device is removed
+ * @shutdown: Function called at shutdown time to quiesce the device
+ * @suspend: Function called when a device is stopped
+ * @resume: Function called when a device is resumed
+ *
+ * Generic DPAA device driver object for device drivers that are registered
+ * with a DPRC bus. This structure is to be embedded in each device-specific
+ * driver structure.
+ */
+struct fsl_mc_driver {
+	struct device_driver driver;
+	const struct fsl_mc_device_match_id *match_id_table;
+	int (*probe)(struct fsl_mc_device *dev);
+	int (*remove)(struct fsl_mc_device *dev);
+	void (*shutdown)(struct fsl_mc_device *dev);
+	int (*suspend)(struct fsl_mc_device *dev, pm_message_t state);
+	int (*resume)(struct fsl_mc_device *dev);
+};
+
+#define to_fsl_mc_driver(_drv) \
+	container_of(_drv, struct fsl_mc_driver, driver)
+
+/**
+ * struct fsl_mc_device_match_id - MC object device Id entry for driver matching
+ * @vendor: vendor ID
+ * @obj_type: MC object type
+ * @ver_major: MC object version major number
+ * @ver_minor: MC object version minor number
+ *
+ * Type of entries in the "device Id" table for MC object devices supported by
+ * a MC object device driver. The last entry of the table has vendor set to 0x0
+ */
+struct fsl_mc_device_match_id {
+	uint16_t vendor;
+	const char obj_type[16];
+	uint32_t ver_major;
+	uint32_t ver_minor;
+};
+
+/**
+ * Bit masks for a MC object device (struct fsl_mc_device) flags
+ */
+#define FSL_MC_IS_DPRC	0x0001
+
+/**
+ * Default DMA mask for devices on a fsl-mc bus
+ */
+#define FSL_MC_DEFAULT_DMA_MASK	(~0ULL)
+
+/**
+ * struct fsl_mc_device - MC object device object
+ * @dev: Linux driver model device object
+ * @dma_mask: Default DMA mask
+ * @flags: MC object device flags
+ * @icid: Isolation context ID for the device
+ * @mc_handle: MC handle for the corresponding MC object opened
+ * @mc_io: Pointer to MC IO object assigned to this device or
+ * NULL if none.
+ * @obj_desc: MC description of the DPAA device
+ * @regions: pointer to array of MMIO region entries
+ *
+ * Generic device object for MC object devices that are "attached" to a
+ * MC bus.
+ *
+ * NOTES:
+ * - For a non-DPRC object its icid is the same as its parent DPRC's icid.
+ * - The SMMU notifier callback gets invoked after device_add() has been
+ *   called for an MC object device, but before the device-specific probe
+ *   callback gets called.
+ */
+struct fsl_mc_device {
+	struct device dev;
+	uint64_t dma_mask;
+	uint16_t flags;
+	uint16_t icid;
+	uint16_t mc_handle;
+	struct fsl_mc_io *mc_io;
+	struct dprc_obj_desc obj_desc;
+	struct resource *regions;
+};
+
+#define to_fsl_mc_device(_dev) \
+	container_of(_dev, struct fsl_mc_device, dev)
+
+/*
+ * module_fsl_mc_driver() - Helper macro for drivers that don't do
+ * anything special in module init/exit.  This eliminates a lot of
+ * boilerplate.  Each module may only use this macro once, and
+ * calling it replaces module_init() and module_exit()
+ */
+#define module_fsl_mc_driver(__fsl_mc_driver) \
+	module_driver(__fsl_mc_driver, fsl_mc_driver_register, \
+		      fsl_mc_driver_unregister)
+
+/*
+ * Macro to avoid include chaining to get THIS_MODULE
+ */
+#define fsl_mc_driver_register(drv) \
+	__fsl_mc_driver_register(drv, THIS_MODULE)
+
+int __must_check __fsl_mc_driver_register(struct fsl_mc_driver *fsl_mc_driver,
+					  struct module *owner);
+
+void fsl_mc_driver_unregister(struct fsl_mc_driver *driver);
+
+extern struct bus_type fsl_mc_bus_type;
+
+#endif /* _FSL_MC_H_ */
diff --git a/include/linux/fsl_mc_private.h b/include/linux/fsl_mc_private.h
new file mode 100644
index 0000000..3ff3f2b
--- /dev/null
+++ b/include/linux/fsl_mc_private.h
@@ -0,0 +1,33 @@
+/*
+ * Freescale Management Complex (MC) bus private declarations
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#ifndef _FSL_MC_PRIVATE_H_
+#define _FSL_MC_PRIVATE_H_
+
+#include <linux/fsl_mc.h>
+#include <linux/mutex.h>
+#include <linux/stringify.h>
+
+#define FSL_MC_DEVICE_MATCH(_mc_dev, _obj_desc) \
+	(strcmp((_mc_dev)->obj_desc.type, (_obj_desc)->type) == 0 && \
+	 (_mc_dev)->obj_desc.id == (_obj_desc)->id)
+
+#define FSL_MC_IS_ALLOCATABLE(_obj_type) \
+	(strcmp(_obj_type, "dpbp") == 0 || \
+	 strcmp(_obj_type, "dpcon") == 0)
+
+int __must_check fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
+				   struct fsl_mc_io *mc_io,
+				   struct device *parent_dev,
+				   struct fsl_mc_device **new_mc_dev);
+
+void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);
+
+#endif /* _FSL_MC_PRIVATE_H_ */
--
1.7.9.7


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

* [PATCH 3/4] drivers/bus: Device driver for FSL-MC DPRC devices
  2014-09-11 17:34 [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series J. German Rivera
  2014-09-11 17:34 ` [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs J. German Rivera
  2014-09-11 17:34 ` [PATCH 2/4] drivers/bus: Freescale Management Complex (fsl-mc) bus driver J. German Rivera
@ 2014-09-11 17:34 ` J. German Rivera
  2014-09-11 17:34 ` [PATCH 4/4] Update MAINTAINERS file J. German Rivera
  2014-09-15 23:44 ` [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series Kim Phillips
  4 siblings, 0 replies; 43+ messages in thread
From: J. German Rivera @ 2014-09-11 17:34 UTC (permalink / raw)
  To: gregkh, arnd, linux-kernel
  Cc: stuart.yoder, Kim.Phillips, scottwood, agraf, linuxppc-release,
	J. German Rivera

From: "J. German Rivera" <German.Rivera@freescale.com>

A DPRC (Data Path Resource Container) is an isolation device
that contains a set of DPAA networking devices to be
assigned to an isolation domain (e.g., a virtual machine).

Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
---
Changes in RFC v4:
- Fixed parameter mismatch for device_find_child() call in fsl_mc_dprc.c

Changes in RFC v3:
- Removed per-bus list of children, and instead use device_for_each_child()
- Use the same structure (struct fsl_mc_device) to represent both
  bus devices and their children.

Changes in RFC v2:
- Removed the 'magic' fields from all structs

 drivers/bus/fsl-mc/Makefile      |    3 +-
 drivers/bus/fsl-mc/fsl_mc_dprc.c |  396 ++++++++++++++++++++++++++++++++++++++
 include/linux/fsl_mc_private.h   |    6 +
 3 files changed, 404 insertions(+), 1 deletion(-)
 create mode 100644 drivers/bus/fsl-mc/fsl_mc_dprc.c

diff --git a/drivers/bus/fsl-mc/Makefile b/drivers/bus/fsl-mc/Makefile
index 2981d70..499dc9b 100644
--- a/drivers/bus/fsl-mc/Makefile
+++ b/drivers/bus/fsl-mc/Makefile
@@ -5,7 +5,8 @@
 #
 # This file is released under the GPLv2
 #
-obj-$(CONFIG_FSL_MC_BUS) += fsl_mc_bus_driver.o
+obj-$(CONFIG_FSL_MC_BUS) += fsl_mc_bus_driver.o \
+			    fsl_mc_dprc.o

 fsl_mc_bus_driver-objs := fsl_mc_bus.o \
 			      fsl_mc_sys.o \
diff --git a/drivers/bus/fsl-mc/fsl_mc_dprc.c b/drivers/bus/fsl-mc/fsl_mc_dprc.c
new file mode 100644
index 0000000..c05cbef
--- /dev/null
+++ b/drivers/bus/fsl-mc/fsl_mc_dprc.c
@@ -0,0 +1,396 @@
+/*
+ * Freescale daata path resource container (DPRC) driver
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/fsl_mc_private.h>
+#include <linux/fsl_mc_sys.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "fsl_dprc_cmd.h"
+
+struct dprc_child_objs {
+	int child_count;
+	struct dprc_obj_desc *child_array;
+};
+
+static int __fsl_mc_device_remove_if_not_in_mc(struct device *dev, void *data)
+{
+	int i;
+	struct dprc_child_objs *objs;
+	struct fsl_mc_device *mc_dev;
+
+	WARN_ON(dev == NULL);
+	WARN_ON(data == NULL);
+	mc_dev = to_fsl_mc_device(dev);
+	objs = data;
+
+	for (i = 0; i < objs->child_count; i++) {
+		struct dprc_obj_desc *obj_desc = &objs->child_array[i];
+
+		if (strlen(obj_desc->type) != 0 &&
+		    FSL_MC_DEVICE_MATCH(mc_dev, obj_desc))
+			break;
+	}
+
+	if (i == objs->child_count)
+		fsl_mc_device_remove(mc_dev);
+
+	return 0;
+}
+
+static int __fsl_mc_device_remove(struct device *dev, void *data)
+{
+	WARN_ON(dev == NULL);
+	WARN_ON(data != NULL);
+	fsl_mc_device_remove(to_fsl_mc_device(dev));
+	return 0;
+}
+
+/**
+ * dprc_remove_devices - Removes devices for objects removed from a DPRC
+ *
+ * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
+ * @obj_desc_array: array of object descriptors for child objects currently
+ * present in the DPRC in the MC.
+ * @num_child_objects_in_mc: number of entries in obj_desc_array
+ *
+ * Synchronizes the state of the Linux bus driver with the actual state of
+ * the MC by removing devices that represent MC objects that have
+ * been dynamically removed in the physical DPRC.
+ */
+static void dprc_remove_devices(struct fsl_mc_device *mc_bus_dev,
+				struct dprc_obj_desc *obj_desc_array,
+				int num_child_objects_in_mc)
+{
+	if (num_child_objects_in_mc != 0) {
+		/*
+		 * Remove child objects that are in the DPRC in Linux,
+		 * but not in the MC:
+		 */
+		struct dprc_child_objs objs;
+
+		objs.child_count = num_child_objects_in_mc;
+		objs.child_array = obj_desc_array;
+		device_for_each_child(&mc_bus_dev->dev, &objs,
+				      __fsl_mc_device_remove_if_not_in_mc);
+	} else {
+		/*
+		 * There are no child objects for this DPRC in the MC.
+		 * So, remove all the child devices from Linux:
+		 */
+		device_for_each_child(&mc_bus_dev->dev, NULL,
+				      __fsl_mc_device_remove);
+	}
+}
+
+static int __fsl_mc_device_match(struct device *dev, void *data)
+{
+	struct dprc_obj_desc *obj_desc = data;
+	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+
+	return FSL_MC_DEVICE_MATCH(mc_dev, obj_desc);
+}
+
+static struct fsl_mc_device *fsl_mc_device_lookup(struct dprc_obj_desc
+								*obj_desc,
+						  struct fsl_mc_device
+								*mc_bus_dev)
+{
+	struct device *dev;
+
+	dev = device_find_child(&mc_bus_dev->dev, obj_desc,
+				__fsl_mc_device_match);
+
+	return (dev != NULL) ? to_fsl_mc_device(dev) : NULL;
+}
+
+/**
+ * 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
+ * @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
+ *
+ * Synchronizes the state of the Linux bus driver with the actual
+ * state of the MC by adding objects that have been newly discovered
+ * in the physical DPRC.
+ */
+static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
+				 struct dprc_obj_desc *obj_desc_array,
+				 int num_child_objects_in_mc)
+{
+	int error;
+	int i;
+
+	for (i = 0; i < num_child_objects_in_mc; i++) {
+		struct dprc_region_desc region_desc;
+		struct fsl_mc_device *child_dev;
+		struct fsl_mc_io *mc_io = NULL;
+		struct dprc_obj_desc *obj_desc = &obj_desc_array[i];
+
+		if (strlen(obj_desc->type) == 0)
+			continue;
+		/*
+		 * Check if device is already known to Linux:
+		 */
+		child_dev = fsl_mc_device_lookup(obj_desc, mc_bus_dev);
+		if (child_dev != NULL)
+			continue;
+
+		if (strcmp(obj_desc->type, "dprc") == 0) {
+			/*
+			 * Get the MC portal physical address for the device
+			 * (specified in the device's first MMIO region):
+			 */
+			if (WARN_ON(obj_desc->region_count == 0))
+				continue;
+
+			error = dprc_get_obj_region(mc_bus_dev->mc_io,
+						    mc_bus_dev->mc_handle,
+						    obj_desc->type,
+						    obj_desc->id,
+						    0, &region_desc);
+			if (error < 0) {
+				dev_err(&mc_bus_dev->dev,
+					"dprc_get_obj_region() failed: %d\n",
+					error);
+				continue;
+			}
+
+			if (region_desc.size !=
+					mc_bus_dev->mc_io->portal_size) {
+				error = -EINVAL;
+				dev_err(&mc_bus_dev->dev,
+					"Invalid MC portal size: %lu\n",
+					region_desc.size);
+				continue;
+			}
+
+			error = fsl_create_mc_io(region_desc.base_paddr,
+						 region_desc.size, 0, &mc_io);
+			if (error < 0)
+				continue;
+		}
+
+		error = fsl_mc_device_add(obj_desc, mc_io, &mc_bus_dev->dev,
+					  &child_dev);
+		if (error < 0) {
+			if (mc_io != NULL)
+				fsl_destroy_mc_io(mc_io);
+
+			continue;
+		}
+	}
+}
+
+/**
+ * dprc_scan_objects - Discover objects in a DPRC
+ *
+ * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
+ *
+ * Detects objects added and removed from a DPRC and synchronizes the
+ * state of the Linux bus driver, MC by adding and removing
+ * devices accordingly.
+ */
+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
+{
+	int num_child_objects;
+	int dprc_get_obj_failures;
+	int error = -EINVAL;
+	struct dprc_obj_desc *child_obj_desc_array = NULL;
+
+	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);
+		goto out;
+	}
+
+	if (num_child_objects != 0) {
+		int i;
+
+		child_obj_desc_array =
+		    kmalloc_array(num_child_objects,
+				  sizeof(*child_obj_desc_array), GFP_KERNEL);
+		if (child_obj_desc_array == NULL) {
+			error = -ENOMEM;
+			dev_err(&mc_bus_dev->dev,
+				"No memory to allocate obj_desc array\n");
+			goto out;
+		}
+
+		/*
+		 * Discover objects currently present in the physical DPRC:
+		 */
+		dprc_get_obj_failures = 0;
+		for (i = 0; i < num_child_objects; i++) {
+			struct dprc_obj_desc *obj_desc =
+			    &child_obj_desc_array[i];
+
+			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);
+				/*
+				 * Mark the obj entry as "invalid", by using the
+				 * empty string as obj type:
+				 */
+				obj_desc->type[0] = '\0';
+				obj_desc->id = error;
+				dprc_get_obj_failures++;
+				continue;
+			}
+
+			dev_info(&mc_bus_dev->dev,
+				 "Discovered object: type %s, id %d\n",
+				 obj_desc->type, obj_desc->id);
+		}
+
+		if (dprc_get_obj_failures != 0) {
+			dev_err(&mc_bus_dev->dev,
+				"%d out of %d devices could not be retrieved\n",
+				dprc_get_obj_failures, num_child_objects);
+		}
+	}
+
+	dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
+			    num_child_objects);
+
+	dprc_add_new_devices(mc_bus_dev, child_obj_desc_array,
+			     num_child_objects);
+
+	error = 0;
+out:
+	if (child_obj_desc_array != NULL)
+		kfree(child_obj_desc_array);
+
+	return error;
+}
+EXPORT_SYMBOL_GPL(dprc_scan_objects);
+
+/**
+ * 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
+ *
+ * Scans the physical DPRC and synchronizes the state of the Linux
+ * bus driver with the actual state of the MC by adding and removing
+ * devices as appropriate.
+ */
+int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
+{
+	int error = -EINVAL;
+
+	error = dprc_scan_objects(mc_bus_dev);
+	if (error < 0)
+		goto error;
+
+	return 0;
+error:
+	return error;
+}
+EXPORT_SYMBOL_GPL(dprc_scan_container);
+
+/**
+ * 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.
+ */
+static int dprc_probe(struct fsl_mc_device *mc_dev)
+{
+	int error = -EINVAL;
+	bool dprc_opened = false;
+
+	if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
+		goto error;
+
+	error = dprc_open(mc_dev->mc_io, mc_dev->obj_desc.id,
+			  &mc_dev->mc_handle);
+	if (error < 0) {
+		dev_err(&mc_dev->dev, "dprc_open() failed: %d\n", error);
+		goto error;
+	}
+
+	dprc_opened = true;
+	error = dprc_scan_container(mc_dev);
+	if (error < 0)
+		goto error;
+
+	dev_info(&mc_dev->dev, "DPRC device bound to driver");
+	return 0;
+error:
+	if (dprc_opened)
+		(void)dprc_close(mc_dev->mc_io, mc_dev->mc_handle);
+
+	return error;
+}
+
+/**
+ * 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.
+ */
+static int dprc_remove(struct fsl_mc_device *mc_dev)
+{
+	int error = -EINVAL;
+
+	if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
+		goto error;
+	if (WARN_ON(mc_dev->mc_io == NULL))
+		goto error;
+
+	device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove);
+	error = dprc_close(mc_dev->mc_io, mc_dev->mc_handle);
+	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;
+error:
+	return error;
+}
+
+static const struct fsl_mc_device_match_id match_id_table[] = {
+	{
+	 .vendor = FSL_MC_VENDOR_FREESCALE,
+	 .obj_type = "dprc",
+	 .ver_major = DPRC_VER_MAJOR,
+	 .ver_minor = DPRC_VER_MINOR},
+	{.vendor = 0x0},
+};
+
+static struct fsl_mc_driver dprc_driver = {
+	.driver = {
+		   .name = FSL_MC_DPRC_DRIVER_NAME,
+		   .owner = THIS_MODULE,
+		   .pm = NULL,
+		   },
+	.match_id_table = match_id_table,
+	.probe = dprc_probe,
+	.remove = dprc_remove,
+};
+
+module_fsl_mc_driver(dprc_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor Inc.");
+MODULE_DESCRIPTION("Freescale's DPRC container driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/fsl_mc_private.h b/include/linux/fsl_mc_private.h
index 3ff3f2b..ece79f3 100644
--- a/include/linux/fsl_mc_private.h
+++ b/include/linux/fsl_mc_private.h
@@ -15,6 +15,8 @@
 #include <linux/mutex.h>
 #include <linux/stringify.h>

+#define FSL_MC_DPRC_DRIVER_NAME    "fsl_mc_dprc"
+
 #define FSL_MC_DEVICE_MATCH(_mc_dev, _obj_desc) \
 	(strcmp((_mc_dev)->obj_desc.type, (_obj_desc)->type) == 0 && \
 	 (_mc_dev)->obj_desc.id == (_obj_desc)->id)
@@ -30,4 +32,8 @@ int __must_check fsl_mc_device_add(struct dprc_obj_desc *obj_desc,

 void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);

+int __must_check dprc_scan_container(struct fsl_mc_device *mc_bus_dev);
+
+int __must_check dprc_scan_objects(struct fsl_mc_device *mc_bus_dev);
+
 #endif /* _FSL_MC_PRIVATE_H_ */
--
1.7.9.7


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

* [PATCH 4/4] Update MAINTAINERS file
  2014-09-11 17:34 [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series J. German Rivera
                   ` (2 preceding siblings ...)
  2014-09-11 17:34 ` [PATCH 3/4] drivers/bus: Device driver for FSL-MC DPRC devices J. German Rivera
@ 2014-09-11 17:34 ` J. German Rivera
  2014-09-15 23:44 ` [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series Kim Phillips
  4 siblings, 0 replies; 43+ messages in thread
From: J. German Rivera @ 2014-09-11 17:34 UTC (permalink / raw)
  To: gregkh, arnd, linux-kernel
  Cc: stuart.yoder, Kim.Phillips, scottwood, agraf, linuxppc-release,
	J. German Rivera

From: "J. German Rivera" <German.Rivera@freescale.com>

Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
---
 MAINTAINERS |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7e2eb4c..eb8597d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3841,6 +3841,14 @@ S:	Maintained
 F:	sound/soc/fsl/fsl*
 F:	sound/soc/fsl/mpc8610_hpcd.c
 
+FREESCALE QORIQ MANAGEMENT COMPLEX DRIVER
+M:	J. German Rivera <German.Rivera@freescale.com>
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+F:	include/linux/fsl_mc*
+F:	include/linux/fsl_dp*
+F:	drivers/bus/fsl-mc/*
+
 FREEVXFS FILESYSTEM
 M:	Christoph Hellwig <hch@infradead.org>
 W:	ftp://ftp.openlinux.org/pub/people/hch/vxfs
-- 
1.7.9.7


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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-11 17:34 ` [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs J. German Rivera
@ 2014-09-11 18:45   ` Joe Perches
  2014-09-17 16:35     ` German Rivera
  2014-09-15 23:44   ` Kim Phillips
  1 sibling, 1 reply; 43+ messages in thread
From: Joe Perches @ 2014-09-11 18:45 UTC (permalink / raw)
  To: J. German Rivera
  Cc: gregkh, arnd, linux-kernel, stuart.yoder, Kim.Phillips,
	scottwood, agraf, linuxppc-release

On Thu, 2014-09-11 at 12:34 -0500, J. German Rivera wrote:
> APIs to access the Management Complex (MC) hardware
> module of Freescale LS2 SoCs. This patch includes
> APIs to check the MC firmware version and to manipulate
> DPRC objects in the MC.

> diff --git a/drivers/bus/fsl-mc/dpmng.c b/drivers/bus/fsl-mc/dpmng.c
[]
> +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
> +{
> +	struct mc_command cmd = { 0 };
> +	int err;
> +
> +	cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION,
> +					  DPMNG_CMDSZ_GET_VERSION,
> +					  MC_CMD_PRI_LOW, 0);
> +
> +	err = mc_send_command(mc_io, &cmd);
> +	if (!err)
> +		DPMNG_RSP_GET_VERSION(cmd, mc_ver_info);
> +
> +	return err;

I think it better style to read when the
failure case is handled immediately by
a return or a "goto out" and the successful
case code is at the same indent level

	err = mc_send_command_(etc...)
	if (err)
		return err;

	DPMNG_RSP_GET_VERSION(cmd, mc_ver_info);

	return 0;
}

> diff --git a/drivers/bus/fsl-mc/dprc.c b/drivers/bus/fsl-mc/dprc.c

> +int dprc_get_container_id(struct fsl_mc_io *mc_io, int *container_id)
> +{
> +	struct mc_command cmd = { 0 };
> +	int err;
> +
> +	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID,
> +					  DPRC_CMDSZ_GET_CONT_ID,
> +					  MC_CMD_PRI_LOW, 0);
> +
> +	err = mc_send_command(mc_io, &cmd);
> +	if (!err)
> +		DPRC_RSP_GET_CONTAINER_ID(cmd, *container_id);
> +
> +	return err;
> +}

Same sort of thing as above.
Actively fail on err and proceed at the same indent
level on success.

> +
> +int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *dprc_handle)
> +{
> +	int err;
> +	struct mc_command cmd = { 0 };
> +
> +	cmd.header = mc_encode_cmd_header(MC_DPRC_CMDID_OPEN,
> +					  MC_CMD_OPEN_SIZE, MC_CMD_PRI_LOW, 0);
> +
> +	DPRC_CMD_OPEN(cmd, container_id);
> +
> +	err = mc_send_command(mc_io, &cmd);
> +	if (!err)
> +		*dprc_handle = MC_CMD_HDR_READ_AUTHID(cmd.header);
> +
> +	return err;
> +}

etc.

I didn't read any more.


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

* Re: [PATCH 2/4] drivers/bus: Freescale Management Complex (fsl-mc) bus driver
  2014-09-11 17:34 ` [PATCH 2/4] drivers/bus: Freescale Management Complex (fsl-mc) bus driver J. German Rivera
@ 2014-09-11 18:49   ` Joe Perches
  2014-09-17 23:50     ` German Rivera
  0 siblings, 1 reply; 43+ messages in thread
From: Joe Perches @ 2014-09-11 18:49 UTC (permalink / raw)
  To: J. German Rivera
  Cc: gregkh, arnd, linux-kernel, stuart.yoder, Kim.Phillips,
	scottwood, agraf, linuxppc-release

On Thu, 2014-09-11 at 12:34 -0500, J. German Rivera wrote:
> From: "J. German Rivera" <German.Rivera@freescale.com>
> 
> Platform device driver that sets up the basic bus infrastructure
> for the fsl-mc bus type, including support for adding/removing
> fsl-mc devices, register/unregister of fsl-mc drivers, and bus
> match support to bind devices to drivers.

[]

> diff --git a/drivers/bus/fsl-mc/fsl_mc_bus.c b/drivers/bus/fsl-mc/fsl_mc_bus.c
[]
> +/**
> + * fsl_mc_bus_match - device to driver matching callback
> + * @dev: the MC object device structure to match against
> + * @drv: the device driver to search for matching MC object device id
> + * structures
> + *
> + * Returns 1 on success, 0 otherwise.
> + */
> +static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv)
> +{
> +	const struct fsl_mc_device_match_id *id;
> +	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
> +	struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
> +	bool found = false;
[]
> +out:
> +	pr_debug("%s: %s %s\n", __func__, dev_name(dev),
> +		 found ? "matched" : "not matched");

Thia should probably use dev_dbg

	dev_dbg(dev, "%smatched\n", found ? "" : "not ");

and let the dynamic debug mechanism emit the
function name if desired.



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

* Re: [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series
  2014-09-11 17:34 [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series J. German Rivera
                   ` (3 preceding siblings ...)
  2014-09-11 17:34 ` [PATCH 4/4] Update MAINTAINERS file J. German Rivera
@ 2014-09-15 23:44 ` Kim Phillips
  2014-09-18  0:20   ` German Rivera
  4 siblings, 1 reply; 43+ messages in thread
From: Kim Phillips @ 2014-09-15 23:44 UTC (permalink / raw)
  To: J. German Rivera
  Cc: gregkh, arnd, linux-kernel, stuart.yoder, Kim.Phillips,
	scottwood, agraf, linuxppc-release

On Thu, 11 Sep 2014 12:34:20 -0500
"J. German Rivera" <German.Rivera@freescale.com> wrote:

> This patch series introduces Linux support for the Freescale
> Management Complex (fsl-mc) hardware.

here are the results of using some tools to check this patchseries:

make C=1 CF="-D__CHECK_ENDIAN__":

drivers/bus/fsl-mc/fsl_mc_sys.c:235:9: warning: context imbalance in 'mc_send_command' - different lock contexts for basic block
drivers/bus/fsl-mc/fsl_mc_dprc.c: In function 'dprc_add_new_devices':
drivers/bus/fsl-mc/fsl_mc_dprc.c:173:6: warning: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type 'uint32_t' [-Wformat=]
      region_desc.size);
      ^

When built as a module (CONFIG_FSL_MC_BUS=m):

ERROR: ".dprc_get_obj" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
ERROR: ".dprc_get_obj_count" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
ERROR: ".dprc_close" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
ERROR: ".dprc_open" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
ERROR: ".dprc_get_obj_region" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
make[1]: *** [__modpost] Error 1
make: *** [modules] Error 2

checkpatch:

WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?

WARNING: DT compatible string "fsl,qoriq-mc" appears un-documented -- check ./Documentation/devicetree/bindings/
#690: FILE: drivers/bus/fsl-mc/fsl_mc_bus.c:528:
+	{.compatible = "fsl,qoriq-mc",},

For the former warning, I'd suggest moving patch 4/4's contents up
in the series.

For the latter warning, googling for the property shows an upstream
effort, so it might be ok, but it'd be nice to provide a
cross-reference to the status of the latest post, to make it easier
for reviewer consumption.

Also, I think you'd get more recipient coverage by using
scripts/get_maintainer.pl.

Thanks,

Kim

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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-11 17:34 ` [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs J. German Rivera
  2014-09-11 18:45   ` Joe Perches
@ 2014-09-15 23:44   ` Kim Phillips
  2014-09-16  4:31     ` Scott Wood
                       ` (2 more replies)
  1 sibling, 3 replies; 43+ messages in thread
From: Kim Phillips @ 2014-09-15 23:44 UTC (permalink / raw)
  To: J. German Rivera
  Cc: gregkh, arnd, linux-kernel, stuart.yoder, Kim.Phillips,
	scottwood, agraf, linuxppc-release

On Thu, 11 Sep 2014 12:34:21 -0500
"J. German Rivera" <German.Rivera@freescale.com> wrote:

> From: "J. German Rivera" <German.Rivera@freescale.com>
> 
> APIs to access the Management Complex (MC) hardware
> module of Freescale LS2 SoCs. This patch includes
> APIs to check the MC firmware version and to manipulate
> DPRC objects in the MC.
> 
> Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
> Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
> ---
>  drivers/bus/fsl-mc/dpmng.c         |   93 +++++
>  drivers/bus/fsl-mc/dprc.c          |  504 +++++++++++++++++++++++
>  drivers/bus/fsl-mc/fsl_dpmng_cmd.h |   83 ++++
>  drivers/bus/fsl-mc/fsl_dprc_cmd.h  |  545 +++++++++++++++++++++++++
>  drivers/bus/fsl-mc/fsl_mc_sys.c    |  237 +++++++++++
>  include/linux/fsl_dpmng.h          |  120 ++++++
>  include/linux/fsl_dprc.h           |  790 ++++++++++++++++++++++++++++++++++++
>  include/linux/fsl_mc_cmd.h         |  182 +++++++++
>  include/linux/fsl_mc_sys.h         |   81 ++++
>  9 files changed, 2635 insertions(+)
>  create mode 100644 drivers/bus/fsl-mc/dpmng.c
>  create mode 100644 drivers/bus/fsl-mc/dprc.c
>  create mode 100644 drivers/bus/fsl-mc/fsl_dpmng_cmd.h
>  create mode 100644 drivers/bus/fsl-mc/fsl_dprc_cmd.h
>  create mode 100644 drivers/bus/fsl-mc/fsl_mc_sys.c
>  create mode 100644 include/linux/fsl_dpmng.h
>  create mode 100644 include/linux/fsl_dprc.h
>  create mode 100644 include/linux/fsl_mc_cmd.h
>  create mode 100644 include/linux/fsl_mc_sys.h

the fsl prefix in the filename fsl_dpmng_cmd.h is redundant with
its directory name fsl-mc/.  Note that I find dashes ('-') in
filenames make them easier to type: is there a reason we're using
underscores here?

Also, any reason why these and future include files aren't being put
in include/linux/fsl/, so as to not pollute the top level
include/linux/?  That way, we can also remove the fsl- prefix from
those filenames, too..

> diff --git a/drivers/bus/fsl-mc/dpmng.c b/drivers/bus/fsl-mc/dpmng.c
> new file mode 100644
> index 0000000..c6ed27c
> --- /dev/null
> +++ b/drivers/bus/fsl-mc/dpmng.c
> @@ -0,0 +1,93 @@
> +/* Copyright 2013-2014 Freescale Semiconductor Inc.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are met:
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in the
> + *       documentation and/or other materials provided with the distribution.
> + *     * Neither the name of Freescale Semiconductor nor the
> + *       names of its contributors may be used to endorse or promote products
> + *       derived from this software without specific prior written permission.
> + *
> + *
> + * ALTERNATIVELY, this software may be distributed under the terms of the
> + * GNU General Public License ("GPL") as published by the Free Software
> + * Foundation, either version 2 of that License or (at your option) any
> + * later version.
> + *
> + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY

interesting, normally this text reads:

"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"

...does that mean we're excluding non-Freescale copyright holders
and contributors from this warranty statement?  That doesn't seem
appropriate for an upstream kernel submission.

> + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
> + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */

This dual BSD-3-clause/GPL license doesn't match that of patch 2's
drivers/bus/fsl-mc/fsl_mc_bus.c, GPLv2:

+/*
+ * Freescale Management Complex (MC) bus driver
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */

any reason the licenses are different?

> +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
> +{
> +	struct mc_command cmd = { 0 };

we can save some cycles if this initialization is not absolutely
necessary: is it?  i.e., does the h/w actually look at the params
section when doing a get_version?  not sure to what other commands
this comment would apply to...at least get_container_id, but maybe
more - all of them?

> diff --git a/drivers/bus/fsl-mc/fsl_mc_sys.c b/drivers/bus/fsl-mc/fsl_mc_sys.c

> +/**
> + * Map an MC portal in the kernel virtual address space
> + */
> +static int map_mc_portal(phys_addr_t mc_portal_phys_addr,
> +			 uint32_t mc_portal_size,
> +			 void __iomem **new_mc_portal_virt_addr)
> +{
> +	void __iomem *mc_portal_virt_addr = NULL;
> +	struct resource *res = NULL;
> +	int error = -EINVAL;
> +
> +	res =
> +	    request_mem_region(mc_portal_phys_addr, mc_portal_size,
> +			       "mc_portal");
> +	if (res == NULL) {
> +		pr_err("request_mem_region() failed for MC portal %#llx\n",
> +		       mc_portal_phys_addr);
> +		error = -EBUSY;
> +		goto error;
> +	}
> +
> +	mc_portal_virt_addr = ioremap_nocache(mc_portal_phys_addr,
> +					      mc_portal_size);
> +	if (mc_portal_virt_addr == NULL) {
> +		pr_err("ioremap_nocache() failed for MC portal %#llx\n",
> +		       mc_portal_phys_addr);
> +		error = -EFAULT;
> +		goto error;
> +	}
> +
> +	*new_mc_portal_virt_addr = mc_portal_virt_addr;
> +	return 0;
> +error:
> +	if (mc_portal_virt_addr != NULL)
> +		iounmap(mc_portal_virt_addr);
> +
> +	if (res != NULL)
> +		release_mem_region(mc_portal_phys_addr, mc_portal_size);
> +
> +	return error;
> +}

unnecessary initializations, bad error codes (both should be
-ENOMEM), unnecessarily complicated error path, plus a simpler
implementation can be made if fn can return the mapped address, like
so:

static void __iomem *map_mc_portal(phys_addr_t mc_portal_phys_addr,
                                   uint32_t mc_portal_size)
{ 
        struct resource *res;
        void __iomem *mapped_addr;

        res = request_mem_region(mc_portal_phys_addr, mc_portal_size, 
                                 "mc_portal");
        if (!res) 
                return NULL;

        mapped_addr = ioremap_nocache(mc_portal_phys_addr,
                                      mc_portal_size);
        if (!mapped_addr)
                release_mem_region(mc_portal_phys_addr, mc_portal_size);

        return mapped_addr;
}

the callsite can return -ENOMEM to its caller if returned NULL.  This
can be improved even further if devm_ functions are used:  this is
just an example of how to simplify the code using early returns
instead of goto error.

> +int __must_check fsl_create_mc_io(phys_addr_t mc_portal_phys_addr,
> +				  uint32_t mc_portal_size,
> +				  uint32_t flags, struct fsl_mc_io **new_mc_io)
> +{
> +	int error = -EINVAL;
> +	struct fsl_mc_io *mc_io = NULL;
> +
> +	mc_io = kzalloc(sizeof(*mc_io), GFP_KERNEL);
> +	if (mc_io == NULL) {
> +		error = -ENOMEM;
> +		pr_err("No memory to allocate mc_io\n");
> +		goto error;
> +	}
> +
> +	mc_io->magic = FSL_MC_IO_MAGIC;
> +	mc_io->flags = flags;
> +	mc_io->portal_phys_addr = mc_portal_phys_addr;
> +	mc_io->portal_size = mc_portal_size;
> +	spin_lock_init(&mc_io->spinlock);
> +	error = map_mc_portal(mc_portal_phys_addr,
> +			      mc_portal_size, &mc_io->portal_virt_addr);
> +	if (error < 0)
> +		goto error;
> +
> +	*new_mc_io = mc_io;
> +	return 0;

if a fn only returns an address or error, it can return ERR_PTR
(e.g., -ENOMEM), and the callsite use IS_ERR() to determine whether
there was an error or address returned.  This makes code much
simpler instead of passing address values back by reference.

> +error:
> +	if (mc_io != NULL) {
> +		if (mc_io->portal_virt_addr != NULL) {
> +			unmap_mc_portal(mc_portal_phys_addr,
> +					mc_portal_size,
> +					mc_io->portal_virt_addr);
> +		}
> +
> +		kfree(mc_io);

kfree can handle being passed NULL, but again, might want to
consider using devm_ functions instead.

> +	}
> +
> +	return error;
> +}
> +EXPORT_SYMBOL_GPL(fsl_create_mc_io);
> +
> +void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
> +{
> +	if (WARN_ON(mc_io->magic != FSL_MC_IO_MAGIC))
> +		return;
> +
> +	if (mc_io->portal_virt_addr != NULL) {
> +		unmap_mc_portal(mc_io->portal_phys_addr,
> +				mc_io->portal_size, mc_io->portal_virt_addr);

unmap_mc_portal already checks for virt_addr, this is another
example where the code goes too far checking for NULL.

> +		mc_io->portal_virt_addr = NULL;
> +	}
> +
> +	mc_io->magic = 0x0;
> +	kfree(mc_io);
> +}
> +EXPORT_SYMBOL_GPL(fsl_destroy_mc_io);
> +
> +static int mc_status_to_error(enum mc_cmd_status status)
> +{
> +	switch (status) {
> +	case MC_CMD_STATUS_OK:
> +		return 0;
> +	case MC_CMD_STATUS_AUTH_ERR:
> +		return -EACCES;
> +	case MC_CMD_STATUS_NO_PRIVILEGE:
> +		return -EPERM;
> +	case MC_CMD_STATUS_DMA_ERR:
> +		return -EIO;
> +	case MC_CMD_STATUS_CONFIG_ERR:
> +		return -EINVAL;
> +	case MC_CMD_STATUS_TIMEOUT:
> +		return -ETIMEDOUT;
> +	case MC_CMD_STATUS_NO_RESOURCE:
> +		return -ENAVAIL;
> +	case MC_CMD_STATUS_NO_MEMORY:
> +		return -ENOMEM;
> +	case MC_CMD_STATUS_BUSY:
> +		return -EBUSY;
> +	case MC_CMD_STATUS_UNSUPPORTED_OP:
> +		return -ENOTSUP;
> +	case MC_CMD_STATUS_INVALID_STATE:
> +		return -ENODEV;
> +	default:
> +		break;
> +	}
> +
> +	/* Not expected to reach here */
> +	return -EINVAL;

but if it does, callsite can't disambiguate between that and e.g.,
MC_CMD_STATUS_CONFIG_ERR.  Also, this would be more readable as a
static const lookup table.

> +}
> +
> +int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
> +{
> +	enum mc_cmd_status status;
> +	unsigned long irqsave_flags = 0;
> +	int error = -EINVAL;
> +	bool lock_acquired = false;
> +	unsigned long jiffies_until_timeout =
> +	    jiffies + MC_CMD_COMPLETION_TIMEOUT;
> +
> +	if (WARN_ON(mc_io->magic != FSL_MC_IO_MAGIC))
> +		goto out;

if the h/w signals an error on the bad magic condition, s/w doesn't
need to check it in its fast path.

> +	if (mc_io->flags & FSL_MC_IO_PORTAL_SHARED) {
> +		spin_lock_irqsave(&mc_io->spinlock, irqsave_flags);
> +		lock_acquired = true;
> +	}
> +
> +	mc_write_command(mc_io->portal_virt_addr, cmd);
> +
> +	for (;;) {
> +		status = mc_read_response(mc_io->portal_virt_addr, cmd);
> +		if (status != MC_CMD_STATUS_READY)
> +			break;
> +
> +		/*
> +		 * TODO: When MC command completion interrupts are supported
> +		 * call wait function here instead of udelay()
> +		 */
> +		udelay(MC_CMD_COMPLETION_POLLING_INTERVAL);
> +		if (time_after_eq(jiffies, jiffies_until_timeout)) {
> +			error = -ETIMEDOUT;
> +			goto out;
> +		}
> +	}
> +
> +	error = mc_status_to_error(status);
> +out:
> +	if (lock_acquired)
> +		spin_unlock_irqrestore(&mc_io->spinlock, irqsave_flags);

so if the portal is shared, we take a lock, disable interrupts, and
then potentially udelay for a whopping 500usec, then check to see if
_100_usec have passed, and thus _always_ issue a timeout error, even
if the device took < 100usec to consume the command???

Not to mention this code will spin perpetually with IRQs disabled if
the read_response never returns ready.  I also don't see a reason
why IRQs are being disabled in the first place - it's not being used
in an IRQ handler...perhaps we need to wait until command completion
IRQs are supported :)

> +/**
> + * @brief	Management Complex firmware version information
> + */
> +#define MC_VER_MAJOR 2
> +#define MC_VER_MINOR 0

code should be adjusted to run on all *compatible* versions of h/w,
not strictly the one set in these defines.

> +/**
> + * @brief	Disconnects one endpoint to remove its network link
> + *
> + * @param[in]   mc_io		Pointer to opaque I/O object
> + * @param[in]	dprc_handle	Handle to the DPRC object
> + * @param[in]   endpoint	Endpoint configuration parameters.
> + *
> + * @returns	'0' on Success; Error code otherwise.
> + * */
> +int dprc_disconnect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
> +		    struct dprc_endpoint *endpoint);
> +
> +/*! @} */

this entire file is riddled with non-kernel-doc comment markers:  see
Documentation/kernel-doc-nano-HOWTO.txt on how to write function and
other types of comments in a kernel-doc compliant format.

> +#ifdef FSL_MC_FIRMWARE
> +/*
> + * MC firmware decodes MC command parameters and encodes MC response parameters
> + */
> +
> +#define MC_CMD_PARAM_OP(_cmd, _param, _offset, _width, _type, _arg) \
> +	((_arg) = (_type)u64_dec((_cmd).params[_param], (_offset), (_width)))
> +
> +#define MC_RSP_PARAM_OP(_cmd, _param, _offset, _width, _type, _arg) \
> +	((_cmd).params[_param] |= u64_enc((_offset), (_width), (_type)(_arg)))
> +
> +#else
> +/*
> + * MC clients (GPP side) encode MC command parameters and decode MC response
> + * parameters
> + */
> +
> +#define MC_CMD_PARAM_OP(_cmd, _param, _offset, _width, _type, _arg) \
> +	((_cmd).params[_param] |= u64_enc((_offset), (_width), (_type)(_arg)))
> +
> +#define MC_RSP_PARAM_OP(_cmd, _param, _offset, _width, _type, _arg) \
> +	((_arg) = (_type)u64_dec((_cmd).params[_param], (_offset), (_width)))
> +
> +#endif /* FSL_MC_FIRMWARE */

FSL_MC_FIRMWARE isn't being defined anywhere; remove.

> diff --git a/include/linux/fsl_mc_sys.h b/include/linux/fsl_mc_sys.h
...
> +#ifndef ENOTSUP
> +#define ENOTSUP		95
> +#endif

This is already being defined as EOPNOTSUPP: either use that,
ENOTSUPP, or, if you can justify it, patch a more generic errno.h
as a separate patch, earlier in the patchseries.

> +#define ioread64(_p)	    readq(_p)
> +#define iowrite64(_v, _p)   writeq(_v, _p)

these definitions have names that are too generic to belong in a FSL
h/w header: conflicts will be introduced once the existing
io{read,write}32 functions get promoted.  Either use readq/writeq
directly, or, if you can justify it, patch a more generic io.h.

Also, is there a reason the 'relaxed' versions of the i/o accessors
aren't being used?

I'm stopping my review here, since I expect numerous changes in the
subsequent patches as a result of changes to this one in the next
version of the series.

Thanks,

Kim

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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-15 23:44   ` Kim Phillips
@ 2014-09-16  4:31     ` Scott Wood
  2014-09-16 19:28       ` Kim Phillips
  2014-09-18  4:17     ` German Rivera
  2014-09-18 23:39     ` Stuart Yoder
  2 siblings, 1 reply; 43+ messages in thread
From: Scott Wood @ 2014-09-16  4:31 UTC (permalink / raw)
  To: Kim Phillips
  Cc: J. German Rivera, gregkh, arnd, linux-kernel, stuart.yoder,
	agraf, linuxppc-release

On Mon, 2014-09-15 at 18:44 -0500, Kim Phillips wrote:
> On Thu, 11 Sep 2014 12:34:21 -0500
> "J. German Rivera" <German.Rivera@freescale.com> wrote:
> 
> > +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
> > +{
> > +	struct mc_command cmd = { 0 };
> 
> we can save some cycles if this initialization is not absolutely
> necessary: is it?  i.e., does the h/w actually look at the params
> section when doing a get_version?  not sure to what other commands
> this comment would apply to...at least get_container_id, but maybe
> more - all of them?

Do you really want to open that can of worms, much less to speed up
something that doesn't look performance critical?  Have fun debugging it
if it turns out the hardware does look at something you didn't
initialize.

> > diff --git a/drivers/bus/fsl-mc/fsl_mc_sys.c b/drivers/bus/fsl-mc/fsl_mc_sys.c
> 
> > +/**
> > + * Map an MC portal in the kernel virtual address space
> > + */
> > +static int map_mc_portal(phys_addr_t mc_portal_phys_addr,
> > +			 uint32_t mc_portal_size,
> > +			 void __iomem **new_mc_portal_virt_addr)
> > +{
> > +	void __iomem *mc_portal_virt_addr = NULL;
> > +	struct resource *res = NULL;
> > +	int error = -EINVAL;
> > +
> > +	res =
> > +	    request_mem_region(mc_portal_phys_addr, mc_portal_size,
> > +			       "mc_portal");
> > +	if (res == NULL) {
> > +		pr_err("request_mem_region() failed for MC portal %#llx\n",
> > +		       mc_portal_phys_addr);
> > +		error = -EBUSY;
> > +		goto error;
> > +	}
> > +
> > +	mc_portal_virt_addr = ioremap_nocache(mc_portal_phys_addr,
> > +					      mc_portal_size);
> > +	if (mc_portal_virt_addr == NULL) {
> > +		pr_err("ioremap_nocache() failed for MC portal %#llx\n",
> > +		       mc_portal_phys_addr);
> > +		error = -EFAULT;
> > +		goto error;
> > +	}
> > +
> > +	*new_mc_portal_virt_addr = mc_portal_virt_addr;
> > +	return 0;
> > +error:
> > +	if (mc_portal_virt_addr != NULL)
> > +		iounmap(mc_portal_virt_addr);
> > +
> > +	if (res != NULL)
> > +		release_mem_region(mc_portal_phys_addr, mc_portal_size);
> > +
> > +	return error;
> > +}
> 
> unnecessary initializations, bad error codes (both should be
> -ENOMEM),

Why should the first one be -ENOMEM?  It's not allocating memory, but
rather reserving I/O space.

>  unnecessarily complicated error path, plus a simpler
> implementation can be made if fn can return the mapped address, like
> so:
> 
> static void __iomem *map_mc_portal(phys_addr_t mc_portal_phys_addr,
>                                    uint32_t mc_portal_size)
> { 
>         struct resource *res;
>         void __iomem *mapped_addr;
> 
>         res = request_mem_region(mc_portal_phys_addr, mc_portal_size, 
>                                  "mc_portal");
>         if (!res) 
>                 return NULL;
> 
>         mapped_addr = ioremap_nocache(mc_portal_phys_addr,
>                                       mc_portal_size);
>         if (!mapped_addr)
>                 release_mem_region(mc_portal_phys_addr, mc_portal_size);
> 
>         return mapped_addr;
> }
> 
> the callsite can return -ENOMEM to its caller if returned NULL.

-ENOMEM would only be appropriate for one of these errors.

> > +#define ioread64(_p)	    readq(_p)
> > +#define iowrite64(_v, _p)   writeq(_v, _p)
> 
> these definitions have names that are too generic to belong in a FSL
> h/w header: conflicts will be introduced once the existing
> io{read,write}32 functions get promoted.  Either use readq/writeq
> directly, or, if you can justify it, patch a more generic io.h.
> 
> Also, is there a reason the 'relaxed' versions of the i/o accessors
> aren't being used?

Raw accessors should only be used in performance critical sections where
it's worth the effort to implement and verify manual synchronization.
My understanding is that the entire management complex is related to
setup, not on the I/O fast path.

-Scott



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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-16  4:31     ` Scott Wood
@ 2014-09-16 19:28       ` Kim Phillips
  2014-09-16 19:58         ` Scott Wood
  0 siblings, 1 reply; 43+ messages in thread
From: Kim Phillips @ 2014-09-16 19:28 UTC (permalink / raw)
  To: Scott Wood
  Cc: J. German Rivera, gregkh, arnd, linux-kernel, stuart.yoder,
	agraf, linuxppc-release

On Mon, 15 Sep 2014 23:31:21 -0500
Scott Wood <scottwood@freescale.com> wrote:

> On Mon, 2014-09-15 at 18:44 -0500, Kim Phillips wrote:
> > On Thu, 11 Sep 2014 12:34:21 -0500
> > "J. German Rivera" <German.Rivera@freescale.com> wrote:
> > 
> > > +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
> > > +{
> > > +	struct mc_command cmd = { 0 };
> > 
> > we can save some cycles if this initialization is not absolutely
> > necessary: is it?  i.e., does the h/w actually look at the params
> > section when doing a get_version?  not sure to what other commands
> > this comment would apply to...at least get_container_id, but maybe
> > more - all of them?
> 
> Do you really want to open that can of worms, much less to speed up
> something that doesn't look performance critical?  Have fun debugging it
> if it turns out the hardware does look at something you didn't
> initialize.

point taken.

> > > diff --git a/drivers/bus/fsl-mc/fsl_mc_sys.c b/drivers/bus/fsl-mc/fsl_mc_sys.c
> > 
> > > +/**
> > > + * Map an MC portal in the kernel virtual address space
> > > + */
> > > +static int map_mc_portal(phys_addr_t mc_portal_phys_addr,
> > > +			 uint32_t mc_portal_size,
> > > +			 void __iomem **new_mc_portal_virt_addr)
> > > +{
> > > +	void __iomem *mc_portal_virt_addr = NULL;
> > > +	struct resource *res = NULL;
> > > +	int error = -EINVAL;
> > > +
> > > +	res =
> > > +	    request_mem_region(mc_portal_phys_addr, mc_portal_size,
> > > +			       "mc_portal");
> > > +	if (res == NULL) {
> > > +		pr_err("request_mem_region() failed for MC portal %#llx\n",
> > > +		       mc_portal_phys_addr);
> > > +		error = -EBUSY;
> > > +		goto error;
> > > +	}
> > > +
> > > +	mc_portal_virt_addr = ioremap_nocache(mc_portal_phys_addr,
> > > +					      mc_portal_size);
> > > +	if (mc_portal_virt_addr == NULL) {
> > > +		pr_err("ioremap_nocache() failed for MC portal %#llx\n",
> > > +		       mc_portal_phys_addr);
> > > +		error = -EFAULT;
> > > +		goto error;
> > > +	}
> > > +
> > > +	*new_mc_portal_virt_addr = mc_portal_virt_addr;
> > > +	return 0;
> > > +error:
> > > +	if (mc_portal_virt_addr != NULL)
> > > +		iounmap(mc_portal_virt_addr);
> > > +
> > > +	if (res != NULL)
> > > +		release_mem_region(mc_portal_phys_addr, mc_portal_size);
> > > +
> > > +	return error;
> > > +}
> > 
> > unnecessary initializations, bad error codes (both should be
> > -ENOMEM),
> 
> Why should the first one be -ENOMEM?  It's not allocating memory, but
> rather reserving I/O space.

I was going with what most of the drivers are already doing, but I
see EFAULT is 'Bad address', which, you're right, is probably more
appropriate.

> >  unnecessarily complicated error path, plus a simpler
> > implementation can be made if fn can return the mapped address, like
> > so:
> > 
> > static void __iomem *map_mc_portal(phys_addr_t mc_portal_phys_addr,
> >                                    uint32_t mc_portal_size)
> > { 
> >         struct resource *res;
> >         void __iomem *mapped_addr;
> > 
> >         res = request_mem_region(mc_portal_phys_addr, mc_portal_size, 
> >                                  "mc_portal");
> >         if (!res) 
> >                 return NULL;
> > 
> >         mapped_addr = ioremap_nocache(mc_portal_phys_addr,
> >                                       mc_portal_size);
> >         if (!mapped_addr)
> >                 release_mem_region(mc_portal_phys_addr, mc_portal_size);
> > 
> >         return mapped_addr;
> > }
> > 
> > the callsite can return -ENOMEM to its caller if returned NULL.
> 
> -ENOMEM would only be appropriate for one of these errors.

in that case, ERR_PTR() can be used to return the specific error.

> > > +#define ioread64(_p)	    readq(_p)
> > > +#define iowrite64(_v, _p)   writeq(_v, _p)
> > 
> > these definitions have names that are too generic to belong in a FSL
> > h/w header: conflicts will be introduced once the existing
> > io{read,write}32 functions get promoted.  Either use readq/writeq
> > directly, or, if you can justify it, patch a more generic io.h.
> > 
> > Also, is there a reason the 'relaxed' versions of the i/o accessors
> > aren't being used?
> 
> Raw accessors should only be used in performance critical sections where
> it's worth the effort to implement and verify manual synchronization.
> My understanding is that the entire management complex is related to
> setup, not on the I/O fast path.

ok.

Thanks,

Kim

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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-16 19:28       ` Kim Phillips
@ 2014-09-16 19:58         ` Scott Wood
  0 siblings, 0 replies; 43+ messages in thread
From: Scott Wood @ 2014-09-16 19:58 UTC (permalink / raw)
  To: Kim Phillips
  Cc: J. German Rivera, gregkh, arnd, linux-kernel, stuart.yoder,
	agraf, linuxppc-release

On Tue, 2014-09-16 at 14:28 -0500, Kim Phillips wrote:
> On Mon, 15 Sep 2014 23:31:21 -0500
> Scott Wood <scottwood@freescale.com> wrote:
> 
> > On Mon, 2014-09-15 at 18:44 -0500, Kim Phillips wrote:
> > > On Thu, 11 Sep 2014 12:34:21 -0500
> > > "J. German Rivera" <German.Rivera@freescale.com> wrote:
> > > 
> > > > diff --git a/drivers/bus/fsl-mc/fsl_mc_sys.c b/drivers/bus/fsl-mc/fsl_mc_sys.c
> > > 
> > > > +/**
> > > > + * Map an MC portal in the kernel virtual address space
> > > > + */
> > > > +static int map_mc_portal(phys_addr_t mc_portal_phys_addr,
> > > > +			 uint32_t mc_portal_size,
> > > > +			 void __iomem **new_mc_portal_virt_addr)
> > > > +{
> > > > +	void __iomem *mc_portal_virt_addr = NULL;
> > > > +	struct resource *res = NULL;
> > > > +	int error = -EINVAL;
> > > > +
> > > > +	res =
> > > > +	    request_mem_region(mc_portal_phys_addr, mc_portal_size,
> > > > +			       "mc_portal");
> > > > +	if (res == NULL) {
> > > > +		pr_err("request_mem_region() failed for MC portal %#llx\n",
> > > > +		       mc_portal_phys_addr);
> > > > +		error = -EBUSY;
> > > > +		goto error;
> > > > +	}
> > > > +
> > > > +	mc_portal_virt_addr = ioremap_nocache(mc_portal_phys_addr,
> > > > +					      mc_portal_size);
> > > > +	if (mc_portal_virt_addr == NULL) {
> > > > +		pr_err("ioremap_nocache() failed for MC portal %#llx\n",
> > > > +		       mc_portal_phys_addr);
> > > > +		error = -EFAULT;
> > > > +		goto error;
> > > > +	}
> > > > +
> > > > +	*new_mc_portal_virt_addr = mc_portal_virt_addr;
> > > > +	return 0;
> > > > +error:
> > > > +	if (mc_portal_virt_addr != NULL)
> > > > +		iounmap(mc_portal_virt_addr);
> > > > +
> > > > +	if (res != NULL)
> > > > +		release_mem_region(mc_portal_phys_addr, mc_portal_size);
> > > > +
> > > > +	return error;
> > > > +}
> > > 
> > > unnecessary initializations, bad error codes (both should be
> > > -ENOMEM),
> > 
> > Why should the first one be -ENOMEM?  It's not allocating memory, but
> > rather reserving I/O space.
> 
> I was going with what most of the drivers are already doing, but I
> see EFAULT is 'Bad address', which, you're right, is probably more
> appropriate.

EFAULT is for userspace addresses that fault.

I don't see consistency on what other drivers use after
request_mem_region() -- some use ENOMEM, some ENODEV, some EBUSY... and
probably others.

I'd probably go with ENXIO or EBUSY.

-Scott



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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-11 18:45   ` Joe Perches
@ 2014-09-17 16:35     ` German Rivera
  0 siblings, 0 replies; 43+ messages in thread
From: German Rivera @ 2014-09-17 16:35 UTC (permalink / raw)
  To: Joe Perches
  Cc: gregkh, arnd, linux-kernel, stuart.yoder, Kim.Phillips,
	scottwood, agraf, linuxppc-release



On 09/11/2014 01:45 PM, Joe Perches wrote:
>
>> diff --git a/drivers/bus/fsl-mc/dpmng.c b/drivers/bus/fsl-mc/dpmng.c
> []
>> +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
>> +{
>> +	struct mc_command cmd = { 0 };
>> +	int err;
>> +
>> +	cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION,
>> +					  DPMNG_CMDSZ_GET_VERSION,
>> +					  MC_CMD_PRI_LOW, 0);
>> +
>> +	err = mc_send_command(mc_io, &cmd);
>> +	if (!err)
>> +		DPMNG_RSP_GET_VERSION(cmd, mc_ver_info);
>> +
>> +	return err;
>
> I think it better style to read when the
> failure case is handled immediately by
> a return or a "goto out" and the successful
> case code is at the same indent level
>
> 	err = mc_send_command_(etc...)
> 	if (err)
> 		return err;
>
> 	DPMNG_RSP_GET_VERSION(cmd, mc_ver_info);
>
> 	return 0;
> }
>
Ok, I'll change this as suggested in the next respin.

>> diff --git a/drivers/bus/fsl-mc/dprc.c b/drivers/bus/fsl-mc/dprc.c
>
>> +int dprc_get_container_id(struct fsl_mc_io *mc_io, int *container_id)
>> +{
>> +	struct mc_command cmd = { 0 };
>> +	int err;
>> +
>> +	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID,
>> +					  DPRC_CMDSZ_GET_CONT_ID,
>> +					  MC_CMD_PRI_LOW, 0);
>> +
>> +	err = mc_send_command(mc_io, &cmd);
>> +	if (!err)
>> +		DPRC_RSP_GET_CONTAINER_ID(cmd, *container_id);
>> +
>> +	return err;
>> +}
>
> Same sort of thing as above.
> Actively fail on err and proceed at the same indent
> level on success.
>
Yes, I'll change all occurrences of this.

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

* Re: [PATCH 2/4] drivers/bus: Freescale Management Complex (fsl-mc) bus driver
  2014-09-11 18:49   ` Joe Perches
@ 2014-09-17 23:50     ` German Rivera
  0 siblings, 0 replies; 43+ messages in thread
From: German Rivera @ 2014-09-17 23:50 UTC (permalink / raw)
  To: Joe Perches
  Cc: gregkh, arnd, linux-kernel, stuart.yoder, Kim.Phillips,
	scottwood, agraf, linuxppc-release


On 09/11/2014 01:49 PM, Joe Perches wrote:
>
>> +out:
>> +	pr_debug("%s: %s %s\n", __func__, dev_name(dev),
>> +		 found ? "matched" : "not matched");
>
> Thia should probably use dev_dbg
>
> 	dev_dbg(dev, "%smatched\n", found ? "" : "not ");
>
> and let the dynamic debug mechanism emit the
> function name if desired.
>
>
Ok, I'll make this change in the v2 respin

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

* Re: [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series
  2014-09-15 23:44 ` [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series Kim Phillips
@ 2014-09-18  0:20   ` German Rivera
  2014-09-18 12:58     ` Alexander Graf
  0 siblings, 1 reply; 43+ messages in thread
From: German Rivera @ 2014-09-18  0:20 UTC (permalink / raw)
  To: Kim Phillips
  Cc: gregkh, arnd, linux-kernel, stuart.yoder, scottwood, agraf,
	linuxppc-release

On 09/15/2014 06:44 PM, Kim Phillips wrote:
> On Thu, 11 Sep 2014 12:34:20 -0500
> "J. German Rivera" <German.Rivera@freescale.com> wrote:
>
>> This patch series introduces Linux support for the Freescale
>> Management Complex (fsl-mc) hardware.
>
> here are the results of using some tools to check this patchseries:
>
> make C=1 CF="-D__CHECK_ENDIAN__":
>
> drivers/bus/fsl-mc/fsl_mc_sys.c:235:9: warning: context imbalance in 'mc_send_command' - different lock contexts for basic block
> drivers/bus/fsl-mc/fsl_mc_dprc.c: In function 'dprc_add_new_devices':
> drivers/bus/fsl-mc/fsl_mc_dprc.c:173:6: warning: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type 'uint32_t' [-Wformat=]
>        region_desc.size);
>        ^
>
I'll fix this in v2 respin.

> When built as a module (CONFIG_FSL_MC_BUS=m):
>
> ERROR: ".dprc_get_obj" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
> ERROR: ".dprc_get_obj_count" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
> ERROR: ".dprc_close" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
> ERROR: ".dprc_open" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
> ERROR: ".dprc_get_obj_region" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
> make[1]: *** [__modpost] Error 1
> make: *** [modules] Error 2
>
I'll fix this in v2 respin.

> checkpatch:
>
> WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
>
> WARNING: DT compatible string "fsl,qoriq-mc" appears un-documented -- check ./Documentation/devicetree/bindings/
> #690: FILE: drivers/bus/fsl-mc/fsl_mc_bus.c:528:
> +	{.compatible = "fsl,qoriq-mc",},
>
> For the former warning, I'd suggest moving patch 4/4's contents up
> in the series.
>
I tried moving 4/4 to be 1/4 but still get the the same warning from 
checkpatch. So, this suggestion does not work. Besides, I took a look
at other commits that update the MAINTAINERS such as
563da3a90364fc29cd09bed034162592e591747a, and that commit comes after 
the commits that added the new files.

> For the latter warning, googling for the property shows an upstream
> effort, so it might be ok, but it'd be nice to provide a
> cross-reference to the status of the latest post, to make it easier
> for reviewer consumption.
>
> Also, I think you'd get more recipient coverage by using
> scripts/get_maintainer.pl.
>
> Thanks,
>
> Kim
>

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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-15 23:44   ` Kim Phillips
  2014-09-16  4:31     ` Scott Wood
@ 2014-09-18  4:17     ` German Rivera
  2014-09-18 13:14       ` Alexander Graf
  2014-09-18 23:39     ` Stuart Yoder
  2 siblings, 1 reply; 43+ messages in thread
From: German Rivera @ 2014-09-18  4:17 UTC (permalink / raw)
  To: Kim Phillips
  Cc: gregkh, arnd, linux-kernel, stuart.yoder, scottwood, agraf,
	linuxppc-release

On 09/15/2014 06:44 PM, Kim Phillips wrote:
> On Thu, 11 Sep 2014 12:34:21 -0500
> "J. German Rivera" <German.Rivera@freescale.com> wrote:
>
>> From: "J. German Rivera" <German.Rivera@freescale.com>
>>
>> APIs to access the Management Complex (MC) hardware
>> module of Freescale LS2 SoCs. This patch includes
>> APIs to check the MC firmware version and to manipulate
>> DPRC objects in the MC.
>>
>> Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
>> Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
>> ---
>>   drivers/bus/fsl-mc/dpmng.c         |   93 +++++
>>   drivers/bus/fsl-mc/dprc.c          |  504 +++++++++++++++++++++++
>>   drivers/bus/fsl-mc/fsl_dpmng_cmd.h |   83 ++++
>>   drivers/bus/fsl-mc/fsl_dprc_cmd.h  |  545 +++++++++++++++++++++++++
>>   drivers/bus/fsl-mc/fsl_mc_sys.c    |  237 +++++++++++
>>   include/linux/fsl_dpmng.h          |  120 ++++++
>>   include/linux/fsl_dprc.h           |  790 ++++++++++++++++++++++++++++++++++++
>>   include/linux/fsl_mc_cmd.h         |  182 +++++++++
>>   include/linux/fsl_mc_sys.h         |   81 ++++
>>   9 files changed, 2635 insertions(+)
>>   create mode 100644 drivers/bus/fsl-mc/dpmng.c
>>   create mode 100644 drivers/bus/fsl-mc/dprc.c
>>   create mode 100644 drivers/bus/fsl-mc/fsl_dpmng_cmd.h
>>   create mode 100644 drivers/bus/fsl-mc/fsl_dprc_cmd.h
>>   create mode 100644 drivers/bus/fsl-mc/fsl_mc_sys.c
>>   create mode 100644 include/linux/fsl_dpmng.h
>>   create mode 100644 include/linux/fsl_dprc.h
>>   create mode 100644 include/linux/fsl_mc_cmd.h
>>   create mode 100644 include/linux/fsl_mc_sys.h
>
> the fsl prefix in the filename fsl_dpmng_cmd.h is redundant with
> its directory name fsl-mc/.  Note that I find dashes ('-') in
> filenames make them easier to type: is there a reason we're using
> underscores here?
>
This is a convention that we decided early on '-' for directory names
and '_' for file names.

> Also, any reason why these and future include files aren't being put
> in include/linux/fsl/, so as to not pollute the top level
> include/linux/?  That way, we can also remove the fsl- prefix from
> those filenames, too..
>
I would like to receive opinions from others about this before making 
any change here.

>> diff --git a/drivers/bus/fsl-mc/dpmng.c b/drivers/bus/fsl-mc/dpmng.c
>> new file mode 100644
>> index 0000000..c6ed27c
>> --- /dev/null
>> +++ b/drivers/bus/fsl-mc/dpmng.c
>> @@ -0,0 +1,93 @@
>> +/* Copyright 2013-2014 Freescale Semiconductor Inc.
>> + *
>> + * Redistribution and use in source and binary forms, with or without
>> + * modification, are permitted provided that the following conditions are met:
>> + *     * Redistributions of source code must retain the above copyright
>> + *       notice, this list of conditions and the following disclaimer.
>> + *     * Redistributions in binary form must reproduce the above copyright
>> + *       notice, this list of conditions and the following disclaimer in the
>> + *       documentation and/or other materials provided with the distribution.
>> + *     * Neither the name of Freescale Semiconductor nor the
>> + *       names of its contributors may be used to endorse or promote products
>> + *       derived from this software without specific prior written permission.
>> + *
>> + *
>> + * ALTERNATIVELY, this software may be distributed under the terms of the
>> + * GNU General Public License ("GPL") as published by the Free Software
>> + * Foundation, either version 2 of that License or (at your option) any
>> + * later version.
>> + *
>> + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
>
> interesting, normally this text reads:
>
> "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"
>
> ...does that mean we're excluding non-Freescale copyright holders
> and contributors from this warranty statement?  That doesn't seem
> appropriate for an upstream kernel submission.
>
I would like to receive opinions from others about this before making 
any change here.

>> + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
>> + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>> + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
>> + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
>> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
>> + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
>> + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> + */
>
> This dual BSD-3-clause/GPL license doesn't match that of patch 2's
> drivers/bus/fsl-mc/fsl_mc_bus.c, GPLv2:
>
This is because the MC flib files in patch 1 can also be used in 
user-space code not just in the kernel. I will not make any change to 
the licenses of the MC flib files included in patch 1.

> +/*
> + * Freescale Management Complex (MC) bus driver
> + *
> + * Copyright (C) 2014 Freescale Semiconductor, Inc.
> + * Author: German Rivera <German.Rivera@freescale.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
>
> any reason the licenses are different?
>
Different teams wrote the files.

>> +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
>> +{
>> +	struct mc_command cmd = { 0 };
>
> we can save some cycles if this initialization is not absolutely
> necessary: is it?  i.e., does the h/w actually look at the params
> section when doing a get_version?  not sure to what other commands
> this comment would apply to...at least get_container_id, but maybe
> more - all of them?
>
I agree with the response from Scott Wood. I will not change this.

>> diff --git a/drivers/bus/fsl-mc/fsl_mc_sys.c b/drivers/bus/fsl-mc/fsl_mc_sys.c
>
>> +/**
>> + * Map an MC portal in the kernel virtual address space
>> + */
>> +static int map_mc_portal(phys_addr_t mc_portal_phys_addr,
>> +			 uint32_t mc_portal_size,
>> +			 void __iomem **new_mc_portal_virt_addr)
>> +{
>> +	void __iomem *mc_portal_virt_addr = NULL;
>> +	struct resource *res = NULL;
>> +	int error = -EINVAL;
>> +
>> +	res =
>> +	    request_mem_region(mc_portal_phys_addr, mc_portal_size,
>> +			       "mc_portal");
>> +	if (res == NULL) {
>> +		pr_err("request_mem_region() failed for MC portal %#llx\n",
>> +		       mc_portal_phys_addr);
>> +		error = -EBUSY;
>> +		goto error;
>> +	}
>> +
>> +	mc_portal_virt_addr = ioremap_nocache(mc_portal_phys_addr,
>> +					      mc_portal_size);
>> +	if (mc_portal_virt_addr == NULL) {
>> +		pr_err("ioremap_nocache() failed for MC portal %#llx\n",
>> +		       mc_portal_phys_addr);
>> +		error = -EFAULT;
>> +		goto error;
>> +	}
>> +
>> +	*new_mc_portal_virt_addr = mc_portal_virt_addr;
>> +	return 0;
>> +error:
>> +	if (mc_portal_virt_addr != NULL)
>> +		iounmap(mc_portal_virt_addr);
>> +
>> +	if (res != NULL)
>> +		release_mem_region(mc_portal_phys_addr, mc_portal_size);
>> +
>> +	return error;
>> +}
>
> unnecessary initializations, bad error codes (both should be
> -ENOMEM),
 >
I disagree, the ioremap_nocache() failure should not be treated
as ENOMEM. As Scott Wood suggested, I'll change the EFAULT error
to ENXIO error.

unnecessarily complicated error path, plus a simpler
> implementation can be made if fn can return the mapped address, like
> so:
>
> static void __iomem *map_mc_portal(phys_addr_t mc_portal_phys_addr,
>                                     uint32_t mc_portal_size)
> {
>          struct resource *res;
>          void __iomem *mapped_addr;
>
>          res = request_mem_region(mc_portal_phys_addr, mc_portal_size,
>                                   "mc_portal");
>          if (!res)
>                  return NULL;
>
>          mapped_addr = ioremap_nocache(mc_portal_phys_addr,
>                                        mc_portal_size);
>          if (!mapped_addr)
>                  release_mem_region(mc_portal_phys_addr, mc_portal_size);
>
>          return mapped_addr;
> }
>
> the callsite can return -ENOMEM to its caller if returned NULL.  This
> can be improved even further if devm_ functions are used:  this is
> just an example of how to simplify the code using early returns
> instead of goto error.

I disagree. Having a common error return point is more maintainable than 
having multiple returns as having the clean-up logic in one place is 
more maintainable and makes the min path (non-error) more readable.

>
>> +int __must_check fsl_create_mc_io(phys_addr_t mc_portal_phys_addr,
>> +				  uint32_t mc_portal_size,
>> +				  uint32_t flags, struct fsl_mc_io **new_mc_io)
>> +{
>> +	int error = -EINVAL;
>> +	struct fsl_mc_io *mc_io = NULL;
>> +
>> +	mc_io = kzalloc(sizeof(*mc_io), GFP_KERNEL);
>> +	if (mc_io == NULL) {
>> +		error = -ENOMEM;
>> +		pr_err("No memory to allocate mc_io\n");
>> +		goto error;
>> +	}
>> +
>> +	mc_io->magic = FSL_MC_IO_MAGIC;
>> +	mc_io->flags = flags;
>> +	mc_io->portal_phys_addr = mc_portal_phys_addr;
>> +	mc_io->portal_size = mc_portal_size;
>> +	spin_lock_init(&mc_io->spinlock);
>> +	error = map_mc_portal(mc_portal_phys_addr,
>> +			      mc_portal_size, &mc_io->portal_virt_addr);
>> +	if (error < 0)
>> +		goto error;
>> +
>> +	*new_mc_io = mc_io;
>> +	return 0;
>
> if a fn only returns an address or error, it can return ERR_PTR
> (e.g., -ENOMEM), and the callsite use IS_ERR() to determine whether
> there was an error or address returned.  This makes code much
> simpler instead of passing address values back by reference.
>
I disagree. I don't see why the alternative you suggest makes the code 
"much simpler".

>> +error:
>> +	if (mc_io != NULL) {
>> +		if (mc_io->portal_virt_addr != NULL) {
>> +			unmap_mc_portal(mc_portal_phys_addr,
>> +					mc_portal_size,
>> +					mc_io->portal_virt_addr);
>> +		}
>> +
>> +		kfree(mc_io);
>
> kfree can handle being passed NULL, but again, might want to
> consider using devm_ functions instead.
>
No. We cannot use devm_ functions here as there is no device passed in.

>> +	}
>> +
>> +	return error;
>> +}
>> +EXPORT_SYMBOL_GPL(fsl_create_mc_io);
>> +
>> +void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
>> +{
>> +	if (WARN_ON(mc_io->magic != FSL_MC_IO_MAGIC))
>> +		return;
>> +
>> +	if (mc_io->portal_virt_addr != NULL) {
>> +		unmap_mc_portal(mc_io->portal_phys_addr,
>> +				mc_io->portal_size, mc_io->portal_virt_addr);
>
> unmap_mc_portal already checks for virt_addr, this is another
> example where the code goes too far checking for NULL.
>
I disagree. Having the extra check is harmless and more importantly 
makes the intent explicit that we should only call unmap_mc_portal if we 
called map_mc_portal earlier.

>> +		mc_io->portal_virt_addr = NULL;
>> +	}
>> +
>> +	mc_io->magic = 0x0;
>> +	kfree(mc_io);
>> +}
>> +EXPORT_SYMBOL_GPL(fsl_destroy_mc_io);
>> +
>> +static int mc_status_to_error(enum mc_cmd_status status)
>> +{
>> +	switch (status) {
>> +	case MC_CMD_STATUS_OK:
>> +		return 0;
>> +	case MC_CMD_STATUS_AUTH_ERR:
>> +		return -EACCES;
>> +	case MC_CMD_STATUS_NO_PRIVILEGE:
>> +		return -EPERM;
>> +	case MC_CMD_STATUS_DMA_ERR:
>> +		return -EIO;
>> +	case MC_CMD_STATUS_CONFIG_ERR:
>> +		return -EINVAL;
>> +	case MC_CMD_STATUS_TIMEOUT:
>> +		return -ETIMEDOUT;
>> +	case MC_CMD_STATUS_NO_RESOURCE:
>> +		return -ENAVAIL;
>> +	case MC_CMD_STATUS_NO_MEMORY:
>> +		return -ENOMEM;
>> +	case MC_CMD_STATUS_BUSY:
>> +		return -EBUSY;
>> +	case MC_CMD_STATUS_UNSUPPORTED_OP:
>> +		return -ENOTSUP;
>> +	case MC_CMD_STATUS_INVALID_STATE:
>> +		return -ENODEV;
>> +	default:
>> +		break;
>> +	}
>> +
>> +	/* Not expected to reach here */
>> +	return -EINVAL;
>
> but if it does, callsite can't disambiguate between that and e.g.,
> MC_CMD_STATUS_CONFIG_ERR.  Also, this would be more readable as a
> static const lookup table.
I will change the switch to a lookup table and fix the -EINVAL
ambiguity in the v2 respin.

>
>> +}
>> +
>> +int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
>> +{
>> +	enum mc_cmd_status status;
>> +	unsigned long irqsave_flags = 0;
>> +	int error = -EINVAL;
>> +	bool lock_acquired = false;
>> +	unsigned long jiffies_until_timeout =
>> +	    jiffies + MC_CMD_COMPLETION_TIMEOUT;
>> +
>> +	if (WARN_ON(mc_io->magic != FSL_MC_IO_MAGIC))
>> +		goto out;
>
> if the h/w signals an error on the bad magic condition, s/w doesn't
> need to check it in its fast path.
>
As per comments from Arnd Bergmann on the RFC patch series, I removed 
the magic field from all structs. I just forgot to do it for this one.
I will remove this magic field in the v2 respin.

>> +	if (mc_io->flags & FSL_MC_IO_PORTAL_SHARED) {
>> +		spin_lock_irqsave(&mc_io->spinlock, irqsave_flags);
>> +		lock_acquired = true;
>> +	}
>> +
>> +	mc_write_command(mc_io->portal_virt_addr, cmd);
>> +
>> +	for (;;) {
>> +		status = mc_read_response(mc_io->portal_virt_addr, cmd);
>> +		if (status != MC_CMD_STATUS_READY)
>> +			break;
>> +
>> +		/*
>> +		 * TODO: When MC command completion interrupts are supported
>> +		 * call wait function here instead of udelay()
>> +		 */
>> +		udelay(MC_CMD_COMPLETION_POLLING_INTERVAL);
>> +		if (time_after_eq(jiffies, jiffies_until_timeout)) {
>> +			error = -ETIMEDOUT;
>> +			goto out;
>> +		}
>> +	}
>> +
>> +	error = mc_status_to_error(status);
>> +out:
>> +	if (lock_acquired)
>> +		spin_unlock_irqrestore(&mc_io->spinlock, irqsave_flags);
>
> so if the portal is shared, we take a lock, disable interrupts, and
> then potentially udelay for a whopping 500usec, then check to see if
> _100_usec have passed, and thus _always_ issue a timeout error, even
> if the device took < 100usec to consume the command???
>
That is not true. The 100 is in jiffies not in usec:

/**
  * Timeout in jiffies to wait for the completion of an MC command
  */
#define MC_CMD_COMPLETION_TIMEOUT   100

/**
  * Delay in microseconds between polling iterations while
  * waiting for MC command completion
  */
#define MC_CMD_COMPLETION_POLLING_INTERVAL  500


> Not to mention this code will spin perpetually with IRQs disabled if
> the read_response never returns ready.  I also don't see a reason
> why IRQs are being disabled in the first place - it's not being used
> in an IRQ handler...perhaps we need to wait until command completion
> IRQs are supported :)
>
I agree that disabling interrupts while doing polling is not efficient. 
I was assuming the worst case scenario of sharing the portal: both
threads and interrupt handlers accessing the same portal at the same 
time. If only threads access the same portal, we don't need to disable 
interrupts and even further we can use a mutex instead of a spinlock.
If only interrupt handlers access a given portal (from multiple CPUs)
we have use a spinlock but we don't need to disabel interrupts.
If both threads and interrupt handlers access a given portal, then
we need to both use a spinlock and disable interrupts

I will change synchronization logic in the v2 respin to avoid
disabling interrupts in the first two cases above.

>> +/**
>> + * @brief	Management Complex firmware version information
>> + */
>> +#define MC_VER_MAJOR 2
>> +#define MC_VER_MINOR 0
>
> code should be adjusted to run on all *compatible* versions of h/w,
> not strictly the one set in these defines.
>
This comment is not precise enough be actionable.
What exactly you want to be changed  here?

>> +/**
>> + * @brief	Disconnects one endpoint to remove its network link
>> + *
>> + * @param[in]   mc_io		Pointer to opaque I/O object
>> + * @param[in]	dprc_handle	Handle to the DPRC object
>> + * @param[in]   endpoint	Endpoint configuration parameters.
>> + *
>> + * @returns	'0' on Success; Error code otherwise.
>> + * */
>> +int dprc_disconnect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
>> +		    struct dprc_endpoint *endpoint);
>> +
>> +/*! @} */
>
> this entire file is riddled with non-kernel-doc comment markers:  see
> Documentation/kernel-doc-nano-HOWTO.txt on how to write function and
> other types of comments in a kernel-doc compliant format.
>
This is because this file is using doxygen comments, as it was developed
by another team. Unless someone else has an objection, I will leave the 
doxygen comments alone and not make any change here.

>> +#ifdef FSL_MC_FIRMWARE
>> +/*
>> + * MC firmware decodes MC command parameters and encodes MC response parameters
>> + */
>> +
>> +#define MC_CMD_PARAM_OP(_cmd, _param, _offset, _width, _type, _arg) \
>> +	((_arg) = (_type)u64_dec((_cmd).params[_param], (_offset), (_width)))
>> +
>> +#define MC_RSP_PARAM_OP(_cmd, _param, _offset, _width, _type, _arg) \
>> +	((_cmd).params[_param] |= u64_enc((_offset), (_width), (_type)(_arg)))
>> +
>> +#else
>> +/*
>> + * MC clients (GPP side) encode MC command parameters and decode MC response
>> + * parameters
>> + */
>> +
>> +#define MC_CMD_PARAM_OP(_cmd, _param, _offset, _width, _type, _arg) \
>> +	((_cmd).params[_param] |= u64_enc((_offset), (_width), (_type)(_arg)))
>> +
>> +#define MC_RSP_PARAM_OP(_cmd, _param, _offset, _width, _type, _arg) \
>> +	((_arg) = (_type)u64_dec((_cmd).params[_param], (_offset), (_width)))
>> +
>> +#endif /* FSL_MC_FIRMWARE */
>
> FSL_MC_FIRMWARE isn't being defined anywhere; remove.
>
I will remove the FSL_MC_FIRMWARE #ifdef in the v2 respin.

>> diff --git a/include/linux/fsl_mc_sys.h b/include/linux/fsl_mc_sys.h
> ...
>> +#ifndef ENOTSUP
>> +#define ENOTSUP		95
>> +#endif
>
> This is already being defined as EOPNOTSUPP: either use that,
> ENOTSUPP, or, if you can justify it, patch a more generic errno.h
> as a separate patch, earlier in the patchseries.
>
I will remove ENOTSUP and use ENOTSUPP instead.

>> +#define ioread64(_p)	    readq(_p)
>> +#define iowrite64(_v, _p)   writeq(_v, _p)
>
> these definitions have names that are too generic to belong in a FSL
> h/w header: conflicts will be introduced once the existing
> io{read,write}32 functions get promoted.  Either use readq/writeq
> directly, or, if you can justify it, patch a more generic io.h.
>
I will remove ioread64() and iowrite64() and use readq() and writeq() 
directly instead.

> Also, is there a reason the 'relaxed' versions of the i/o accessors
> aren't being used?
>
Scott Wood responded to this already.

> I'm stopping my review here, since I expect numerous changes in the
> subsequent patches as a result of changes to this one in the next
> version of the series.
>
> Thanks,
>
> Kim
>

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

* Re: [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series
  2014-09-18  0:20   ` German Rivera
@ 2014-09-18 12:58     ` Alexander Graf
  2014-09-19  0:31       ` German Rivera
  0 siblings, 1 reply; 43+ messages in thread
From: Alexander Graf @ 2014-09-18 12:58 UTC (permalink / raw)
  To: German Rivera
  Cc: Kim Phillips, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	<stuart.yoder@freescale.com>,
	<scottwood@freescale.com>,
	<linuxppc-release@linux.freescale.net>



> Am 18.09.2014 um 02:20 schrieb German Rivera <German.Rivera@freescale.com>:
> 
>> On 09/15/2014 06:44 PM, Kim Phillips wrote:
>> On Thu, 11 Sep 2014 12:34:20 -0500
>> "J. German Rivera" <German.Rivera@freescale.com> wrote:
>> 
>>> This patch series introduces Linux support for the Freescale
>>> Management Complex (fsl-mc) hardware.
>> 
>> here are the results of using some tools to check this patchseries:
>> 
>> make C=1 CF="-D__CHECK_ENDIAN__":
>> 
>> drivers/bus/fsl-mc/fsl_mc_sys.c:235:9: warning: context imbalance in 'mc_send_command' - different lock contexts for basic block
>> drivers/bus/fsl-mc/fsl_mc_dprc.c: In function 'dprc_add_new_devices':
>> drivers/bus/fsl-mc/fsl_mc_dprc.c:173:6: warning: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type 'uint32_t' [-Wformat=]
>>       region_desc.size);
>>       ^
> I'll fix this in v2 respin.
> 
>> When built as a module (CONFIG_FSL_MC_BUS=m):
>> 
>> ERROR: ".dprc_get_obj" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
>> ERROR: ".dprc_get_obj_count" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
>> ERROR: ".dprc_close" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
>> ERROR: ".dprc_open" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
>> ERROR: ".dprc_get_obj_region" [drivers/bus/fsl-mc/fsl_mc_dprc.ko] undefined!
>> make[1]: *** [__modpost] Error 1
>> make: *** [modules] Error 2
> I'll fix this in v2 respin.
> 
>> checkpatch:
>> 
>> WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
>> 
>> WARNING: DT compatible string "fsl,qoriq-mc" appears un-documented -- check ./Documentation/devicetree/bindings/
>> #690: FILE: drivers/bus/fsl-mc/fsl_mc_bus.c:528:
>> +    {.compatible = "fsl,qoriq-mc",},
>> 
>> For the former warning, I'd suggest moving patch 4/4's contents up
>> in the series.
> I tried moving 4/4 to be 1/4 but still get the the same warning from checkpatch. So, this suggestion does not work. Besides, I took a look
> at other commits that update the MAINTAINERS such as
> 563da3a90364fc29cd09bed034162592e591747a, and that commit comes after the commits that added the new files.

The alternative would be to add MAINTAINERS entries for the files you add in the patch that adds the files.


Alex


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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-18  4:17     ` German Rivera
@ 2014-09-18 13:14       ` Alexander Graf
  2014-09-18 20:22         ` Kim Phillips
                           ` (3 more replies)
  0 siblings, 4 replies; 43+ messages in thread
From: Alexander Graf @ 2014-09-18 13:14 UTC (permalink / raw)
  To: German Rivera
  Cc: Kim Phillips, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	<stuart.yoder@freescale.com>,
	<scottwood@freescale.com>,
	<linuxppc-release@linux.freescale.net>



> Am 18.09.2014 um 06:17 schrieb German Rivera <German.Rivera@freescale.com>:
> 
>> On 09/15/2014 06:44 PM, Kim Phillips wrote:
>> On Thu, 11 Sep 2014 12:34:21 -0500
>> "J. German Rivera" <German.Rivera@freescale.com> wrote:
>> 
>>> From: "J. German Rivera" <German.Rivera@freescale.com>
>>> 
>>> APIs to access the Management Complex (MC) hardware
>>> module of Freescale LS2 SoCs. This patch includes
>>> APIs to check the MC firmware version and to manipulate
>>> DPRC objects in the MC.
>>> 
>>> Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
>>> Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
>>> ---
>>>  drivers/bus/fsl-mc/dpmng.c         |   93 +++++
>>>  drivers/bus/fsl-mc/dprc.c          |  504 +++++++++++++++++++++++
>>>  drivers/bus/fsl-mc/fsl_dpmng_cmd.h |   83 ++++
>>>  drivers/bus/fsl-mc/fsl_dprc_cmd.h  |  545 +++++++++++++++++++++++++
>>>  drivers/bus/fsl-mc/fsl_mc_sys.c    |  237 +++++++++++
>>>  include/linux/fsl_dpmng.h          |  120 ++++++
>>>  include/linux/fsl_dprc.h           |  790 ++++++++++++++++++++++++++++++++++++
>>>  include/linux/fsl_mc_cmd.h         |  182 +++++++++
>>>  include/linux/fsl_mc_sys.h         |   81 ++++
>>>  9 files changed, 2635 insertions(+)
>>>  create mode 100644 drivers/bus/fsl-mc/dpmng.c
>>>  create mode 100644 drivers/bus/fsl-mc/dprc.c
>>>  create mode 100644 drivers/bus/fsl-mc/fsl_dpmng_cmd.h
>>>  create mode 100644 drivers/bus/fsl-mc/fsl_dprc_cmd.h
>>>  create mode 100644 drivers/bus/fsl-mc/fsl_mc_sys.c
>>>  create mode 100644 include/linux/fsl_dpmng.h
>>>  create mode 100644 include/linux/fsl_dprc.h
>>>  create mode 100644 include/linux/fsl_mc_cmd.h
>>>  create mode 100644 include/linux/fsl_mc_sys.h
>> 
>> the fsl prefix in the filename fsl_dpmng_cmd.h is redundant with
>> its directory name fsl-mc/.  Note that I find dashes ('-') in
>> filenames make them easier to type: is there a reason we're using
>> underscores here?
> This is a convention that we decided early on '-' for directory names
> and '_' for file names.
> 
>> Also, any reason why these and future include files aren't being put
>> in include/linux/fsl/, so as to not pollute the top level
>> include/linux/?  That way, we can also remove the fsl- prefix from
>> those filenames, too..
> I would like to receive opinions from others about this before making any change here.
> 
>>> diff --git a/drivers/bus/fsl-mc/dpmng.c b/drivers/bus/fsl-mc/dpmng.c
>>> new file mode 100644
>>> index 0000000..c6ed27c
>>> --- /dev/null
>>> +++ b/drivers/bus/fsl-mc/dpmng.c
>>> @@ -0,0 +1,93 @@
>>> +/* Copyright 2013-2014 Freescale Semiconductor Inc.
>>> + *
>>> + * Redistribution and use in source and binary forms, with or without
>>> + * modification, are permitted provided that the following conditions are met:
>>> + *     * Redistributions of source code must retain the above copyright
>>> + *       notice, this list of conditions and the following disclaimer.
>>> + *     * Redistributions in binary form must reproduce the above copyright
>>> + *       notice, this list of conditions and the following disclaimer in the
>>> + *       documentation and/or other materials provided with the distribution.
>>> + *     * Neither the name of Freescale Semiconductor nor the
>>> + *       names of its contributors may be used to endorse or promote products
>>> + *       derived from this software without specific prior written permission.
>>> + *
>>> + *
>>> + * ALTERNATIVELY, this software may be distributed under the terms of the
>>> + * GNU General Public License ("GPL") as published by the Free Software
>>> + * Foundation, either version 2 of that License or (at your option) any
>>> + * later version.
>>> + *
>>> + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
>> 
>> interesting, normally this text reads:
>> 
>> "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"
>> 
>> ...does that mean we're excluding non-Freescale copyright holders
>> and contributors from this warranty statement?  That doesn't seem
>> appropriate for an upstream kernel submission.
> I would like to receive opinions from others about this before making any change here.

IANAL, but I would prefer to have this identical to the rest of Linux to be on the safe side.

> 
>>> + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
>>> + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>>> + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
>>> + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
>>> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
>>> + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>>> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>>> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
>>> + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>>> + */
>> 
>> This dual BSD-3-clause/GPL license doesn't match that of patch 2's
>> drivers/bus/fsl-mc/fsl_mc_bus.c, GPLv2:
> This is because the MC flib files in patch 1 can also be used in user-space code not just in the kernel. I will not make any change to the licenses of the MC flib files included in patch 1.
> 
>> +/*
>> + * Freescale Management Complex (MC) bus driver
>> + *
>> + * Copyright (C) 2014 Freescale Semiconductor, Inc.
>> + * Author: German Rivera <German.Rivera@freescale.com>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2. This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> 
>> any reason the licenses are different?
> Different teams wrote the files.
> 
>>> +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
>>> +{
>>> +    struct mc_command cmd = { 0 };
>> 
>> we can save some cycles if this initialization is not absolutely
>> necessary: is it?  i.e., does the h/w actually look at the params
>> section when doing a get_version?  not sure to what other commands
>> this comment would apply to...at least get_container_id, but maybe
>> more - all of them?
> I agree with the response from Scott Wood. I will not change this.
> 
>>> diff --git a/drivers/bus/fsl-mc/fsl_mc_sys.c b/drivers/bus/fsl-mc/fsl_mc_sys.c
>> 
>>> +/**
>>> + * Map an MC portal in the kernel virtual address space
>>> + */
>>> +static int map_mc_portal(phys_addr_t mc_portal_phys_addr,
>>> +             uint32_t mc_portal_size,
>>> +             void __iomem **new_mc_portal_virt_addr)
>>> +{
>>> +    void __iomem *mc_portal_virt_addr = NULL;
>>> +    struct resource *res = NULL;
>>> +    int error = -EINVAL;
>>> +
>>> +    res =
>>> +        request_mem_region(mc_portal_phys_addr, mc_portal_size,
>>> +                   "mc_portal");
>>> +    if (res == NULL) {
>>> +        pr_err("request_mem_region() failed for MC portal %#llx\n",
>>> +               mc_portal_phys_addr);
>>> +        error = -EBUSY;
>>> +        goto error;
>>> +    }
>>> +
>>> +    mc_portal_virt_addr = ioremap_nocache(mc_portal_phys_addr,
>>> +                          mc_portal_size);
>>> +    if (mc_portal_virt_addr == NULL) {
>>> +        pr_err("ioremap_nocache() failed for MC portal %#llx\n",
>>> +               mc_portal_phys_addr);
>>> +        error = -EFAULT;
>>> +        goto error;
>>> +    }
>>> +
>>> +    *new_mc_portal_virt_addr = mc_portal_virt_addr;
>>> +    return 0;
>>> +error:
>>> +    if (mc_portal_virt_addr != NULL)
>>> +        iounmap(mc_portal_virt_addr);
>>> +
>>> +    if (res != NULL)
>>> +        release_mem_region(mc_portal_phys_addr, mc_portal_size);
>>> +
>>> +    return error;
>>> +}
>> 
>> unnecessary initializations, bad error codes (both should be
>> -ENOMEM),
> >
> I disagree, the ioremap_nocache() failure should not be treated
> as ENOMEM. As Scott Wood suggested, I'll change the EFAULT error
> to ENXIO error.
> 
> unnecessarily complicated error path, plus a simpler
>> implementation can be made if fn can return the mapped address, like
>> so:
>> 
>> static void __iomem *map_mc_portal(phys_addr_t mc_portal_phys_addr,
>>                                    uint32_t mc_portal_size)
>> {
>>         struct resource *res;
>>         void __iomem *mapped_addr;
>> 
>>         res = request_mem_region(mc_portal_phys_addr, mc_portal_size,
>>                                  "mc_portal");
>>         if (!res)
>>                 return NULL;
>> 
>>         mapped_addr = ioremap_nocache(mc_portal_phys_addr,
>>                                       mc_portal_size);
>>         if (!mapped_addr)
>>                 release_mem_region(mc_portal_phys_addr, mc_portal_size);
>> 
>>         return mapped_addr;
>> }
>> 
>> the callsite can return -ENOMEM to its caller if returned NULL.  This
>> can be improved even further if devm_ functions are used:  this is
>> just an example of how to simplify the code using early returns
>> instead of goto error.
> 
> I disagree. Having a common error return point is more maintainable than having multiple returns as having the clean-up logic in one place is more maintainable and makes the min path (non-error) more readable.
> 
>> 
>>> +int __must_check fsl_create_mc_io(phys_addr_t mc_portal_phys_addr,
>>> +                  uint32_t mc_portal_size,
>>> +                  uint32_t flags, struct fsl_mc_io **new_mc_io)
>>> +{
>>> +    int error = -EINVAL;
>>> +    struct fsl_mc_io *mc_io = NULL;
>>> +
>>> +    mc_io = kzalloc(sizeof(*mc_io), GFP_KERNEL);
>>> +    if (mc_io == NULL) {
>>> +        error = -ENOMEM;
>>> +        pr_err("No memory to allocate mc_io\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    mc_io->magic = FSL_MC_IO_MAGIC;
>>> +    mc_io->flags = flags;
>>> +    mc_io->portal_phys_addr = mc_portal_phys_addr;
>>> +    mc_io->portal_size = mc_portal_size;
>>> +    spin_lock_init(&mc_io->spinlock);
>>> +    error = map_mc_portal(mc_portal_phys_addr,
>>> +                  mc_portal_size, &mc_io->portal_virt_addr);
>>> +    if (error < 0)
>>> +        goto error;
>>> +
>>> +    *new_mc_io = mc_io;
>>> +    return 0;
>> 
>> if a fn only returns an address or error, it can return ERR_PTR
>> (e.g., -ENOMEM), and the callsite use IS_ERR() to determine whether
>> there was an error or address returned.  This makes code much
>> simpler instead of passing address values back by reference.
> I disagree. I don't see why the alternative you suggest makes the code "much simpler".
> 
>>> +error:
>>> +    if (mc_io != NULL) {
>>> +        if (mc_io->portal_virt_addr != NULL) {
>>> +            unmap_mc_portal(mc_portal_phys_addr,
>>> +                    mc_portal_size,
>>> +                    mc_io->portal_virt_addr);
>>> +        }
>>> +
>>> +        kfree(mc_io);
>> 
>> kfree can handle being passed NULL, but again, might want to
>> consider using devm_ functions instead.
> No. We cannot use devm_ functions here as there is no device passed in.

Is it a good idea to lose your device context in any function? Whenever I dropped contexts in helper I usually ended up regretting it later ;).

> 
>>> +    }
>>> +
>>> +    return error;
>>> +}
>>> +EXPORT_SYMBOL_GPL(fsl_create_mc_io);
>>> +
>>> +void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
>>> +{
>>> +    if (WARN_ON(mc_io->magic != FSL_MC_IO_MAGIC))
>>> +        return;
>>> +
>>> +    if (mc_io->portal_virt_addr != NULL) {
>>> +        unmap_mc_portal(mc_io->portal_phys_addr,
>>> +                mc_io->portal_size, mc_io->portal_virt_addr);
>> 
>> unmap_mc_portal already checks for virt_addr, this is another
>> example where the code goes too far checking for NULL.
> I disagree. Having the extra check is harmless and more importantly makes the intent explicit that we should only call unmap_mc_portal if we called map_mc_portal earlier.
> 
>>> +        mc_io->portal_virt_addr = NULL;
>>> +    }
>>> +
>>> +    mc_io->magic = 0x0;
>>> +    kfree(mc_io);
>>> +}
>>> +EXPORT_SYMBOL_GPL(fsl_destroy_mc_io);
>>> +
>>> +static int mc_status_to_error(enum mc_cmd_status status)
>>> +{
>>> +    switch (status) {
>>> +    case MC_CMD_STATUS_OK:
>>> +        return 0;
>>> +    case MC_CMD_STATUS_AUTH_ERR:
>>> +        return -EACCES;
>>> +    case MC_CMD_STATUS_NO_PRIVILEGE:
>>> +        return -EPERM;
>>> +    case MC_CMD_STATUS_DMA_ERR:
>>> +        return -EIO;
>>> +    case MC_CMD_STATUS_CONFIG_ERR:
>>> +        return -EINVAL;
>>> +    case MC_CMD_STATUS_TIMEOUT:
>>> +        return -ETIMEDOUT;
>>> +    case MC_CMD_STATUS_NO_RESOURCE:
>>> +        return -ENAVAIL;
>>> +    case MC_CMD_STATUS_NO_MEMORY:
>>> +        return -ENOMEM;
>>> +    case MC_CMD_STATUS_BUSY:
>>> +        return -EBUSY;
>>> +    case MC_CMD_STATUS_UNSUPPORTED_OP:
>>> +        return -ENOTSUP;
>>> +    case MC_CMD_STATUS_INVALID_STATE:
>>> +        return -ENODEV;
>>> +    default:
>>> +        break;
>>> +    }
>>> +
>>> +    /* Not expected to reach here */
>>> +    return -EINVAL;
>> 
>> but if it does, callsite can't disambiguate between that and e.g.,
>> MC_CMD_STATUS_CONFIG_ERR.  Also, this would be more readable as a
>> static const lookup table.
> I will change the switch to a lookup table and fix the -EINVAL
> ambiguity in the v2 respin.
> 
>> 
>>> +}
>>> +
>>> +int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
>>> +{
>>> +    enum mc_cmd_status status;
>>> +    unsigned long irqsave_flags = 0;
>>> +    int error = -EINVAL;
>>> +    bool lock_acquired = false;
>>> +    unsigned long jiffies_until_timeout =
>>> +        jiffies + MC_CMD_COMPLETION_TIMEOUT;
>>> +
>>> +    if (WARN_ON(mc_io->magic != FSL_MC_IO_MAGIC))
>>> +        goto out;
>> 
>> if the h/w signals an error on the bad magic condition, s/w doesn't
>> need to check it in its fast path.
> As per comments from Arnd Bergmann on the RFC patch series, I removed the magic field from all structs. I just forgot to do it for this one.
> I will remove this magic field in the v2 respin.
> 
>>> +    if (mc_io->flags & FSL_MC_IO_PORTAL_SHARED) {
>>> +        spin_lock_irqsave(&mc_io->spinlock, irqsave_flags);
>>> +        lock_acquired = true;
>>> +    }
>>> +
>>> +    mc_write_command(mc_io->portal_virt_addr, cmd);
>>> +
>>> +    for (;;) {
>>> +        status = mc_read_response(mc_io->portal_virt_addr, cmd);
>>> +        if (status != MC_CMD_STATUS_READY)
>>> +            break;
>>> +
>>> +        /*
>>> +         * TODO: When MC command completion interrupts are supported
>>> +         * call wait function here instead of udelay()
>>> +         */
>>> +        udelay(MC_CMD_COMPLETION_POLLING_INTERVAL);
>>> +        if (time_after_eq(jiffies, jiffies_until_timeout)) {
>>> +            error = -ETIMEDOUT;
>>> +            goto out;
>>> +        }
>>> +    }
>>> +
>>> +    error = mc_status_to_error(status);
>>> +out:
>>> +    if (lock_acquired)
>>> +        spin_unlock_irqrestore(&mc_io->spinlock, irqsave_flags);
>> 
>> so if the portal is shared, we take a lock, disable interrupts, and
>> then potentially udelay for a whopping 500usec, then check to see if
>> _100_usec have passed, and thus _always_ issue a timeout error, even
>> if the device took < 100usec to consume the command???
> That is not true. The 100 is in jiffies not in usec:

If you always wait for 100 jiffies, the timeout code suddenly depends on the HZ value which is kernel configuration, no? Wouldn't it be better to base the timeout on real wall time?

> 
> /**
> * Timeout in jiffies to wait for the completion of an MC command
> */
> #define MC_CMD_COMPLETION_TIMEOUT   100
> 
> /**
> * Delay in microseconds between polling iterations while
> * waiting for MC command completion
> */
> #define MC_CMD_COMPLETION_POLLING_INTERVAL  500
> 
> 
>> Not to mention this code will spin perpetually with IRQs disabled if
>> the read_response never returns ready.  I also don't see a reason
>> why IRQs are being disabled in the first place - it's not being used
>> in an IRQ handler...perhaps we need to wait until command completion
>> IRQs are supported :)
> I agree that disabling interrupts while doing polling is not efficient. I was assuming the worst case scenario of sharing the portal: both
> threads and interrupt handlers accessing the same portal at the same time. If only threads access the same portal, we don't need to disable interrupts and even further we can use a mutex instead of a spinlock.
> If only interrupt handlers access a given portal (from multiple CPUs)
> we have use a spinlock but we don't need to disabel interrupts.
> If both threads and interrupt handlers access a given portal, then
> we need to both use a spinlock and disable interrupts
> 
> I will change synchronization logic in the v2 respin to avoid
> disabling interrupts in the first two cases above.
> 
>>> +/**
>>> + * @brief    Management Complex firmware version information
>>> + */
>>> +#define MC_VER_MAJOR 2
>>> +#define MC_VER_MINOR 0
>> 
>> code should be adjusted to run on all *compatible* versions of h/w,
>> not strictly the one set in these defines.
> This comment is not precise enough be actionable.
> What exactly you want to be changed  here?

I think the easy thing to do is to convert the exact version check into a ranged version check: have minimum and maximum versions you support. Or a list of exact versions you support. Or not check for the version at all - or only for the major version and guarantee that the major version indicates backwards compatibility.

> 
>>> +/**
>>> + * @brief    Disconnects one endpoint to remove its network link
>>> + *
>>> + * @param[in]   mc_io        Pointer to opaque I/O object
>>> + * @param[in]    dprc_handle    Handle to the DPRC object
>>> + * @param[in]   endpoint    Endpoint configuration parameters.
>>> + *
>>> + * @returns    '0' on Success; Error code otherwise.
>>> + * */
>>> +int dprc_disconnect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
>>> +            struct dprc_endpoint *endpoint);
>>> +
>>> +/*! @} */
>> 
>> this entire file is riddled with non-kernel-doc comment markers:  see
>> Documentation/kernel-doc-nano-HOWTO.txt on how to write function and
>> other types of comments in a kernel-doc compliant format.
> This is because this file is using doxygen comments, as it was developed
> by another team. Unless someone else has an objection, I will leave the doxygen comments alone and not make any change here.

Do you see any other source files in Linux using doxygen comments? Mixing different documentation styles can easily become a big mess, because you can't generate external documentation consistently for the whole tree.


Alex


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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-18 13:14       ` Alexander Graf
@ 2014-09-18 20:22         ` Kim Phillips
  2014-09-18 23:03           ` Scott Wood
                             ` (2 more replies)
  2014-09-19  0:18         ` Stuart Yoder
                           ` (2 subsequent siblings)
  3 siblings, 3 replies; 43+ messages in thread
From: Kim Phillips @ 2014-09-18 20:22 UTC (permalink / raw)
  To: Alexander Graf
  Cc: German Rivera, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	<stuart.yoder@freescale.com>,
	<scottwood@freescale.com>,
	<linuxppc-release@linux.freescale.net>

On Thu, 18 Sep 2014 15:14:03 +0200
Alexander Graf <agraf@suse.de> wrote:

> > Am 18.09.2014 um 06:17 schrieb German Rivera <German.Rivera@freescale.com>:
> > 
> >> On 09/15/2014 06:44 PM, Kim Phillips wrote:
> >> On Thu, 11 Sep 2014 12:34:21 -0500
> >> "J. German Rivera" <German.Rivera@freescale.com> wrote:
> >> 
> >>> From: "J. German Rivera" <German.Rivera@freescale.com>
> >>> 
> >>> APIs to access the Management Complex (MC) hardware
> >>> module of Freescale LS2 SoCs. This patch includes
> >>> APIs to check the MC firmware version and to manipulate
> >>> DPRC objects in the MC.
> >>> 
> >>> Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
> >>> Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
> >>> ---
> >>>  drivers/bus/fsl-mc/dpmng.c         |   93 +++++
> >>>  drivers/bus/fsl-mc/dprc.c          |  504 +++++++++++++++++++++++
> >>>  drivers/bus/fsl-mc/fsl_dpmng_cmd.h |   83 ++++
> >>>  drivers/bus/fsl-mc/fsl_dprc_cmd.h  |  545 +++++++++++++++++++++++++
> >>>  drivers/bus/fsl-mc/fsl_mc_sys.c    |  237 +++++++++++
> >>>  include/linux/fsl_dpmng.h          |  120 ++++++
> >>>  include/linux/fsl_dprc.h           |  790 ++++++++++++++++++++++++++++++++++++
> >>>  include/linux/fsl_mc_cmd.h         |  182 +++++++++
> >>>  include/linux/fsl_mc_sys.h         |   81 ++++
> >>>  9 files changed, 2635 insertions(+)
> >>>  create mode 100644 drivers/bus/fsl-mc/dpmng.c
> >>>  create mode 100644 drivers/bus/fsl-mc/dprc.c
> >>>  create mode 100644 drivers/bus/fsl-mc/fsl_dpmng_cmd.h
> >>>  create mode 100644 drivers/bus/fsl-mc/fsl_dprc_cmd.h
> >>>  create mode 100644 drivers/bus/fsl-mc/fsl_mc_sys.c
> >>>  create mode 100644 include/linux/fsl_dpmng.h
> >>>  create mode 100644 include/linux/fsl_dprc.h
> >>>  create mode 100644 include/linux/fsl_mc_cmd.h
> >>>  create mode 100644 include/linux/fsl_mc_sys.h
> >> 
> >> the fsl prefix in the filename fsl_dpmng_cmd.h is redundant with
> >> its directory name fsl-mc/.  Note that I find dashes ('-') in
> >> filenames make them easier to type: is there a reason we're using
> >> underscores here?
> > This is a convention that we decided early on '-' for directory names
> > and '_' for file names.

based on what?

> > unnecessarily complicated error path, plus a simpler
> >> implementation can be made if fn can return the mapped address, like
> >> so:
> >> 
> >> static void __iomem *map_mc_portal(phys_addr_t mc_portal_phys_addr,
> >>                                    uint32_t mc_portal_size)
> >> {
> >>         struct resource *res;
> >>         void __iomem *mapped_addr;
> >> 
> >>         res = request_mem_region(mc_portal_phys_addr, mc_portal_size,
> >>                                  "mc_portal");
> >>         if (!res)
> >>                 return NULL;
> >> 
> >>         mapped_addr = ioremap_nocache(mc_portal_phys_addr,
> >>                                       mc_portal_size);
> >>         if (!mapped_addr)
> >>                 release_mem_region(mc_portal_phys_addr, mc_portal_size);
> >> 
> >>         return mapped_addr;
> >> }
> >> 
> >> the callsite can return -ENOMEM to its caller if returned NULL.  This
> >> can be improved even further if devm_ functions are used:  this is
> >> just an example of how to simplify the code using early returns
> >> instead of goto error.
> > 
> > I disagree. Having a common error return point is more maintainable than having multiple returns as having the clean-up logic in one place is more maintainable and makes the min path (non-error) more readable.

my comment is not that much different from Joe's here:

https://lkml.org/lkml/2014/9/17/381

but hopefully all this will change with a devm_ based implementation.

> >>> +int __must_check fsl_create_mc_io(phys_addr_t mc_portal_phys_addr,
> >>> +                  uint32_t mc_portal_size,
> >>> +                  uint32_t flags, struct fsl_mc_io **new_mc_io)
> >>> +{
> >>> +    int error = -EINVAL;
> >>> +    struct fsl_mc_io *mc_io = NULL;
> >>> +
> >>> +    mc_io = kzalloc(sizeof(*mc_io), GFP_KERNEL);
> >>> +    if (mc_io == NULL) {
> >>> +        error = -ENOMEM;
> >>> +        pr_err("No memory to allocate mc_io\n");
> >>> +        goto error;
> >>> +    }
> >>> +
> >>> +    mc_io->magic = FSL_MC_IO_MAGIC;
> >>> +    mc_io->flags = flags;
> >>> +    mc_io->portal_phys_addr = mc_portal_phys_addr;
> >>> +    mc_io->portal_size = mc_portal_size;
> >>> +    spin_lock_init(&mc_io->spinlock);
> >>> +    error = map_mc_portal(mc_portal_phys_addr,
> >>> +                  mc_portal_size, &mc_io->portal_virt_addr);
> >>> +    if (error < 0)
> >>> +        goto error;
> >>> +
> >>> +    *new_mc_io = mc_io;
> >>> +    return 0;
> >> 
> >> if a fn only returns an address or error, it can return ERR_PTR
> >> (e.g., -ENOMEM), and the callsite use IS_ERR() to determine whether
> >> there was an error or address returned.  This makes code much
> >> simpler instead of passing address values back by reference.
> > I disagree. I don't see why the alternative you suggest makes the code "much simpler".

because it eliminates the need for the extra pass-by-reference
argument struct fsl_mc_io **new_mc_io.

> >>> +void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
> >>> +{
> >>> +    if (WARN_ON(mc_io->magic != FSL_MC_IO_MAGIC))
> >>> +        return;
> >>> +
> >>> +    if (mc_io->portal_virt_addr != NULL) {
> >>> +        unmap_mc_portal(mc_io->portal_phys_addr,
> >>> +                mc_io->portal_size, mc_io->portal_virt_addr);
> >> 
> >> unmap_mc_portal already checks for virt_addr, this is another
> >> example where the code goes too far checking for NULL.
> > I disagree. Having the extra check is harmless and more importantly makes the intent explicit that we should only call unmap_mc_portal if we called map_mc_portal earlier.

the code is doing this:

        if (mc_io->portal_virt_addr != NULL) {
	        if (WARN_ON(mc_portal_virt_addr == NULL))
        	        return;

which is redundant and therefore makes it unnecessarily complicated,
after all, a stack trace will occur if mc_portal_virt_addr is
referenced anyway, making the WARN_ON clause redundant, too.

> >>> +        mc_io->portal_virt_addr = NULL;
> >>> +    }
> >>> +
> >>> +    mc_io->magic = 0x0;
> >>> +    kfree(mc_io);
> >>> +}

btw, what's the point of zeroing out things that are being freed?

> >>> +/**
> >>> + * @brief    Management Complex firmware version information
> >>> + */
> >>> +#define MC_VER_MAJOR 2
> >>> +#define MC_VER_MINOR 0
> >> 
> >> code should be adjusted to run on all *compatible* versions of h/w,
> >> not strictly the one set in these defines.
> > This comment is not precise enough be actionable.
> > What exactly you want to be changed  here?
> 
> I think the easy thing to do is to convert the exact version check into a ranged version check: have minimum and maximum versions you support. Or a list of exact versions you support. Or not check for the version at all - or only for the major version and guarantee that the major version indicates backwards compatibility.

yes, this was my point: elsewhere I noticed the code denies to run
iff those defines are not matched exactly: that code should change
to run as Alex describes.

> >>> +/**
> >>> + * @brief    Disconnects one endpoint to remove its network link
> >>> + *
> >>> + * @param[in]   mc_io        Pointer to opaque I/O object
> >>> + * @param[in]    dprc_handle    Handle to the DPRC object
> >>> + * @param[in]   endpoint    Endpoint configuration parameters.
> >>> + *
> >>> + * @returns    '0' on Success; Error code otherwise.
> >>> + * */
> >>> +int dprc_disconnect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
> >>> +            struct dprc_endpoint *endpoint);
> >>> +
> >>> +/*! @} */
> >> 
> >> this entire file is riddled with non-kernel-doc comment markers:  see
> >> Documentation/kernel-doc-nano-HOWTO.txt on how to write function and
> >> other types of comments in a kernel-doc compliant format.
> > This is because this file is using doxygen comments, as it was developed
> > by another team. Unless someone else has an objection, I will leave the doxygen comments alone and not make any change here.
> 
> Do you see any other source files in Linux using doxygen comments? Mixing different documentation styles can easily become a big mess, because you can't generate external documentation consistently for the whole tree.

Thanks Alex,

Kim

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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-18 20:22         ` Kim Phillips
@ 2014-09-18 23:03           ` Scott Wood
  2014-09-18 23:13           ` Stuart Yoder
  2014-09-19  3:05           ` German Rivera
  2 siblings, 0 replies; 43+ messages in thread
From: Scott Wood @ 2014-09-18 23:03 UTC (permalink / raw)
  To: Kim Phillips
  Cc: Alexander Graf, German Rivera, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	<stuart.yoder@freescale.com>,
	<linuxppc-release@linux.freescale.net>

On Thu, 2014-09-18 at 15:22 -0500, Kim Phillips wrote:
> On Thu, 18 Sep 2014 15:14:03 +0200
> Alexander Graf <agraf@suse.de> wrote:
> 
> > > Am 18.09.2014 um 06:17 schrieb German Rivera <German.Rivera@freescale.com>:
> > > 
> > >> On 09/15/2014 06:44 PM, Kim Phillips wrote:
> > >> On Thu, 11 Sep 2014 12:34:21 -0500
> > >> "J. German Rivera" <German.Rivera@freescale.com> wrote:
> > >> 
> > >>> From: "J. German Rivera" <German.Rivera@freescale.com>
> > >>> 
> > >>> APIs to access the Management Complex (MC) hardware
> > >>> module of Freescale LS2 SoCs. This patch includes
> > >>> APIs to check the MC firmware version and to manipulate
> > >>> DPRC objects in the MC.
> > >>> 
> > >>> Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
> > >>> Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
> > >>> ---
> > >>>  drivers/bus/fsl-mc/dpmng.c         |   93 +++++
> > >>>  drivers/bus/fsl-mc/dprc.c          |  504 +++++++++++++++++++++++
> > >>>  drivers/bus/fsl-mc/fsl_dpmng_cmd.h |   83 ++++
> > >>>  drivers/bus/fsl-mc/fsl_dprc_cmd.h  |  545 +++++++++++++++++++++++++
> > >>>  drivers/bus/fsl-mc/fsl_mc_sys.c    |  237 +++++++++++
> > >>>  include/linux/fsl_dpmng.h          |  120 ++++++
> > >>>  include/linux/fsl_dprc.h           |  790 ++++++++++++++++++++++++++++++++++++
> > >>>  include/linux/fsl_mc_cmd.h         |  182 +++++++++
> > >>>  include/linux/fsl_mc_sys.h         |   81 ++++
> > >>>  9 files changed, 2635 insertions(+)
> > >>>  create mode 100644 drivers/bus/fsl-mc/dpmng.c
> > >>>  create mode 100644 drivers/bus/fsl-mc/dprc.c
> > >>>  create mode 100644 drivers/bus/fsl-mc/fsl_dpmng_cmd.h
> > >>>  create mode 100644 drivers/bus/fsl-mc/fsl_dprc_cmd.h
> > >>>  create mode 100644 drivers/bus/fsl-mc/fsl_mc_sys.c
> > >>>  create mode 100644 include/linux/fsl_dpmng.h
> > >>>  create mode 100644 include/linux/fsl_dprc.h
> > >>>  create mode 100644 include/linux/fsl_mc_cmd.h
> > >>>  create mode 100644 include/linux/fsl_mc_sys.h
> > >> 
> > >> the fsl prefix in the filename fsl_dpmng_cmd.h is redundant with
> > >> its directory name fsl-mc/.  Note that I find dashes ('-') in
> > >> filenames make them easier to type: is there a reason we're using
> > >> underscores here?
> > > This is a convention that we decided early on '-' for directory names
> > > and '_' for file names.
> 
> based on what?

I agree with Kim here.

> > >>> +/**
> > >>> + * @brief    Management Complex firmware version information
> > >>> + */
> > >>> +#define MC_VER_MAJOR 2
> > >>> +#define MC_VER_MINOR 0
> > >> 
> > >> code should be adjusted to run on all *compatible* versions of h/w,
> > >> not strictly the one set in these defines.
> > > This comment is not precise enough be actionable.
> > > What exactly you want to be changed  here?
> > 
> >
> > I think the easy thing to do is to convert the exact version check
> > into a ranged version check: have minimum and maximum versions you
> > support. Or a list of exact versions you support. Or not check for the
> > version at all - or only for the major version and guarantee that the
> > major version indicates backwards compatibility.
> >
> yes, this was my point: elsewhere I noticed the code denies to run
> iff those defines are not matched exactly: that code should change
> to run as Alex describes.

Also keep in mind that in the future we may need to support multiple
versions that behave differently.

-Scott



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

* RE: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-18 20:22         ` Kim Phillips
  2014-09-18 23:03           ` Scott Wood
@ 2014-09-18 23:13           ` Stuart Yoder
  2014-09-18 23:29             ` Scott Wood
  2014-09-19  3:05           ` German Rivera
  2 siblings, 1 reply; 43+ messages in thread
From: Stuart Yoder @ 2014-09-18 23:13 UTC (permalink / raw)
  To: Kim Phillips, Alexander Graf
  Cc: Jose Rivera, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	Scott Wood, <linuxppc-release@linux.freescale.net>



> -----Original Message-----
> From: Kim Phillips [mailto:kim.phillips@freescale.com]
> Sent: Thursday, September 18, 2014 3:23 PM
> To: Alexander Graf
> Cc: Rivera Jose-B46482; <gregkh@linuxfoundation.org>; <arnd@arndb.de>; <linux-kernel@vger.kernel.org>; Yoder
> Stuart-B08248; Wood Scott-B07421; <linuxppc-release@linux.freescale.net>
> Subject: Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
> 
> On Thu, 18 Sep 2014 15:14:03 +0200
> Alexander Graf <agraf@suse.de> wrote:
> 
> > > Am 18.09.2014 um 06:17 schrieb German Rivera <German.Rivera@freescale.com>:
> > >
> > >> On 09/15/2014 06:44 PM, Kim Phillips wrote:
> > >> On Thu, 11 Sep 2014 12:34:21 -0500
> > >> "J. German Rivera" <German.Rivera@freescale.com> wrote:
> > >>
> > >>> From: "J. German Rivera" <German.Rivera@freescale.com>
> > >>>
> > >>> APIs to access the Management Complex (MC) hardware
> > >>> module of Freescale LS2 SoCs. This patch includes
> > >>> APIs to check the MC firmware version and to manipulate
> > >>> DPRC objects in the MC.
> > >>>
> > >>> Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
> > >>> Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
> > >>> ---
> > >>>  drivers/bus/fsl-mc/dpmng.c         |   93 +++++
> > >>>  drivers/bus/fsl-mc/dprc.c          |  504 +++++++++++++++++++++++
> > >>>  drivers/bus/fsl-mc/fsl_dpmng_cmd.h |   83 ++++
> > >>>  drivers/bus/fsl-mc/fsl_dprc_cmd.h  |  545 +++++++++++++++++++++++++
> > >>>  drivers/bus/fsl-mc/fsl_mc_sys.c    |  237 +++++++++++
> > >>>  include/linux/fsl_dpmng.h          |  120 ++++++
> > >>>  include/linux/fsl_dprc.h           |  790 ++++++++++++++++++++++++++++++++++++
> > >>>  include/linux/fsl_mc_cmd.h         |  182 +++++++++
> > >>>  include/linux/fsl_mc_sys.h         |   81 ++++
> > >>>  9 files changed, 2635 insertions(+)
> > >>>  create mode 100644 drivers/bus/fsl-mc/dpmng.c
> > >>>  create mode 100644 drivers/bus/fsl-mc/dprc.c
> > >>>  create mode 100644 drivers/bus/fsl-mc/fsl_dpmng_cmd.h
> > >>>  create mode 100644 drivers/bus/fsl-mc/fsl_dprc_cmd.h
> > >>>  create mode 100644 drivers/bus/fsl-mc/fsl_mc_sys.c
> > >>>  create mode 100644 include/linux/fsl_dpmng.h
> > >>>  create mode 100644 include/linux/fsl_dprc.h
> > >>>  create mode 100644 include/linux/fsl_mc_cmd.h
> > >>>  create mode 100644 include/linux/fsl_mc_sys.h
> > >>
> > >> the fsl prefix in the filename fsl_dpmng_cmd.h is redundant with
> > >> its directory name fsl-mc/.  Note that I find dashes ('-') in
> > >> filenames make them easier to type: is there a reason we're using
> > >> underscores here?
> > > This is a convention that we decided early on '-' for directory names
> > > and '_' for file names.
> 
> based on what?

We looked at how generally files were named in kernel source.

For what it's worth in my 3.16 branch:

$ find drivers/ -type f | grep '-' | wc -l
4308
$ find drivers/ -type f | grep '_' | wc -l
6507

...it seems that there are far more files named with underscores.  If Greg
or Arnd wants the files renamed, fine, but other than that I see no reason
to change this.

Stuart

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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-18 23:13           ` Stuart Yoder
@ 2014-09-18 23:29             ` Scott Wood
  2014-09-18 23:46               ` Stuart Yoder
  0 siblings, 1 reply; 43+ messages in thread
From: Scott Wood @ 2014-09-18 23:29 UTC (permalink / raw)
  To: Yoder Stuart-B08248
  Cc: Phillips Kim-R1AAHA, Alexander Graf, Rivera Jose-B46482, gregkh,
	arnd, linux-kernel

On Thu, 2014-09-18 at 18:13 -0500, Yoder Stuart-B08248 wrote:
> 
> > -----Original Message-----
> > From: Kim Phillips [mailto:kim.phillips@freescale.com]
> > Sent: Thursday, September 18, 2014 3:23 PM
> > To: Alexander Graf
> > Cc: Rivera Jose-B46482; <gregkh@linuxfoundation.org>; <arnd@arndb.de>; <linux-kernel@vger.kernel.org>; Yoder
> > Stuart-B08248; Wood Scott-B07421; <linuxppc-release@linux.freescale.net>
> > Subject: Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
> > 
> > On Thu, 18 Sep 2014 15:14:03 +0200
> > Alexander Graf <agraf@suse.de> wrote:
> > 
> > > > Am 18.09.2014 um 06:17 schrieb German Rivera <German.Rivera@freescale.com>:
> > > >
> > > >> On 09/15/2014 06:44 PM, Kim Phillips wrote:
> > > >> On Thu, 11 Sep 2014 12:34:21 -0500
> > > >> "J. German Rivera" <German.Rivera@freescale.com> wrote:
> > > >>
> > > >>> From: "J. German Rivera" <German.Rivera@freescale.com>
> > > >>>
> > > >>> APIs to access the Management Complex (MC) hardware
> > > >>> module of Freescale LS2 SoCs. This patch includes
> > > >>> APIs to check the MC firmware version and to manipulate
> > > >>> DPRC objects in the MC.
> > > >>>
> > > >>> Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
> > > >>> Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
> > > >>> ---
> > > >>>  drivers/bus/fsl-mc/dpmng.c         |   93 +++++
> > > >>>  drivers/bus/fsl-mc/dprc.c          |  504 +++++++++++++++++++++++
> > > >>>  drivers/bus/fsl-mc/fsl_dpmng_cmd.h |   83 ++++
> > > >>>  drivers/bus/fsl-mc/fsl_dprc_cmd.h  |  545 +++++++++++++++++++++++++
> > > >>>  drivers/bus/fsl-mc/fsl_mc_sys.c    |  237 +++++++++++
> > > >>>  include/linux/fsl_dpmng.h          |  120 ++++++
> > > >>>  include/linux/fsl_dprc.h           |  790 ++++++++++++++++++++++++++++++++++++
> > > >>>  include/linux/fsl_mc_cmd.h         |  182 +++++++++
> > > >>>  include/linux/fsl_mc_sys.h         |   81 ++++
> > > >>>  9 files changed, 2635 insertions(+)
> > > >>>  create mode 100644 drivers/bus/fsl-mc/dpmng.c
> > > >>>  create mode 100644 drivers/bus/fsl-mc/dprc.c
> > > >>>  create mode 100644 drivers/bus/fsl-mc/fsl_dpmng_cmd.h
> > > >>>  create mode 100644 drivers/bus/fsl-mc/fsl_dprc_cmd.h
> > > >>>  create mode 100644 drivers/bus/fsl-mc/fsl_mc_sys.c
> > > >>>  create mode 100644 include/linux/fsl_dpmng.h
> > > >>>  create mode 100644 include/linux/fsl_dprc.h
> > > >>>  create mode 100644 include/linux/fsl_mc_cmd.h
> > > >>>  create mode 100644 include/linux/fsl_mc_sys.h
> > > >>
> > > >> the fsl prefix in the filename fsl_dpmng_cmd.h is redundant with
> > > >> its directory name fsl-mc/.  Note that I find dashes ('-') in
> > > >> filenames make them easier to type: is there a reason we're using
> > > >> underscores here?
> > > > This is a convention that we decided early on '-' for directory names
> > > > and '_' for file names.
> > 
> > based on what?
> 
> We looked at how generally files were named in kernel source.
> 
> For what it's worth in my 3.16 branch:
> 
> $ find drivers/ -type f | grep '-' | wc -l
> 4308
> $ find drivers/ -type f | grep '_' | wc -l
> 6507
> 
> ...it seems that there are far more files named with underscores.  If Greg
> or Arnd wants the files renamed, fine, but other than that I see no reason
> to change this.

60% isn't "far more".  Regardless of whether we change this (dashes are
easier to read, easier to type, and are what English normally uses --
underscores are for when you can't use a dash for technical reasons),
let's not start making rules based on weak statistical inferences.

Plus, why limit the search to drivers?  E.g. if you looked at arch/
you'd reach the opposite conclusion.

-Scott



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

* RE: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-15 23:44   ` Kim Phillips
  2014-09-16  4:31     ` Scott Wood
  2014-09-18  4:17     ` German Rivera
@ 2014-09-18 23:39     ` Stuart Yoder
  2014-09-18 23:53       ` Scott Wood
  2 siblings, 1 reply; 43+ messages in thread
From: Stuart Yoder @ 2014-09-18 23:39 UTC (permalink / raw)
  To: Kim Phillips, Jose Rivera
  Cc: gregkh, arnd, linux-kernel, Kim Phillips, Scott Wood, agraf,
	linuxppc-release



> -----Original Message-----
> From: Kim Phillips [mailto:kim.phillips@freescale.com]
> Sent: Monday, September 15, 2014 6:45 PM
> To: Rivera Jose-B46482
> Cc: gregkh@linuxfoundation.org; arnd@arndb.de; linux-kernel@vger.kernel.org; Yoder Stuart-B08248; Phillips
> Kim-R1AAHA; Wood Scott-B07421; agraf@suse.de; linuxppc-release@linux.freescale.net
> Subject: Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
> 
> On Thu, 11 Sep 2014 12:34:21 -0500
> "J. German Rivera" <German.Rivera@freescale.com> wrote:
> 
> > From: "J. German Rivera" <German.Rivera@freescale.com>
> >
> > APIs to access the Management Complex (MC) hardware
> > module of Freescale LS2 SoCs. This patch includes
> > APIs to check the MC firmware version and to manipulate
> > DPRC objects in the MC.
> >
> > Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
> > Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
> > ---
> >  drivers/bus/fsl-mc/dpmng.c         |   93 +++++
> >  drivers/bus/fsl-mc/dprc.c          |  504 +++++++++++++++++++++++
> >  drivers/bus/fsl-mc/fsl_dpmng_cmd.h |   83 ++++
> >  drivers/bus/fsl-mc/fsl_dprc_cmd.h  |  545 +++++++++++++++++++++++++
> >  drivers/bus/fsl-mc/fsl_mc_sys.c    |  237 +++++++++++
> >  include/linux/fsl_dpmng.h          |  120 ++++++
> >  include/linux/fsl_dprc.h           |  790 ++++++++++++++++++++++++++++++++++++
> >  include/linux/fsl_mc_cmd.h         |  182 +++++++++
> >  include/linux/fsl_mc_sys.h         |   81 ++++
> >  9 files changed, 2635 insertions(+)
> >  create mode 100644 drivers/bus/fsl-mc/dpmng.c
> >  create mode 100644 drivers/bus/fsl-mc/dprc.c
> >  create mode 100644 drivers/bus/fsl-mc/fsl_dpmng_cmd.h
> >  create mode 100644 drivers/bus/fsl-mc/fsl_dprc_cmd.h
> >  create mode 100644 drivers/bus/fsl-mc/fsl_mc_sys.c
> >  create mode 100644 include/linux/fsl_dpmng.h
> >  create mode 100644 include/linux/fsl_dprc.h
> >  create mode 100644 include/linux/fsl_mc_cmd.h
> >  create mode 100644 include/linux/fsl_mc_sys.h
> 
> the fsl prefix in the filename fsl_dpmng_cmd.h is redundant with
> its directory name fsl-mc/.  Note that I find dashes ('-') in
> filenames make them easier to type: is there a reason we're using
> underscores here?
> 
> Also, any reason why these and future include files aren't being put
> in include/linux/fsl/, so as to not pollute the top level
> include/linux/?  That way, we can also remove the fsl- prefix from
> those filenames, too..

There is nothing in include/linux/fsl except 1 driver from 2 years ago.
Why is that?

I'd also prefer to see these headers is include/linux/fsl, but given that
the directory is essentially unused it seemed that include/linux was more
conventional.

> > diff --git a/drivers/bus/fsl-mc/dpmng.c b/drivers/bus/fsl-mc/dpmng.c
> > new file mode 100644
> > index 0000000..c6ed27c
> > --- /dev/null
> > +++ b/drivers/bus/fsl-mc/dpmng.c
> > @@ -0,0 +1,93 @@
> > +/* Copyright 2013-2014 Freescale Semiconductor Inc.
> > + *
> > + * Redistribution and use in source and binary forms, with or without
> > + * modification, are permitted provided that the following conditions are met:
> > + *     * Redistributions of source code must retain the above copyright
> > + *       notice, this list of conditions and the following disclaimer.
> > + *     * Redistributions in binary form must reproduce the above copyright
> > + *       notice, this list of conditions and the following disclaimer in the
> > + *       documentation and/or other materials provided with the distribution.
> > + *     * Neither the name of Freescale Semiconductor nor the
> > + *       names of its contributors may be used to endorse or promote products
> > + *       derived from this software without specific prior written permission.
> > + *
> > + *
> > + * ALTERNATIVELY, this software may be distributed under the terms of the
> > + * GNU General Public License ("GPL") as published by the Free Software
> > + * Foundation, either version 2 of that License or (at your option) any
> > + * later version.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
> 
> interesting, normally this text reads:
> 
> "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"
> 
> ...does that mean we're excluding non-Freescale copyright holders
> and contributors from this warranty statement?  That doesn't seem
> appropriate for an upstream kernel submission.

This is a standard license dual license used by Freescale, wording
most likely set by the legal dept. 

There are many instances of it in the kernel (mostly in device trees).

git grep 'THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor' | wc -l
180

Unless it is condition of being accepted into the kernel I want
to leave it as is.

Stuart

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

* RE: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-18 23:29             ` Scott Wood
@ 2014-09-18 23:46               ` Stuart Yoder
  0 siblings, 0 replies; 43+ messages in thread
From: Stuart Yoder @ 2014-09-18 23:46 UTC (permalink / raw)
  To: Scott Wood
  Cc: Kim Phillips, Alexander Graf, Jose Rivera, gregkh, arnd, linux-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 4571 bytes --]



> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Thursday, September 18, 2014 6:29 PM
> To: Yoder Stuart-B08248
> Cc: Phillips Kim-R1AAHA; Alexander Graf; Rivera Jose-B46482; gregkh@linuxfoundation.org; arnd@arndb.de;
> linux-kernel@vger.kernel.org
> Subject: Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
> 
> On Thu, 2014-09-18 at 18:13 -0500, Yoder Stuart-B08248 wrote:
> >
> > > -----Original Message-----
> > > From: Kim Phillips [mailto:kim.phillips@freescale.com]
> > > Sent: Thursday, September 18, 2014 3:23 PM
> > > To: Alexander Graf
> > > Cc: Rivera Jose-B46482; <gregkh@linuxfoundation.org>; <arnd@arndb.de>; <linux-kernel@vger.kernel.org>;
> Yoder
> > > Stuart-B08248; Wood Scott-B07421; <linuxppc-release@linux.freescale.net>
> > > Subject: Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
> > >
> > > On Thu, 18 Sep 2014 15:14:03 +0200
> > > Alexander Graf <agraf@suse.de> wrote:
> > >
> > > > > Am 18.09.2014 um 06:17 schrieb German Rivera <German.Rivera@freescale.com>:
> > > > >
> > > > >> On 09/15/2014 06:44 PM, Kim Phillips wrote:
> > > > >> On Thu, 11 Sep 2014 12:34:21 -0500
> > > > >> "J. German Rivera" <German.Rivera@freescale.com> wrote:
> > > > >>
> > > > >>> From: "J. German Rivera" <German.Rivera@freescale.com>
> > > > >>>
> > > > >>> APIs to access the Management Complex (MC) hardware
> > > > >>> module of Freescale LS2 SoCs. This patch includes
> > > > >>> APIs to check the MC firmware version and to manipulate
> > > > >>> DPRC objects in the MC.
> > > > >>>
> > > > >>> Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
> > > > >>> Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
> > > > >>> ---
> > > > >>>  drivers/bus/fsl-mc/dpmng.c         |   93 +++++
> > > > >>>  drivers/bus/fsl-mc/dprc.c          |  504 +++++++++++++++++++++++
> > > > >>>  drivers/bus/fsl-mc/fsl_dpmng_cmd.h |   83 ++++
> > > > >>>  drivers/bus/fsl-mc/fsl_dprc_cmd.h  |  545 +++++++++++++++++++++++++
> > > > >>>  drivers/bus/fsl-mc/fsl_mc_sys.c    |  237 +++++++++++
> > > > >>>  include/linux/fsl_dpmng.h          |  120 ++++++
> > > > >>>  include/linux/fsl_dprc.h           |  790 ++++++++++++++++++++++++++++++++++++
> > > > >>>  include/linux/fsl_mc_cmd.h         |  182 +++++++++
> > > > >>>  include/linux/fsl_mc_sys.h         |   81 ++++
> > > > >>>  9 files changed, 2635 insertions(+)
> > > > >>>  create mode 100644 drivers/bus/fsl-mc/dpmng.c
> > > > >>>  create mode 100644 drivers/bus/fsl-mc/dprc.c
> > > > >>>  create mode 100644 drivers/bus/fsl-mc/fsl_dpmng_cmd.h
> > > > >>>  create mode 100644 drivers/bus/fsl-mc/fsl_dprc_cmd.h
> > > > >>>  create mode 100644 drivers/bus/fsl-mc/fsl_mc_sys.c
> > > > >>>  create mode 100644 include/linux/fsl_dpmng.h
> > > > >>>  create mode 100644 include/linux/fsl_dprc.h
> > > > >>>  create mode 100644 include/linux/fsl_mc_cmd.h
> > > > >>>  create mode 100644 include/linux/fsl_mc_sys.h
> > > > >>
> > > > >> the fsl prefix in the filename fsl_dpmng_cmd.h is redundant with
> > > > >> its directory name fsl-mc/.  Note that I find dashes ('-') in
> > > > >> filenames make them easier to type: is there a reason we're using
> > > > >> underscores here?
> > > > > This is a convention that we decided early on '-' for directory names
> > > > > and '_' for file names.
> > >
> > > based on what?
> >
> > We looked at how generally files were named in kernel source.
> >
> > For what it's worth in my 3.16 branch:
> >
> > $ find drivers/ -type f | grep '-' | wc -l
> > 4308
> > $ find drivers/ -type f | grep '_' | wc -l
> > 6507
> >
> > ...it seems that there are far more files named with underscores.  If Greg
> > or Arnd wants the files renamed, fine, but other than that I see no reason
> > to change this.
> 
> 60% isn't "far more".  Regardless of whether we change this (dashes are
> easier to read, easier to type, and are what English normally uses --
> underscores are for when you can't use a dash for technical reasons),
> let's not start making rules based on weak statistical inferences.
> 
> Plus, why limit the search to drivers?

It's a driver and we looked at the precedent/conventions used by
other drivers.

> E.g. if you looked at arch/
> you'd reach the opposite conclusion.

I guess if you look at the kernel as a whole it's almost exactly
50/50.  So, don't understand how anyone can say it is _clear_
that underscores are better.

Stuart
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-18 23:39     ` Stuart Yoder
@ 2014-09-18 23:53       ` Scott Wood
  0 siblings, 0 replies; 43+ messages in thread
From: Scott Wood @ 2014-09-18 23:53 UTC (permalink / raw)
  To: Yoder Stuart-B08248
  Cc: Phillips Kim-R1AAHA, Rivera Jose-B46482, gregkh, arnd,
	linux-kernel, agraf, linuxppc-release

On Thu, 2014-09-18 at 18:39 -0500, Yoder Stuart-B08248 wrote:
> 
> > -----Original Message-----
> > From: Kim Phillips [mailto:kim.phillips@freescale.com]
> > Sent: Monday, September 15, 2014 6:45 PM
> > To: Rivera Jose-B46482
> > Cc: gregkh@linuxfoundation.org; arnd@arndb.de; linux-kernel@vger.kernel.org; Yoder Stuart-B08248; Phillips
> > Kim-R1AAHA; Wood Scott-B07421; agraf@suse.de; linuxppc-release@linux.freescale.net
> > Subject: Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
> > 
> > On Thu, 11 Sep 2014 12:34:21 -0500
> > "J. German Rivera" <German.Rivera@freescale.com> wrote:
> > 
> > > From: "J. German Rivera" <German.Rivera@freescale.com>
> > >
> > > APIs to access the Management Complex (MC) hardware
> > > module of Freescale LS2 SoCs. This patch includes
> > > APIs to check the MC firmware version and to manipulate
> > > DPRC objects in the MC.
> > >
> > > Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
> > > Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
> > > ---
> > >  drivers/bus/fsl-mc/dpmng.c         |   93 +++++
> > >  drivers/bus/fsl-mc/dprc.c          |  504 +++++++++++++++++++++++
> > >  drivers/bus/fsl-mc/fsl_dpmng_cmd.h |   83 ++++
> > >  drivers/bus/fsl-mc/fsl_dprc_cmd.h  |  545 +++++++++++++++++++++++++
> > >  drivers/bus/fsl-mc/fsl_mc_sys.c    |  237 +++++++++++
> > >  include/linux/fsl_dpmng.h          |  120 ++++++
> > >  include/linux/fsl_dprc.h           |  790 ++++++++++++++++++++++++++++++++++++
> > >  include/linux/fsl_mc_cmd.h         |  182 +++++++++
> > >  include/linux/fsl_mc_sys.h         |   81 ++++
> > >  9 files changed, 2635 insertions(+)
> > >  create mode 100644 drivers/bus/fsl-mc/dpmng.c
> > >  create mode 100644 drivers/bus/fsl-mc/dprc.c
> > >  create mode 100644 drivers/bus/fsl-mc/fsl_dpmng_cmd.h
> > >  create mode 100644 drivers/bus/fsl-mc/fsl_dprc_cmd.h
> > >  create mode 100644 drivers/bus/fsl-mc/fsl_mc_sys.c
> > >  create mode 100644 include/linux/fsl_dpmng.h
> > >  create mode 100644 include/linux/fsl_dprc.h
> > >  create mode 100644 include/linux/fsl_mc_cmd.h
> > >  create mode 100644 include/linux/fsl_mc_sys.h
> > 
> > the fsl prefix in the filename fsl_dpmng_cmd.h is redundant with
> > its directory name fsl-mc/.  Note that I find dashes ('-') in
> > filenames make them easier to type: is there a reason we're using
> > underscores here?
> > 
> > Also, any reason why these and future include files aren't being put
> > in include/linux/fsl/, so as to not pollute the top level
> > include/linux/?  That way, we can also remove the fsl- prefix from
> > those filenames, too..
> 
> There is nothing in include/linux/fsl except 1 driver from 2 years ago.
> Why is that?
> 
> I'd also prefer to see these headers is include/linux/fsl, but given that
> the directory is essentially unused it seemed that include/linux was more
> conventional.

I thought I saw some other patch dump some more things in there recently
-- maybe LS1 stuff?

-Scott



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

* RE: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-18 13:14       ` Alexander Graf
  2014-09-18 20:22         ` Kim Phillips
@ 2014-09-19  0:18         ` Stuart Yoder
  2014-09-19  2:34         ` German Rivera
  2014-09-19 18:25         ` Stuart Yoder
  3 siblings, 0 replies; 43+ messages in thread
From: Stuart Yoder @ 2014-09-19  0:18 UTC (permalink / raw)
  To: Alexander Graf, Jose Rivera
  Cc: Kim Phillips, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	Scott Wood, <linuxppc-release@linux.freescale.net>

+/**
> >>> + * @brief    Disconnects one endpoint to remove its network link
> >>> + *
> >>> + * @param[in]   mc_io        Pointer to opaque I/O object
> >>> + * @param[in]    dprc_handle    Handle to the DPRC object
> >>> + * @param[in]   endpoint    Endpoint configuration parameters.
> >>> + *
> >>> + * @returns    '0' on Success; Error code otherwise.
> >>> + * */
> >>> +int dprc_disconnect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
> >>> +            struct dprc_endpoint *endpoint);
> >>> +
> >>> +/*! @} */
> >>
> >> this entire file is riddled with non-kernel-doc comment markers:  see
> >> Documentation/kernel-doc-nano-HOWTO.txt on how to write function and
> >> other types of comments in a kernel-doc compliant format.
> > This is because this file is using doxygen comments, as it was developed
> > by another team. Unless someone else has an objection, I will leave the doxygen comments alone and not make
> any change here.
> 
> Do you see any other source files in Linux using doxygen comments?

Yes.  Grep around a bit and you'll see examples of it.  I grep'ed for some
doxygen tags and found close to 200 source files with them.

> Mixing different documentation styles can
> easily become a big mess, because you can't generate external documentation consistently for the whole tree.

As German mentioned elsewhere, this file is an interface to a hardware block,
was written by another team targetting a wide variety of environments-- u-boot,
Linux, user space, other OSes etc.

We left the doxygen stuff there because while admitedly not used much, there
are other examples of it in the kernel and the documentation seems useful.
If it can't go into the kernel as is, we can just delete it.

If doxygen is not allowed, it would be nice to see checkpatch updated to complain.

Thanks,
Stuart

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

* Re: [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series
  2014-09-18 12:58     ` Alexander Graf
@ 2014-09-19  0:31       ` German Rivera
  0 siblings, 0 replies; 43+ messages in thread
From: German Rivera @ 2014-09-19  0:31 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Kim Phillips, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	<stuart.yoder@freescale.com>,
	<scottwood@freescale.com>,
	<linuxppc-release@linux.freescale.net>


On 09/18/2014 07:58 AM, Alexander Graf wrote:

>>
>>> checkpatch:
>>>
>>> WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
>>>
>>> WARNING: DT compatible string "fsl,qoriq-mc" appears un-documented -- check ./Documentation/devicetree/bindings/
>>> #690: FILE: drivers/bus/fsl-mc/fsl_mc_bus.c:528:
>>> +    {.compatible = "fsl,qoriq-mc",},
>>>
>>> For the former warning, I'd suggest moving patch 4/4's contents up
>>> in the series.
>> I tried moving 4/4 to be 1/4 but still get the the same warning from checkpatch. So, this suggestion does not work. Besides, I took a look
>> at other commits that update the MAINTAINERS such as
>> 563da3a90364fc29cd09bed034162592e591747a, and that commit comes after the commits that added the new files.
>
> The alternative would be to add MAINTAINERS entries for the files you add in the patch that adds the files.
>
I tried this but still get the checpatch warning:

WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?

Still, I will add MAINTAINERS entries in each patch that adds files, 
instead of having a separate patch just for that.

>
> Alex
>

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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-18 13:14       ` Alexander Graf
  2014-09-18 20:22         ` Kim Phillips
  2014-09-19  0:18         ` Stuart Yoder
@ 2014-09-19  2:34         ` German Rivera
  2014-09-19 18:25         ` Stuart Yoder
  3 siblings, 0 replies; 43+ messages in thread
From: German Rivera @ 2014-09-19  2:34 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Kim Phillips, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	<stuart.yoder@freescale.com>,
	<scottwood@freescale.com>,
	<linuxppc-release@linux.freescale.net>

On 09/18/2014 08:14 AM, Alexander Graf wrote:
>

>>>
>>>> +int __must_check fsl_create_mc_io(phys_addr_t mc_portal_phys_addr,
>>>> +                  uint32_t mc_portal_size,
>>>> +                  uint32_t flags, struct fsl_mc_io **new_mc_io)
>>>> +{
>>>> +    int error = -EINVAL;
>>>> +    struct fsl_mc_io *mc_io = NULL;
>>>> +
>>>> +    mc_io = kzalloc(sizeof(*mc_io), GFP_KERNEL);
>>>> +    if (mc_io == NULL) {
>>>> +        error = -ENOMEM;
>>>> +        pr_err("No memory to allocate mc_io\n");
>>>> +        goto error;
>>>> +    }
>>>> +
>>>> +    mc_io->magic = FSL_MC_IO_MAGIC;
>>>> +    mc_io->flags = flags;
>>>> +    mc_io->portal_phys_addr = mc_portal_phys_addr;
>>>> +    mc_io->portal_size = mc_portal_size;
>>>> +    spin_lock_init(&mc_io->spinlock);
>>>> +    error = map_mc_portal(mc_portal_phys_addr,
>>>> +                  mc_portal_size, &mc_io->portal_virt_addr);
>>>> +    if (error < 0)
>>>> +        goto error;
>>>> +
>>>> +    *new_mc_io = mc_io;
>>>> +    return 0;
>>>
>>> if a fn only returns an address or error, it can return ERR_PTR
>>> (e.g., -ENOMEM), and the callsite use IS_ERR() to determine whether
>>> there was an error or address returned.  This makes code much
>>> simpler instead of passing address values back by reference.
>> I disagree. I don't see why the alternative you suggest makes the code "much simpler".
>>
>>>> +error:
>>>> +    if (mc_io != NULL) {
>>>> +        if (mc_io->portal_virt_addr != NULL) {
>>>> +            unmap_mc_portal(mc_portal_phys_addr,
>>>> +                    mc_portal_size,
>>>> +                    mc_io->portal_virt_addr);
>>>> +        }
>>>> +
>>>> +        kfree(mc_io);
>>>
>>> kfree can handle being passed NULL, but again, might want to
>>> consider using devm_ functions instead.
>> No. We cannot use devm_ functions here as there is no device passed in.
>
> Is it a good idea to lose your device context in any function? Whenever I dropped contexts in helper I usually ended up regretting it later ;).
>
OK, I will add a dev param to this the fsl_mc_io_create() function, to
enable the use of devm_ APIs.

>>>> +    if (mc_io->flags & FSL_MC_IO_PORTAL_SHARED) {
>>>> +        spin_lock_irqsave(&mc_io->spinlock, irqsave_flags);
>>>> +        lock_acquired = true;
>>>> +    }
>>>> +
>>>> +    mc_write_command(mc_io->portal_virt_addr, cmd);
>>>> +
>>>> +    for (;;) {
>>>> +        status = mc_read_response(mc_io->portal_virt_addr, cmd);
>>>> +        if (status != MC_CMD_STATUS_READY)
>>>> +            break;
>>>> +
>>>> +        /*
>>>> +         * TODO: When MC command completion interrupts are supported
>>>> +         * call wait function here instead of udelay()
>>>> +         */
>>>> +        udelay(MC_CMD_COMPLETION_POLLING_INTERVAL);
>>>> +        if (time_after_eq(jiffies, jiffies_until_timeout)) {
>>>> +            error = -ETIMEDOUT;
>>>> +            goto out;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    error = mc_status_to_error(status);
>>>> +out:
>>>> +    if (lock_acquired)
>>>> +        spin_unlock_irqrestore(&mc_io->spinlock, irqsave_flags);
>>>
>>> so if the portal is shared, we take a lock, disable interrupts, and
>>> then potentially udelay for a whopping 500usec, then check to see if
>>> _100_usec have passed, and thus _always_ issue a timeout error, even
>>> if the device took < 100usec to consume the command???
>> That is not true. The 100 is in jiffies not in usec:
>
> If you always wait for 100 jiffies, the timeout code suddenly depends on the HZ value which is kernel configuration, no? Wouldn't it be better to base the timeout on real wall time?
>
I will change the value of the timeout to be a function of HZ instead of 
a hard-coded jiffies value. Also, to avoid future confusion, I'll
rename the timeout and delay macros to include their units:

/**
  * Timeout in jiffies to wait for the completion of an MC command
  */
#define MC_CMD_COMPLETION_TIMEOUT_JIFFIES   (HZ / 2)	/* 500 ms */

/**
  * Delay in microseconds between polling iterations while
  * waiting for MC command completion
  */
#define MC_CMD_COMPLETION_POLLING_INTERVAL_USECS    500	/* 0.5 ms */

>>
>> /**
>> * Timeout in jiffies to wait for the completion of an MC command
>> */
>> #define MC_CMD_COMPLETION_TIMEOUT   100
>>
>> /**
>> * Delay in microseconds between polling iterations while
>> * waiting for MC command completion
>> */
>> #define MC_CMD_COMPLETION_POLLING_INTERVAL  500
>>
>>
>>> Not to mention this code will spin perpetually with IRQs disabled if
>>> the read_response never returns ready.  I also don't see a reason
>>> why IRQs are being disabled in the first place - it's not being used
>>> in an IRQ handler...perhaps we need to wait until command completion
>>> IRQs are supported :)
>> I agree that disabling interrupts while doing polling is not efficient. I was assuming the worst case scenario of sharing the portal: both
>> threads and interrupt handlers accessing the same portal at the same time. If only threads access the same portal, we don't need to disable interrupts and even further we can use a mutex instead of a spinlock.
>> If only interrupt handlers access a given portal (from multiple CPUs)
>> we have use a spinlock but we don't need to disabel interrupts.
>> If both threads and interrupt handlers access a given portal, then
>> we need to both use a spinlock and disable interrupts
>>
>> I will change synchronization logic in the v2 respin to avoid
>> disabling interrupts in the first two cases above.
>>
>>>> +/**
>>>> + * @brief    Management Complex firmware version information
>>>> + */
>>>> +#define MC_VER_MAJOR 2
>>>> +#define MC_VER_MINOR 0
>>>
>>> code should be adjusted to run on all *compatible* versions of h/w,
>>> not strictly the one set in these defines.
>> This comment is not precise enough be actionable.
>> What exactly you want to be changed  here?
>
> I think the easy thing to do is to convert the exact version check into a ranged version check: have minimum and maximum versions you support. Or a list of exact versions you support. Or not check for the version at all - or only for the major version and guarantee that the major version indicates backwards compatibility.
>
I will keep only the major version check and remove the minor version check.

>>
>>>> +/**
>>>> + * @brief    Disconnects one endpoint to remove its network link
>>>> + *
>>>> + * @param[in]   mc_io        Pointer to opaque I/O object
>>>> + * @param[in]    dprc_handle    Handle to the DPRC object
>>>> + * @param[in]   endpoint    Endpoint configuration parameters.
>>>> + *
>>>> + * @returns    '0' on Success; Error code otherwise.
>>>> + * */
>>>> +int dprc_disconnect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
>>>> +            struct dprc_endpoint *endpoint);
>>>> +
>>>> +/*! @} */
>>>
>>> this entire file is riddled with non-kernel-doc comment markers:  see
>>> Documentation/kernel-doc-nano-HOWTO.txt on how to write function and
>>> other types of comments in a kernel-doc compliant format.
>> This is because this file is using doxygen comments, as it was developed
>> by another team. Unless someone else has an objection, I will leave the doxygen comments alone and not make any change here.
>
> Do you see any other source files in Linux using doxygen comments? Mixing different documentation styles can easily become a big mess, because you can't generate external documentation consistently for the whole tree.
>
>
Stuart already answered this question.


> Alex
>

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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-18 20:22         ` Kim Phillips
  2014-09-18 23:03           ` Scott Wood
  2014-09-18 23:13           ` Stuart Yoder
@ 2014-09-19  3:05           ` German Rivera
  2014-09-19 17:19             ` Kim Phillips
  2 siblings, 1 reply; 43+ messages in thread
From: German Rivera @ 2014-09-19  3:05 UTC (permalink / raw)
  To: Kim Phillips, Alexander Graf
  Cc: <gregkh@linuxfoundation.org>, <arnd@arndb.de>,
	<linux-kernel@vger.kernel.org>,
	<stuart.yoder@freescale.com>,
	<scottwood@freescale.com>,
	<linuxppc-release@linux.freescale.net>


On 09/18/2014 03:22 PM, Kim Phillips wrote:
> On Thu, 18 Sep 2014 15:14:03 +0200

>>> unnecessarily complicated error path, plus a simpler
>>>> implementation can be made if fn can return the mapped address, like
>>>> so:
>>>>
>>>> static void __iomem *map_mc_portal(phys_addr_t mc_portal_phys_addr,
>>>>                                     uint32_t mc_portal_size)
>>>> {
>>>>          struct resource *res;
>>>>          void __iomem *mapped_addr;
>>>>
>>>>          res = request_mem_region(mc_portal_phys_addr, mc_portal_size,
>>>>                                   "mc_portal");
>>>>          if (!res)
>>>>                  return NULL;
>>>>
>>>>          mapped_addr = ioremap_nocache(mc_portal_phys_addr,
>>>>                                        mc_portal_size);
>>>>          if (!mapped_addr)
>>>>                  release_mem_region(mc_portal_phys_addr, mc_portal_size);
>>>>
>>>>          return mapped_addr;
>>>> }
>>>>
>>>> the callsite can return -ENOMEM to its caller if returned NULL.  This
>>>> can be improved even further if devm_ functions are used:  this is
>>>> just an example of how to simplify the code using early returns
>>>> instead of goto error.
>>>
>>> I disagree. Having a common error return point is more maintainable than having multiple returns as having the clean-up logic in one place is more maintainable and makes the min path (non-error) more readable.
>
> my comment is not that much different from Joe's here:
>
> https://lkml.org/lkml/2014/9/17/381
>
> but hopefully all this will change with a devm_ based implementation.
>
I will refactor this function to use devm_ functions, to simplify the 
error cleanup logic as you suggested, but still keep the current
signature of the function, as I don't think it is a good practice
to just return NULL in case of error, hiding the actual cause of the 
error. Also, mixing returning a valid pointer and an error encoded
as an invalid pointer is not clean and can be error-prone for callers, 
if some caller just checks for NULL instead of using IS_ERR() ir
IS_ERR_OR_NULL().


>>>>> +int __must_check fsl_create_mc_io(phys_addr_t mc_portal_phys_addr,
>>>>> +                  uint32_t mc_portal_size,
>>>>> +                  uint32_t flags, struct fsl_mc_io **new_mc_io)
>>>>> +{
>>>>> +    int error = -EINVAL;
>>>>> +    struct fsl_mc_io *mc_io = NULL;
>>>>> +
>>>>> +    mc_io = kzalloc(sizeof(*mc_io), GFP_KERNEL);
>>>>> +    if (mc_io == NULL) {
>>>>> +        error = -ENOMEM;
>>>>> +        pr_err("No memory to allocate mc_io\n");
>>>>> +        goto error;
>>>>> +    }
>>>>> +
>>>>> +    mc_io->magic = FSL_MC_IO_MAGIC;
>>>>> +    mc_io->flags = flags;
>>>>> +    mc_io->portal_phys_addr = mc_portal_phys_addr;
>>>>> +    mc_io->portal_size = mc_portal_size;
>>>>> +    spin_lock_init(&mc_io->spinlock);
>>>>> +    error = map_mc_portal(mc_portal_phys_addr,
>>>>> +                  mc_portal_size, &mc_io->portal_virt_addr);
>>>>> +    if (error < 0)
>>>>> +        goto error;
>>>>> +
>>>>> +    *new_mc_io = mc_io;
>>>>> +    return 0;
>>>>
>>>> if a fn only returns an address or error, it can return ERR_PTR
>>>> (e.g., -ENOMEM), and the callsite use IS_ERR() to determine whether
>>>> there was an error or address returned.  This makes code much
>>>> simpler instead of passing address values back by reference.
>>> I disagree. I don't see why the alternative you suggest makes the code "much simpler".
>
> because it eliminates the need for the extra pass-by-reference
> argument struct fsl_mc_io **new_mc_io.
>
Having an extra pass-by-reference argument does not make the code
that complicated. Bit more importantly the simplicity that you gain
by not using the extra pass-by-reference pointer comes at the price
of making the interface less safer to use (more error-prone
for the caller as I mentioned above), which I think it is a bad trade off.

>>>>> +void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
>>>>> +{
>>>>> +    if (WARN_ON(mc_io->magic != FSL_MC_IO_MAGIC))
>>>>> +        return;
>>>>> +
>>>>> +    if (mc_io->portal_virt_addr != NULL) {
>>>>> +        unmap_mc_portal(mc_io->portal_phys_addr,
>>>>> +                mc_io->portal_size, mc_io->portal_virt_addr);
>>>>
>>>> unmap_mc_portal already checks for virt_addr, this is another
>>>> example where the code goes too far checking for NULL.
>>> I disagree. Having the extra check is harmless and more importantly makes the intent explicit that we should only call unmap_mc_portal if we called map_mc_portal earlier.
>
> the code is doing this:
>
>          if (mc_io->portal_virt_addr != NULL) {
> 	        if (WARN_ON(mc_portal_virt_addr == NULL))
>          	        return;
>
> which is redundant and therefore makes it unnecessarily complicated,
> after all, a stack trace will occur if mc_portal_virt_addr is
> referenced anyway, making the WARN_ON clause redundant, too.
>
All this will be gone with the refactoring to use devm_ APIs.

>>>>> +        mc_io->portal_virt_addr = NULL;
>>>>> +    }
>>>>> +
>>>>> +    mc_io->magic = 0x0;
>>>>> +    kfree(mc_io);
>>>>> +}
>
> btw, what's the point of zeroing out things that are being freed?
>
In this particular case, this comment doe snot apply anymore, as
the magic filed will be removed.

>>>>> +/**
>>>>> + * @brief    Management Complex firmware version information
>>>>> + */
>>>>> +#define MC_VER_MAJOR 2
>>>>> +#define MC_VER_MINOR 0
>>>>
>>>> code should be adjusted to run on all *compatible* versions of h/w,
>>>> not strictly the one set in these defines.
>>> This comment is not precise enough be actionable.
>>> What exactly you want to be changed  here?
>>
>> I think the easy thing to do is to convert the exact version check into a ranged version check: have minimum and maximum versions you support. Or a list of exact versions you support. Or not check for the version at all - or only for the major version and guarantee that the major version indicates backwards compatibility.
>
> yes, this was my point: elsewhere I noticed the code denies to run
> iff those defines are not matched exactly: that code should change
> to run as Alex describes.
>
As I mentioned in the reply to Alex, I will remove the minor version check.


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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-19  3:05           ` German Rivera
@ 2014-09-19 17:19             ` Kim Phillips
  2014-09-19 19:06               ` Stuart Yoder
  0 siblings, 1 reply; 43+ messages in thread
From: Kim Phillips @ 2014-09-19 17:19 UTC (permalink / raw)
  To: German Rivera
  Cc: Alexander Graf, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	<stuart.yoder@freescale.com>,
	<scottwood@freescale.com>,
	<linuxppc-release@linux.freescale.net>

On Thu, 18 Sep 2014 22:05:03 -0500
German Rivera <German.Rivera@freescale.com> wrote:

> On 09/18/2014 03:22 PM, Kim Phillips wrote:
> > On Thu, 18 Sep 2014 15:14:03 +0200
> 
> >>> unnecessarily complicated error path, plus a simpler
> >>>> implementation can be made if fn can return the mapped address, like
> >>>> so:
> >>>>
> >>>> static void __iomem *map_mc_portal(phys_addr_t mc_portal_phys_addr,
> >>>>                                     uint32_t mc_portal_size)
> >>>> {
> >>>>          struct resource *res;
> >>>>          void __iomem *mapped_addr;
> >>>>
> >>>>          res = request_mem_region(mc_portal_phys_addr, mc_portal_size,
> >>>>                                   "mc_portal");
> >>>>          if (!res)
> >>>>                  return NULL;
> >>>>
> >>>>          mapped_addr = ioremap_nocache(mc_portal_phys_addr,
> >>>>                                        mc_portal_size);
> >>>>          if (!mapped_addr)
> >>>>                  release_mem_region(mc_portal_phys_addr, mc_portal_size);
> >>>>
> >>>>          return mapped_addr;
> >>>> }
> >>>>
> >>>> the callsite can return -ENOMEM to its caller if returned NULL.  This
> >>>> can be improved even further if devm_ functions are used:  this is
> >>>> just an example of how to simplify the code using early returns
> >>>> instead of goto error.
> >>>
> >>> I disagree. Having a common error return point is more maintainable than having multiple returns as having the clean-up logic in one place is more maintainable and makes the min path (non-error) more readable.
> >
> > my comment is not that much different from Joe's here:
> >
> > https://lkml.org/lkml/2014/9/17/381
> >
> > but hopefully all this will change with a devm_ based implementation.
> >
> I will refactor this function to use devm_ functions, to simplify the 
> error cleanup logic as you suggested, but still keep the current
> signature of the function, as I don't think it is a good practice
> to just return NULL in case of error, hiding the actual cause of the 
> error. Also, mixing returning a valid pointer and an error encoded
> as an invalid pointer is not clean and can be error-prone for callers, 
> if some caller just checks for NULL instead of using IS_ERR() ir
> IS_ERR_OR_NULL().

we'll make sure callers don't do that then :)

> >>>>> +void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
> >>>>> +{
> >>>>> +    if (WARN_ON(mc_io->magic != FSL_MC_IO_MAGIC))
> >>>>> +        return;
> >>>>> +
> >>>>> +    if (mc_io->portal_virt_addr != NULL) {
> >>>>> +        unmap_mc_portal(mc_io->portal_phys_addr,
> >>>>> +                mc_io->portal_size, mc_io->portal_virt_addr);
> >>>>
> >>>> unmap_mc_portal already checks for virt_addr, this is another
> >>>> example where the code goes too far checking for NULL.
> >>> I disagree. Having the extra check is harmless and more importantly makes the intent explicit that we should only call unmap_mc_portal if we called map_mc_portal earlier.
> >
> > the code is doing this:
> >
> >          if (mc_io->portal_virt_addr != NULL) {
> > 	        if (WARN_ON(mc_portal_virt_addr == NULL))
> >          	        return;
> >
> > which is redundant and therefore makes it unnecessarily complicated,
> > after all, a stack trace will occur if mc_portal_virt_addr is
> > referenced anyway, making the WARN_ON clause redundant, too.
> >
> All this will be gone with the refactoring to use devm_ APIs.

sounds good.

> >>>>> +        mc_io->portal_virt_addr = NULL;
> >>>>> +    }
> >>>>> +
> >>>>> +    mc_io->magic = 0x0;
> >>>>> +    kfree(mc_io);
> >>>>> +}
> >
> > btw, what's the point of zeroing out things that are being freed?
> >
> In this particular case, this comment doe snot apply anymore, as
> the magic filed will be removed.

it still applies for portal_virt_addr.

> >>>>> +/**
> >>>>> + * @brief    Management Complex firmware version information
> >>>>> + */
> >>>>> +#define MC_VER_MAJOR 2
> >>>>> +#define MC_VER_MINOR 0
> >>>>
> >>>> code should be adjusted to run on all *compatible* versions of h/w,
> >>>> not strictly the one set in these defines.
> >>> This comment is not precise enough be actionable.
> >>> What exactly you want to be changed  here?
> >>
> >> I think the easy thing to do is to convert the exact version check into a ranged version check: have minimum and maximum versions you support. Or a list of exact versions you support. Or not check for the version at all - or only for the major version and guarantee that the major version indicates backwards compatibility.
> >
> > yes, this was my point: elsewhere I noticed the code denies to run
> > iff those defines are not matched exactly: that code should change
> > to run as Alex describes.
> >
> As I mentioned in the reply to Alex, I will remove the minor version check.

the code should be able to run on all subsequent versions of the
h/w, even in the major version case.

Kim

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

* RE: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-18 13:14       ` Alexander Graf
                           ` (2 preceding siblings ...)
  2014-09-19  2:34         ` German Rivera
@ 2014-09-19 18:25         ` Stuart Yoder
  2014-09-19 20:58           ` Kim Phillips
  3 siblings, 1 reply; 43+ messages in thread
From: Stuart Yoder @ 2014-09-19 18:25 UTC (permalink / raw)
  To: Alexander Graf, Jose Rivera
  Cc: Kim Phillips, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	Scott Wood, <linuxppc-release@linux.freescale.net>



> -----Original Message-----
> From: Yoder Stuart-B08248
> Sent: Thursday, September 18, 2014 7:19 PM
> To: 'Alexander Graf'; Rivera Jose-B46482
> Cc: Phillips Kim-R1AAHA; <gregkh@linuxfoundation.org>; <arnd@arndb.de>; <linux-kernel@vger.kernel.org>; Wood
> Scott-B07421; <linuxppc-release@linux.freescale.net>
> Subject: RE: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
> 
> +/**
> > >>> + * @brief    Disconnects one endpoint to remove its network link
> > >>> + *
> > >>> + * @param[in]   mc_io        Pointer to opaque I/O object
> > >>> + * @param[in]    dprc_handle    Handle to the DPRC object
> > >>> + * @param[in]   endpoint    Endpoint configuration parameters.
> > >>> + *
> > >>> + * @returns    '0' on Success; Error code otherwise.
> > >>> + * */
> > >>> +int dprc_disconnect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
> > >>> +            struct dprc_endpoint *endpoint);
> > >>> +
> > >>> +/*! @} */
> > >>
> > >> this entire file is riddled with non-kernel-doc comment markers:  see
> > >> Documentation/kernel-doc-nano-HOWTO.txt on how to write function and
> > >> other types of comments in a kernel-doc compliant format.
> > > This is because this file is using doxygen comments, as it was developed
> > > by another team. Unless someone else has an objection, I will leave the doxygen comments alone and not
> make
> > any change here.
> >
> > Do you see any other source files in Linux using doxygen comments?
> 
> Yes.  Grep around a bit and you'll see examples of it.  I grep'ed for some
> doxygen tags and found close to 200 source files with them.
> 
> > Mixing different documentation styles can
> > easily become a big mess, because you can't generate external documentation consistently for the whole
> tree.
> 
> As German mentioned elsewhere, this file is an interface to a hardware block,
> was written by another team targetting a wide variety of environments-- u-boot,
> Linux, user space, other OSes etc.
> 
> We left the doxygen stuff there because while admitedly not used much, there
> are other examples of it in the kernel and the documentation seems useful.
> If it can't go into the kernel as is, we can just delete it.

...to be clear, we could just delete the doyxen tags.  There is no scenario
where I would envision anyone generating documentation from these files in
the kernel.  The tags are there because of where we grabbed the source from.
It certainly would benefit no one by conversion to kerneldoc.

However, just leaving the comments and doxygen tags alone as is would be nice.

Stuart


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

* RE: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-19 17:19             ` Kim Phillips
@ 2014-09-19 19:06               ` Stuart Yoder
  2014-09-19 20:24                 ` Kim Phillips
  0 siblings, 1 reply; 43+ messages in thread
From: Stuart Yoder @ 2014-09-19 19:06 UTC (permalink / raw)
  To: Kim Phillips, Jose Rivera
  Cc: Alexander Graf, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	Scott Wood, <linuxppc-release@linux.freescale.net>

> > >>>>> +/**
> > >>>>> + * @brief    Management Complex firmware version information
> > >>>>> + */
> > >>>>> +#define MC_VER_MAJOR 2
> > >>>>> +#define MC_VER_MINOR 0
> > >>>>
> > >>>> code should be adjusted to run on all *compatible* versions of h/w,
> > >>>> not strictly the one set in these defines.
> > >>> This comment is not precise enough be actionable.
> > >>> What exactly you want to be changed  here?
> > >>
> > >> I think the easy thing to do is to convert the exact version check into a ranged version check: have
> minimum and maximum versions you support. Or a list of exact versions you support. Or not check for the
> version at all - or only for the major version and guarantee that the major version indicates backwards
> compatibility.
> > >
> > > yes, this was my point: elsewhere I noticed the code denies to run
> > > iff those defines are not matched exactly: that code should change
> > > to run as Alex describes.
> > >
> > As I mentioned in the reply to Alex, I will remove the minor version check.
> 
> the code should be able to run on all subsequent versions of the
> h/w, even in the major version case.

You're right, in the future if there are future major versions we would want this
same driver to function on multiple versions of the hardware.  But at this
point in time we don't know what future evolutions there will be and we 
need the check to error out for now.   The driver will have to be changed
in the future to dynamically deal with different versions.

We could add a TODO in the driver to note that.

Stuart

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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-19 19:06               ` Stuart Yoder
@ 2014-09-19 20:24                 ` Kim Phillips
  2014-09-19 20:32                   ` Alexander Graf
  2014-09-19 21:30                   ` Stuart Yoder
  0 siblings, 2 replies; 43+ messages in thread
From: Kim Phillips @ 2014-09-19 20:24 UTC (permalink / raw)
  To: Yoder Stuart-B08248
  Cc: Rivera Jose-B46482, Alexander Graf,
	<gregkh@linuxfoundation.org>, <arnd@arndb.de>,
	<linux-kernel@vger.kernel.org>,
	Wood Scott-B07421, <linuxppc-release@linux.freescale.net>

On Fri, 19 Sep 2014 14:06:32 -0500
Yoder Stuart-B08248 <stuart.yoder@freescale.com> wrote:

> > > >>>>> +/**
> > > >>>>> + * @brief    Management Complex firmware version information
> > > >>>>> + */
> > > >>>>> +#define MC_VER_MAJOR 2
> > > >>>>> +#define MC_VER_MINOR 0
> > > >>>>
> > > >>>> code should be adjusted to run on all *compatible* versions of h/w,
> > > >>>> not strictly the one set in these defines.
> > > >>> This comment is not precise enough be actionable.
> > > >>> What exactly you want to be changed  here?
> > > >>
> > > >> I think the easy thing to do is to convert the exact version check into a ranged version check: have
> > minimum and maximum versions you support. Or a list of exact versions you support. Or not check for the
> > version at all - or only for the major version and guarantee that the major version indicates backwards
> > compatibility.
> > > >
> > > > yes, this was my point: elsewhere I noticed the code denies to run
> > > > iff those defines are not matched exactly: that code should change
> > > > to run as Alex describes.
> > > >
> > > As I mentioned in the reply to Alex, I will remove the minor version check.
> > 
> > the code should be able to run on all subsequent versions of the
> > h/w, even in the major version case.
> 
> You're right, in the future if there are future major versions we would want this
> same driver to function on multiple versions of the hardware.  But at this
> point in time we don't know what future evolutions there will be and we 
> need the check to error out for now.

why?  We have to make the standard assumption that newer versions
will be backward compatible, in which case the driver should be left
to run.

>   The driver will have to be changed
> in the future to dynamically deal with different versions.
> 
> We could add a TODO in the driver to note that.

"TODO: add support for new h/w versions" is almost universally true
for all drivers, we don't need to write that down.

Support for new h/w versions with new features should be
incrementally added once they're known.

Kim

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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-19 20:24                 ` Kim Phillips
@ 2014-09-19 20:32                   ` Alexander Graf
  2014-09-19 20:41                     ` Scott Wood
  2014-09-19 21:37                     ` Stuart Yoder
  2014-09-19 21:30                   ` Stuart Yoder
  1 sibling, 2 replies; 43+ messages in thread
From: Alexander Graf @ 2014-09-19 20:32 UTC (permalink / raw)
  To: Kim Phillips, Yoder Stuart-B08248
  Cc: Rivera Jose-B46482, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	Wood Scott-B07421, <linuxppc-release@linux.freescale.net>



On 19.09.14 22:24, Kim Phillips wrote:
> On Fri, 19 Sep 2014 14:06:32 -0500
> Yoder Stuart-B08248 <stuart.yoder@freescale.com> wrote:
> 
>>>>>>>>> +/**
>>>>>>>>> + * @brief    Management Complex firmware version information
>>>>>>>>> + */
>>>>>>>>> +#define MC_VER_MAJOR 2
>>>>>>>>> +#define MC_VER_MINOR 0
>>>>>>>>
>>>>>>>> code should be adjusted to run on all *compatible* versions of h/w,
>>>>>>>> not strictly the one set in these defines.
>>>>>>> This comment is not precise enough be actionable.
>>>>>>> What exactly you want to be changed  here?
>>>>>>
>>>>>> I think the easy thing to do is to convert the exact version check into a ranged version check: have
>>> minimum and maximum versions you support. Or a list of exact versions you support. Or not check for the
>>> version at all - or only for the major version and guarantee that the major version indicates backwards
>>> compatibility.
>>>>>
>>>>> yes, this was my point: elsewhere I noticed the code denies to run
>>>>> iff those defines are not matched exactly: that code should change
>>>>> to run as Alex describes.
>>>>>
>>>> As I mentioned in the reply to Alex, I will remove the minor version check.
>>>
>>> the code should be able to run on all subsequent versions of the
>>> h/w, even in the major version case.
>>
>> You're right, in the future if there are future major versions we would want this
>> same driver to function on multiple versions of the hardware.  But at this
>> point in time we don't know what future evolutions there will be and we 
>> need the check to error out for now.
> 
> why?  We have to make the standard assumption that newer versions
> will be backward compatible, in which case the driver should be left
> to run.

How much is the interface set in stone? Can we indicate to the MC that
we want version x of the protocol? Then the MC can tell us whether it's
compatible or not.

> 
>>   The driver will have to be changed
>> in the future to dynamically deal with different versions.
>>
>> We could add a TODO in the driver to note that.
> 
> "TODO: add support for new h/w versions" is almost universally true
> for all drivers, we don't need to write that down.
> 
> Support for new h/w versions with new features should be
> incrementally added once they're known.

The "version id" is basically the equivalent of the pci device id. We
don't add wildcards there either for unknown pieces of hardware, so
limiting to driver to "known good" devices is sane IMHO.


Alex

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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-19 20:32                   ` Alexander Graf
@ 2014-09-19 20:41                     ` Scott Wood
  2014-09-19 21:46                       ` Alexander Graf
  2014-09-19 21:37                     ` Stuart Yoder
  1 sibling, 1 reply; 43+ messages in thread
From: Scott Wood @ 2014-09-19 20:41 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Kim Phillips, Yoder Stuart-B08248, Rivera Jose-B46482,
	<gregkh@linuxfoundation.org>, <arnd@arndb.de>,
	<linux-kernel@vger.kernel.org>,
	<linuxppc-release@linux.freescale.net>

On Fri, 2014-09-19 at 22:32 +0200, Alexander Graf wrote:
> 
> On 19.09.14 22:24, Kim Phillips wrote:
> > On Fri, 19 Sep 2014 14:06:32 -0500
> > Yoder Stuart-B08248 <stuart.yoder@freescale.com> wrote:
> > 
> >>>>>>>>> +/**
> >>>>>>>>> + * @brief    Management Complex firmware version information
> >>>>>>>>> + */
> >>>>>>>>> +#define MC_VER_MAJOR 2
> >>>>>>>>> +#define MC_VER_MINOR 0
> >>>>>>>>
> >>>>>>>> code should be adjusted to run on all *compatible* versions of h/w,
> >>>>>>>> not strictly the one set in these defines.
> >>>>>>> This comment is not precise enough be actionable.
> >>>>>>> What exactly you want to be changed  here?
> >>>>>>
> >>>>>> I think the easy thing to do is to convert the exact version check into a ranged version check: have
> >>> minimum and maximum versions you support. Or a list of exact versions you support. Or not check for the
> >>> version at all - or only for the major version and guarantee that the major version indicates backwards
> >>> compatibility.
> >>>>>
> >>>>> yes, this was my point: elsewhere I noticed the code denies to run
> >>>>> iff those defines are not matched exactly: that code should change
> >>>>> to run as Alex describes.
> >>>>>
> >>>> As I mentioned in the reply to Alex, I will remove the minor version check.
> >>>
> >>> the code should be able to run on all subsequent versions of the
> >>> h/w, even in the major version case.
> >>
> >> You're right, in the future if there are future major versions we would want this
> >> same driver to function on multiple versions of the hardware.  But at this
> >> point in time we don't know what future evolutions there will be and we 
> >> need the check to error out for now.
> > 
> > why?  We have to make the standard assumption that newer versions
> > will be backward compatible, in which case the driver should be left
> > to run.
> 
> How much is the interface set in stone? Can we indicate to the MC that
> we want version x of the protocol? Then the MC can tell us whether it's
> compatible or not.

I don't trust that new versions will be 100% backwards compatible
(though I hope they will be), but do we normally bother making a driver
refuse to run on newer versions?  Sure, if we need to explicitly match a
comptible string or PCI ID, the match will be rejected if the driver
doesn't know about it, but if it's a version in a register we usually
only check for known issues with certain versions.
 
> >>   The driver will have to be changed
> >> in the future to dynamically deal with different versions.
> >>
> >> We could add a TODO in the driver to note that.
> > 
> > "TODO: add support for new h/w versions" is almost universally true
> > for all drivers, we don't need to write that down.
> > 
> > Support for new h/w versions with new features should be
> > incrementally added once they're known.
> 
> The "version id" is basically the equivalent of the pci device id. We
> don't add wildcards there either for unknown pieces of hardware, so
> limiting to driver to "known good" devices is sane IMHO.

How would you go about adding a wildcard to a PCI ID even if you wanted
to?  Version information on PCI is not separate from device
identification.

-Scott



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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-19 18:25         ` Stuart Yoder
@ 2014-09-19 20:58           ` Kim Phillips
  2014-09-22 14:42             ` Stuart Yoder
  0 siblings, 1 reply; 43+ messages in thread
From: Kim Phillips @ 2014-09-19 20:58 UTC (permalink / raw)
  To: Yoder Stuart-B08248
  Cc: Alexander Graf, Rivera Jose-B46482, Phillips Kim-R1AAHA,
	<gregkh@linuxfoundation.org>, <arnd@arndb.de>,
	<linux-kernel@vger.kernel.org>,
	Wood Scott-B07421, <linuxppc-release@linux.freescale.net>

On Fri, 19 Sep 2014 13:25:06 -0500
Yoder Stuart-B08248 <stuart.yoder@freescale.com> wrote:

> > From: Yoder Stuart-B08248
> > Sent: Thursday, September 18, 2014 7:19 PM
> > 
> > +/**
> > > >>> + * @brief    Disconnects one endpoint to remove its network link
> > > >>> + *
> > > >>> + * @param[in]   mc_io        Pointer to opaque I/O object
> > > >>> + * @param[in]    dprc_handle    Handle to the DPRC object
> > > >>> + * @param[in]   endpoint    Endpoint configuration parameters.
> > > >>> + *
> > > >>> + * @returns    '0' on Success; Error code otherwise.
> > > >>> + * */
> > > >>> +int dprc_disconnect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
> > > >>> +            struct dprc_endpoint *endpoint);
> > > >>> +
> > > >>> +/*! @} */
> > > >>
> > > >> this entire file is riddled with non-kernel-doc comment markers:  see
> > > >> Documentation/kernel-doc-nano-HOWTO.txt on how to write function and
> > > >> other types of comments in a kernel-doc compliant format.
> > > > This is because this file is using doxygen comments, as it was developed
> > > > by another team. Unless someone else has an objection, I will leave the doxygen comments alone and not
> > make
> > > any change here.
> > >
> > > Do you see any other source files in Linux using doxygen comments?
> > 
> > Yes.  Grep around a bit and you'll see examples of it.  I grep'ed for some
> > doxygen tags and found close to 200 source files with them.

grepping for the one in this patch above - "! @}" - returns nothing.

> > > Mixing different documentation styles can
> > > easily become a big mess, because you can't generate external documentation consistently for the whole
> > tree.
> > 
> > As German mentioned elsewhere, this file is an interface to a hardware block,
> > was written by another team targetting a wide variety of environments-- u-boot,
> > Linux, user space, other OSes etc.
> > 
> > We left the doxygen stuff there because while admitedly not used much, there
> > are other examples of it in the kernel and the documentation seems useful.
> > If it can't go into the kernel as is, we can just delete it.
> 
> ...to be clear, we could just delete the doyxen tags.  There is no scenario
> where I would envision anyone generating documentation from these files in
> the kernel.  The tags are there because of where we grabbed the source from.
> It certainly would benefit no one by conversion to kerneldoc.

except kerneldoc users :)

> However, just leaving the comments and doxygen tags alone as is would be nice.

they are incompatible with kerneldoc.

Kim

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

* RE: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-19 20:24                 ` Kim Phillips
  2014-09-19 20:32                   ` Alexander Graf
@ 2014-09-19 21:30                   ` Stuart Yoder
  1 sibling, 0 replies; 43+ messages in thread
From: Stuart Yoder @ 2014-09-19 21:30 UTC (permalink / raw)
  To: Kim Phillips
  Cc: Jose Rivera, Alexander Graf, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	Scott Wood, <linuxppc-release@linux.freescale.net>



> -----Original Message-----
> From: Kim Phillips [mailto:kim.phillips@freescale.com]
> Sent: Friday, September 19, 2014 3:25 PM
> To: Yoder Stuart-B08248
> Cc: Rivera Jose-B46482; Alexander Graf; <gregkh@linuxfoundation.org>; <arnd@arndb.de>; <linux-
> kernel@vger.kernel.org>; Wood Scott-B07421; <linuxppc-release@linux.freescale.net>
> Subject: Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
> 
> On Fri, 19 Sep 2014 14:06:32 -0500
> Yoder Stuart-B08248 <stuart.yoder@freescale.com> wrote:
> 
> > > > >>>>> +/**
> > > > >>>>> + * @brief    Management Complex firmware version information
> > > > >>>>> + */
> > > > >>>>> +#define MC_VER_MAJOR 2
> > > > >>>>> +#define MC_VER_MINOR 0
> > > > >>>>
> > > > >>>> code should be adjusted to run on all *compatible* versions of h/w,
> > > > >>>> not strictly the one set in these defines.
> > > > >>> This comment is not precise enough be actionable.
> > > > >>> What exactly you want to be changed  here?
> > > > >>
> > > > >> I think the easy thing to do is to convert the exact version check into a ranged version check: have
> > > minimum and maximum versions you support. Or a list of exact versions you support. Or not check for the
> > > version at all - or only for the major version and guarantee that the major version indicates backwards
> > > compatibility.
> > > > >
> > > > > yes, this was my point: elsewhere I noticed the code denies to run
> > > > > iff those defines are not matched exactly: that code should change
> > > > > to run as Alex describes.
> > > > >
> > > > As I mentioned in the reply to Alex, I will remove the minor version check.
> > >
> > > the code should be able to run on all subsequent versions of the
> > > h/w, even in the major version case.
> >
> > You're right, in the future if there are future major versions we would want this
> > same driver to function on multiple versions of the hardware.  But at this
> > point in time we don't know what future evolutions there will be and we
> > need the check to error out for now.
> 
> why?  We have to make the standard assumption that newer versions
> will be backward compatible, in which case the driver should be left
> to run.

If future changes are backward compatible then only the minor version changes.  That is
the explicit definition of the meaning of major/minor version for this device.

If the major number changes, then it is not backward compatible and will require
driver changes.  So this "error out" check is temporary until we reach that future
point, where it can be removed and we can hopefully implement dynamic handling
of the incompatibility.

Stuart


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

* RE: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-19 20:32                   ` Alexander Graf
  2014-09-19 20:41                     ` Scott Wood
@ 2014-09-19 21:37                     ` Stuart Yoder
  1 sibling, 0 replies; 43+ messages in thread
From: Stuart Yoder @ 2014-09-19 21:37 UTC (permalink / raw)
  To: Alexander Graf, Kim Phillips
  Cc: Jose Rivera, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	Scott Wood, <linuxppc-release@linux.freescale.net>,
	nir.erez



> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de]
> Sent: Friday, September 19, 2014 3:33 PM
> To: Phillips Kim-R1AAHA; Yoder Stuart-B08248
> Cc: Rivera Jose-B46482; <gregkh@linuxfoundation.org>; <arnd@arndb.de>; <linux-kernel@vger.kernel.org>; Wood
> Scott-B07421; <linuxppc-release@linux.freescale.net>
> Subject: Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
> 
> 
> 
> On 19.09.14 22:24, Kim Phillips wrote:
> > On Fri, 19 Sep 2014 14:06:32 -0500
> > Yoder Stuart-B08248 <stuart.yoder@freescale.com> wrote:
> >
> >>>>>>>>> +/**
> >>>>>>>>> + * @brief    Management Complex firmware version information
> >>>>>>>>> + */
> >>>>>>>>> +#define MC_VER_MAJOR 2
> >>>>>>>>> +#define MC_VER_MINOR 0
> >>>>>>>>
> >>>>>>>> code should be adjusted to run on all *compatible* versions of h/w,
> >>>>>>>> not strictly the one set in these defines.
> >>>>>>> This comment is not precise enough be actionable.
> >>>>>>> What exactly you want to be changed  here?
> >>>>>>
> >>>>>> I think the easy thing to do is to convert the exact version check into a ranged version check: have
> >>> minimum and maximum versions you support. Or a list of exact versions you support. Or not check for the
> >>> version at all - or only for the major version and guarantee that the major version indicates backwards
> >>> compatibility.
> >>>>>
> >>>>> yes, this was my point: elsewhere I noticed the code denies to run
> >>>>> iff those defines are not matched exactly: that code should change
> >>>>> to run as Alex describes.
> >>>>>
> >>>> As I mentioned in the reply to Alex, I will remove the minor version check.
> >>>
> >>> the code should be able to run on all subsequent versions of the
> >>> h/w, even in the major version case.
> >>
> >> You're right, in the future if there are future major versions we would want this
> >> same driver to function on multiple versions of the hardware.  But at this
> >> point in time we don't know what future evolutions there will be and we
> >> need the check to error out for now.
> >
> > why?  We have to make the standard assumption that newer versions
> > will be backward compatible, in which case the driver should be left
> > to run.
> 
> How much is the interface set in stone?

It is set in stone, in that a particular version has an specific set of
commands.

> Can we indicate to the MC that
> we want version x of the protocol? Then the MC can tell us whether it's
> compatible or not.

No, it's not that clever.  For the DPRC object there is a set of commands
with a binary interface. The major/minor version number tell us what version
of the hw object we are dealing with...what commands are there, what version
of the binary interface is there.

Stuart

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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-19 20:41                     ` Scott Wood
@ 2014-09-19 21:46                       ` Alexander Graf
  2014-09-20 15:36                         ` Stuart Yoder
  0 siblings, 1 reply; 43+ messages in thread
From: Alexander Graf @ 2014-09-19 21:46 UTC (permalink / raw)
  To: Scott Wood
  Cc: Kim Phillips, Yoder Stuart-B08248, Rivera Jose-B46482,
	<gregkh@linuxfoundation.org>, <arnd@arndb.de>,
	<linux-kernel@vger.kernel.org>,
	<linuxppc-release@linux.freescale.net>



On 19.09.14 22:41, Scott Wood wrote:
> On Fri, 2014-09-19 at 22:32 +0200, Alexander Graf wrote:
>>
>> On 19.09.14 22:24, Kim Phillips wrote:
>>> On Fri, 19 Sep 2014 14:06:32 -0500
>>> Yoder Stuart-B08248 <stuart.yoder@freescale.com> wrote:
>>>
>>>>>>>>>>> +/**
>>>>>>>>>>> + * @brief    Management Complex firmware version information
>>>>>>>>>>> + */
>>>>>>>>>>> +#define MC_VER_MAJOR 2
>>>>>>>>>>> +#define MC_VER_MINOR 0
>>>>>>>>>>
>>>>>>>>>> code should be adjusted to run on all *compatible* versions of h/w,
>>>>>>>>>> not strictly the one set in these defines.
>>>>>>>>> This comment is not precise enough be actionable.
>>>>>>>>> What exactly you want to be changed  here?
>>>>>>>>
>>>>>>>> I think the easy thing to do is to convert the exact version check into a ranged version check: have
>>>>> minimum and maximum versions you support. Or a list of exact versions you support. Or not check for the
>>>>> version at all - or only for the major version and guarantee that the major version indicates backwards
>>>>> compatibility.
>>>>>>>
>>>>>>> yes, this was my point: elsewhere I noticed the code denies to run
>>>>>>> iff those defines are not matched exactly: that code should change
>>>>>>> to run as Alex describes.
>>>>>>>
>>>>>> As I mentioned in the reply to Alex, I will remove the minor version check.
>>>>>
>>>>> the code should be able to run on all subsequent versions of the
>>>>> h/w, even in the major version case.
>>>>
>>>> You're right, in the future if there are future major versions we would want this
>>>> same driver to function on multiple versions of the hardware.  But at this
>>>> point in time we don't know what future evolutions there will be and we 
>>>> need the check to error out for now.
>>>
>>> why?  We have to make the standard assumption that newer versions
>>> will be backward compatible, in which case the driver should be left
>>> to run.
>>
>> How much is the interface set in stone? Can we indicate to the MC that
>> we want version x of the protocol? Then the MC can tell us whether it's
>> compatible or not.
> 
> I don't trust that new versions will be 100% backwards compatible
> (though I hope they will be), but do we normally bother making a driver
> refuse to run on newer versions?  Sure, if we need to explicitly match a
> comptible string or PCI ID, the match will be rejected if the driver
> doesn't know about it, but if it's a version in a register we usually
> only check for known issues with certain versions.

If the major number is defined as "this interface is incompatible", it
really is on the same lines as a PCI ID or a new compatible string, no?

So IMHO having a version check on the major version is reasonable as a
sanity check.

>  
>>>>   The driver will have to be changed
>>>> in the future to dynamically deal with different versions.
>>>>
>>>> We could add a TODO in the driver to note that.
>>>
>>> "TODO: add support for new h/w versions" is almost universally true
>>> for all drivers, we don't need to write that down.
>>>
>>> Support for new h/w versions with new features should be
>>> incrementally added once they're known.
>>
>> The "version id" is basically the equivalent of the pci device id. We
>> don't add wildcards there either for unknown pieces of hardware, so
>> limiting to driver to "known good" devices is sane IMHO.
> 
> How would you go about adding a wildcard to a PCI ID even if you wanted
> to?  Version information on PCI is not separate from device
> identification.

Yup. Hence you can't expect a new version of e1000 to work with an old
driver for example - it will have a new PCI ID. So on most hardware, we
do have major version checks through that interface. If you want, the
"revision" config space field in PCI could be the equivalent of a minor
version number here - drivers still match because the device ID itself
still matches.

The alternative to the approach taken here would be to have an "mc
bridge device" that gets proper device tree compatible versioning.
Overall the matching and compatibility decision would then lie in the
device tree.

Speaking of which, how does Linux find this new bus? I couldn't find
anything that describes the device tree bindings, but maybe I just
missed them.


Alex

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

* RE: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-19 21:46                       ` Alexander Graf
@ 2014-09-20 15:36                         ` Stuart Yoder
  0 siblings, 0 replies; 43+ messages in thread
From: Stuart Yoder @ 2014-09-20 15:36 UTC (permalink / raw)
  To: Alexander Graf, Scott Wood
  Cc: Kim Phillips, Jose Rivera, <gregkh@linuxfoundation.org>,
	<arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	<linuxppc-release@linux.freescale.net>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 501 bytes --]

> Speaking of which, how does Linux find this new bus? I couldn't find
> anything that describes the device tree bindings, but maybe I just
> missed them.

There is a separate thread on the ARM mailing list with the device tree
and binding (device tree will be in arch/arm64):

http://www.spinics.net/lists/arm-kernel/msg354635.html

Stuart
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* RE: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-19 20:58           ` Kim Phillips
@ 2014-09-22 14:42             ` Stuart Yoder
  2014-09-22 14:57               ` <gregkh@linuxfoundation.org>
  0 siblings, 1 reply; 43+ messages in thread
From: Stuart Yoder @ 2014-09-22 14:42 UTC (permalink / raw)
  To: Kim Phillips
  Cc: Alexander Graf, Jose Rivera, Kim Phillips,
	<gregkh@linuxfoundation.org>, <arnd@arndb.de>,
	<linux-kernel@vger.kernel.org>,
	Scott Wood, <linuxppc-release@linux.freescale.net>



> -----Original Message-----
> From: Kim Phillips [mailto:kim.phillips@freescale.com]
> Sent: Friday, September 19, 2014 3:58 PM
> To: Yoder Stuart-B08248
> Cc: Alexander Graf; Rivera Jose-B46482; Phillips Kim-R1AAHA; <gregkh@linuxfoundation.org>; <arnd@arndb.de>;
> <linux-kernel@vger.kernel.org>; Wood Scott-B07421; <linuxppc-release@linux.freescale.net>
> Subject: Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
> 
> On Fri, 19 Sep 2014 13:25:06 -0500
> Yoder Stuart-B08248 <stuart.yoder@freescale.com> wrote:
> 
> > > From: Yoder Stuart-B08248
> > > Sent: Thursday, September 18, 2014 7:19 PM
> > >
> > > +/**
> > > > >>> + * @brief    Disconnects one endpoint to remove its network link
> > > > >>> + *
> > > > >>> + * @param[in]   mc_io        Pointer to opaque I/O object
> > > > >>> + * @param[in]    dprc_handle    Handle to the DPRC object
> > > > >>> + * @param[in]   endpoint    Endpoint configuration parameters.
> > > > >>> + *
> > > > >>> + * @returns    '0' on Success; Error code otherwise.
> > > > >>> + * */
> > > > >>> +int dprc_disconnect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
> > > > >>> +            struct dprc_endpoint *endpoint);
> > > > >>> +
> > > > >>> +/*! @} */
> > > > >>
> > > > >> this entire file is riddled with non-kernel-doc comment markers:  see
> > > > >> Documentation/kernel-doc-nano-HOWTO.txt on how to write function and
> > > > >> other types of comments in a kernel-doc compliant format.
> > > > > This is because this file is using doxygen comments, as it was developed
> > > > > by another team. Unless someone else has an objection, I will leave the doxygen comments alone and
> not
> > > make
> > > > any change here.
> > > >
> > > > Do you see any other source files in Linux using doxygen comments?
> > >
> > > Yes.  Grep around a bit and you'll see examples of it.  I grep'ed for some
> > > doxygen tags and found close to 200 source files with them.
> 
> grepping for the one in this patch above - "! @}" - returns nothing.
> 
> > > > Mixing different documentation styles can
> > > > easily become a big mess, because you can't generate external documentation consistently for the whole
> > > tree.
> > >
> > > As German mentioned elsewhere, this file is an interface to a hardware block,
> > > was written by another team targetting a wide variety of environments-- u-boot,
> > > Linux, user space, other OSes etc.
> > >
> > > We left the doxygen stuff there because while admitedly not used much, there
> > > are other examples of it in the kernel and the documentation seems useful.
> > > If it can't go into the kernel as is, we can just delete it.
> >
> > ...to be clear, we could just delete the doyxen tags.  There is no scenario
> > where I would envision anyone generating documentation from these files in
> > the kernel.  The tags are there because of where we grabbed the source from.
> > It certainly would benefit no one by conversion to kerneldoc.
> 
> except kerneldoc users :)
> 
> > However, just leaving the comments and doxygen tags alone as is would be nice.
> 
> they are incompatible with kerneldoc.

Seriously, no one is going to ever generate docs from this obscure bit of code
documenting an internal interface within this driver.  Makes no sense to convert
the comments to kerneldoc.

I completely get what you are saying with respect to comments actually documenting
kernel interfaces used by different kernel components or uapi interfaces.

The doxygen tags are there because this code originated in a different project. That
code was intended to be Linux-style compliant and complies with checkpatch --strict.
However, we can sanitize the code and remove the tags if they are causing grief.
It's too bad though, because we'll have to fork this interface code from its origin.

Stuart




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

* Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-22 14:42             ` Stuart Yoder
@ 2014-09-22 14:57               ` <gregkh@linuxfoundation.org>
  2014-09-22 15:01                 ` Stuart Yoder
  0 siblings, 1 reply; 43+ messages in thread
From: <gregkh@linuxfoundation.org> @ 2014-09-22 14:57 UTC (permalink / raw)
  To: Stuart Yoder
  Cc: Kim Phillips, Alexander Graf, Jose Rivera, <arnd@arndb.de>,
	<linux-kernel@vger.kernel.org>,
	Scott Wood, <linuxppc-release@linux.freescale.net>

On Mon, Sep 22, 2014 at 02:42:10PM +0000, Stuart Yoder wrote:
> 
> 
> > -----Original Message-----
> > From: Kim Phillips [mailto:kim.phillips@freescale.com]
> > Sent: Friday, September 19, 2014 3:58 PM
> > To: Yoder Stuart-B08248
> > Cc: Alexander Graf; Rivera Jose-B46482; Phillips Kim-R1AAHA; <gregkh@linuxfoundation.org>; <arnd@arndb.de>;
> > <linux-kernel@vger.kernel.org>; Wood Scott-B07421; <linuxppc-release@linux.freescale.net>
> > Subject: Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
> > 
> > On Fri, 19 Sep 2014 13:25:06 -0500
> > Yoder Stuart-B08248 <stuart.yoder@freescale.com> wrote:
> > 
> > > > From: Yoder Stuart-B08248
> > > > Sent: Thursday, September 18, 2014 7:19 PM
> > > >
> > > > +/**
> > > > > >>> + * @brief    Disconnects one endpoint to remove its network link
> > > > > >>> + *
> > > > > >>> + * @param[in]   mc_io        Pointer to opaque I/O object
> > > > > >>> + * @param[in]    dprc_handle    Handle to the DPRC object
> > > > > >>> + * @param[in]   endpoint    Endpoint configuration parameters.
> > > > > >>> + *
> > > > > >>> + * @returns    '0' on Success; Error code otherwise.
> > > > > >>> + * */
> > > > > >>> +int dprc_disconnect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
> > > > > >>> +            struct dprc_endpoint *endpoint);
> > > > > >>> +
> > > > > >>> +/*! @} */
> > > > > >>
> > > > > >> this entire file is riddled with non-kernel-doc comment markers:  see
> > > > > >> Documentation/kernel-doc-nano-HOWTO.txt on how to write function and
> > > > > >> other types of comments in a kernel-doc compliant format.
> > > > > > This is because this file is using doxygen comments, as it was developed
> > > > > > by another team. Unless someone else has an objection, I will leave the doxygen comments alone and
> > not
> > > > make
> > > > > any change here.
> > > > >
> > > > > Do you see any other source files in Linux using doxygen comments?
> > > >
> > > > Yes.  Grep around a bit and you'll see examples of it.  I grep'ed for some
> > > > doxygen tags and found close to 200 source files with them.
> > 
> > grepping for the one in this patch above - "! @}" - returns nothing.
> > 
> > > > > Mixing different documentation styles can
> > > > > easily become a big mess, because you can't generate external documentation consistently for the whole
> > > > tree.
> > > >
> > > > As German mentioned elsewhere, this file is an interface to a hardware block,
> > > > was written by another team targetting a wide variety of environments-- u-boot,
> > > > Linux, user space, other OSes etc.
> > > >
> > > > We left the doxygen stuff there because while admitedly not used much, there
> > > > are other examples of it in the kernel and the documentation seems useful.
> > > > If it can't go into the kernel as is, we can just delete it.
> > >
> > > ...to be clear, we could just delete the doyxen tags.  There is no scenario
> > > where I would envision anyone generating documentation from these files in
> > > the kernel.  The tags are there because of where we grabbed the source from.
> > > It certainly would benefit no one by conversion to kerneldoc.
> > 
> > except kerneldoc users :)
> > 
> > > However, just leaving the comments and doxygen tags alone as is would be nice.
> > 
> > they are incompatible with kerneldoc.
> 
> Seriously, no one is going to ever generate docs from this obscure bit of code
> documenting an internal interface within this driver.  Makes no sense to convert
> the comments to kerneldoc.
> 
> I completely get what you are saying with respect to comments actually documenting
> kernel interfaces used by different kernel components or uapi interfaces.
> 
> The doxygen tags are there because this code originated in a different project. That
> code was intended to be Linux-style compliant and complies with checkpatch --strict.
> However, we can sanitize the code and remove the tags if they are causing grief.
> It's too bad though, because we'll have to fork this interface code from its origin.

You "forked" the code when you asked for it be merged into the kernel
tree.  You shouldn't ever have to rely on the "old" version again, so
please, remove the doxygen mess.

greg k-h

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

* RE: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
  2014-09-22 14:57               ` <gregkh@linuxfoundation.org>
@ 2014-09-22 15:01                 ` Stuart Yoder
  0 siblings, 0 replies; 43+ messages in thread
From: Stuart Yoder @ 2014-09-22 15:01 UTC (permalink / raw)
  To: <gregkh@linuxfoundation.org>
  Cc: Kim Phillips, Alexander Graf, Jose Rivera, <arnd@arndb.de>,
	<linux-kernel@vger.kernel.org>,
	Scott Wood, <linuxppc-release@linux.freescale.net>,
	nir.erez



> -----Original Message-----
> From: <gregkh@linuxfoundation.org> [mailto:gregkh@linuxfoundation.org]
> Sent: Monday, September 22, 2014 9:58 AM
> To: Yoder Stuart-B08248
> Cc: Phillips Kim-R1AAHA; Alexander Graf; Rivera Jose-B46482; <arnd@arndb.de>; <linux-kernel@vger.kernel.org>;
> Wood Scott-B07421; <linuxppc-release@linux.freescale.net>
> Subject: Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
> 
> On Mon, Sep 22, 2014 at 02:42:10PM +0000, Stuart Yoder wrote:
> >
> >
> > > -----Original Message-----
> > > From: Kim Phillips [mailto:kim.phillips@freescale.com]
> > > Sent: Friday, September 19, 2014 3:58 PM
> > > To: Yoder Stuart-B08248
> > > Cc: Alexander Graf; Rivera Jose-B46482; Phillips Kim-R1AAHA; <gregkh@linuxfoundation.org>;
> <arnd@arndb.de>;
> > > <linux-kernel@vger.kernel.org>; Wood Scott-B07421; <linuxppc-release@linux.freescale.net>
> > > Subject: Re: [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs
> > >
> > > On Fri, 19 Sep 2014 13:25:06 -0500
> > > Yoder Stuart-B08248 <stuart.yoder@freescale.com> wrote:
> > >
> > > > > From: Yoder Stuart-B08248
> > > > > Sent: Thursday, September 18, 2014 7:19 PM
> > > > >
> > > > > +/**
> > > > > > >>> + * @brief    Disconnects one endpoint to remove its network link
> > > > > > >>> + *
> > > > > > >>> + * @param[in]   mc_io        Pointer to opaque I/O object
> > > > > > >>> + * @param[in]    dprc_handle    Handle to the DPRC object
> > > > > > >>> + * @param[in]   endpoint    Endpoint configuration parameters.
> > > > > > >>> + *
> > > > > > >>> + * @returns    '0' on Success; Error code otherwise.
> > > > > > >>> + * */
> > > > > > >>> +int dprc_disconnect(struct fsl_mc_io *mc_io, uint16_t dprc_handle,
> > > > > > >>> +            struct dprc_endpoint *endpoint);
> > > > > > >>> +
> > > > > > >>> +/*! @} */
> > > > > > >>
> > > > > > >> this entire file is riddled with non-kernel-doc comment markers:  see
> > > > > > >> Documentation/kernel-doc-nano-HOWTO.txt on how to write function and
> > > > > > >> other types of comments in a kernel-doc compliant format.
> > > > > > > This is because this file is using doxygen comments, as it was developed
> > > > > > > by another team. Unless someone else has an objection, I will leave the doxygen comments alone
> and
> > > not
> > > > > make
> > > > > > any change here.
> > > > > >
> > > > > > Do you see any other source files in Linux using doxygen comments?
> > > > >
> > > > > Yes.  Grep around a bit and you'll see examples of it.  I grep'ed for some
> > > > > doxygen tags and found close to 200 source files with them.
> > >
> > > grepping for the one in this patch above - "! @}" - returns nothing.
> > >
> > > > > > Mixing different documentation styles can
> > > > > > easily become a big mess, because you can't generate external documentation consistently for the
> whole
> > > > > tree.
> > > > >
> > > > > As German mentioned elsewhere, this file is an interface to a hardware block,
> > > > > was written by another team targetting a wide variety of environments-- u-boot,
> > > > > Linux, user space, other OSes etc.
> > > > >
> > > > > We left the doxygen stuff there because while admitedly not used much, there
> > > > > are other examples of it in the kernel and the documentation seems useful.
> > > > > If it can't go into the kernel as is, we can just delete it.
> > > >
> > > > ...to be clear, we could just delete the doyxen tags.  There is no scenario
> > > > where I would envision anyone generating documentation from these files in
> > > > the kernel.  The tags are there because of where we grabbed the source from.
> > > > It certainly would benefit no one by conversion to kerneldoc.
> > >
> > > except kerneldoc users :)
> > >
> > > > However, just leaving the comments and doxygen tags alone as is would be nice.
> > >
> > > they are incompatible with kerneldoc.
> >
> > Seriously, no one is going to ever generate docs from this obscure bit of code
> > documenting an internal interface within this driver.  Makes no sense to convert
> > the comments to kerneldoc.
> >
> > I completely get what you are saying with respect to comments actually documenting
> > kernel interfaces used by different kernel components or uapi interfaces.
> >
> > The doxygen tags are there because this code originated in a different project. That
> > code was intended to be Linux-style compliant and complies with checkpatch --strict.
> > However, we can sanitize the code and remove the tags if they are causing grief.
> > It's too bad though, because we'll have to fork this interface code from its origin.
> 
> You "forked" the code when you asked for it be merged into the kernel
> tree.  You shouldn't ever have to rely on the "old" version again, so
> please, remove the doxygen mess.

Will do.

Stuart

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

end of thread, other threads:[~2014-09-22 15:01 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-11 17:34 [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series J. German Rivera
2014-09-11 17:34 ` [PATCH 1/4] drivers/bus: Added Freescale Management Complex APIs J. German Rivera
2014-09-11 18:45   ` Joe Perches
2014-09-17 16:35     ` German Rivera
2014-09-15 23:44   ` Kim Phillips
2014-09-16  4:31     ` Scott Wood
2014-09-16 19:28       ` Kim Phillips
2014-09-16 19:58         ` Scott Wood
2014-09-18  4:17     ` German Rivera
2014-09-18 13:14       ` Alexander Graf
2014-09-18 20:22         ` Kim Phillips
2014-09-18 23:03           ` Scott Wood
2014-09-18 23:13           ` Stuart Yoder
2014-09-18 23:29             ` Scott Wood
2014-09-18 23:46               ` Stuart Yoder
2014-09-19  3:05           ` German Rivera
2014-09-19 17:19             ` Kim Phillips
2014-09-19 19:06               ` Stuart Yoder
2014-09-19 20:24                 ` Kim Phillips
2014-09-19 20:32                   ` Alexander Graf
2014-09-19 20:41                     ` Scott Wood
2014-09-19 21:46                       ` Alexander Graf
2014-09-20 15:36                         ` Stuart Yoder
2014-09-19 21:37                     ` Stuart Yoder
2014-09-19 21:30                   ` Stuart Yoder
2014-09-19  0:18         ` Stuart Yoder
2014-09-19  2:34         ` German Rivera
2014-09-19 18:25         ` Stuart Yoder
2014-09-19 20:58           ` Kim Phillips
2014-09-22 14:42             ` Stuart Yoder
2014-09-22 14:57               ` <gregkh@linuxfoundation.org>
2014-09-22 15:01                 ` Stuart Yoder
2014-09-18 23:39     ` Stuart Yoder
2014-09-18 23:53       ` Scott Wood
2014-09-11 17:34 ` [PATCH 2/4] drivers/bus: Freescale Management Complex (fsl-mc) bus driver J. German Rivera
2014-09-11 18:49   ` Joe Perches
2014-09-17 23:50     ` German Rivera
2014-09-11 17:34 ` [PATCH 3/4] drivers/bus: Device driver for FSL-MC DPRC devices J. German Rivera
2014-09-11 17:34 ` [PATCH 4/4] Update MAINTAINERS file J. German Rivera
2014-09-15 23:44 ` [PATCH 0/4] drivers/bus: Freescale Management Complex bus driver patch series Kim Phillips
2014-09-18  0:20   ` German Rivera
2014-09-18 12:58     ` Alexander Graf
2014-09-19  0:31       ` German Rivera

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).