[PATCH RESEND v4 05/11] staging: fsl-mc: Extended MC bus allocator to include IRQs

2016-01-06 Thread J. German Rivera
From: "J. German Rivera" 

All the IRQs for DPAA2 objects in the same DPRC must use
the ICID of that DPRC, as their device Id in the GIC-ITS.
Thus, all these IRQs must share the same ITT table in the GIC.
As a result, a pool of IRQs with the same device Id must be
preallocated per DPRC (fsl-mc bus instance). So, the fsl-mc
bus object allocator is extended to also provide services
to allocate IRQs to DPAA2 devices, from their parent fsl-mc bus
IRQ pool.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-allocator.c   | 199 
 drivers/staging/fsl-mc/include/mc-private.h |  15 +++
 drivers/staging/fsl-mc/include/mc.h |   9 ++
 3 files changed, 223 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c 
b/drivers/staging/fsl-mc/bus/mc-allocator.c
index 88d1857..c5fa628 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -15,6 +15,7 @@
 #include "../include/dpcon-cmd.h"
 #include "dpmcp-cmd.h"
 #include "dpmcp.h"
+#include 

 /**
  * fsl_mc_resource_pool_add_device - add allocatable device to a resource
@@ -160,6 +161,7 @@ static const char *const fsl_mc_pool_type_strings[] = {
[FSL_MC_POOL_DPMCP] = "dpmcp",
[FSL_MC_POOL_DPBP] = "dpbp",
[FSL_MC_POOL_DPCON] = "dpcon",
+   [FSL_MC_POOL_IRQ] = "irq",
 };

 static int __must_check object_type_to_pool_type(const char *object_type,
@@ -465,6 +467,203 @@ void fsl_mc_object_free(struct fsl_mc_device *mc_adev)
 }
 EXPORT_SYMBOL_GPL(fsl_mc_object_free);

+/*
+ * Initialize the interrupt pool associated with a MC bus.
+ * It allocates a block of IRQs from the GIC-ITS
+ */
+int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
+unsigned int irq_count)
+{
+   unsigned int i;
+   struct msi_desc *msi_desc;
+   struct fsl_mc_device_irq *irq_resources;
+   struct fsl_mc_device_irq *mc_dev_irq;
+   int error;
+   struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+   struct fsl_mc_resource_pool *res_pool =
+   &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
+
+   if (WARN_ON(irq_count == 0 ||
+   irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS))
+   return -EINVAL;
+
+   error = fsl_mc_msi_domain_alloc_irqs(&mc_bus_dev->dev, irq_count);
+   if (error < 0)
+   return error;
+
+   irq_resources = devm_kzalloc(&mc_bus_dev->dev,
+sizeof(*irq_resources) * irq_count,
+GFP_KERNEL);
+   if (!irq_resources) {
+   error = -ENOMEM;
+   goto cleanup_msi_irqs;
+   }
+
+   for (i = 0; i < irq_count; i++) {
+   mc_dev_irq = &irq_resources[i];
+
+   /*
+* NOTE: This mc_dev_irq's MSI addr/value pair will be set
+* by the fsl_mc_msi_write_msg() callback
+*/
+   mc_dev_irq->resource.type = res_pool->type;
+   mc_dev_irq->resource.data = mc_dev_irq;
+   mc_dev_irq->resource.parent_pool = res_pool;
+   INIT_LIST_HEAD(&mc_dev_irq->resource.node);
+   list_add_tail(&mc_dev_irq->resource.node, &res_pool->free_list);
+   }
+
+   for_each_msi_entry(msi_desc, &mc_bus_dev->dev) {
+   mc_dev_irq = &irq_resources[msi_desc->fsl_mc.msi_index];
+   mc_dev_irq->msi_desc = msi_desc;
+   mc_dev_irq->resource.id = msi_desc->irq;
+   }
+
+   res_pool->max_count = irq_count;
+   res_pool->free_count = irq_count;
+   mc_bus->irq_resources = irq_resources;
+   return 0;
+
+cleanup_msi_irqs:
+   fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
+   return error;
+}
+EXPORT_SYMBOL_GPL(fsl_mc_populate_irq_pool);
+
+/**
+ * Teardown the interrupt pool associated with an MC bus.
+ * It frees the IRQs that were allocated to the pool, back to the GIC-ITS.
+ */
+void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus)
+{
+   struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+   struct fsl_mc_resource_pool *res_pool =
+   &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
+
+   if (WARN_ON(!mc_bus->irq_resources))
+   return;
+
+   if (WARN_ON(res_pool->max_count == 0))
+   return;
+
+   if (WARN_ON(res_pool->free_count != res_pool->max_count))
+   return;
+
+   INIT_LIST_HEAD(&res_pool->free_list);
+   res_pool->max_count = 0;
+   res_pool->free_count = 0;
+   mc_bus->irq_resources = NULL;
+   fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
+}
+EXP

[PATCH RESEND v4 03/11] staging: fsl-mc: Added generic MSI support for FSL-MC devices

2016-01-06 Thread J. German Rivera
From: "J. German Rivera" 

Created an MSI domain for the fsl-mc bus-- including functions
to create a domain, find a domain, alloc/free domain irqs, and
bus specific overrides for domain and irq_chip ops.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4:
- Addressed comments from Marc Zyngier:
  * Re-implemented fsl_mc_find_msi_domain() using of_msi_get_domain()

Changes in v3:
- Addressed comments from Marc Zyngier:
  * Added WARN_ON in fsl_mc_msi_set_desc to check that caller does
not set set_desc
  * Changed type of paddr in irq_cfg to be phys_addr_t
  * Added WARN_ON in fsl_mc_msi_update_chip_op() to check that caller
does not set irq_write_msi_msg

Changes in v2: none

 drivers/staging/fsl-mc/bus/Kconfig  |   1 +
 drivers/staging/fsl-mc/bus/Makefile |   1 +
 drivers/staging/fsl-mc/bus/mc-msi.c | 276 
 drivers/staging/fsl-mc/include/dprc.h   |   2 +-
 drivers/staging/fsl-mc/include/mc-private.h |  17 ++
 drivers/staging/fsl-mc/include/mc.h |  17 ++
 6 files changed, 313 insertions(+), 1 deletion(-)
 create mode 100644 drivers/staging/fsl-mc/bus/mc-msi.c

diff --git a/drivers/staging/fsl-mc/bus/Kconfig 
b/drivers/staging/fsl-mc/bus/Kconfig
index 0d779d9..c498ac6 100644
--- a/drivers/staging/fsl-mc/bus/Kconfig
+++ b/drivers/staging/fsl-mc/bus/Kconfig
@@ -9,6 +9,7 @@
 config FSL_MC_BUS
tristate "Freescale Management Complex (MC) bus driver"
depends on OF && ARM64
+   select GENERIC_MSI_IRQ_DOMAIN
help
  Driver to enable the bus infrastructure for the Freescale
   QorIQ Management Complex (fsl-mc). The fsl-mc is a hardware
diff --git a/drivers/staging/fsl-mc/bus/Makefile 
b/drivers/staging/fsl-mc/bus/Makefile
index 25433a9..a5f2ba4 100644
--- a/drivers/staging/fsl-mc/bus/Makefile
+++ b/drivers/staging/fsl-mc/bus/Makefile
@@ -13,5 +13,6 @@ mc-bus-driver-objs := mc-bus.o \
  dpmng.o \
  dprc-driver.o \
  mc-allocator.o \
+ mc-msi.o \
  dpmcp.o \
  dpbp.o
diff --git a/drivers/staging/fsl-mc/bus/mc-msi.c 
b/drivers/staging/fsl-mc/bus/mc-msi.c
new file mode 100644
index 000..3a8258f
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/mc-msi.c
@@ -0,0 +1,276 @@
+/*
+ * Freescale Management Complex (MC) bus driver MSI support
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera 
+ *
+ * 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 "../include/mc-private.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../include/mc-sys.h"
+#include "dprc-cmd.h"
+
+static void fsl_mc_msi_set_desc(msi_alloc_info_t *arg,
+   struct msi_desc *desc)
+{
+   arg->desc = desc;
+   arg->hwirq = (irq_hw_number_t)desc->fsl_mc.msi_index;
+}
+
+static void fsl_mc_msi_update_dom_ops(struct msi_domain_info *info)
+{
+   struct msi_domain_ops *ops = info->ops;
+
+   if (WARN_ON(!ops))
+   return;
+
+   /*
+* set_desc should not be set by the caller
+*/
+   if (WARN_ON(ops->set_desc))
+   return;
+
+   ops->set_desc = fsl_mc_msi_set_desc;
+}
+
+static void __fsl_mc_msi_write_msg(struct fsl_mc_device *mc_bus_dev,
+  struct fsl_mc_device_irq *mc_dev_irq)
+{
+   int error;
+   struct fsl_mc_device *owner_mc_dev = mc_dev_irq->mc_dev;
+   struct msi_desc *msi_desc = mc_dev_irq->msi_desc;
+   struct dprc_irq_cfg irq_cfg;
+
+   /*
+* msi_desc->msg.address is 0x0 when this function is invoked in
+* the free_irq() code path. In this case, for the MC, we don't
+* really need to "unprogram" the MSI, so we just return.
+*/
+   if (msi_desc->msg.address_lo == 0x0 && msi_desc->msg.address_hi == 0x0)
+   return;
+
+   if (WARN_ON(!owner_mc_dev))
+   return;
+
+   irq_cfg.paddr = ((u64)msi_desc->msg.address_hi << 32) |
+   msi_desc->msg.address_lo;
+   irq_cfg.val = msi_desc->msg.data;
+   irq_cfg.user_irq_id = msi_desc->irq;
+
+   if (owner_mc_dev == mc_bus_dev) {
+   /*
+* IRQ is for the mc_bus_dev's DPRC itself
+*/
+   error = dprc_set_irq(mc_bus_dev->mc_io,
+MC_CMD_FLAG_INTR_DIS | MC_CMD_FLAG_PRI,
+mc_bus_dev->mc_handle,
+mc_dev_irq->dev_irq_index,
+&irq

[PATCH RESEND v4 04/11] staging: fsl-mc: Added GICv3-ITS support for FSL-MC MSIs

2016-01-06 Thread J. German Rivera
From: "J. German Rivera" 

Added platform-specific MSI support layer for FSL-MC devices.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4:
- Addressed comments from Marc Zyngier:
  * Moved bus type check earlier in its_fsl_mc_msi_prepare()
  * Removed its_dev_id variable
  * Changed some assignments to keep both sides on the same line

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/Makefile|   1 +
 .../staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c | 127 +
 drivers/staging/fsl-mc/include/mc-private.h|   4 +
 3 files changed, 132 insertions(+)
 create mode 100644 drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c

diff --git a/drivers/staging/fsl-mc/bus/Makefile 
b/drivers/staging/fsl-mc/bus/Makefile
index a5f2ba4..e731517 100644
--- a/drivers/staging/fsl-mc/bus/Makefile
+++ b/drivers/staging/fsl-mc/bus/Makefile
@@ -14,5 +14,6 @@ mc-bus-driver-objs := mc-bus.o \
  dprc-driver.o \
  mc-allocator.o \
  mc-msi.o \
+ irq-gic-v3-its-fsl-mc-msi.o \
  dpmcp.o \
  dpbp.o
diff --git a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c 
b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
new file mode 100644
index 000..4e8e822
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
@@ -0,0 +1,127 @@
+/*
+ * Freescale Management Complex (MC) bus driver MSI support
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera 
+ *
+ * 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 "../include/mc-private.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../include/mc-sys.h"
+#include "dprc-cmd.h"
+
+static struct irq_chip its_msi_irq_chip = {
+   .name = "fsl-mc-bus-msi",
+   .irq_mask = irq_chip_mask_parent,
+   .irq_unmask = irq_chip_unmask_parent,
+   .irq_eoi = irq_chip_eoi_parent,
+   .irq_set_affinity = msi_domain_set_affinity
+};
+
+static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
+ struct device *dev,
+ int nvec, msi_alloc_info_t *info)
+{
+   struct fsl_mc_device *mc_bus_dev;
+   struct msi_domain_info *msi_info;
+
+   if (WARN_ON(dev->bus != &fsl_mc_bus_type))
+   return -EINVAL;
+
+   mc_bus_dev = to_fsl_mc_device(dev);
+   if (WARN_ON(!(mc_bus_dev->flags & FSL_MC_IS_DPRC)))
+   return -EINVAL;
+
+   /*
+* Set the device Id to be passed to the GIC-ITS:
+*
+* NOTE: This device id corresponds to the IOMMU stream ID
+* associated with the DPRC object (ICID).
+*/
+   info->scratchpad[0].ul = mc_bus_dev->icid;
+   msi_info = msi_get_domain_info(msi_domain->parent);
+   return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info);
+}
+
+static struct msi_domain_ops its_fsl_mc_msi_ops = {
+   .msi_prepare = its_fsl_mc_msi_prepare,
+};
+
+static struct msi_domain_info its_fsl_mc_msi_domain_info = {
+   .flags  = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
+   .ops= &its_fsl_mc_msi_ops,
+   .chip   = &its_msi_irq_chip,
+};
+
+static const struct of_device_id its_device_id[] = {
+   {   .compatible = "arm,gic-v3-its", },
+   {},
+};
+
+int __init its_fsl_mc_msi_init(void)
+{
+   struct device_node *np;
+   struct irq_domain *parent;
+   struct irq_domain *mc_msi_domain;
+
+   for (np = of_find_matching_node(NULL, its_device_id); np;
+np = of_find_matching_node(np, its_device_id)) {
+   if (!of_property_read_bool(np, "msi-controller"))
+   continue;
+
+   parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
+   if (!parent || !msi_get_domain_info(parent)) {
+   pr_err("%s: unable to locate ITS domain\n",
+  np->full_name);
+   continue;
+   }
+
+   mc_msi_domain = fsl_mc_msi_create_irq_domain(
+of_node_to_fwnode(np),
+&its_fsl_mc_msi_domain_info,
+parent);
+   if (!mc_msi_domain) {
+   pr_err("%s: unable to create fsl-mc domain\n",
+  np->full_name);
+   continue;
+   }
+
+   WARN_ON(mc_msi_domain->
+   host_da

[PATCH RESEND v4 11/11] staging: fsl-mc: Added MSI support to the MC bus driver

2016-01-06 Thread J. German Rivera
From: "J. German Rivera" 

Initialize/Cleanup ITS-MSI support for the MC bus driver at driver
init/exit time. Associate an MSI domain with each DPAA2 child device.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-bus.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index d34f1af..9317561 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -16,6 +16,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include "../include/dpmng.h"
 #include "../include/mc-sys.h"
 #include "dprc-cmd.h"
@@ -472,6 +474,8 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
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;
+   dev_set_msi_domain(&mc_dev->dev,
+  dev_get_msi_domain(&parent_mc_dev->dev));
}

/*
@@ -833,8 +837,15 @@ static int __init fsl_mc_bus_driver_init(void)
if (error < 0)
goto error_cleanup_dprc_driver;

+   error = its_fsl_mc_msi_init();
+   if (error < 0)
+   goto error_cleanup_mc_allocator;
+
return 0;

+error_cleanup_mc_allocator:
+   fsl_mc_allocator_driver_exit();
+
 error_cleanup_dprc_driver:
dprc_driver_exit();

@@ -856,6 +867,7 @@ static void __exit fsl_mc_bus_driver_exit(void)
if (WARN_ON(!mc_dev_cache))
return;

+   its_fsl_mc_msi_cleanup();
fsl_mc_allocator_driver_exit();
dprc_driver_exit();
platform_driver_unregister(&fsl_mc_bus_driver);
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v4 09/11] staging: fsl-mc: Fixed bug in dprc_probe() error path

2016-01-06 Thread J. German Rivera
From: "J. German Rivera" 

Destroy mc_io in error path in dprc_probe() only if the mc_io was
created in this function.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2:
- Addressed comment from Dan Carpenter:
  * Renamed goto error labels to indicate what the goto does

 drivers/staging/fsl-mc/bus/dprc-driver.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 38fc404..42b2494 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -401,6 +401,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
size_t region_size;
struct device *parent_dev = mc_dev->dev.parent;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   bool mc_io_created = false;
bool msi_domain_set = false;

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
@@ -413,6 +414,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
/*
 * This is a child DPRC:
 */
+   if (WARN_ON(parent_dev->bus != &fsl_mc_bus_type))
+   return -EINVAL;
+
if (WARN_ON(mc_dev->obj_desc.region_count == 0))
return -EINVAL;

@@ -427,6 +431,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 &mc_dev->mc_io);
if (error < 0)
return error;
+
+   mc_io_created = true;
+
/*
 * Inherit parent MSI domain:
 */
@@ -457,7 +464,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
  &mc_dev->mc_handle);
if (error < 0) {
dev_err(&mc_dev->dev, "dprc_open() failed: %d\n", error);
-   goto error_cleanup_mc_io;
+   goto error_cleanup_msi_domain;
}

mutex_init(&mc_bus->scan_mutex);
@@ -475,11 +482,15 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 error_cleanup_open:
(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);

-error_cleanup_mc_io:
+error_cleanup_msi_domain:
if (msi_domain_set)
dev_set_msi_domain(&mc_dev->dev, NULL);

-   fsl_destroy_mc_io(mc_dev->mc_io);
+   if (mc_io_created) {
+   fsl_destroy_mc_io(mc_dev->mc_io);
+   mc_dev->mc_io = NULL;
+   }
+
return error;
 }

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v4 00/11] staging: fsl-mc: MC bus MSI support

2016-01-06 Thread J. German Rivera
*** This is a resend of the last iteration of this patch series ***

This patch series addresses the following item from the TODO list
for the MC bus driver to exit staging:

* Interrupt support. For meaningful driver support we need
  interrupts, and thus need message interrupt support by the bus
  driver.

MC Bus MSI Support Architecture
===
A new IRQ domain bus token is added for the FSL-MC bus.
An MSI IRQ domain is created for each top-level (root) data-path
resource container (DPRC), based on its msi-parent in the device
tree (which is the GIC-ITS). Child DPRCs inherit the MSI IRQ
domain form their parent DPRC.

MC Bus MSI Allocation
-
Given the way in which the GIC-ITS works, we need to pre-allocate
a block of MSIs in the GIC-ITS for the IRQs of all the DPAA2 objects
in the same data-path resource container (DPRC) and for the IRQ of
the DPRC iself.

This is due to the fact that all the IRQs for DPAA2 objects in the
same DPRC (and the DPRC's own IRQ) must use the same "device Id" in
the GIC-ITS. Thus, all these IRQs must share the same ITT table in
the GIC-ITS, and therefore must be allocated in the GIC-ITS as
a block of MSIs for the same "device Id".

This is because all the DPAA2 objects in the same DPRC (and the
DPRC itself) use the DPRC's SMMU stream ID as their device Id for
the GIC-ITS.
The DPAA2 Management Complex (MC) firmware does not assign a separate
SMMU stream ID to each DPAA2 object. The MC only assigns SMMU stream
IDs to DPRCs. In MC terms, the stream ID assigned to a DPRC is known
as the DPRC's Isolation Context ID (ICID).

As a consequence of having to pre-allocate a block of MSIs in
the GIC-ITS, the object allocator of the MC bus driver needs to be
extended to provide IRQ allocation services to DPAA2 device drivers
and to the DPRC driver. For a given DPAA2 object, MSIs are allocated
from the corresponding DPRC's pool of pre-allocated MSIs. The MSI
for the DPRC itself is also allocated from this pool.

The following are the patches in this series:

Patch 1: Added domain bus token DOMAIN_BUS_FSL_MC_MSI
Patch 2: Added Added FSL-MC-specific member to the msi_desc's union
Patch 3: Added generic MSI support for FSL-MC devices
Patch 4: Added GICv3-ITS support for FSL-MC MSIs
Patch 5: Extended MC bus allocator to include IRQs
Patch 6: Changed DPRC built-in portal's mc_io to be atomic
Patch 7: Populate the IRQ pool for an MC bus instance
Patch 8: Set MSI domain for DPRC objects
Patch 9: Fixed bug in dprc_probe() error path
Patch 10: Added DPRC interrupt handler
Patch 11: Added MSI support to the MC bus driver

CHANGE HISTORY

Changes in v4:
- Addressed comments from Marc Zyngier for patches 3, 4, 8.
  See details in each patch.

Changes in v3:
- Addressed comments from Marc Zyngier for patch 3.
  See details in patch 3.

Changes in v2:
- Addressed comment from Jiang Liu in patch 2
  See details in patch 2.
- Addressed comment from Dan Carpenter in patch 9
  See details in patch 9.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v4 02/11] fsl-mc: msi: Added FSL-MC-specific member to the msi_desc's union

2016-01-06 Thread J. German Rivera
From: "J. German Rivera" 

FSL-MC is a bus type different from PCI and platform, so it needs
its own member in the msi_desc's union.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2:
- Addressed comment from Jiang Liu
  * Added a dedicated structure for FSL-MC in struct msi_desc

 include/linux/msi.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/linux/msi.h b/include/linux/msi.h
index f71a25e..152e51a 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -33,6 +33,14 @@ struct platform_msi_desc {
 };

 /**
+ * fsl_mc_msi_desc - FSL-MC device specific msi descriptor data
+ * @msi_index: The index of the MSI descriptor
+ */
+struct fsl_mc_msi_desc {
+   u16 msi_index;
+};
+
+/**
  * struct msi_desc - Descriptor structure for MSI based interrupts
  * @list:  List head for management
  * @irq:   The base interrupt number
@@ -87,6 +95,7 @@ struct msi_desc {
 * tree wide cleanup.
 */
struct platform_msi_desc platform;
+   struct fsl_mc_msi_desc fsl_mc;
};
 };

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v4 01/11] irqdomain: Added domain bus token DOMAIN_BUS_FSL_MC_MSI

2016-01-06 Thread J. German Rivera
From: "J. German Rivera" 

Since an FSL-MC bus is a new bus type that is neither PCI nor
PLATFORM, we need a new domain bus token to disambiguate the
IRQ domain for FSL-MC MSIs.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2: none

 include/linux/irqdomain.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index d5e5c5b..c0cb5d1 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -73,6 +73,7 @@ enum irq_domain_bus_token {
DOMAIN_BUS_PCI_MSI,
DOMAIN_BUS_PLATFORM_MSI,
DOMAIN_BUS_NEXUS,
+   DOMAIN_BUS_FSL_MC_MSI,
 };

 /**
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v4 06/11] staging: fsl-mc: Changed DPRC built-in portal's mc_io to be atomic

2016-01-06 Thread J. German Rivera
From: "J. German Rivera" 

The DPRC built-in portal's mc_io is used to send commands to the MC
to program MSIs for MC objects. This is done by the
fsl_mc_msi_write_msg() callback, which is invoked by the generic MSI
layer with interrupts disabled. As a result, the mc_io used in
fsl_mc_msi_write_msg needs to be an atomic mc_io.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 4 +++-
 drivers/staging/fsl-mc/bus/mc-bus.c  | 3 ++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 2c4cd70..767d437 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -396,7 +396,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
error = fsl_create_mc_io(&mc_dev->dev,
 mc_dev->regions[0].start,
 region_size,
-NULL, 0, &mc_dev->mc_io);
+NULL,
+FSL_MC_IO_ATOMIC_CONTEXT_PORTAL,
+&mc_dev->mc_io);
if (error < 0)
return error;
}
diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index 84db55b..d34f1af 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -702,7 +702,8 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
mc_portal_phys_addr = res.start;
mc_portal_size = resource_size(&res);
error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
-mc_portal_size, NULL, 0, &mc_io);
+mc_portal_size, NULL,
+FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
if (error < 0)
return error;

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v4 07/11] staging: fsl-mc: Populate the IRQ pool for an MC bus instance

2016-01-06 Thread J. German Rivera
From: "J. German Rivera" 

Scan the corresponding DPRC container to get total count
of IRQs needed by all its child DPAA2 objects. Then,
preallocate a set of MSI IRQs with the DPRC's ICID
(GIT-ITS device Id) to populate the the DPRC's IRQ pool.
Each child DPAA2 object in the DPRC and the DPRC object itself
will allocate their necessary MSI IRQs from the DPRC's IRQ pool,
in their driver probe function.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c| 24 ++--
 drivers/staging/fsl-mc/include/mc-private.h |  3 ++-
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 767d437..ef1bb93 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -241,6 +241,7 @@ static void dprc_cleanup_all_resource_pools(struct 
fsl_mc_device *mc_bus_dev)
  * dprc_scan_objects - Discover objects in a DPRC
  *
  * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
+ * @total_irq_count: total number of IRQs needed by objects in the DPRC.
  *
  * Detects objects added and removed from a DPRC and synchronizes the
  * state of the Linux bus driver, MC by adding and removing
@@ -254,11 +255,13 @@ static void dprc_cleanup_all_resource_pools(struct 
fsl_mc_device *mc_bus_dev)
  * populated before they can get allocation requests from probe callbacks
  * of the device drivers for the non-allocatable devices.
  */
-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+ unsigned int *total_irq_count)
 {
int num_child_objects;
int dprc_get_obj_failures;
int error;
+   unsigned int irq_count = mc_bus_dev->obj_desc.irq_count;
struct dprc_obj_desc *child_obj_desc_array = NULL;

error = dprc_get_obj_count(mc_bus_dev->mc_io,
@@ -307,6 +310,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
continue;
}

+   irq_count += obj_desc->irq_count;
dev_dbg(&mc_bus_dev->dev,
"Discovered object: type %s, id %d\n",
obj_desc->type, obj_desc->id);
@@ -319,6 +323,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
}
}

+   *total_irq_count = irq_count;
dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
num_child_objects);

@@ -344,6 +349,7 @@ EXPORT_SYMBOL_GPL(dprc_scan_objects);
 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 {
int error;
+   unsigned int irq_count;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);

dprc_init_all_resource_pools(mc_bus_dev);
@@ -352,11 +358,25 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 * Discover objects in the DPRC:
 */
mutex_lock(&mc_bus->scan_mutex);
-   error = dprc_scan_objects(mc_bus_dev);
+   error = dprc_scan_objects(mc_bus_dev, &irq_count);
mutex_unlock(&mc_bus->scan_mutex);
if (error < 0)
goto error;

+   if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) {
+   if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
+   dev_warn(&mc_bus_dev->dev,
+"IRQs needed (%u) exceed IRQs preallocated 
(%u)\n",
+irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   }
+
+   error = fsl_mc_populate_irq_pool(
+   mc_bus,
+   FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   if (error < 0)
+   goto error;
+   }
+
return 0;
 error:
dprc_cleanup_all_resource_pools(mc_bus_dev);
diff --git a/drivers/staging/fsl-mc/include/mc-private.h 
b/drivers/staging/fsl-mc/include/mc-private.h
index 3babe92..be72a44 100644
--- a/drivers/staging/fsl-mc/include/mc-private.h
+++ b/drivers/staging/fsl-mc/include/mc-private.h
@@ -114,7 +114,8 @@ void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);

 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev);

-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev);
+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+ unsigned int *total_irq_count);

 int __init dprc_driver_init(void);

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v4 10/11] staging: fsl-mc: Added DPRC interrupt handler

2016-01-06 Thread J. German Rivera
From: "J. German Rivera" 

The interrupt handler for DPRC IRQs is added. DPRC IRQs are
generated for hot plug events related to DPAA2 objects in a given
DPRC. These events include, creating/destroying DPAA2 objects in
the DPRC, changing the "plugged" state of DPAA2 objects and moving
objects between DPRCs.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 247 +++
 1 file changed, 247 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 42b2494..52c6fce 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "dprc-cmd.h"

 struct dprc_child_objs {
@@ -386,6 +387,230 @@ error:
 EXPORT_SYMBOL_GPL(dprc_scan_container);

 /**
+ * dprc_irq0_handler - Regular ISR for DPRC interrupt 0
+ *
+ * @irq: IRQ number of the interrupt being handled
+ * @arg: Pointer to device structure
+ */
+static irqreturn_t dprc_irq0_handler(int irq_num, void *arg)
+{
+   return IRQ_WAKE_THREAD;
+}
+
+/**
+ * dprc_irq0_handler_thread - Handler thread function for DPRC interrupt 0
+ *
+ * @irq: IRQ number of the interrupt being handled
+ * @arg: Pointer to device structure
+ */
+static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
+{
+   int error;
+   u32 status;
+   struct device *dev = (struct device *)arg;
+   struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+   struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   struct fsl_mc_io *mc_io = mc_dev->mc_io;
+   struct msi_desc *msi_desc = mc_dev->irqs[0]->msi_desc;
+
+   dev_dbg(dev, "DPRC IRQ %d triggered on CPU %u\n",
+   irq_num, smp_processor_id());
+
+   if (WARN_ON(!(mc_dev->flags & FSL_MC_IS_DPRC)))
+   return IRQ_HANDLED;
+
+   mutex_lock(&mc_bus->scan_mutex);
+   if (WARN_ON(!msi_desc || msi_desc->irq != (u32)irq_num))
+   goto out;
+
+   error = dprc_get_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
+   &status);
+   if (error < 0) {
+   dev_err(dev,
+   "dprc_get_irq_status() failed: %d\n", error);
+   goto out;
+   }
+
+   error = dprc_clear_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
+ status);
+   if (error < 0) {
+   dev_err(dev,
+   "dprc_clear_irq_status() failed: %d\n", error);
+   goto out;
+   }
+
+   if (status & (DPRC_IRQ_EVENT_OBJ_ADDED |
+ DPRC_IRQ_EVENT_OBJ_REMOVED |
+ DPRC_IRQ_EVENT_CONTAINER_DESTROYED |
+ DPRC_IRQ_EVENT_OBJ_DESTROYED |
+ DPRC_IRQ_EVENT_OBJ_CREATED)) {
+   unsigned int irq_count;
+
+   error = dprc_scan_objects(mc_dev, &irq_count);
+   if (error < 0) {
+   /*
+* If the error is -ENXIO, we ignore it, as it indicates
+* that the object scan was aborted, as we detected that
+* an object was removed from the DPRC in the MC, while
+* we were scanning the DPRC.
+*/
+   if (error != -ENXIO) {
+   dev_err(dev, "dprc_scan_objects() failed: %d\n",
+   error);
+   }
+
+   goto out;
+   }
+
+   if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
+   dev_warn(dev,
+"IRQs needed (%u) exceed IRQs preallocated 
(%u)\n",
+irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   }
+   }
+
+out:
+   mutex_unlock(&mc_bus->scan_mutex);
+   return IRQ_HANDLED;
+}
+
+/*
+ * Disable and clear interrupt for a given DPRC object
+ */
+static int disable_dprc_irq(struct fsl_mc_device *mc_dev)
+{
+   int error;
+   struct fsl_mc_io *mc_io = mc_dev->mc_io;
+
+   WARN_ON(mc_dev->obj_desc.irq_count != 1);
+
+   /*
+* Disable generation of interrupt, while we configure it:
+*/
+   error = dprc_set_irq_enable(mc_io, 0, mc_dev->mc_handle, 0, 0);
+   if (error < 0) {
+   dev_err(&mc_dev->dev,
+   "Disabling DPRC IRQ failed: dprc_set_irq_enable() 
failed: %d\n",
+   error);
+   return error;
+   }
+
+   /*
+* Disable all interrupt causes for the interrupt:
+*/
+   error = dprc_set_irq_mas

[PATCH RESEND v4 08/11] staging: fsl-mc: set MSI domain for DPRC objects

2016-01-06 Thread J. German Rivera
From: "J. German Rivera" 

THE MSI domain associated with a root DPRC object is
obtained form the device tree. Child DPRCs inherit
the parent DPRC MSI domain.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4:
- Addressed comments from Marc Zyngier:
  * Changed call to fsl_mc_find_msi_domain() to match new
signature changed in patch 3.

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 39 
 1 file changed, 39 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index ef1bb93..38fc404 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -13,6 +13,7 @@
 #include "../include/mc-sys.h"
 #include 
 #include 
+#include 
 #include "dprc-cmd.h"

 struct dprc_child_objs {
@@ -398,11 +399,16 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 {
int error;
size_t region_size;
+   struct device *parent_dev = mc_dev->dev.parent;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   bool msi_domain_set = false;

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
return -EINVAL;

+   if (WARN_ON(dev_get_msi_domain(&mc_dev->dev)))
+   return -EINVAL;
+
if (!mc_dev->mc_io) {
/*
 * This is a child DPRC:
@@ -421,6 +427,30 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 &mc_dev->mc_io);
if (error < 0)
return error;
+   /*
+* Inherit parent MSI domain:
+*/
+   dev_set_msi_domain(&mc_dev->dev,
+  dev_get_msi_domain(parent_dev));
+   msi_domain_set = true;
+   } else {
+   /*
+* This is a root DPRC
+*/
+   struct irq_domain *mc_msi_domain;
+
+   if (WARN_ON(parent_dev->bus == &fsl_mc_bus_type))
+   return -EINVAL;
+
+   error = fsl_mc_find_msi_domain(parent_dev,
+  &mc_msi_domain);
+   if (error < 0) {
+   dev_warn(&mc_dev->dev,
+"WARNING: MC bus without interrupt support\n");
+   } else {
+   dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
+   msi_domain_set = true;
+   }
}

error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
@@ -446,6 +476,9 @@ error_cleanup_open:
(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);

 error_cleanup_mc_io:
+   if (msi_domain_set)
+   dev_set_msi_domain(&mc_dev->dev, NULL);
+
fsl_destroy_mc_io(mc_dev->mc_io);
return error;
 }
@@ -463,6 +496,7 @@ error_cleanup_mc_io:
 static int dprc_remove(struct fsl_mc_device *mc_dev)
 {
int error;
+   struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
return -EINVAL;
@@ -475,6 +509,11 @@ static int dprc_remove(struct fsl_mc_device *mc_dev)
if (error < 0)
dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);

+   if (dev_get_msi_domain(&mc_dev->dev)) {
+   fsl_mc_cleanup_irq_pool(mc_bus);
+   dev_set_msi_domain(&mc_dev->dev, NULL);
+   }
+
dev_info(&mc_dev->dev, "DPRC device unbound from driver");
return 0;
 }
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 03/11] staging: fsl-mc: Added generic MSI support for FSL-MC devices

2015-12-11 Thread J. German Rivera
Created an MSI domain for the fsl-mc bus-- including functions
to create a domain, find a domain, alloc/free domain irqs, and
bus specific overrides for domain and irq_chip ops.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4:
- Addressed comments from Marc Zyngier:
  * Re-implemented fsl_mc_find_msi_domain() using of_msi_get_domain()

Changes in v3:
- Addressed comments from Marc Zyngier:
  * Added WARN_ON in fsl_mc_msi_set_desc to check that caller does
not set set_desc
  * Changed type of paddr in irq_cfg to be phys_addr_t
  * Added WARN_ON in fsl_mc_msi_update_chip_op() to check that caller
does not set irq_write_msi_msg

Changes in v2: none

 drivers/staging/fsl-mc/bus/Kconfig  |   1 +
 drivers/staging/fsl-mc/bus/Makefile |   1 +
 drivers/staging/fsl-mc/bus/mc-msi.c | 276 
 drivers/staging/fsl-mc/include/dprc.h   |   2 +-
 drivers/staging/fsl-mc/include/mc-private.h |  17 ++
 drivers/staging/fsl-mc/include/mc.h |  17 ++
 6 files changed, 313 insertions(+), 1 deletion(-)
 create mode 100644 drivers/staging/fsl-mc/bus/mc-msi.c

diff --git a/drivers/staging/fsl-mc/bus/Kconfig 
b/drivers/staging/fsl-mc/bus/Kconfig
index 0d779d9..c498ac6 100644
--- a/drivers/staging/fsl-mc/bus/Kconfig
+++ b/drivers/staging/fsl-mc/bus/Kconfig
@@ -9,6 +9,7 @@
 config FSL_MC_BUS
tristate "Freescale Management Complex (MC) bus driver"
depends on OF && ARM64
+   select GENERIC_MSI_IRQ_DOMAIN
help
  Driver to enable the bus infrastructure for the Freescale
   QorIQ Management Complex (fsl-mc). The fsl-mc is a hardware
diff --git a/drivers/staging/fsl-mc/bus/Makefile 
b/drivers/staging/fsl-mc/bus/Makefile
index 25433a9..a5f2ba4 100644
--- a/drivers/staging/fsl-mc/bus/Makefile
+++ b/drivers/staging/fsl-mc/bus/Makefile
@@ -13,5 +13,6 @@ mc-bus-driver-objs := mc-bus.o \
  dpmng.o \
  dprc-driver.o \
  mc-allocator.o \
+ mc-msi.o \
  dpmcp.o \
  dpbp.o
diff --git a/drivers/staging/fsl-mc/bus/mc-msi.c 
b/drivers/staging/fsl-mc/bus/mc-msi.c
new file mode 100644
index 000..3a8258f
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/mc-msi.c
@@ -0,0 +1,276 @@
+/*
+ * Freescale Management Complex (MC) bus driver MSI support
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera 
+ *
+ * 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 "../include/mc-private.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../include/mc-sys.h"
+#include "dprc-cmd.h"
+
+static void fsl_mc_msi_set_desc(msi_alloc_info_t *arg,
+   struct msi_desc *desc)
+{
+   arg->desc = desc;
+   arg->hwirq = (irq_hw_number_t)desc->fsl_mc.msi_index;
+}
+
+static void fsl_mc_msi_update_dom_ops(struct msi_domain_info *info)
+{
+   struct msi_domain_ops *ops = info->ops;
+
+   if (WARN_ON(!ops))
+   return;
+
+   /*
+* set_desc should not be set by the caller
+*/
+   if (WARN_ON(ops->set_desc))
+   return;
+
+   ops->set_desc = fsl_mc_msi_set_desc;
+}
+
+static void __fsl_mc_msi_write_msg(struct fsl_mc_device *mc_bus_dev,
+  struct fsl_mc_device_irq *mc_dev_irq)
+{
+   int error;
+   struct fsl_mc_device *owner_mc_dev = mc_dev_irq->mc_dev;
+   struct msi_desc *msi_desc = mc_dev_irq->msi_desc;
+   struct dprc_irq_cfg irq_cfg;
+
+   /*
+* msi_desc->msg.address is 0x0 when this function is invoked in
+* the free_irq() code path. In this case, for the MC, we don't
+* really need to "unprogram" the MSI, so we just return.
+*/
+   if (msi_desc->msg.address_lo == 0x0 && msi_desc->msg.address_hi == 0x0)
+   return;
+
+   if (WARN_ON(!owner_mc_dev))
+   return;
+
+   irq_cfg.paddr = ((u64)msi_desc->msg.address_hi << 32) |
+   msi_desc->msg.address_lo;
+   irq_cfg.val = msi_desc->msg.data;
+   irq_cfg.user_irq_id = msi_desc->irq;
+
+   if (owner_mc_dev == mc_bus_dev) {
+   /*
+* IRQ is for the mc_bus_dev's DPRC itself
+*/
+   error = dprc_set_irq(mc_bus_dev->mc_io,
+MC_CMD_FLAG_INTR_DIS | MC_CMD_FLAG_PRI,
+mc_bus_dev->mc_handle,
+mc_dev_irq->dev_irq_index,
+&irq_cfg);
+   if (error < 0) {
+ 

[PATCH v4 11/11] staging: fsl-mc: Added MSI support to the MC bus driver

2015-12-11 Thread J. German Rivera
Initialize/Cleanup ITS-MSI support for the MC bus driver at driver
init/exit time. Associate an MSI domain with each DPAA2 child device.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-bus.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index d34f1af..9317561 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -16,6 +16,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include "../include/dpmng.h"
 #include "../include/mc-sys.h"
 #include "dprc-cmd.h"
@@ -472,6 +474,8 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
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;
+   dev_set_msi_domain(&mc_dev->dev,
+  dev_get_msi_domain(&parent_mc_dev->dev));
}

/*
@@ -833,8 +837,15 @@ static int __init fsl_mc_bus_driver_init(void)
if (error < 0)
goto error_cleanup_dprc_driver;

+   error = its_fsl_mc_msi_init();
+   if (error < 0)
+   goto error_cleanup_mc_allocator;
+
return 0;

+error_cleanup_mc_allocator:
+   fsl_mc_allocator_driver_exit();
+
 error_cleanup_dprc_driver:
dprc_driver_exit();

@@ -856,6 +867,7 @@ static void __exit fsl_mc_bus_driver_exit(void)
if (WARN_ON(!mc_dev_cache))
return;

+   its_fsl_mc_msi_cleanup();
fsl_mc_allocator_driver_exit();
dprc_driver_exit();
platform_driver_unregister(&fsl_mc_bus_driver);
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 10/11] staging: fsl-mc: Added DPRC interrupt handler

2015-12-11 Thread J. German Rivera
The interrupt handler for DPRC IRQs is added. DPRC IRQs are
generated for hot plug events related to DPAA2 objects in a given
DPRC. These events include, creating/destroying DPAA2 objects in
the DPRC, changing the "plugged" state of DPAA2 objects and moving
objects between DPRCs.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 247 +++
 1 file changed, 247 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 42b2494..52c6fce 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "dprc-cmd.h"

 struct dprc_child_objs {
@@ -386,6 +387,230 @@ error:
 EXPORT_SYMBOL_GPL(dprc_scan_container);

 /**
+ * dprc_irq0_handler - Regular ISR for DPRC interrupt 0
+ *
+ * @irq: IRQ number of the interrupt being handled
+ * @arg: Pointer to device structure
+ */
+static irqreturn_t dprc_irq0_handler(int irq_num, void *arg)
+{
+   return IRQ_WAKE_THREAD;
+}
+
+/**
+ * dprc_irq0_handler_thread - Handler thread function for DPRC interrupt 0
+ *
+ * @irq: IRQ number of the interrupt being handled
+ * @arg: Pointer to device structure
+ */
+static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
+{
+   int error;
+   u32 status;
+   struct device *dev = (struct device *)arg;
+   struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+   struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   struct fsl_mc_io *mc_io = mc_dev->mc_io;
+   struct msi_desc *msi_desc = mc_dev->irqs[0]->msi_desc;
+
+   dev_dbg(dev, "DPRC IRQ %d triggered on CPU %u\n",
+   irq_num, smp_processor_id());
+
+   if (WARN_ON(!(mc_dev->flags & FSL_MC_IS_DPRC)))
+   return IRQ_HANDLED;
+
+   mutex_lock(&mc_bus->scan_mutex);
+   if (WARN_ON(!msi_desc || msi_desc->irq != (u32)irq_num))
+   goto out;
+
+   error = dprc_get_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
+   &status);
+   if (error < 0) {
+   dev_err(dev,
+   "dprc_get_irq_status() failed: %d\n", error);
+   goto out;
+   }
+
+   error = dprc_clear_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
+ status);
+   if (error < 0) {
+   dev_err(dev,
+   "dprc_clear_irq_status() failed: %d\n", error);
+   goto out;
+   }
+
+   if (status & (DPRC_IRQ_EVENT_OBJ_ADDED |
+ DPRC_IRQ_EVENT_OBJ_REMOVED |
+ DPRC_IRQ_EVENT_CONTAINER_DESTROYED |
+ DPRC_IRQ_EVENT_OBJ_DESTROYED |
+ DPRC_IRQ_EVENT_OBJ_CREATED)) {
+   unsigned int irq_count;
+
+   error = dprc_scan_objects(mc_dev, &irq_count);
+   if (error < 0) {
+   /*
+* If the error is -ENXIO, we ignore it, as it indicates
+* that the object scan was aborted, as we detected that
+* an object was removed from the DPRC in the MC, while
+* we were scanning the DPRC.
+*/
+   if (error != -ENXIO) {
+   dev_err(dev, "dprc_scan_objects() failed: %d\n",
+   error);
+   }
+
+   goto out;
+   }
+
+   if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
+   dev_warn(dev,
+"IRQs needed (%u) exceed IRQs preallocated 
(%u)\n",
+irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   }
+   }
+
+out:
+   mutex_unlock(&mc_bus->scan_mutex);
+   return IRQ_HANDLED;
+}
+
+/*
+ * Disable and clear interrupt for a given DPRC object
+ */
+static int disable_dprc_irq(struct fsl_mc_device *mc_dev)
+{
+   int error;
+   struct fsl_mc_io *mc_io = mc_dev->mc_io;
+
+   WARN_ON(mc_dev->obj_desc.irq_count != 1);
+
+   /*
+* Disable generation of interrupt, while we configure it:
+*/
+   error = dprc_set_irq_enable(mc_io, 0, mc_dev->mc_handle, 0, 0);
+   if (error < 0) {
+   dev_err(&mc_dev->dev,
+   "Disabling DPRC IRQ failed: dprc_set_irq_enable() 
failed: %d\n",
+   error);
+   return error;
+   }
+
+   /*
+* Disable all interrupt causes for the interrupt:
+*/
+   error = dprc_set_irq_mask(mc_io, 0, mc_dev->mc_

[PATCH v4 08/11] staging: fsl-mc: set MSI domain for DPRC objects

2015-12-11 Thread J. German Rivera
THE MSI domain associated with a root DPRC object is
obtained form the device tree. Child DPRCs inherit
the parent DPRC MSI domain.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4:
- Addressed comments from Marc Zyngier:
  * Changed call to fsl_mc_find_msi_domain() to match new
signature changed in patch 3.

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 39 
 1 file changed, 39 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index ef1bb93..38fc404 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -13,6 +13,7 @@
 #include "../include/mc-sys.h"
 #include 
 #include 
+#include 
 #include "dprc-cmd.h"

 struct dprc_child_objs {
@@ -398,11 +399,16 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 {
int error;
size_t region_size;
+   struct device *parent_dev = mc_dev->dev.parent;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   bool msi_domain_set = false;

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
return -EINVAL;

+   if (WARN_ON(dev_get_msi_domain(&mc_dev->dev)))
+   return -EINVAL;
+
if (!mc_dev->mc_io) {
/*
 * This is a child DPRC:
@@ -421,6 +427,30 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 &mc_dev->mc_io);
if (error < 0)
return error;
+   /*
+* Inherit parent MSI domain:
+*/
+   dev_set_msi_domain(&mc_dev->dev,
+  dev_get_msi_domain(parent_dev));
+   msi_domain_set = true;
+   } else {
+   /*
+* This is a root DPRC
+*/
+   struct irq_domain *mc_msi_domain;
+
+   if (WARN_ON(parent_dev->bus == &fsl_mc_bus_type))
+   return -EINVAL;
+
+   error = fsl_mc_find_msi_domain(parent_dev,
+  &mc_msi_domain);
+   if (error < 0) {
+   dev_warn(&mc_dev->dev,
+"WARNING: MC bus without interrupt support\n");
+   } else {
+   dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
+   msi_domain_set = true;
+   }
}

error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
@@ -446,6 +476,9 @@ error_cleanup_open:
(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);

 error_cleanup_mc_io:
+   if (msi_domain_set)
+   dev_set_msi_domain(&mc_dev->dev, NULL);
+
fsl_destroy_mc_io(mc_dev->mc_io);
return error;
 }
@@ -463,6 +496,7 @@ error_cleanup_mc_io:
 static int dprc_remove(struct fsl_mc_device *mc_dev)
 {
int error;
+   struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
return -EINVAL;
@@ -475,6 +509,11 @@ static int dprc_remove(struct fsl_mc_device *mc_dev)
if (error < 0)
dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);

+   if (dev_get_msi_domain(&mc_dev->dev)) {
+   fsl_mc_cleanup_irq_pool(mc_bus);
+   dev_set_msi_domain(&mc_dev->dev, NULL);
+   }
+
dev_info(&mc_dev->dev, "DPRC device unbound from driver");
return 0;
 }
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 04/11] staging: fsl-mc: Added GICv3-ITS support for FSL-MC MSIs

2015-12-11 Thread J. German Rivera
Added platform-specific MSI support layer for FSL-MC devices.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4:
- Addressed comments from Marc Zyngier:
  * Moved bus type check earlier in its_fsl_mc_msi_prepare()
  * Removed its_dev_id variable
  * Changed some assignments to keep both sides on the same line

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/Makefile|   1 +
 .../staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c | 127 +
 drivers/staging/fsl-mc/include/mc-private.h|   4 +
 3 files changed, 132 insertions(+)
 create mode 100644 drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c

diff --git a/drivers/staging/fsl-mc/bus/Makefile 
b/drivers/staging/fsl-mc/bus/Makefile
index a5f2ba4..e731517 100644
--- a/drivers/staging/fsl-mc/bus/Makefile
+++ b/drivers/staging/fsl-mc/bus/Makefile
@@ -14,5 +14,6 @@ mc-bus-driver-objs := mc-bus.o \
  dprc-driver.o \
  mc-allocator.o \
  mc-msi.o \
+ irq-gic-v3-its-fsl-mc-msi.o \
  dpmcp.o \
  dpbp.o
diff --git a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c 
b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
new file mode 100644
index 000..4e8e822
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
@@ -0,0 +1,127 @@
+/*
+ * Freescale Management Complex (MC) bus driver MSI support
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera 
+ *
+ * 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 "../include/mc-private.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../include/mc-sys.h"
+#include "dprc-cmd.h"
+
+static struct irq_chip its_msi_irq_chip = {
+   .name = "fsl-mc-bus-msi",
+   .irq_mask = irq_chip_mask_parent,
+   .irq_unmask = irq_chip_unmask_parent,
+   .irq_eoi = irq_chip_eoi_parent,
+   .irq_set_affinity = msi_domain_set_affinity
+};
+
+static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
+ struct device *dev,
+ int nvec, msi_alloc_info_t *info)
+{
+   struct fsl_mc_device *mc_bus_dev;
+   struct msi_domain_info *msi_info;
+
+   if (WARN_ON(dev->bus != &fsl_mc_bus_type))
+   return -EINVAL;
+
+   mc_bus_dev = to_fsl_mc_device(dev);
+   if (WARN_ON(!(mc_bus_dev->flags & FSL_MC_IS_DPRC)))
+   return -EINVAL;
+
+   /*
+* Set the device Id to be passed to the GIC-ITS:
+*
+* NOTE: This device id corresponds to the IOMMU stream ID
+* associated with the DPRC object (ICID).
+*/
+   info->scratchpad[0].ul = mc_bus_dev->icid;
+   msi_info = msi_get_domain_info(msi_domain->parent);
+   return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info);
+}
+
+static struct msi_domain_ops its_fsl_mc_msi_ops = {
+   .msi_prepare = its_fsl_mc_msi_prepare,
+};
+
+static struct msi_domain_info its_fsl_mc_msi_domain_info = {
+   .flags  = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
+   .ops= &its_fsl_mc_msi_ops,
+   .chip   = &its_msi_irq_chip,
+};
+
+static const struct of_device_id its_device_id[] = {
+   {   .compatible = "arm,gic-v3-its", },
+   {},
+};
+
+int __init its_fsl_mc_msi_init(void)
+{
+   struct device_node *np;
+   struct irq_domain *parent;
+   struct irq_domain *mc_msi_domain;
+
+   for (np = of_find_matching_node(NULL, its_device_id); np;
+np = of_find_matching_node(np, its_device_id)) {
+   if (!of_property_read_bool(np, "msi-controller"))
+   continue;
+
+   parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
+   if (!parent || !msi_get_domain_info(parent)) {
+   pr_err("%s: unable to locate ITS domain\n",
+  np->full_name);
+   continue;
+   }
+
+   mc_msi_domain = fsl_mc_msi_create_irq_domain(
+of_node_to_fwnode(np),
+&its_fsl_mc_msi_domain_info,
+parent);
+   if (!mc_msi_domain) {
+   pr_err("%s: unable to create fsl-mc domain\n",
+  np->full_name);
+   continue;
+   }
+
+   WARN_ON(mc_msi_domain->
+   host_data != &its_fsl_mc_msi_domain_info)

[PATCH v4 01/11] irqdomain: Added domain bus token DOMAIN_BUS_FSL_MC_MSI

2015-12-11 Thread J. German Rivera
Since an FSL-MC bus is a new bus type that is neither PCI nor
PLATFORM, we need a new domain bus token to disambiguate the
IRQ domain for FSL-MC MSIs.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2: none

 include/linux/irqdomain.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index d5e5c5b..c0cb5d1 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -73,6 +73,7 @@ enum irq_domain_bus_token {
DOMAIN_BUS_PCI_MSI,
DOMAIN_BUS_PLATFORM_MSI,
DOMAIN_BUS_NEXUS,
+   DOMAIN_BUS_FSL_MC_MSI,
 };

 /**
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 06/11] staging: fsl-mc: Changed DPRC built-in portal's mc_io to be atomic

2015-12-11 Thread J. German Rivera
The DPRC built-in portal's mc_io is used to send commands to the MC
to program MSIs for MC objects. This is done by the
fsl_mc_msi_write_msg() callback, which is invoked by the generic MSI
layer with interrupts disabled. As a result, the mc_io used in
fsl_mc_msi_write_msg needs to be an atomic mc_io.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 4 +++-
 drivers/staging/fsl-mc/bus/mc-bus.c  | 3 ++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 2c4cd70..767d437 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -396,7 +396,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
error = fsl_create_mc_io(&mc_dev->dev,
 mc_dev->regions[0].start,
 region_size,
-NULL, 0, &mc_dev->mc_io);
+NULL,
+FSL_MC_IO_ATOMIC_CONTEXT_PORTAL,
+&mc_dev->mc_io);
if (error < 0)
return error;
}
diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index 84db55b..d34f1af 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -702,7 +702,8 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
mc_portal_phys_addr = res.start;
mc_portal_size = resource_size(&res);
error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
-mc_portal_size, NULL, 0, &mc_io);
+mc_portal_size, NULL,
+FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
if (error < 0)
return error;

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 07/11] staging: fsl-mc: Populate the IRQ pool for an MC bus instance

2015-12-11 Thread J. German Rivera
Scan the corresponding DPRC container to get total count
of IRQs needed by all its child DPAA2 objects. Then,
preallocate a set of MSI IRQs with the DPRC's ICID
(GIT-ITS device Id) to populate the the DPRC's IRQ pool.
Each child DPAA2 object in the DPRC and the DPRC object itself
will allocate their necessary MSI IRQs from the DPRC's IRQ pool,
in their driver probe function.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c| 24 ++--
 drivers/staging/fsl-mc/include/mc-private.h |  3 ++-
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 767d437..ef1bb93 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -241,6 +241,7 @@ static void dprc_cleanup_all_resource_pools(struct 
fsl_mc_device *mc_bus_dev)
  * dprc_scan_objects - Discover objects in a DPRC
  *
  * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
+ * @total_irq_count: total number of IRQs needed by objects in the DPRC.
  *
  * Detects objects added and removed from a DPRC and synchronizes the
  * state of the Linux bus driver, MC by adding and removing
@@ -254,11 +255,13 @@ static void dprc_cleanup_all_resource_pools(struct 
fsl_mc_device *mc_bus_dev)
  * populated before they can get allocation requests from probe callbacks
  * of the device drivers for the non-allocatable devices.
  */
-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+ unsigned int *total_irq_count)
 {
int num_child_objects;
int dprc_get_obj_failures;
int error;
+   unsigned int irq_count = mc_bus_dev->obj_desc.irq_count;
struct dprc_obj_desc *child_obj_desc_array = NULL;

error = dprc_get_obj_count(mc_bus_dev->mc_io,
@@ -307,6 +310,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
continue;
}

+   irq_count += obj_desc->irq_count;
dev_dbg(&mc_bus_dev->dev,
"Discovered object: type %s, id %d\n",
obj_desc->type, obj_desc->id);
@@ -319,6 +323,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
}
}

+   *total_irq_count = irq_count;
dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
num_child_objects);

@@ -344,6 +349,7 @@ EXPORT_SYMBOL_GPL(dprc_scan_objects);
 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 {
int error;
+   unsigned int irq_count;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);

dprc_init_all_resource_pools(mc_bus_dev);
@@ -352,11 +358,25 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 * Discover objects in the DPRC:
 */
mutex_lock(&mc_bus->scan_mutex);
-   error = dprc_scan_objects(mc_bus_dev);
+   error = dprc_scan_objects(mc_bus_dev, &irq_count);
mutex_unlock(&mc_bus->scan_mutex);
if (error < 0)
goto error;

+   if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) {
+   if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
+   dev_warn(&mc_bus_dev->dev,
+"IRQs needed (%u) exceed IRQs preallocated 
(%u)\n",
+irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   }
+
+   error = fsl_mc_populate_irq_pool(
+   mc_bus,
+   FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   if (error < 0)
+   goto error;
+   }
+
return 0;
 error:
dprc_cleanup_all_resource_pools(mc_bus_dev);
diff --git a/drivers/staging/fsl-mc/include/mc-private.h 
b/drivers/staging/fsl-mc/include/mc-private.h
index 3babe92..be72a44 100644
--- a/drivers/staging/fsl-mc/include/mc-private.h
+++ b/drivers/staging/fsl-mc/include/mc-private.h
@@ -114,7 +114,8 @@ void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);

 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev);

-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev);
+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+ unsigned int *total_irq_count);

 int __init dprc_driver_init(void);

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 00/11] staging: fsl-mc: MC bus MSI support

2015-12-11 Thread J. German Rivera
This patch series addresses the following item from the TODO list
for the MC bus driver to exit staging:

* Interrupt support. For meaningful driver support we need
  interrupts, and thus need message interrupt support by the bus
  driver.

MC Bus MSI Support Architecture
===
A new IRQ domain bus token is added for the FSL-MC bus.
An MSI IRQ domain is created for each top-level (root) data-path
resource container (DPRC), based on its msi-parent in the device
tree (which is the GIC-ITS). Child DPRCs inherit the MSI IRQ
domain form their parent DPRC.

MC Bus MSI Allocation
-
Given the way in which the GIC-ITS works, we need to pre-allocate
a block of MSIs in the GIC-ITS for the IRQs of all the DPAA2 objects
in the same data-path resource container (DPRC) and for the IRQ of
the DPRC iself.

This is due to the fact that all the IRQs for DPAA2 objects in the
same DPRC (and the DPRC's own IRQ) must use the same "device Id" in
the GIC-ITS. Thus, all these IRQs must share the same ITT table in
the GIC-ITS, and therefore must be allocated in the GIC-ITS as
a block of MSIs for the same "device Id".

This is because all the DPAA2 objects in the same DPRC (and the
DPRC itself) use the DPRC's SMMU stream ID as their device Id for
the GIC-ITS.
The DPAA2 Management Complex (MC) firmware does not assign a separate
SMMU stream ID to each DPAA2 object. The MC only assigns SMMU stream
IDs to DPRCs. In MC terms, the stream ID assigned to a DPRC is known
as the DPRC's Isolation Context ID (ICID).

As a consequence of having to pre-allocate a block of MSIs in
the GIC-ITS, the object allocator of the MC bus driver needs to be
extended to provide IRQ allocation services to DPAA2 device drivers
and to the DPRC driver. For a given DPAA2 object, MSIs are allocated
from the corresponding DPRC's pool of pre-allocated MSIs. The MSI
for the DPRC itself is also allocated from this pool.

The following are the patches in this series:

Patch 1: Added domain bus token DOMAIN_BUS_FSL_MC_MSI
Patch 2: Added Added FSL-MC-specific member to the msi_desc's union
Patch 3: Added generic MSI support for FSL-MC devices
Patch 4: Added GICv3-ITS support for FSL-MC MSIs
Patch 5: Extended MC bus allocator to include IRQs
Patch 6: Changed DPRC built-in portal's mc_io to be atomic
Patch 7: Populate the IRQ pool for an MC bus instance
Patch 8: Set MSI domain for DPRC objects
Patch 9: Fixed bug in dprc_probe() error path
Patch 10: Added DPRC interrupt handler
Patch 11: Added MSI support to the MC bus driver

CHANGE HISTORY

Changes in v4:
- Addressed comments from Marc Zyngier for patches 3, 4, 8.
  See details in each patch.

Changes in v3:
- Addressed comments from Marc Zyngier for patch 3.
  See details in patch 3.

Changes in v2:
- Addressed comment from Jiang Liu in patch 2
  See details in patch 2.
- Addressed comment from Dan Carpenter in patch 9
  See details in patch 9.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 02/11] fsl-mc: msi: Added FSL-MC-specific member to the msi_desc's union

2015-12-11 Thread J. German Rivera
FSL-MC is a bus type different from PCI and platform, so it needs
its own member in the msi_desc's union.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2:
- Addressed comment from Jiang Liu
  * Added a dedicated structure for FSL-MC in struct msi_desc

 include/linux/msi.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/linux/msi.h b/include/linux/msi.h
index f71a25e..152e51a 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -33,6 +33,14 @@ struct platform_msi_desc {
 };

 /**
+ * fsl_mc_msi_desc - FSL-MC device specific msi descriptor data
+ * @msi_index: The index of the MSI descriptor
+ */
+struct fsl_mc_msi_desc {
+   u16 msi_index;
+};
+
+/**
  * struct msi_desc - Descriptor structure for MSI based interrupts
  * @list:  List head for management
  * @irq:   The base interrupt number
@@ -87,6 +95,7 @@ struct msi_desc {
 * tree wide cleanup.
 */
struct platform_msi_desc platform;
+   struct fsl_mc_msi_desc fsl_mc;
};
 };

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 09/11] staging: fsl-mc: Fixed bug in dprc_probe() error path

2015-12-11 Thread J. German Rivera
Destroy mc_io in error path in dprc_probe() only if the mc_io was
created in this function.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2:
- Addressed comment from Dan Carpenter:
  * Renamed goto error labels to indicate what the goto does

 drivers/staging/fsl-mc/bus/dprc-driver.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 38fc404..42b2494 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -401,6 +401,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
size_t region_size;
struct device *parent_dev = mc_dev->dev.parent;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   bool mc_io_created = false;
bool msi_domain_set = false;

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
@@ -413,6 +414,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
/*
 * This is a child DPRC:
 */
+   if (WARN_ON(parent_dev->bus != &fsl_mc_bus_type))
+   return -EINVAL;
+
if (WARN_ON(mc_dev->obj_desc.region_count == 0))
return -EINVAL;

@@ -427,6 +431,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 &mc_dev->mc_io);
if (error < 0)
return error;
+
+   mc_io_created = true;
+
/*
 * Inherit parent MSI domain:
 */
@@ -457,7 +464,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
  &mc_dev->mc_handle);
if (error < 0) {
dev_err(&mc_dev->dev, "dprc_open() failed: %d\n", error);
-   goto error_cleanup_mc_io;
+   goto error_cleanup_msi_domain;
}

mutex_init(&mc_bus->scan_mutex);
@@ -475,11 +482,15 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 error_cleanup_open:
(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);

-error_cleanup_mc_io:
+error_cleanup_msi_domain:
if (msi_domain_set)
dev_set_msi_domain(&mc_dev->dev, NULL);

-   fsl_destroy_mc_io(mc_dev->mc_io);
+   if (mc_io_created) {
+   fsl_destroy_mc_io(mc_dev->mc_io);
+   mc_dev->mc_io = NULL;
+   }
+
return error;
 }

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 05/11] staging: fsl-mc: Extended MC bus allocator to include IRQs

2015-12-11 Thread J. German Rivera
All the IRQs for DPAA2 objects in the same DPRC must use
the ICID of that DPRC, as their device Id in the GIC-ITS.
Thus, all these IRQs must share the same ITT table in the GIC.
As a result, a pool of IRQs with the same device Id must be
preallocated per DPRC (fsl-mc bus instance). So, the fsl-mc
bus object allocator is extended to also provide services
to allocate IRQs to DPAA2 devices, from their parent fsl-mc bus
IRQ pool.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v4: none

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-allocator.c   | 199 
 drivers/staging/fsl-mc/include/mc-private.h |  15 +++
 drivers/staging/fsl-mc/include/mc.h |   9 ++
 3 files changed, 223 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c 
b/drivers/staging/fsl-mc/bus/mc-allocator.c
index 88d1857..c5fa628 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -15,6 +15,7 @@
 #include "../include/dpcon-cmd.h"
 #include "dpmcp-cmd.h"
 #include "dpmcp.h"
+#include 

 /**
  * fsl_mc_resource_pool_add_device - add allocatable device to a resource
@@ -160,6 +161,7 @@ static const char *const fsl_mc_pool_type_strings[] = {
[FSL_MC_POOL_DPMCP] = "dpmcp",
[FSL_MC_POOL_DPBP] = "dpbp",
[FSL_MC_POOL_DPCON] = "dpcon",
+   [FSL_MC_POOL_IRQ] = "irq",
 };

 static int __must_check object_type_to_pool_type(const char *object_type,
@@ -465,6 +467,203 @@ void fsl_mc_object_free(struct fsl_mc_device *mc_adev)
 }
 EXPORT_SYMBOL_GPL(fsl_mc_object_free);

+/*
+ * Initialize the interrupt pool associated with a MC bus.
+ * It allocates a block of IRQs from the GIC-ITS
+ */
+int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
+unsigned int irq_count)
+{
+   unsigned int i;
+   struct msi_desc *msi_desc;
+   struct fsl_mc_device_irq *irq_resources;
+   struct fsl_mc_device_irq *mc_dev_irq;
+   int error;
+   struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+   struct fsl_mc_resource_pool *res_pool =
+   &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
+
+   if (WARN_ON(irq_count == 0 ||
+   irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS))
+   return -EINVAL;
+
+   error = fsl_mc_msi_domain_alloc_irqs(&mc_bus_dev->dev, irq_count);
+   if (error < 0)
+   return error;
+
+   irq_resources = devm_kzalloc(&mc_bus_dev->dev,
+sizeof(*irq_resources) * irq_count,
+GFP_KERNEL);
+   if (!irq_resources) {
+   error = -ENOMEM;
+   goto cleanup_msi_irqs;
+   }
+
+   for (i = 0; i < irq_count; i++) {
+   mc_dev_irq = &irq_resources[i];
+
+   /*
+* NOTE: This mc_dev_irq's MSI addr/value pair will be set
+* by the fsl_mc_msi_write_msg() callback
+*/
+   mc_dev_irq->resource.type = res_pool->type;
+   mc_dev_irq->resource.data = mc_dev_irq;
+   mc_dev_irq->resource.parent_pool = res_pool;
+   INIT_LIST_HEAD(&mc_dev_irq->resource.node);
+   list_add_tail(&mc_dev_irq->resource.node, &res_pool->free_list);
+   }
+
+   for_each_msi_entry(msi_desc, &mc_bus_dev->dev) {
+   mc_dev_irq = &irq_resources[msi_desc->fsl_mc.msi_index];
+   mc_dev_irq->msi_desc = msi_desc;
+   mc_dev_irq->resource.id = msi_desc->irq;
+   }
+
+   res_pool->max_count = irq_count;
+   res_pool->free_count = irq_count;
+   mc_bus->irq_resources = irq_resources;
+   return 0;
+
+cleanup_msi_irqs:
+   fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
+   return error;
+}
+EXPORT_SYMBOL_GPL(fsl_mc_populate_irq_pool);
+
+/**
+ * Teardown the interrupt pool associated with an MC bus.
+ * It frees the IRQs that were allocated to the pool, back to the GIC-ITS.
+ */
+void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus)
+{
+   struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+   struct fsl_mc_resource_pool *res_pool =
+   &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
+
+   if (WARN_ON(!mc_bus->irq_resources))
+   return;
+
+   if (WARN_ON(res_pool->max_count == 0))
+   return;
+
+   if (WARN_ON(res_pool->free_count != res_pool->max_count))
+   return;
+
+   INIT_LIST_HEAD(&res_pool->free_list);
+   res_pool->max_count = 0;
+   res_pool->free_count = 0;
+   mc_bus->irq_resources = NULL;
+   fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
+}
+EXPORT_SYMBOL_GPL(fsl_mc_cleanup_irq_poo

[PATCH RESEND v3 11/11] staging: fsl-mc: Added MSI support to the MC bus driver

2015-11-24 Thread J. German Rivera
Initialize/Cleanup ITS-MSI support for the MC bus driver at driver
init/exit time. Associate an MSI domain with each DPAA2 child device.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-bus.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index d34f1af..9317561 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -16,6 +16,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include "../include/dpmng.h"
 #include "../include/mc-sys.h"
 #include "dprc-cmd.h"
@@ -472,6 +474,8 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
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;
+   dev_set_msi_domain(&mc_dev->dev,
+  dev_get_msi_domain(&parent_mc_dev->dev));
}

/*
@@ -833,8 +837,15 @@ static int __init fsl_mc_bus_driver_init(void)
if (error < 0)
goto error_cleanup_dprc_driver;

+   error = its_fsl_mc_msi_init();
+   if (error < 0)
+   goto error_cleanup_mc_allocator;
+
return 0;

+error_cleanup_mc_allocator:
+   fsl_mc_allocator_driver_exit();
+
 error_cleanup_dprc_driver:
dprc_driver_exit();

@@ -856,6 +867,7 @@ static void __exit fsl_mc_bus_driver_exit(void)
if (WARN_ON(!mc_dev_cache))
return;

+   its_fsl_mc_msi_cleanup();
fsl_mc_allocator_driver_exit();
dprc_driver_exit();
platform_driver_unregister(&fsl_mc_bus_driver);
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v3 09/11] staging: fsl-mc: Fixed bug in dprc_probe() error path

2015-11-24 Thread J. German Rivera
Destroy mc_io in error path in dprc_probe() only if the mc_io was
created in this function.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2:
- Addressed comment from Dan Carpenter:
  * Renamed goto error labels to indicate what the goto does

 drivers/staging/fsl-mc/bus/dprc-driver.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 6d83035..cfbd779 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -401,6 +401,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
size_t region_size;
struct device *parent_dev = mc_dev->dev.parent;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   bool mc_io_created = false;
bool msi_domain_set = false;

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
@@ -413,6 +414,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
/*
 * This is a child DPRC:
 */
+   if (WARN_ON(parent_dev->bus != &fsl_mc_bus_type))
+   return -EINVAL;
+
if (WARN_ON(mc_dev->obj_desc.region_count == 0))
return -EINVAL;

@@ -427,6 +431,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 &mc_dev->mc_io);
if (error < 0)
return error;
+
+   mc_io_created = true;
+
/*
 * Inherit parent MSI domain:
 */
@@ -457,7 +464,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
  &mc_dev->mc_handle);
if (error < 0) {
dev_err(&mc_dev->dev, "dprc_open() failed: %d\n", error);
-   goto error_cleanup_mc_io;
+   goto error_cleanup_msi_domain;
}

mutex_init(&mc_bus->scan_mutex);
@@ -475,11 +482,15 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 error_cleanup_open:
(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);

-error_cleanup_mc_io:
+error_cleanup_msi_domain:
if (msi_domain_set)
dev_set_msi_domain(&mc_dev->dev, NULL);

-   fsl_destroy_mc_io(mc_dev->mc_io);
+   if (mc_io_created) {
+   fsl_destroy_mc_io(mc_dev->mc_io);
+   mc_dev->mc_io = NULL;
+   }
+
return error;
 }

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v3 06/11] staging: fsl-mc: Changed DPRC built-in portal's mc_io to be atomic

2015-11-24 Thread J. German Rivera
The DPRC built-in portal's mc_io is used to send commands to the MC
to program MSIs for MC objects. This is done by the
fsl_mc_msi_write_msg() callback, which is invoked by the generic MSI
layer with interrupts disabled. As a result, the mc_io used in
fsl_mc_msi_write_msg needs to be an atomic mc_io.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 4 +++-
 drivers/staging/fsl-mc/bus/mc-bus.c  | 3 ++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 2c4cd70..767d437 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -396,7 +396,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
error = fsl_create_mc_io(&mc_dev->dev,
 mc_dev->regions[0].start,
 region_size,
-NULL, 0, &mc_dev->mc_io);
+NULL,
+FSL_MC_IO_ATOMIC_CONTEXT_PORTAL,
+&mc_dev->mc_io);
if (error < 0)
return error;
}
diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index 84db55b..d34f1af 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -702,7 +702,8 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
mc_portal_phys_addr = res.start;
mc_portal_size = resource_size(&res);
error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
-mc_portal_size, NULL, 0, &mc_io);
+mc_portal_size, NULL,
+FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
if (error < 0)
return error;

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v3 00/11] staging: fsl-mc: MC bus MSI support

2015-11-24 Thread J. German Rivera
*** This is a resend of the last iteration of this patch series ***

This patch series addresses the following item from the TODO list
for the MC bus driver to exit staging:

* Interrupt support. For meaningful driver support we need
  interrupts, and thus need message interrupt support by the bus
  driver.

MC Bus MSI Support Architecture
===
A new IRQ domain bus token is added for the FSL-MC bus.
An MSI IRQ domain is created for each top-level (root) data-path
resource container (DPRC), based on its msi-parent in the device
tree (which is the GIC-ITS). Child DPRCs inherit the MSI IRQ
domain form their parent DPRC.

MC Bus MSI Allocation
-
Given the way in which the GIC-ITS works, we need to pre-allocate
a block of MSIs in the GIC-ITS for the IRQs of all the DPAA2 objects
in the same data-path resource container (DPRC) and for the IRQ of
the DPRC iself.

This is due to the fact that all the IRQs for DPAA2 objects in the
same DPRC (and the DPRC's own IRQ) must use the same "device Id" in
the GIC-ITS. Thus, all these IRQs must share the same ITT table in
the GIC-ITS, and therefore must be allocated in the GIC-ITS as
a block of MSIs for the same "device Id".

This is because all the DPAA2 objects in the same DPRC (and the
DPRC itself) use the DPRC's SMMU stream ID as their device Id for
the GIC-ITS.
The DPAA2 Management Complex (MC) firmware does not assign a separate
SMMU stream ID to each DPAA2 object. The MC only assigns SMMU stream
IDs to DPRCs. In MC terms, the stream ID assigned to a DPRC is known
as the DPRC's Isolation Context ID (ICID).

As a consequence of having to pre-allocate a block of MSIs in
the GIC-ITS, the object allocator of the MC bus driver needs to be
extended to provide IRQ allocation services to DPAA2 device drivers
and to the DPRC driver. For a given DPAA2 object, MSIs are allocated
from the corresponding DPRC's pool of pre-allocated MSIs. The MSI
for the DPRC itself is also allocated from this pool.

The following are the patches in this series:

Patch 1: Added domain bus token DOMAIN_BUS_FSL_MC_MSI
Patch 2: Added Added FSL-MC-specific member to the msi_desc's union
Patch 3: Added generic MSI support for FSL-MC devices
Patch 4: Added GICv3-ITS support for FSL-MC MSIs
Patch 5: Extended MC bus allocator to include IRQs
Patch 6: Changed DPRC built-in portal's mc_io to be atomic
Patch 7: Populate the IRQ pool for an MC bus instance
Patch 8: Set MSI domain for DPRC objects
Patch 9: Fixed bug in dprc_probe() error path
Patch 10: Added DPRC interrupt handler
Patch 11: Added MSI support to the MC bus driver

CHANGE HISTORY

Changes in v3:
- Addressed comments from Marc Zyngier for patch 3.
  See details in patch 3.

Changes in v2:
- Addressed comment from Jiang Liu in patch 2
  See details in patch 2.
- Addressed comment from Dan Carpenter in patch 9
  See details in patch 9.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v3 05/11] staging: fsl-mc: Extended MC bus allocator to include IRQs

2015-11-24 Thread J. German Rivera
All the IRQs for DPAA2 objects in the same DPRC must use
the ICID of that DPRC, as their device Id in the GIC-ITS.
Thus, all these IRQs must share the same ITT table in the GIC.
As a result, a pool of IRQs with the same device Id must be
preallocated per DPRC (fsl-mc bus instance). So, the fsl-mc
bus object allocator is extended to also provide services
to allocate IRQs to DPAA2 devices, from their parent fsl-mc bus
IRQ pool.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-allocator.c   | 199 
 drivers/staging/fsl-mc/include/mc-private.h |  15 +++
 drivers/staging/fsl-mc/include/mc.h |   9 ++
 3 files changed, 223 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c 
b/drivers/staging/fsl-mc/bus/mc-allocator.c
index 88d1857..c5fa628 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -15,6 +15,7 @@
 #include "../include/dpcon-cmd.h"
 #include "dpmcp-cmd.h"
 #include "dpmcp.h"
+#include 

 /**
  * fsl_mc_resource_pool_add_device - add allocatable device to a resource
@@ -160,6 +161,7 @@ static const char *const fsl_mc_pool_type_strings[] = {
[FSL_MC_POOL_DPMCP] = "dpmcp",
[FSL_MC_POOL_DPBP] = "dpbp",
[FSL_MC_POOL_DPCON] = "dpcon",
+   [FSL_MC_POOL_IRQ] = "irq",
 };

 static int __must_check object_type_to_pool_type(const char *object_type,
@@ -465,6 +467,203 @@ void fsl_mc_object_free(struct fsl_mc_device *mc_adev)
 }
 EXPORT_SYMBOL_GPL(fsl_mc_object_free);

+/*
+ * Initialize the interrupt pool associated with a MC bus.
+ * It allocates a block of IRQs from the GIC-ITS
+ */
+int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
+unsigned int irq_count)
+{
+   unsigned int i;
+   struct msi_desc *msi_desc;
+   struct fsl_mc_device_irq *irq_resources;
+   struct fsl_mc_device_irq *mc_dev_irq;
+   int error;
+   struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+   struct fsl_mc_resource_pool *res_pool =
+   &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
+
+   if (WARN_ON(irq_count == 0 ||
+   irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS))
+   return -EINVAL;
+
+   error = fsl_mc_msi_domain_alloc_irqs(&mc_bus_dev->dev, irq_count);
+   if (error < 0)
+   return error;
+
+   irq_resources = devm_kzalloc(&mc_bus_dev->dev,
+sizeof(*irq_resources) * irq_count,
+GFP_KERNEL);
+   if (!irq_resources) {
+   error = -ENOMEM;
+   goto cleanup_msi_irqs;
+   }
+
+   for (i = 0; i < irq_count; i++) {
+   mc_dev_irq = &irq_resources[i];
+
+   /*
+* NOTE: This mc_dev_irq's MSI addr/value pair will be set
+* by the fsl_mc_msi_write_msg() callback
+*/
+   mc_dev_irq->resource.type = res_pool->type;
+   mc_dev_irq->resource.data = mc_dev_irq;
+   mc_dev_irq->resource.parent_pool = res_pool;
+   INIT_LIST_HEAD(&mc_dev_irq->resource.node);
+   list_add_tail(&mc_dev_irq->resource.node, &res_pool->free_list);
+   }
+
+   for_each_msi_entry(msi_desc, &mc_bus_dev->dev) {
+   mc_dev_irq = &irq_resources[msi_desc->fsl_mc.msi_index];
+   mc_dev_irq->msi_desc = msi_desc;
+   mc_dev_irq->resource.id = msi_desc->irq;
+   }
+
+   res_pool->max_count = irq_count;
+   res_pool->free_count = irq_count;
+   mc_bus->irq_resources = irq_resources;
+   return 0;
+
+cleanup_msi_irqs:
+   fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
+   return error;
+}
+EXPORT_SYMBOL_GPL(fsl_mc_populate_irq_pool);
+
+/**
+ * Teardown the interrupt pool associated with an MC bus.
+ * It frees the IRQs that were allocated to the pool, back to the GIC-ITS.
+ */
+void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus)
+{
+   struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+   struct fsl_mc_resource_pool *res_pool =
+   &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
+
+   if (WARN_ON(!mc_bus->irq_resources))
+   return;
+
+   if (WARN_ON(res_pool->max_count == 0))
+   return;
+
+   if (WARN_ON(res_pool->free_count != res_pool->max_count))
+   return;
+
+   INIT_LIST_HEAD(&res_pool->free_list);
+   res_pool->max_count = 0;
+   res_pool->free_count = 0;
+   mc_bus->irq_resources = NULL;
+   fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
+}
+EXPORT_SYMBOL_GPL(fsl_mc_cleanup_irq_pool);
+
+/**
+ * It a

[PATCH RESEND v3 10/11] staging: fsl-mc: Added DPRC interrupt handler

2015-11-24 Thread J. German Rivera
The interrupt handler for DPRC IRQs is added. DPRC IRQs are
generated for hot plug events related to DPAA2 objects in a given
DPRC. These events include, creating/destroying DPAA2 objects in
the DPRC, changing the "plugged" state of DPAA2 objects and moving
objects between DPRCs.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 247 +++
 1 file changed, 247 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index cfbd779..a9fd1e4 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "dprc-cmd.h"

 struct dprc_child_objs {
@@ -386,6 +387,230 @@ error:
 EXPORT_SYMBOL_GPL(dprc_scan_container);

 /**
+ * dprc_irq0_handler - Regular ISR for DPRC interrupt 0
+ *
+ * @irq: IRQ number of the interrupt being handled
+ * @arg: Pointer to device structure
+ */
+static irqreturn_t dprc_irq0_handler(int irq_num, void *arg)
+{
+   return IRQ_WAKE_THREAD;
+}
+
+/**
+ * dprc_irq0_handler_thread - Handler thread function for DPRC interrupt 0
+ *
+ * @irq: IRQ number of the interrupt being handled
+ * @arg: Pointer to device structure
+ */
+static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
+{
+   int error;
+   u32 status;
+   struct device *dev = (struct device *)arg;
+   struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+   struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   struct fsl_mc_io *mc_io = mc_dev->mc_io;
+   struct msi_desc *msi_desc = mc_dev->irqs[0]->msi_desc;
+
+   dev_dbg(dev, "DPRC IRQ %d triggered on CPU %u\n",
+   irq_num, smp_processor_id());
+
+   if (WARN_ON(!(mc_dev->flags & FSL_MC_IS_DPRC)))
+   return IRQ_HANDLED;
+
+   mutex_lock(&mc_bus->scan_mutex);
+   if (WARN_ON(!msi_desc || msi_desc->irq != (u32)irq_num))
+   goto out;
+
+   error = dprc_get_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
+   &status);
+   if (error < 0) {
+   dev_err(dev,
+   "dprc_get_irq_status() failed: %d\n", error);
+   goto out;
+   }
+
+   error = dprc_clear_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
+ status);
+   if (error < 0) {
+   dev_err(dev,
+   "dprc_clear_irq_status() failed: %d\n", error);
+   goto out;
+   }
+
+   if (status & (DPRC_IRQ_EVENT_OBJ_ADDED |
+ DPRC_IRQ_EVENT_OBJ_REMOVED |
+ DPRC_IRQ_EVENT_CONTAINER_DESTROYED |
+ DPRC_IRQ_EVENT_OBJ_DESTROYED |
+ DPRC_IRQ_EVENT_OBJ_CREATED)) {
+   unsigned int irq_count;
+
+   error = dprc_scan_objects(mc_dev, &irq_count);
+   if (error < 0) {
+   /*
+* If the error is -ENXIO, we ignore it, as it indicates
+* that the object scan was aborted, as we detected that
+* an object was removed from the DPRC in the MC, while
+* we were scanning the DPRC.
+*/
+   if (error != -ENXIO) {
+   dev_err(dev, "dprc_scan_objects() failed: %d\n",
+   error);
+   }
+
+   goto out;
+   }
+
+   if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
+   dev_warn(dev,
+"IRQs needed (%u) exceed IRQs preallocated 
(%u)\n",
+irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   }
+   }
+
+out:
+   mutex_unlock(&mc_bus->scan_mutex);
+   return IRQ_HANDLED;
+}
+
+/*
+ * Disable and clear interrupt for a given DPRC object
+ */
+static int disable_dprc_irq(struct fsl_mc_device *mc_dev)
+{
+   int error;
+   struct fsl_mc_io *mc_io = mc_dev->mc_io;
+
+   WARN_ON(mc_dev->obj_desc.irq_count != 1);
+
+   /*
+* Disable generation of interrupt, while we configure it:
+*/
+   error = dprc_set_irq_enable(mc_io, 0, mc_dev->mc_handle, 0, 0);
+   if (error < 0) {
+   dev_err(&mc_dev->dev,
+   "Disabling DPRC IRQ failed: dprc_set_irq_enable() 
failed: %d\n",
+   error);
+   return error;
+   }
+
+   /*
+* Disable all interrupt causes for the interrupt:
+*/
+   error = dprc_set_irq_mask(mc_io, 0, mc_dev->mc_handle, 0, 0x0);
+   if (err

[PATCH RESEND v3 02/11] fsl-mc: msi: Added FSL-MC-specific member to the msi_desc's union

2015-11-24 Thread J. German Rivera
FSL-MC is a bus type different from PCI and platform, so it needs
its own member in the msi_desc's union.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2:
- Addressed comment from Jiang Liu
  * Added a dedicated structure for FSL-MC in struct msi_desc

 include/linux/msi.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/linux/msi.h b/include/linux/msi.h
index f71a25e..152e51a 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -33,6 +33,14 @@ struct platform_msi_desc {
 };

 /**
+ * fsl_mc_msi_desc - FSL-MC device specific msi descriptor data
+ * @msi_index: The index of the MSI descriptor
+ */
+struct fsl_mc_msi_desc {
+   u16 msi_index;
+};
+
+/**
  * struct msi_desc - Descriptor structure for MSI based interrupts
  * @list:  List head for management
  * @irq:   The base interrupt number
@@ -87,6 +95,7 @@ struct msi_desc {
 * tree wide cleanup.
 */
struct platform_msi_desc platform;
+   struct fsl_mc_msi_desc fsl_mc;
};
 };

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v3 01/11] irqdomain: Added domain bus token DOMAIN_BUS_FSL_MC_MSI

2015-11-24 Thread J. German Rivera
Since an FSL-MC bus is a new bus type that is neither PCI nor
PLATFORM, we need a new domain bus token to disambiguate the
IRQ domain for FSL-MC MSIs.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 include/linux/irqdomain.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index d5e5c5b..c0cb5d1 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -73,6 +73,7 @@ enum irq_domain_bus_token {
DOMAIN_BUS_PCI_MSI,
DOMAIN_BUS_PLATFORM_MSI,
DOMAIN_BUS_NEXUS,
+   DOMAIN_BUS_FSL_MC_MSI,
 };

 /**
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v3 07/11] staging: fsl-mc: Populate the IRQ pool for an MC bus instance

2015-11-24 Thread J. German Rivera
Scan the corresponding DPRC container to get total count
of IRQs needed by all its child DPAA2 objects. Then,
preallocate a set of MSI IRQs with the DPRC's ICID
(GIT-ITS device Id) to populate the the DPRC's IRQ pool.
Each child DPAA2 object in the DPRC and the DPRC object itself
will allocate their necessary MSI IRQs from the DPRC's IRQ pool,
in their driver probe function.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c| 24 ++--
 drivers/staging/fsl-mc/include/mc-private.h |  3 ++-
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 767d437..ef1bb93 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -241,6 +241,7 @@ static void dprc_cleanup_all_resource_pools(struct 
fsl_mc_device *mc_bus_dev)
  * dprc_scan_objects - Discover objects in a DPRC
  *
  * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
+ * @total_irq_count: total number of IRQs needed by objects in the DPRC.
  *
  * Detects objects added and removed from a DPRC and synchronizes the
  * state of the Linux bus driver, MC by adding and removing
@@ -254,11 +255,13 @@ static void dprc_cleanup_all_resource_pools(struct 
fsl_mc_device *mc_bus_dev)
  * populated before they can get allocation requests from probe callbacks
  * of the device drivers for the non-allocatable devices.
  */
-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+ unsigned int *total_irq_count)
 {
int num_child_objects;
int dprc_get_obj_failures;
int error;
+   unsigned int irq_count = mc_bus_dev->obj_desc.irq_count;
struct dprc_obj_desc *child_obj_desc_array = NULL;

error = dprc_get_obj_count(mc_bus_dev->mc_io,
@@ -307,6 +310,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
continue;
}

+   irq_count += obj_desc->irq_count;
dev_dbg(&mc_bus_dev->dev,
"Discovered object: type %s, id %d\n",
obj_desc->type, obj_desc->id);
@@ -319,6 +323,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
}
}

+   *total_irq_count = irq_count;
dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
num_child_objects);

@@ -344,6 +349,7 @@ EXPORT_SYMBOL_GPL(dprc_scan_objects);
 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 {
int error;
+   unsigned int irq_count;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);

dprc_init_all_resource_pools(mc_bus_dev);
@@ -352,11 +358,25 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 * Discover objects in the DPRC:
 */
mutex_lock(&mc_bus->scan_mutex);
-   error = dprc_scan_objects(mc_bus_dev);
+   error = dprc_scan_objects(mc_bus_dev, &irq_count);
mutex_unlock(&mc_bus->scan_mutex);
if (error < 0)
goto error;

+   if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) {
+   if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
+   dev_warn(&mc_bus_dev->dev,
+"IRQs needed (%u) exceed IRQs preallocated 
(%u)\n",
+irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   }
+
+   error = fsl_mc_populate_irq_pool(
+   mc_bus,
+   FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   if (error < 0)
+   goto error;
+   }
+
return 0;
 error:
dprc_cleanup_all_resource_pools(mc_bus_dev);
diff --git a/drivers/staging/fsl-mc/include/mc-private.h 
b/drivers/staging/fsl-mc/include/mc-private.h
index e685934..bd514ee 100644
--- a/drivers/staging/fsl-mc/include/mc-private.h
+++ b/drivers/staging/fsl-mc/include/mc-private.h
@@ -114,7 +114,8 @@ void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);

 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev);

-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev);
+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+ unsigned int *total_irq_count);

 int __init dprc_driver_init(void);

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v3 03/11] staging: fsl-mc: Added generic MSI support for FSL-MC devices

2015-11-24 Thread J. German Rivera
Created an MSI domain for the fsl-mc bus-- including functions
to create a domain, find a domain, alloc/free domain irqs, and
bus specific overrides for domain and irq_chip ops.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3:
- Addressed comments from Marc Zyngier:
  * Added WARN_ON in fsl_mc_msi_set_desc to check that caller does
not set set_desc
  * Changed type of paddr in irq_cfg to be phys_addr_t
  * Added WARN_ON in fsl_mc_msi_update_chip_op() to check that caller
does not set irq_write_msi_msg

Changes in v2: none

 drivers/staging/fsl-mc/bus/Kconfig  |   1 +
 drivers/staging/fsl-mc/bus/Makefile |   1 +
 drivers/staging/fsl-mc/bus/mc-msi.c | 285 
 drivers/staging/fsl-mc/include/dprc.h   |   2 +-
 drivers/staging/fsl-mc/include/mc-private.h |  17 ++
 drivers/staging/fsl-mc/include/mc.h |  17 ++
 6 files changed, 322 insertions(+), 1 deletion(-)
 create mode 100644 drivers/staging/fsl-mc/bus/mc-msi.c

diff --git a/drivers/staging/fsl-mc/bus/Kconfig 
b/drivers/staging/fsl-mc/bus/Kconfig
index 0d779d9..c498ac6 100644
--- a/drivers/staging/fsl-mc/bus/Kconfig
+++ b/drivers/staging/fsl-mc/bus/Kconfig
@@ -9,6 +9,7 @@
 config FSL_MC_BUS
tristate "Freescale Management Complex (MC) bus driver"
depends on OF && ARM64
+   select GENERIC_MSI_IRQ_DOMAIN
help
  Driver to enable the bus infrastructure for the Freescale
   QorIQ Management Complex (fsl-mc). The fsl-mc is a hardware
diff --git a/drivers/staging/fsl-mc/bus/Makefile 
b/drivers/staging/fsl-mc/bus/Makefile
index 25433a9..a5f2ba4 100644
--- a/drivers/staging/fsl-mc/bus/Makefile
+++ b/drivers/staging/fsl-mc/bus/Makefile
@@ -13,5 +13,6 @@ mc-bus-driver-objs := mc-bus.o \
  dpmng.o \
  dprc-driver.o \
  mc-allocator.o \
+ mc-msi.o \
  dpmcp.o \
  dpbp.o
diff --git a/drivers/staging/fsl-mc/bus/mc-msi.c 
b/drivers/staging/fsl-mc/bus/mc-msi.c
new file mode 100644
index 000..d6ac465
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/mc-msi.c
@@ -0,0 +1,285 @@
+/*
+ * Freescale Management Complex (MC) bus driver MSI support
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera 
+ *
+ * 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 "../include/mc-private.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../include/mc-sys.h"
+#include "dprc-cmd.h"
+
+static void fsl_mc_msi_set_desc(msi_alloc_info_t *arg,
+   struct msi_desc *desc)
+{
+   arg->desc = desc;
+   arg->hwirq = (irq_hw_number_t)desc->fsl_mc.msi_index;
+}
+
+static void fsl_mc_msi_update_dom_ops(struct msi_domain_info *info)
+{
+   struct msi_domain_ops *ops = info->ops;
+
+   if (WARN_ON(!ops))
+   return;
+
+   /*
+* set_desc should not be set by the caller
+*/
+   if (WARN_ON(ops->set_desc))
+   return;
+
+   ops->set_desc = fsl_mc_msi_set_desc;
+}
+
+static void __fsl_mc_msi_write_msg(struct fsl_mc_device *mc_bus_dev,
+  struct fsl_mc_device_irq *mc_dev_irq)
+{
+   int error;
+   struct fsl_mc_device *owner_mc_dev = mc_dev_irq->mc_dev;
+   struct msi_desc *msi_desc = mc_dev_irq->msi_desc;
+   struct dprc_irq_cfg irq_cfg;
+
+   /*
+* msi_desc->msg.address is 0x0 when this function is invoked in
+* the free_irq() code path. In this case, for the MC, we don't
+* really need to "unprogram" the MSI, so we just return.
+*/
+   if (msi_desc->msg.address_lo == 0x0 && msi_desc->msg.address_hi == 0x0)
+   return;
+
+   if (WARN_ON(!owner_mc_dev))
+   return;
+
+   irq_cfg.paddr = ((u64)msi_desc->msg.address_hi << 32) |
+   msi_desc->msg.address_lo;
+   irq_cfg.val = msi_desc->msg.data;
+   irq_cfg.user_irq_id = msi_desc->irq;
+
+   if (owner_mc_dev == mc_bus_dev) {
+   /*
+* IRQ is for the mc_bus_dev's DPRC itself
+*/
+   error = dprc_set_irq(mc_bus_dev->mc_io,
+MC_CMD_FLAG_INTR_DIS | MC_CMD_FLAG_PRI,
+mc_bus_dev->mc_handle,
+mc_dev_irq->dev_irq_index,
+&irq_cfg);
+   if (error < 0) {
+   dev_err(&owner_mc_dev->dev,
+   "dprc_set_irq() failed: %d\n", error);
+   }

[PATCH RESEND v3 04/11] staging: fsl-mc: Added GICv3-ITS support for FSL-MC MSIs

2015-11-24 Thread J. German Rivera
Added platform-specific MSI support layer for FSL-MC devices.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/Makefile|   1 +
 .../staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c | 127 +
 drivers/staging/fsl-mc/include/mc-private.h|   4 +
 3 files changed, 132 insertions(+)
 create mode 100644 drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c

diff --git a/drivers/staging/fsl-mc/bus/Makefile 
b/drivers/staging/fsl-mc/bus/Makefile
index a5f2ba4..e731517 100644
--- a/drivers/staging/fsl-mc/bus/Makefile
+++ b/drivers/staging/fsl-mc/bus/Makefile
@@ -14,5 +14,6 @@ mc-bus-driver-objs := mc-bus.o \
  dprc-driver.o \
  mc-allocator.o \
  mc-msi.o \
+ irq-gic-v3-its-fsl-mc-msi.o \
  dpmcp.o \
  dpbp.o
diff --git a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c 
b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
new file mode 100644
index 000..5319afa
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
@@ -0,0 +1,127 @@
+/*
+ * Freescale Management Complex (MC) bus driver MSI support
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera 
+ *
+ * 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 "../include/mc-private.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../include/mc-sys.h"
+#include "dprc-cmd.h"
+
+static struct irq_chip its_msi_irq_chip = {
+   .name = "fsl-mc-bus-msi",
+   .irq_mask = irq_chip_mask_parent,
+   .irq_unmask = irq_chip_unmask_parent,
+   .irq_eoi = irq_chip_eoi_parent,
+   .irq_set_affinity = msi_domain_set_affinity
+};
+
+static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
+ struct device *dev,
+ int nvec, msi_alloc_info_t *info)
+{
+   u32 its_dev_id;
+   struct fsl_mc_device *mc_bus_dev = to_fsl_mc_device(dev);
+   struct msi_domain_info *msi_info;
+
+   if (WARN_ON(dev->bus != &fsl_mc_bus_type))
+   return -EINVAL;
+
+   if (WARN_ON(!(mc_bus_dev->flags & FSL_MC_IS_DPRC)))
+   return -EINVAL;
+
+   /*
+* Set the device Id to be passed to the GIC-ITS:
+*
+* NOTE: This device id corresponds to the IOMMU stream ID
+* associated with the DPRC object (ICID).
+*/
+   its_dev_id = mc_bus_dev->icid;
+   info->scratchpad[0].ul = its_dev_id;
+   msi_info = msi_get_domain_info(msi_domain->parent);
+   return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info);
+}
+
+static struct msi_domain_ops its_fsl_mc_msi_ops = {
+   .msi_prepare = its_fsl_mc_msi_prepare,
+};
+
+static struct msi_domain_info its_fsl_mc_msi_domain_info = {
+   .flags  = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
+   .ops= &its_fsl_mc_msi_ops,
+   .chip   = &its_msi_irq_chip,
+};
+
+static const struct of_device_id its_device_id[] = {
+   {   .compatible = "arm,gic-v3-its", },
+   {},
+};
+
+int __init its_fsl_mc_msi_init(void)
+{
+   struct device_node *np;
+   struct irq_domain *parent;
+   struct irq_domain *mc_msi_domain;
+
+   for (np = of_find_matching_node(NULL, its_device_id); np;
+np = of_find_matching_node(np, its_device_id)) {
+   if (!of_property_read_bool(np, "msi-controller"))
+   continue;
+
+   parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
+   if (!parent || !msi_get_domain_info(parent)) {
+   pr_err("%s: unable to locate ITS domain\n",
+  np->full_name);
+   continue;
+   }
+
+   mc_msi_domain =
+   fsl_mc_msi_create_irq_domain(of_node_to_fwnode(np),
+&its_fsl_mc_msi_domain_info,
+parent);
+   if (!mc_msi_domain) {
+   pr_err("%s: unable to create fsl-mc domain\n",
+  np->full_name);
+   continue;
+   }
+
+   WARN_ON(mc_msi_domain->host_data !=
+   &its_fsl_mc_msi_domain_info);
+
+   pr_info("fsl-mc MSI: %s domain created\n", np->full_name);
+   }
+
+   return 0;
+}
+
+void its_fsl_mc_msi_cleanup(void)
+{
+   struct device_node *np;
+
+

[PATCH RESEND v3 08/11] staging: fsl-mc: set MSI domain for DPRC objects

2015-11-24 Thread J. German Rivera
THE MSI domain associated with a root DPRC object is
obtained form the device tree. Child DPRCs inherit
the parent DPRC MSI domain.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 39 
 1 file changed, 39 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index ef1bb93..6d83035 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -13,6 +13,7 @@
 #include "../include/mc-sys.h"
 #include 
 #include 
+#include 
 #include "dprc-cmd.h"

 struct dprc_child_objs {
@@ -398,11 +399,16 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 {
int error;
size_t region_size;
+   struct device *parent_dev = mc_dev->dev.parent;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   bool msi_domain_set = false;

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
return -EINVAL;

+   if (WARN_ON(dev_get_msi_domain(&mc_dev->dev)))
+   return -EINVAL;
+
if (!mc_dev->mc_io) {
/*
 * This is a child DPRC:
@@ -421,6 +427,30 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 &mc_dev->mc_io);
if (error < 0)
return error;
+   /*
+* Inherit parent MSI domain:
+*/
+   dev_set_msi_domain(&mc_dev->dev,
+  dev_get_msi_domain(parent_dev));
+   msi_domain_set = true;
+   } else {
+   /*
+* This is a root DPRC
+*/
+   struct irq_domain *mc_msi_domain;
+
+   if (WARN_ON(parent_dev->bus == &fsl_mc_bus_type))
+   return -EINVAL;
+
+   error = fsl_mc_find_msi_domain(parent_dev->of_node,
+  &mc_msi_domain);
+   if (error < 0) {
+   dev_warn(&mc_dev->dev,
+"WARNING: MC bus without interrupt support\n");
+   } else {
+   dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
+   msi_domain_set = true;
+   }
}

error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
@@ -446,6 +476,9 @@ error_cleanup_open:
(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);

 error_cleanup_mc_io:
+   if (msi_domain_set)
+   dev_set_msi_domain(&mc_dev->dev, NULL);
+
fsl_destroy_mc_io(mc_dev->mc_io);
return error;
 }
@@ -463,6 +496,7 @@ error_cleanup_mc_io:
 static int dprc_remove(struct fsl_mc_device *mc_dev)
 {
int error;
+   struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
return -EINVAL;
@@ -475,6 +509,11 @@ static int dprc_remove(struct fsl_mc_device *mc_dev)
if (error < 0)
dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);

+   if (dev_get_msi_domain(&mc_dev->dev)) {
+   fsl_mc_cleanup_irq_pool(mc_bus);
+   dev_set_msi_domain(&mc_dev->dev, NULL);
+   }
+
dev_info(&mc_dev->dev, "DPRC device unbound from driver");
return 0;
 }
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v6] arm64: dts: Added syscon-reboot node for FSL's LS2080A SoC

2015-11-06 Thread J. German Rivera
Added sys-reboot node to the FSL's LS2080A SoC DT to leverage
the ARM-generic reboot mechanism for this SoC. This mechanism
is enabled through CONFIG_POWER_RESET_SYSCON.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY:

Changes in v6:
- Addressed comment from Javier Martinez Canillas
  * Moved change history out of actual commit message
- Addressed comment from Leo Li
  * Refer to LS2080A in compatible string

Changes in v5:
- Addressed comment from Stuart Yoder
  * Fixed commit message to refer to LS2080A instead of LS2085A.

Changes in v4:
- Addressed comment from Arnd Bergmann:
  * Changed compatible string to be more specific
  * Changed node name to 'syscon' instead of 'rstcr'
  * Changed address to lower case hex
- Addressed comment form Stuart Yoder:
  * Rebase on top of branch arm-soc/for-next

Changes in v3:
- Addressed comment form Stuart Yoder:
  * Expose only the reset register

Changes in v2:
- Addressed comment form Stuart Yoder:
  * Removed "@" from reboot node

 arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
index e81cd48..65ac35f 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
@@ -153,6 +153,18 @@
};
};

+   rstcr: syscon@1e6 {
+   compatible = "fsl,ls2080a-rstcr", "syscon";
+   reg = <0x0 0x1e6 0x0 0x4>;
+   };
+
+   reboot {
+   compatible ="syscon-reboot";
+   regmap = <&rstcr>;
+   offset = <0x0>;
+   mask = <0x2>;
+   };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 00/11] staging: fsl-mc: MC bus MSI support

2015-11-06 Thread J. German Rivera
This patch series addresses the following item from the TODO list
for the MC bus driver to exit staging:

* Interrupt support. For meaningful driver support we need
  interrupts, and thus need message interrupt support by the bus
  driver.

MC Bus MSI Support Architecture
===
A new IRQ domain bus token is added for the FSL-MC bus.
An MSI IRQ domain is created for each top-level (root) data-path
resource container (DPRC), based on its msi-parent in the device
tree (which is the GIC-ITS). Child DPRCs inherit the MSI IRQ
domain form their parent DPRC.

MC Bus MSI Allocation
-
Given the way in which the GIC-ITS works, we need to pre-allocate
a block of MSIs in the GIC-ITS for the IRQs of all the DPAA2 objects
in the same data-path resource container (DPRC) and for the IRQ of
the DPRC iself.

This is due to the fact that all the IRQs for DPAA2 objects in the
same DPRC (and the DPRC's own IRQ) must use the same "device Id" in
the GIC-ITS. Thus, all these IRQs must share the same ITT table in
the GIC-ITS, and therefore must be allocated in the GIC-ITS as
a block of MSIs for the same "device Id".

This is because all the DPAA2 objects in the same DPRC (and the
DPRC itself) use the DPRC's SMMU stream ID as their device Id for
the GIC-ITS.
The DPAA2 Management Complex (MC) firmware does not assign a separate
SMMU stream ID to each DPAA2 object. The MC only assigns SMMU stream
IDs to DPRCs. In MC terms, the stream ID assigned to a DPRC is known
as the DPRC's Isolation Context ID (ICID).

As a consequence of having to pre-allocate a block of MSIs in
the GIC-ITS, the object allocator of the MC bus driver needs to be
extended to provide IRQ allocation services to DPAA2 device drivers
and to the DPRC driver. For a given DPAA2 object, MSIs are allocated
from the corresponding DPRC's pool of pre-allocated MSIs. The MSI
for the DPRC itself is also allocated from this pool.

The following are the patches in this series:

Patch 1: Added domain bus token DOMAIN_BUS_FSL_MC_MSI
Patch 2: Added generic MSI support for FSL-MC devices
Patch 3: Added GICv3-ITS support for FSL-MC MSIs
Patch 4: Extended MC bus allocator to include IRQs
Patch 5: Changed DPRC built-in portal's mc_io to be atomic
Patch 6: Populate the IRQ pool for an MC bus instance
Patch 7: Set MSI domain for DPRC objects
Patch 8: Fixed bug in dprc_probe() error path
Patch 9: Added DPRC interrupt handler
Patch 10: Added MSI support to the MC bus driver

CHANGE HISTORY

Changes in v3:
- Addressed comment from Marc Zyngier for patch 3.
  See details in patch 3.

Changes in v2:
- Addressed comment from Jiang Liu in patch 2.
  See details in patch 2.
- Addressed comment from Dan Carpenter in patch 9
  See details in patch 9.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 02/11] fsl-mc: msi: Added FSL-MC-specific member to the msi_desc's union

2015-11-06 Thread J. German Rivera
FSL-MC is a bus type different from PCI and platform, so it needs
its own member in the msi_desc's union.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2:
- Addressed comment from Jiang Liu
  * Added a dedicated structure for FSL-MC in struct msi_desc

 include/linux/msi.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/linux/msi.h b/include/linux/msi.h
index f71a25e..152e51a 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -33,6 +33,14 @@ struct platform_msi_desc {
 };

 /**
+ * fsl_mc_msi_desc - FSL-MC device specific msi descriptor data
+ * @msi_index: The index of the MSI descriptor
+ */
+struct fsl_mc_msi_desc {
+   u16 msi_index;
+};
+
+/**
  * struct msi_desc - Descriptor structure for MSI based interrupts
  * @list:  List head for management
  * @irq:   The base interrupt number
@@ -87,6 +95,7 @@ struct msi_desc {
 * tree wide cleanup.
 */
struct platform_msi_desc platform;
+   struct fsl_mc_msi_desc fsl_mc;
};
 };

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 08/11] staging: fsl-mc: set MSI domain for DPRC objects

2015-11-06 Thread J. German Rivera
THE MSI domain associated with a root DPRC object is
obtained form the device tree. Child DPRCs inherit
the parent DPRC MSI domain.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 39 
 1 file changed, 39 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 3bcd161..455379d 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -13,6 +13,7 @@
 #include "../include/mc-sys.h"
 #include 
 #include 
+#include 
 #include "dprc-cmd.h"

 struct dprc_child_objs {
@@ -398,11 +399,16 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 {
int error;
size_t region_size;
+   struct device *parent_dev = mc_dev->dev.parent;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   bool msi_domain_set = false;

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
return -EINVAL;

+   if (WARN_ON(dev_get_msi_domain(&mc_dev->dev)))
+   return -EINVAL;
+
if (!mc_dev->mc_io) {
/*
 * This is a child DPRC:
@@ -421,6 +427,30 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 &mc_dev->mc_io);
if (error < 0)
return error;
+   /*
+* Inherit parent MSI domain:
+*/
+   dev_set_msi_domain(&mc_dev->dev,
+  dev_get_msi_domain(parent_dev));
+   msi_domain_set = true;
+   } else {
+   /*
+* This is a root DPRC
+*/
+   struct irq_domain *mc_msi_domain;
+
+   if (WARN_ON(parent_dev->bus == &fsl_mc_bus_type))
+   return -EINVAL;
+
+   error = fsl_mc_find_msi_domain(parent_dev->of_node,
+  &mc_msi_domain);
+   if (error < 0) {
+   dev_warn(&mc_dev->dev,
+"WARNING: MC bus without interrupt support\n");
+   } else {
+   dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
+   msi_domain_set = true;
+   }
}

error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
@@ -446,6 +476,9 @@ error_cleanup_open:
(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);

 error_cleanup_mc_io:
+   if (msi_domain_set)
+   dev_set_msi_domain(&mc_dev->dev, NULL);
+
fsl_destroy_mc_io(mc_dev->mc_io);
return error;
 }
@@ -463,6 +496,7 @@ error_cleanup_mc_io:
 static int dprc_remove(struct fsl_mc_device *mc_dev)
 {
int error;
+   struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
return -EINVAL;
@@ -475,6 +509,11 @@ static int dprc_remove(struct fsl_mc_device *mc_dev)
if (error < 0)
dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);

+   if (dev_get_msi_domain(&mc_dev->dev)) {
+   fsl_mc_cleanup_irq_pool(mc_bus);
+   dev_set_msi_domain(&mc_dev->dev, NULL);
+   }
+
dev_info(&mc_dev->dev, "DPRC device unbound from driver");
return 0;
 }
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 10/11] staging: fsl-mc: Added DPRC interrupt handler

2015-11-06 Thread J. German Rivera
The interrupt handler for DPRC IRQs is added. DPRC IRQs are
generated for hot plug events related to DPAA2 objects in a given
DPRC. These events include, creating/destroying DPAA2 objects in
the DPRC, changing the "plugged" state of DPAA2 objects and moving
objects between DPRCs.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 247 +++
 1 file changed, 247 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 7f1ceb5..0bd2e63 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "dprc-cmd.h"

 struct dprc_child_objs {
@@ -386,6 +387,230 @@ error:
 EXPORT_SYMBOL_GPL(dprc_scan_container);

 /**
+ * dprc_irq0_handler - Regular ISR for DPRC interrupt 0
+ *
+ * @irq: IRQ number of the interrupt being handled
+ * @arg: Pointer to device structure
+ */
+static irqreturn_t dprc_irq0_handler(int irq_num, void *arg)
+{
+   return IRQ_WAKE_THREAD;
+}
+
+/**
+ * dprc_irq0_handler_thread - Handler thread function for DPRC interrupt 0
+ *
+ * @irq: IRQ number of the interrupt being handled
+ * @arg: Pointer to device structure
+ */
+static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
+{
+   int error;
+   u32 status;
+   struct device *dev = (struct device *)arg;
+   struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+   struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   struct fsl_mc_io *mc_io = mc_dev->mc_io;
+   struct msi_desc *msi_desc = mc_dev->irqs[0]->msi_desc;
+
+   dev_dbg(dev, "DPRC IRQ %d triggered on CPU %u\n",
+   irq_num, smp_processor_id());
+
+   if (WARN_ON(!(mc_dev->flags & FSL_MC_IS_DPRC)))
+   return IRQ_HANDLED;
+
+   mutex_lock(&mc_bus->scan_mutex);
+   if (WARN_ON(!msi_desc || msi_desc->irq != (u32)irq_num))
+   goto out;
+
+   error = dprc_get_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
+   &status);
+   if (error < 0) {
+   dev_err(dev,
+   "dprc_get_irq_status() failed: %d\n", error);
+   goto out;
+   }
+
+   error = dprc_clear_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
+ status);
+   if (error < 0) {
+   dev_err(dev,
+   "dprc_clear_irq_status() failed: %d\n", error);
+   goto out;
+   }
+
+   if (status & (DPRC_IRQ_EVENT_OBJ_ADDED |
+ DPRC_IRQ_EVENT_OBJ_REMOVED |
+ DPRC_IRQ_EVENT_CONTAINER_DESTROYED |
+ DPRC_IRQ_EVENT_OBJ_DESTROYED |
+ DPRC_IRQ_EVENT_OBJ_CREATED)) {
+   unsigned int irq_count;
+
+   error = dprc_scan_objects(mc_dev, &irq_count);
+   if (error < 0) {
+   /*
+* If the error is -ENXIO, we ignore it, as it indicates
+* that the object scan was aborted, as we detected that
+* an object was removed from the DPRC in the MC, while
+* we were scanning the DPRC.
+*/
+   if (error != -ENXIO) {
+   dev_err(dev, "dprc_scan_objects() failed: %d\n",
+   error);
+   }
+
+   goto out;
+   }
+
+   if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
+   dev_warn(dev,
+"IRQs needed (%u) exceed IRQs preallocated 
(%u)\n",
+irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   }
+   }
+
+out:
+   mutex_unlock(&mc_bus->scan_mutex);
+   return IRQ_HANDLED;
+}
+
+/*
+ * Disable and clear interrupt for a given DPRC object
+ */
+static int disable_dprc_irq(struct fsl_mc_device *mc_dev)
+{
+   int error;
+   struct fsl_mc_io *mc_io = mc_dev->mc_io;
+
+   WARN_ON(mc_dev->obj_desc.irq_count != 1);
+
+   /*
+* Disable generation of interrupt, while we configure it:
+*/
+   error = dprc_set_irq_enable(mc_io, 0, mc_dev->mc_handle, 0, 0);
+   if (error < 0) {
+   dev_err(&mc_dev->dev,
+   "Disabling DPRC IRQ failed: dprc_set_irq_enable() 
failed: %d\n",
+   error);
+   return error;
+   }
+
+   /*
+* Disable all interrupt causes for the interrupt:
+*/
+   error = dprc_set_irq_mask(mc_io, 0, mc_dev->mc_handle, 0, 0x0);
+   if (err

[PATCH v3 05/11] staging: fsl-mc: Extended MC bus allocator to include IRQs

2015-11-06 Thread J. German Rivera
All the IRQs for DPAA2 objects in the same DPRC must use
the ICID of that DPRC, as their device Id in the GIC-ITS.
Thus, all these IRQs must share the same ITT table in the GIC.
As a result, a pool of IRQs with the same device Id must be
preallocated per DPRC (fsl-mc bus instance). So, the fsl-mc
bus object allocator is extended to also provide services
to allocate IRQs to DPAA2 devices, from their parent fsl-mc bus
IRQ pool.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-allocator.c   | 199 
 drivers/staging/fsl-mc/include/mc-private.h |  15 +++
 drivers/staging/fsl-mc/include/mc.h |   9 ++
 3 files changed, 223 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c 
b/drivers/staging/fsl-mc/bus/mc-allocator.c
index 88d1857..c5fa628 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -15,6 +15,7 @@
 #include "../include/dpcon-cmd.h"
 #include "dpmcp-cmd.h"
 #include "dpmcp.h"
+#include 

 /**
  * fsl_mc_resource_pool_add_device - add allocatable device to a resource
@@ -160,6 +161,7 @@ static const char *const fsl_mc_pool_type_strings[] = {
[FSL_MC_POOL_DPMCP] = "dpmcp",
[FSL_MC_POOL_DPBP] = "dpbp",
[FSL_MC_POOL_DPCON] = "dpcon",
+   [FSL_MC_POOL_IRQ] = "irq",
 };

 static int __must_check object_type_to_pool_type(const char *object_type,
@@ -465,6 +467,203 @@ void fsl_mc_object_free(struct fsl_mc_device *mc_adev)
 }
 EXPORT_SYMBOL_GPL(fsl_mc_object_free);

+/*
+ * Initialize the interrupt pool associated with a MC bus.
+ * It allocates a block of IRQs from the GIC-ITS
+ */
+int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
+unsigned int irq_count)
+{
+   unsigned int i;
+   struct msi_desc *msi_desc;
+   struct fsl_mc_device_irq *irq_resources;
+   struct fsl_mc_device_irq *mc_dev_irq;
+   int error;
+   struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+   struct fsl_mc_resource_pool *res_pool =
+   &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
+
+   if (WARN_ON(irq_count == 0 ||
+   irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS))
+   return -EINVAL;
+
+   error = fsl_mc_msi_domain_alloc_irqs(&mc_bus_dev->dev, irq_count);
+   if (error < 0)
+   return error;
+
+   irq_resources = devm_kzalloc(&mc_bus_dev->dev,
+sizeof(*irq_resources) * irq_count,
+GFP_KERNEL);
+   if (!irq_resources) {
+   error = -ENOMEM;
+   goto cleanup_msi_irqs;
+   }
+
+   for (i = 0; i < irq_count; i++) {
+   mc_dev_irq = &irq_resources[i];
+
+   /*
+* NOTE: This mc_dev_irq's MSI addr/value pair will be set
+* by the fsl_mc_msi_write_msg() callback
+*/
+   mc_dev_irq->resource.type = res_pool->type;
+   mc_dev_irq->resource.data = mc_dev_irq;
+   mc_dev_irq->resource.parent_pool = res_pool;
+   INIT_LIST_HEAD(&mc_dev_irq->resource.node);
+   list_add_tail(&mc_dev_irq->resource.node, &res_pool->free_list);
+   }
+
+   for_each_msi_entry(msi_desc, &mc_bus_dev->dev) {
+   mc_dev_irq = &irq_resources[msi_desc->fsl_mc.msi_index];
+   mc_dev_irq->msi_desc = msi_desc;
+   mc_dev_irq->resource.id = msi_desc->irq;
+   }
+
+   res_pool->max_count = irq_count;
+   res_pool->free_count = irq_count;
+   mc_bus->irq_resources = irq_resources;
+   return 0;
+
+cleanup_msi_irqs:
+   fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
+   return error;
+}
+EXPORT_SYMBOL_GPL(fsl_mc_populate_irq_pool);
+
+/**
+ * Teardown the interrupt pool associated with an MC bus.
+ * It frees the IRQs that were allocated to the pool, back to the GIC-ITS.
+ */
+void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus)
+{
+   struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+   struct fsl_mc_resource_pool *res_pool =
+   &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
+
+   if (WARN_ON(!mc_bus->irq_resources))
+   return;
+
+   if (WARN_ON(res_pool->max_count == 0))
+   return;
+
+   if (WARN_ON(res_pool->free_count != res_pool->max_count))
+   return;
+
+   INIT_LIST_HEAD(&res_pool->free_list);
+   res_pool->max_count = 0;
+   res_pool->free_count = 0;
+   mc_bus->irq_resources = NULL;
+   fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
+}
+EXPORT_SYMBOL_GPL(fsl_mc_cleanup_irq_pool);
+
+/**
+ * It a

[PATCH v3 09/11] staging: fsl-mc: Fixed bug in dprc_probe() error path

2015-11-06 Thread J. German Rivera
Destroy mc_io in error path in dprc_probe() only if the mc_io was
created in this function.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none
- Addressed comment from Dan Carpenter
  * Renamed goto error labels to indicate what the goto does

 drivers/staging/fsl-mc/bus/dprc-driver.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 455379d..7f1ceb5 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -401,6 +401,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
size_t region_size;
struct device *parent_dev = mc_dev->dev.parent;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   bool mc_io_created = false;
bool msi_domain_set = false;

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
@@ -413,6 +414,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
/*
 * This is a child DPRC:
 */
+   if (WARN_ON(parent_dev->bus != &fsl_mc_bus_type))
+   return -EINVAL;
+
if (WARN_ON(mc_dev->obj_desc.region_count == 0))
return -EINVAL;

@@ -427,6 +431,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 &mc_dev->mc_io);
if (error < 0)
return error;
+
+   mc_io_created = true;
+
/*
 * Inherit parent MSI domain:
 */
@@ -457,7 +464,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
  &mc_dev->mc_handle);
if (error < 0) {
dev_err(&mc_dev->dev, "dprc_open() failed: %d\n", error);
-   goto error_cleanup_mc_io;
+   goto error_cleanup_msi_domain;
}

mutex_init(&mc_bus->scan_mutex);
@@ -475,11 +482,15 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 error_cleanup_open:
(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);

-error_cleanup_mc_io:
+error_cleanup_msi_domain:
if (msi_domain_set)
dev_set_msi_domain(&mc_dev->dev, NULL);

-   fsl_destroy_mc_io(mc_dev->mc_io);
+   if (mc_io_created) {
+   fsl_destroy_mc_io(mc_dev->mc_io);
+   mc_dev->mc_io = NULL;
+   }
+
return error;
 }

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 06/11] staging: fsl-mc: Changed DPRC built-in portal's mc_io to be atomic

2015-11-06 Thread J. German Rivera
The DPRC built-in portal's mc_io is used to send commands to the MC
to program MSIs for MC objects. This is done by the
fsl_mc_msi_write_msg() callback, which is invoked by the generic MSI
layer with interrupts disabled. As a result, the mc_io used in
fsl_mc_msi_write_msg needs to be an atomic mc_io.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 4 +++-
 drivers/staging/fsl-mc/bus/mc-bus.c  | 3 ++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index a9ead0d..7bb30dd 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -396,7 +396,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
error = fsl_create_mc_io(&mc_dev->dev,
 mc_dev->regions[0].start,
 region_size,
-NULL, 0, &mc_dev->mc_io);
+NULL,
+FSL_MC_IO_ATOMIC_CONTEXT_PORTAL,
+&mc_dev->mc_io);
if (error < 0)
return error;
}
diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index 84db55b..d34f1af 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -702,7 +702,8 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
mc_portal_phys_addr = res.start;
mc_portal_size = resource_size(&res);
error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
-mc_portal_size, NULL, 0, &mc_io);
+mc_portal_size, NULL,
+FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
if (error < 0)
return error;

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 03/11] staging: fsl-mc: Added generic MSI support for FSL-MC devices

2015-11-06 Thread J. German Rivera
Created an MSI domain for the fsl-mc bus-- including functions
to create a domain, find a domain, alloc/free domain irqs, and
bus specific overrides for domain and irq_chip ops.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none
- Addressed comments from Marc Zyngier:
  * Added WARN_ON in fsl_mc_msi_set_desc to check that caller does
not set set_desc
  * Changed type of paddr in irq_cfg to be phys_addr_t
  * Added WARN_ON in fsl_mc_msi_update_chip_op() to check that caller
does not set irq_write_msi_msg

Changes in v2: none

 drivers/staging/fsl-mc/bus/Kconfig  |   1 +
 drivers/staging/fsl-mc/bus/Makefile |   1 +
 drivers/staging/fsl-mc/bus/mc-msi.c | 285 
 drivers/staging/fsl-mc/include/dprc.h   |   2 +-
 drivers/staging/fsl-mc/include/mc-private.h |  17 ++
 drivers/staging/fsl-mc/include/mc.h |  17 ++
 6 files changed, 322 insertions(+), 1 deletion(-)
 create mode 100644 drivers/staging/fsl-mc/bus/mc-msi.c

diff --git a/drivers/staging/fsl-mc/bus/Kconfig 
b/drivers/staging/fsl-mc/bus/Kconfig
index 0d779d9..c498ac6 100644
--- a/drivers/staging/fsl-mc/bus/Kconfig
+++ b/drivers/staging/fsl-mc/bus/Kconfig
@@ -9,6 +9,7 @@
 config FSL_MC_BUS
tristate "Freescale Management Complex (MC) bus driver"
depends on OF && ARM64
+   select GENERIC_MSI_IRQ_DOMAIN
help
  Driver to enable the bus infrastructure for the Freescale
   QorIQ Management Complex (fsl-mc). The fsl-mc is a hardware
diff --git a/drivers/staging/fsl-mc/bus/Makefile 
b/drivers/staging/fsl-mc/bus/Makefile
index 25433a9..a5f2ba4 100644
--- a/drivers/staging/fsl-mc/bus/Makefile
+++ b/drivers/staging/fsl-mc/bus/Makefile
@@ -13,5 +13,6 @@ mc-bus-driver-objs := mc-bus.o \
  dpmng.o \
  dprc-driver.o \
  mc-allocator.o \
+ mc-msi.o \
  dpmcp.o \
  dpbp.o
diff --git a/drivers/staging/fsl-mc/bus/mc-msi.c 
b/drivers/staging/fsl-mc/bus/mc-msi.c
new file mode 100644
index 000..d6ac465
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/mc-msi.c
@@ -0,0 +1,285 @@
+/*
+ * Freescale Management Complex (MC) bus driver MSI support
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera 
+ *
+ * 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 "../include/mc-private.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../include/mc-sys.h"
+#include "dprc-cmd.h"
+
+static void fsl_mc_msi_set_desc(msi_alloc_info_t *arg,
+   struct msi_desc *desc)
+{
+   arg->desc = desc;
+   arg->hwirq = (irq_hw_number_t)desc->fsl_mc.msi_index;
+}
+
+static void fsl_mc_msi_update_dom_ops(struct msi_domain_info *info)
+{
+   struct msi_domain_ops *ops = info->ops;
+
+   if (WARN_ON(!ops))
+   return;
+
+   /*
+* set_desc should not be set by the caller
+*/
+   if (WARN_ON(ops->set_desc))
+   return;
+
+   ops->set_desc = fsl_mc_msi_set_desc;
+}
+
+static void __fsl_mc_msi_write_msg(struct fsl_mc_device *mc_bus_dev,
+  struct fsl_mc_device_irq *mc_dev_irq)
+{
+   int error;
+   struct fsl_mc_device *owner_mc_dev = mc_dev_irq->mc_dev;
+   struct msi_desc *msi_desc = mc_dev_irq->msi_desc;
+   struct dprc_irq_cfg irq_cfg;
+
+   /*
+* msi_desc->msg.address is 0x0 when this function is invoked in
+* the free_irq() code path. In this case, for the MC, we don't
+* really need to "unprogram" the MSI, so we just return.
+*/
+   if (msi_desc->msg.address_lo == 0x0 && msi_desc->msg.address_hi == 0x0)
+   return;
+
+   if (WARN_ON(!owner_mc_dev))
+   return;
+
+   irq_cfg.paddr = ((u64)msi_desc->msg.address_hi << 32) |
+   msi_desc->msg.address_lo;
+   irq_cfg.val = msi_desc->msg.data;
+   irq_cfg.user_irq_id = msi_desc->irq;
+
+   if (owner_mc_dev == mc_bus_dev) {
+   /*
+* IRQ is for the mc_bus_dev's DPRC itself
+*/
+   error = dprc_set_irq(mc_bus_dev->mc_io,
+MC_CMD_FLAG_INTR_DIS | MC_CMD_FLAG_PRI,
+mc_bus_dev->mc_handle,
+mc_dev_irq->dev_irq_index,
+&irq_cfg);
+   if (error < 0) {
+   dev_err(&owner_mc_dev->dev,
+   "dprc_set_irq() failed: %d\n", error);
+   }

[PATCH v3 11/11] staging: fsl-mc: Added MSI support to the MC bus driver

2015-11-06 Thread J. German Rivera
Initialize/Cleanup ITS-MSI support for the MC bus driver at driver
init/exit time. Associate an MSI domain with each DPAA2 child device.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-bus.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index d34f1af..9317561 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -16,6 +16,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include "../include/dpmng.h"
 #include "../include/mc-sys.h"
 #include "dprc-cmd.h"
@@ -472,6 +474,8 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
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;
+   dev_set_msi_domain(&mc_dev->dev,
+  dev_get_msi_domain(&parent_mc_dev->dev));
}

/*
@@ -833,8 +837,15 @@ static int __init fsl_mc_bus_driver_init(void)
if (error < 0)
goto error_cleanup_dprc_driver;

+   error = its_fsl_mc_msi_init();
+   if (error < 0)
+   goto error_cleanup_mc_allocator;
+
return 0;

+error_cleanup_mc_allocator:
+   fsl_mc_allocator_driver_exit();
+
 error_cleanup_dprc_driver:
dprc_driver_exit();

@@ -856,6 +867,7 @@ static void __exit fsl_mc_bus_driver_exit(void)
if (WARN_ON(!mc_dev_cache))
return;

+   its_fsl_mc_msi_cleanup();
fsl_mc_allocator_driver_exit();
dprc_driver_exit();
platform_driver_unregister(&fsl_mc_bus_driver);
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 04/11] staging: fsl-mc: Added GICv3-ITS support for FSL-MC MSIs

2015-11-06 Thread J. German Rivera
Added platform-specific MSI support layer for FSL-MC devices.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/Makefile|   1 +
 .../staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c | 127 +
 drivers/staging/fsl-mc/include/mc-private.h|   4 +
 3 files changed, 132 insertions(+)
 create mode 100644 drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c

diff --git a/drivers/staging/fsl-mc/bus/Makefile 
b/drivers/staging/fsl-mc/bus/Makefile
index a5f2ba4..e731517 100644
--- a/drivers/staging/fsl-mc/bus/Makefile
+++ b/drivers/staging/fsl-mc/bus/Makefile
@@ -14,5 +14,6 @@ mc-bus-driver-objs := mc-bus.o \
  dprc-driver.o \
  mc-allocator.o \
  mc-msi.o \
+ irq-gic-v3-its-fsl-mc-msi.o \
  dpmcp.o \
  dpbp.o
diff --git a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c 
b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
new file mode 100644
index 000..5319afa
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
@@ -0,0 +1,127 @@
+/*
+ * Freescale Management Complex (MC) bus driver MSI support
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera 
+ *
+ * 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 "../include/mc-private.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../include/mc-sys.h"
+#include "dprc-cmd.h"
+
+static struct irq_chip its_msi_irq_chip = {
+   .name = "fsl-mc-bus-msi",
+   .irq_mask = irq_chip_mask_parent,
+   .irq_unmask = irq_chip_unmask_parent,
+   .irq_eoi = irq_chip_eoi_parent,
+   .irq_set_affinity = msi_domain_set_affinity
+};
+
+static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
+ struct device *dev,
+ int nvec, msi_alloc_info_t *info)
+{
+   u32 its_dev_id;
+   struct fsl_mc_device *mc_bus_dev = to_fsl_mc_device(dev);
+   struct msi_domain_info *msi_info;
+
+   if (WARN_ON(dev->bus != &fsl_mc_bus_type))
+   return -EINVAL;
+
+   if (WARN_ON(!(mc_bus_dev->flags & FSL_MC_IS_DPRC)))
+   return -EINVAL;
+
+   /*
+* Set the device Id to be passed to the GIC-ITS:
+*
+* NOTE: This device id corresponds to the IOMMU stream ID
+* associated with the DPRC object (ICID).
+*/
+   its_dev_id = mc_bus_dev->icid;
+   info->scratchpad[0].ul = its_dev_id;
+   msi_info = msi_get_domain_info(msi_domain->parent);
+   return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info);
+}
+
+static struct msi_domain_ops its_fsl_mc_msi_ops = {
+   .msi_prepare = its_fsl_mc_msi_prepare,
+};
+
+static struct msi_domain_info its_fsl_mc_msi_domain_info = {
+   .flags  = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
+   .ops= &its_fsl_mc_msi_ops,
+   .chip   = &its_msi_irq_chip,
+};
+
+static const struct of_device_id its_device_id[] = {
+   {   .compatible = "arm,gic-v3-its", },
+   {},
+};
+
+int __init its_fsl_mc_msi_init(void)
+{
+   struct device_node *np;
+   struct irq_domain *parent;
+   struct irq_domain *mc_msi_domain;
+
+   for (np = of_find_matching_node(NULL, its_device_id); np;
+np = of_find_matching_node(np, its_device_id)) {
+   if (!of_property_read_bool(np, "msi-controller"))
+   continue;
+
+   parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
+   if (!parent || !msi_get_domain_info(parent)) {
+   pr_err("%s: unable to locate ITS domain\n",
+  np->full_name);
+   continue;
+   }
+
+   mc_msi_domain =
+   fsl_mc_msi_create_irq_domain(of_node_to_fwnode(np),
+&its_fsl_mc_msi_domain_info,
+parent);
+   if (!mc_msi_domain) {
+   pr_err("%s: unable to create fsl-mc domain\n",
+  np->full_name);
+   continue;
+   }
+
+   WARN_ON(mc_msi_domain->host_data !=
+   &its_fsl_mc_msi_domain_info);
+
+   pr_info("fsl-mc MSI: %s domain created\n", np->full_name);
+   }
+
+   return 0;
+}
+
+void its_fsl_mc_msi_cleanup(void)
+{
+   struct device_node *np;
+
+

[PATCH v3 01/11] irqdomain: Added domain bus token DOMAIN_BUS_FSL_MC_MSI

2015-11-06 Thread J. German Rivera
Since an FSL-MC bus is a new bus type that is neither PCI nor
PLATFORM, we need a new domain bus token to disambiguate the
IRQ domain for FSL-MC MSIs.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 include/linux/irqdomain.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index d5e5c5b..c0cb5d1 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -73,6 +73,7 @@ enum irq_domain_bus_token {
DOMAIN_BUS_PCI_MSI,
DOMAIN_BUS_PLATFORM_MSI,
DOMAIN_BUS_NEXUS,
+   DOMAIN_BUS_FSL_MC_MSI,
 };

 /**
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 07/11] staging: fsl-mc: Populate the IRQ pool for an MC bus instance

2015-11-06 Thread J. German Rivera
Scan the corresponding DPRC container to get total count
of IRQs needed by all its child DPAA2 objects. Then,
preallocate a set of MSI IRQs with the DPRC's ICID
(GIT-ITS device Id) to populate the the DPRC's IRQ pool.
Each child DPAA2 object in the DPRC and the DPRC object itself
will allocate their necessary MSI IRQs from the DPRC's IRQ pool,
in their driver probe function.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c| 24 ++--
 drivers/staging/fsl-mc/include/mc-private.h |  3 ++-
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 7bb30dd..3bcd161 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -241,6 +241,7 @@ static void dprc_cleanup_all_resource_pools(struct 
fsl_mc_device *mc_bus_dev)
  * dprc_scan_objects - Discover objects in a DPRC
  *
  * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
+ * @total_irq_count: total number of IRQs needed by objects in the DPRC.
  *
  * Detects objects added and removed from a DPRC and synchronizes the
  * state of the Linux bus driver, MC by adding and removing
@@ -254,11 +255,13 @@ static void dprc_cleanup_all_resource_pools(struct 
fsl_mc_device *mc_bus_dev)
  * populated before they can get allocation requests from probe callbacks
  * of the device drivers for the non-allocatable devices.
  */
-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+ unsigned int *total_irq_count)
 {
int num_child_objects;
int dprc_get_obj_failures;
int error;
+   unsigned int irq_count = mc_bus_dev->obj_desc.irq_count;
struct dprc_obj_desc *child_obj_desc_array = NULL;

error = dprc_get_obj_count(mc_bus_dev->mc_io,
@@ -307,6 +310,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
continue;
}

+   irq_count += obj_desc->irq_count;
dev_dbg(&mc_bus_dev->dev,
"Discovered object: type %s, id %d\n",
obj_desc->type, obj_desc->id);
@@ -319,6 +323,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
}
}

+   *total_irq_count = irq_count;
dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
num_child_objects);

@@ -344,6 +349,7 @@ EXPORT_SYMBOL_GPL(dprc_scan_objects);
 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 {
int error;
+   unsigned int irq_count;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);

dprc_init_all_resource_pools(mc_bus_dev);
@@ -352,11 +358,25 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 * Discover objects in the DPRC:
 */
mutex_lock(&mc_bus->scan_mutex);
-   error = dprc_scan_objects(mc_bus_dev);
+   error = dprc_scan_objects(mc_bus_dev, &irq_count);
mutex_unlock(&mc_bus->scan_mutex);
if (error < 0)
goto error;

+   if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) {
+   if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
+   dev_warn(&mc_bus_dev->dev,
+"IRQs needed (%u) exceed IRQs preallocated 
(%u)\n",
+irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   }
+
+   error = fsl_mc_populate_irq_pool(
+   mc_bus,
+   FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   if (error < 0)
+   goto error;
+   }
+
return 0;
 error:
dprc_cleanup_all_resource_pools(mc_bus_dev);
diff --git a/drivers/staging/fsl-mc/include/mc-private.h 
b/drivers/staging/fsl-mc/include/mc-private.h
index 97295f0..27834ea 100644
--- a/drivers/staging/fsl-mc/include/mc-private.h
+++ b/drivers/staging/fsl-mc/include/mc-private.h
@@ -114,7 +114,8 @@ void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);

 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev);

-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev);
+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+ unsigned int *total_irq_count);

 int __init dprc_driver_init(void);

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] arm64: dts: Added syscon-reboot node for FSL's LS2080A SoC

2015-11-06 Thread J. German Rivera
Added sys-reboot node to the FSL's LS2080A SoC DT to leverage
the ARM-generic reboot mechanism for this SoC. This mechanism
is enabled through CONFIG_POWER_RESET_SYSCON.

CHANGE HISTORY:

Changes in v3:
- Addressed comment from Stuart Yoder
  * Fixed commit message to refer to LS2080A instead of LS2085A.

Changes in v2:
- Addressed comment form Stuart Yoder:
  * Removed "@" from reboot node

Changes in v3:
- Addressed comment form Stuart Yoder:
  * Expose only the reset register

Changes in v4:
- Addressed comment from Arnd Bergmann:
  * Changed compatible string to be more specific
  * Changed node name to 'syscon' instead of 'rstcr'
  * Changed address to lower case hex
- Addressed comment form Stuart Yoder:
  * Rebase on top of branch arm-soc/for-next

Signed-off-by: J. German Rivera 
---
 arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
index e81cd48..a790a90 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
@@ -153,6 +153,18 @@
};
};
 
+   rstcr: syscon@1e6 {
+   compatible = "fsl,ls2085a-rstcr", "syscon";
+   reg = <0x0 0x1e6 0x0 0x4>;
+   };
+
+   reboot {
+   compatible ="syscon-reboot";
+   regmap = <&rstcr>;
+   offset = <0x0>;
+   mask = <0x2>;
+   };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
-- 
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4] arm64: dts: Added syscon-reboot node for FSL's LS2085A SoC

2015-10-30 Thread J. German Rivera
Added sys-reboot node to the FSL's LS2085A SoC DT to leverage
the ARM-generic reboot mechanism for this SoC. This mechanism
is enabled through CONFIG_POWER_RESET_SYSCON.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY:

Changes in v2:
- Addressed comment form Stuart Yoder:
  * Removed "@" from reboot node

Changes in v3:
- Addressed comment form Stuart Yoder:
  * Expose only the reset register

Changes in v4:
- Addressed comment from Arnd Bergmann:
  * Changed compatible string to be more specific
  * Changed node name to 'syscon' instead of 'rstcr'
  * Changed address to lower case hex
- Addressed comment form Stuart Yoder:
  * Rebase on top of branch arm-soc/for-next

 arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
index e81cd48..a790a90 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
@@ -153,6 +153,18 @@
};
};

+   rstcr: syscon@1e6 {
+   compatible = "fsl,ls2085a-rstcr", "syscon";
+   reg = <0x0 0x1e6 0x0 0x4>;
+   };
+
+   reboot {
+   compatible ="syscon-reboot";
+   regmap = <&rstcr>;
+   offset = <0x0>;
+   mask = <0x2>;
+   };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 04/11] staging: fsl-mc: Added GICv3-ITS support for FSL-MC MSIs

2015-10-30 Thread J. German Rivera
Added platform-specific MSI support layer for FSL-MC devices.

Signed-off-by: J. German Rivera 
---
Changes in v2: none

 drivers/staging/fsl-mc/bus/Makefile|   1 +
 .../staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c | 127 +
 drivers/staging/fsl-mc/include/mc-private.h|   4 +
 3 files changed, 132 insertions(+)
 create mode 100644 drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c

diff --git a/drivers/staging/fsl-mc/bus/Makefile 
b/drivers/staging/fsl-mc/bus/Makefile
index a5f2ba4..e731517 100644
--- a/drivers/staging/fsl-mc/bus/Makefile
+++ b/drivers/staging/fsl-mc/bus/Makefile
@@ -14,5 +14,6 @@ mc-bus-driver-objs := mc-bus.o \
  dprc-driver.o \
  mc-allocator.o \
  mc-msi.o \
+ irq-gic-v3-its-fsl-mc-msi.o \
  dpmcp.o \
  dpbp.o
diff --git a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c 
b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
new file mode 100644
index 000..5319afa
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
@@ -0,0 +1,127 @@
+/*
+ * Freescale Management Complex (MC) bus driver MSI support
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera 
+ *
+ * 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 "../include/mc-private.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../include/mc-sys.h"
+#include "dprc-cmd.h"
+
+static struct irq_chip its_msi_irq_chip = {
+   .name = "fsl-mc-bus-msi",
+   .irq_mask = irq_chip_mask_parent,
+   .irq_unmask = irq_chip_unmask_parent,
+   .irq_eoi = irq_chip_eoi_parent,
+   .irq_set_affinity = msi_domain_set_affinity
+};
+
+static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
+ struct device *dev,
+ int nvec, msi_alloc_info_t *info)
+{
+   u32 its_dev_id;
+   struct fsl_mc_device *mc_bus_dev = to_fsl_mc_device(dev);
+   struct msi_domain_info *msi_info;
+
+   if (WARN_ON(dev->bus != &fsl_mc_bus_type))
+   return -EINVAL;
+
+   if (WARN_ON(!(mc_bus_dev->flags & FSL_MC_IS_DPRC)))
+   return -EINVAL;
+
+   /*
+* Set the device Id to be passed to the GIC-ITS:
+*
+* NOTE: This device id corresponds to the IOMMU stream ID
+* associated with the DPRC object (ICID).
+*/
+   its_dev_id = mc_bus_dev->icid;
+   info->scratchpad[0].ul = its_dev_id;
+   msi_info = msi_get_domain_info(msi_domain->parent);
+   return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info);
+}
+
+static struct msi_domain_ops its_fsl_mc_msi_ops = {
+   .msi_prepare = its_fsl_mc_msi_prepare,
+};
+
+static struct msi_domain_info its_fsl_mc_msi_domain_info = {
+   .flags  = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
+   .ops= &its_fsl_mc_msi_ops,
+   .chip   = &its_msi_irq_chip,
+};
+
+static const struct of_device_id its_device_id[] = {
+   {   .compatible = "arm,gic-v3-its", },
+   {},
+};
+
+int __init its_fsl_mc_msi_init(void)
+{
+   struct device_node *np;
+   struct irq_domain *parent;
+   struct irq_domain *mc_msi_domain;
+
+   for (np = of_find_matching_node(NULL, its_device_id); np;
+np = of_find_matching_node(np, its_device_id)) {
+   if (!of_property_read_bool(np, "msi-controller"))
+   continue;
+
+   parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
+   if (!parent || !msi_get_domain_info(parent)) {
+   pr_err("%s: unable to locate ITS domain\n",
+  np->full_name);
+   continue;
+   }
+
+   mc_msi_domain =
+   fsl_mc_msi_create_irq_domain(of_node_to_fwnode(np),
+&its_fsl_mc_msi_domain_info,
+parent);
+   if (!mc_msi_domain) {
+   pr_err("%s: unable to create fsl-mc domain\n",
+  np->full_name);
+   continue;
+   }
+
+   WARN_ON(mc_msi_domain->host_data !=
+   &its_fsl_mc_msi_domain_info);
+
+   pr_info("fsl-mc MSI: %s domain created\n", np->full_name);
+   }
+
+   return 0;
+}
+
+void its_fsl_mc_msi_cleanup(void)
+{
+   struct device_node *np;
+
+   for (np 

[PATCH v2 06/11] staging: fsl-mc: Changed DPRC built-in portal's mc_io to be atomic

2015-10-30 Thread J. German Rivera
The DPRC built-in portal's mc_io is used to send commands to the MC
to program MSIs for MC objects. This is done by the
fsl_mc_msi_write_msg() callback, which is invoked by the generic MSI
layer with interrupts disabled. As a result, the mc_io used in
fsl_mc_msi_write_msg needs to be an atomic mc_io.

Signed-off-by: J. German Rivera 
---
Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 4 +++-
 drivers/staging/fsl-mc/bus/mc-bus.c  | 3 ++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index a9ead0d..7bb30dd 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -396,7 +396,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
error = fsl_create_mc_io(&mc_dev->dev,
 mc_dev->regions[0].start,
 region_size,
-NULL, 0, &mc_dev->mc_io);
+NULL,
+FSL_MC_IO_ATOMIC_CONTEXT_PORTAL,
+&mc_dev->mc_io);
if (error < 0)
return error;
}
diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index 84db55b..d34f1af 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -702,7 +702,8 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
mc_portal_phys_addr = res.start;
mc_portal_size = resource_size(&res);
error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
-mc_portal_size, NULL, 0, &mc_io);
+mc_portal_size, NULL,
+FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
if (error < 0)
return error;

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 03/11] staging: fsl-mc: Added generic MSI support for FSL-MC devices

2015-10-30 Thread J. German Rivera
Created an MSI domain for the fsl-mc bus-- including functions
to create a domain, find a domain, alloc/free domain irqs, and
bus specific overrides for domain and irq_chip ops.

Signed-off-by: J. German Rivera 
---
Changes in v2: none

 drivers/staging/fsl-mc/bus/Kconfig  |   1 +
 drivers/staging/fsl-mc/bus/Makefile |   1 +
 drivers/staging/fsl-mc/bus/mc-msi.c | 276 
 drivers/staging/fsl-mc/include/mc-private.h |  17 ++
 drivers/staging/fsl-mc/include/mc.h |  17 ++
 5 files changed, 312 insertions(+)
 create mode 100644 drivers/staging/fsl-mc/bus/mc-msi.c

diff --git a/drivers/staging/fsl-mc/bus/Kconfig 
b/drivers/staging/fsl-mc/bus/Kconfig
index 0d779d9..c498ac6 100644
--- a/drivers/staging/fsl-mc/bus/Kconfig
+++ b/drivers/staging/fsl-mc/bus/Kconfig
@@ -9,6 +9,7 @@
 config FSL_MC_BUS
tristate "Freescale Management Complex (MC) bus driver"
depends on OF && ARM64
+   select GENERIC_MSI_IRQ_DOMAIN
help
  Driver to enable the bus infrastructure for the Freescale
   QorIQ Management Complex (fsl-mc). The fsl-mc is a hardware
diff --git a/drivers/staging/fsl-mc/bus/Makefile 
b/drivers/staging/fsl-mc/bus/Makefile
index 25433a9..a5f2ba4 100644
--- a/drivers/staging/fsl-mc/bus/Makefile
+++ b/drivers/staging/fsl-mc/bus/Makefile
@@ -13,5 +13,6 @@ mc-bus-driver-objs := mc-bus.o \
  dpmng.o \
  dprc-driver.o \
  mc-allocator.o \
+ mc-msi.o \
  dpmcp.o \
  dpbp.o
diff --git a/drivers/staging/fsl-mc/bus/mc-msi.c 
b/drivers/staging/fsl-mc/bus/mc-msi.c
new file mode 100644
index 000..81b53e3
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/mc-msi.c
@@ -0,0 +1,276 @@
+/*
+ * Freescale Management Complex (MC) bus driver MSI support
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera 
+ *
+ * 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 "../include/mc-private.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../include/mc-sys.h"
+#include "dprc-cmd.h"
+
+static void fsl_mc_msi_set_desc(msi_alloc_info_t *arg,
+   struct msi_desc *desc)
+{
+   arg->desc = desc;
+   arg->hwirq = (irq_hw_number_t)desc->fsl_mc.msi_index;
+}
+
+static void fsl_mc_msi_update_dom_ops(struct msi_domain_info *info)
+{
+   struct msi_domain_ops *ops = info->ops;
+
+   if (WARN_ON(!ops))
+   return;
+
+   if (!ops->set_desc)
+   ops->set_desc = fsl_mc_msi_set_desc;
+}
+
+static void __fsl_mc_msi_write_msg(struct fsl_mc_device *mc_bus_dev,
+  struct fsl_mc_device_irq *mc_dev_irq)
+{
+   int error;
+   struct fsl_mc_device *owner_mc_dev = mc_dev_irq->mc_dev;
+   struct msi_desc *msi_desc = mc_dev_irq->msi_desc;
+   struct dprc_irq_cfg irq_cfg;
+
+   /*
+* msi_desc->msg.address is 0x0 when this function is invoked in
+* the free_irq() code path. In this case, for the MC, we don't
+* really need to "unprogram" the MSI, so we just return.
+*/
+   if (msi_desc->msg.address_lo == 0x0 && msi_desc->msg.address_hi == 0x0)
+   return;
+
+   if (WARN_ON(!owner_mc_dev))
+   return;
+
+   irq_cfg.paddr = ((u64)msi_desc->msg.address_hi << 32) |
+   msi_desc->msg.address_lo;
+   irq_cfg.val = msi_desc->msg.data;
+   irq_cfg.user_irq_id = msi_desc->irq;
+
+   /*
+* DPRCs and other objects use different commands to set up IRQs,
+* so we have to differentiate them here.
+*/
+   if (owner_mc_dev == mc_bus_dev) {
+   /*
+* IRQ is for the mc_bus_dev's DPRC itself
+*/
+   error = dprc_set_irq(mc_bus_dev->mc_io,
+MC_CMD_FLAG_INTR_DIS | MC_CMD_FLAG_PRI,
+mc_bus_dev->mc_handle,
+mc_dev_irq->dev_irq_index,
+&irq_cfg);
+   if (error < 0) {
+   dev_err(&owner_mc_dev->dev,
+   "dprc_set_irq() failed: %d\n", error);
+   }
+   } else {
+   error = dprc_set_obj_irq(mc_bus_dev->mc_io,
+MC_CMD_FLAG_INTR_DIS | MC_CMD_FLAG_PRI,
+mc_bus_dev->mc_handle,
+owner_mc_dev->obj_desc.type,
+ 

[PATCH v2 11/11] staging: fsl-mc: Added MSI support to the MC bus driver

2015-10-30 Thread J. German Rivera
Initialize/Cleanup ITS-MSI support for the MC bus driver at driver
init/exit time. Associate an MSI domain with each DPAA2 child device.

Signed-off-by: J. German Rivera 
---
Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-bus.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index d34f1af..9317561 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -16,6 +16,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include "../include/dpmng.h"
 #include "../include/mc-sys.h"
 #include "dprc-cmd.h"
@@ -472,6 +474,8 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
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;
+   dev_set_msi_domain(&mc_dev->dev,
+  dev_get_msi_domain(&parent_mc_dev->dev));
}

/*
@@ -833,8 +837,15 @@ static int __init fsl_mc_bus_driver_init(void)
if (error < 0)
goto error_cleanup_dprc_driver;

+   error = its_fsl_mc_msi_init();
+   if (error < 0)
+   goto error_cleanup_mc_allocator;
+
return 0;

+error_cleanup_mc_allocator:
+   fsl_mc_allocator_driver_exit();
+
 error_cleanup_dprc_driver:
dprc_driver_exit();

@@ -856,6 +867,7 @@ static void __exit fsl_mc_bus_driver_exit(void)
if (WARN_ON(!mc_dev_cache))
return;

+   its_fsl_mc_msi_cleanup();
fsl_mc_allocator_driver_exit();
dprc_driver_exit();
platform_driver_unregister(&fsl_mc_bus_driver);
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 07/11] staging: fsl-mc: Populate the IRQ pool for an MC bus instance

2015-10-30 Thread J. German Rivera
Scan the corresponding DPRC container to get total count
of IRQs needed by all its child DPAA2 objects. Then,
preallocate a set of MSI IRQs with the DPRC's ICID
(GIT-ITS device Id) to populate the the DPRC's IRQ pool.
Each child DPAA2 object in the DPRC and the DPRC object itself
will allocate their necessary MSI IRQs from the DPRC's IRQ pool,
in their driver probe function.

Signed-off-by: J. German Rivera 
---
Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c| 24 ++--
 drivers/staging/fsl-mc/include/mc-private.h |  3 ++-
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 7bb30dd..3bcd161 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -241,6 +241,7 @@ static void dprc_cleanup_all_resource_pools(struct 
fsl_mc_device *mc_bus_dev)
  * dprc_scan_objects - Discover objects in a DPRC
  *
  * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
+ * @total_irq_count: total number of IRQs needed by objects in the DPRC.
  *
  * Detects objects added and removed from a DPRC and synchronizes the
  * state of the Linux bus driver, MC by adding and removing
@@ -254,11 +255,13 @@ static void dprc_cleanup_all_resource_pools(struct 
fsl_mc_device *mc_bus_dev)
  * populated before they can get allocation requests from probe callbacks
  * of the device drivers for the non-allocatable devices.
  */
-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+ unsigned int *total_irq_count)
 {
int num_child_objects;
int dprc_get_obj_failures;
int error;
+   unsigned int irq_count = mc_bus_dev->obj_desc.irq_count;
struct dprc_obj_desc *child_obj_desc_array = NULL;

error = dprc_get_obj_count(mc_bus_dev->mc_io,
@@ -307,6 +310,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
continue;
}

+   irq_count += obj_desc->irq_count;
dev_dbg(&mc_bus_dev->dev,
"Discovered object: type %s, id %d\n",
obj_desc->type, obj_desc->id);
@@ -319,6 +323,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
}
}

+   *total_irq_count = irq_count;
dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
num_child_objects);

@@ -344,6 +349,7 @@ EXPORT_SYMBOL_GPL(dprc_scan_objects);
 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 {
int error;
+   unsigned int irq_count;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);

dprc_init_all_resource_pools(mc_bus_dev);
@@ -352,11 +358,25 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 * Discover objects in the DPRC:
 */
mutex_lock(&mc_bus->scan_mutex);
-   error = dprc_scan_objects(mc_bus_dev);
+   error = dprc_scan_objects(mc_bus_dev, &irq_count);
mutex_unlock(&mc_bus->scan_mutex);
if (error < 0)
goto error;

+   if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) {
+   if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
+   dev_warn(&mc_bus_dev->dev,
+"IRQs needed (%u) exceed IRQs preallocated 
(%u)\n",
+irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   }
+
+   error = fsl_mc_populate_irq_pool(
+   mc_bus,
+   FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   if (error < 0)
+   goto error;
+   }
+
return 0;
 error:
dprc_cleanup_all_resource_pools(mc_bus_dev);
diff --git a/drivers/staging/fsl-mc/include/mc-private.h 
b/drivers/staging/fsl-mc/include/mc-private.h
index 97295f0..27834ea 100644
--- a/drivers/staging/fsl-mc/include/mc-private.h
+++ b/drivers/staging/fsl-mc/include/mc-private.h
@@ -114,7 +114,8 @@ void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);

 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev);

-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev);
+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+ unsigned int *total_irq_count);

 int __init dprc_driver_init(void);

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 10/11] staging: fsl-mc: Added DPRC interrupt handler

2015-10-30 Thread J. German Rivera
The interrupt handler for DPRC IRQs is added. DPRC IRQs are
generated for hot plug events related to DPAA2 objects in a given
DPRC. These events include, creating/destroying DPAA2 objects in
the DPRC, changing the "plugged" state of DPAA2 objects and moving
objects between DPRCs.

Signed-off-by: J. German Rivera 
---
Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 247 +++
 1 file changed, 247 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 7f1ceb5..0bd2e63 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "dprc-cmd.h"

 struct dprc_child_objs {
@@ -386,6 +387,230 @@ error:
 EXPORT_SYMBOL_GPL(dprc_scan_container);

 /**
+ * dprc_irq0_handler - Regular ISR for DPRC interrupt 0
+ *
+ * @irq: IRQ number of the interrupt being handled
+ * @arg: Pointer to device structure
+ */
+static irqreturn_t dprc_irq0_handler(int irq_num, void *arg)
+{
+   return IRQ_WAKE_THREAD;
+}
+
+/**
+ * dprc_irq0_handler_thread - Handler thread function for DPRC interrupt 0
+ *
+ * @irq: IRQ number of the interrupt being handled
+ * @arg: Pointer to device structure
+ */
+static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
+{
+   int error;
+   u32 status;
+   struct device *dev = (struct device *)arg;
+   struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+   struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   struct fsl_mc_io *mc_io = mc_dev->mc_io;
+   struct msi_desc *msi_desc = mc_dev->irqs[0]->msi_desc;
+
+   dev_dbg(dev, "DPRC IRQ %d triggered on CPU %u\n",
+   irq_num, smp_processor_id());
+
+   if (WARN_ON(!(mc_dev->flags & FSL_MC_IS_DPRC)))
+   return IRQ_HANDLED;
+
+   mutex_lock(&mc_bus->scan_mutex);
+   if (WARN_ON(!msi_desc || msi_desc->irq != (u32)irq_num))
+   goto out;
+
+   error = dprc_get_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
+   &status);
+   if (error < 0) {
+   dev_err(dev,
+   "dprc_get_irq_status() failed: %d\n", error);
+   goto out;
+   }
+
+   error = dprc_clear_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
+ status);
+   if (error < 0) {
+   dev_err(dev,
+   "dprc_clear_irq_status() failed: %d\n", error);
+   goto out;
+   }
+
+   if (status & (DPRC_IRQ_EVENT_OBJ_ADDED |
+ DPRC_IRQ_EVENT_OBJ_REMOVED |
+ DPRC_IRQ_EVENT_CONTAINER_DESTROYED |
+ DPRC_IRQ_EVENT_OBJ_DESTROYED |
+ DPRC_IRQ_EVENT_OBJ_CREATED)) {
+   unsigned int irq_count;
+
+   error = dprc_scan_objects(mc_dev, &irq_count);
+   if (error < 0) {
+   /*
+* If the error is -ENXIO, we ignore it, as it indicates
+* that the object scan was aborted, as we detected that
+* an object was removed from the DPRC in the MC, while
+* we were scanning the DPRC.
+*/
+   if (error != -ENXIO) {
+   dev_err(dev, "dprc_scan_objects() failed: %d\n",
+   error);
+   }
+
+   goto out;
+   }
+
+   if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
+   dev_warn(dev,
+"IRQs needed (%u) exceed IRQs preallocated 
(%u)\n",
+irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   }
+   }
+
+out:
+   mutex_unlock(&mc_bus->scan_mutex);
+   return IRQ_HANDLED;
+}
+
+/*
+ * Disable and clear interrupt for a given DPRC object
+ */
+static int disable_dprc_irq(struct fsl_mc_device *mc_dev)
+{
+   int error;
+   struct fsl_mc_io *mc_io = mc_dev->mc_io;
+
+   WARN_ON(mc_dev->obj_desc.irq_count != 1);
+
+   /*
+* Disable generation of interrupt, while we configure it:
+*/
+   error = dprc_set_irq_enable(mc_io, 0, mc_dev->mc_handle, 0, 0);
+   if (error < 0) {
+   dev_err(&mc_dev->dev,
+   "Disabling DPRC IRQ failed: dprc_set_irq_enable() 
failed: %d\n",
+   error);
+   return error;
+   }
+
+   /*
+* Disable all interrupt causes for the interrupt:
+*/
+   error = dprc_set_irq_mask(mc_io, 0, mc_dev->mc_handle, 0, 0x0);
+   if (error < 0) {
+   de

[PATCH v2 02/11] fsl-mc: msi: Added FSL-MC-specific member to the msi_desc's union

2015-10-30 Thread J. German Rivera
FSL-MC is a bus type different from PCI and platform, so it needs
its own member in the msi_desc's union.

Signed-off-by: J. German Rivera 
---
Changes in v2:
- Addressed comment from Jiang Liu
  * Added a dedicated structure for FSL-MC in struct msi_desc

 include/linux/msi.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/linux/msi.h b/include/linux/msi.h
index f71a25e..152e51a 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -33,6 +33,14 @@ struct platform_msi_desc {
 };

 /**
+ * fsl_mc_msi_desc - FSL-MC device specific msi descriptor data
+ * @msi_index: The index of the MSI descriptor
+ */
+struct fsl_mc_msi_desc {
+   u16 msi_index;
+};
+
+/**
  * struct msi_desc - Descriptor structure for MSI based interrupts
  * @list:  List head for management
  * @irq:   The base interrupt number
@@ -87,6 +95,7 @@ struct msi_desc {
 * tree wide cleanup.
 */
struct platform_msi_desc platform;
+   struct fsl_mc_msi_desc fsl_mc;
};
 };

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 05/11] staging: fsl-mc: Extended MC bus allocator to include IRQs

2015-10-30 Thread J. German Rivera
All the IRQs for DPAA2 objects in the same DPRC must use
the ICID of that DPRC, as their device Id in the GIC-ITS.
Thus, all these IRQs must share the same ITT table in the GIC.
As a result, a pool of IRQs with the same device Id must be
preallocated per DPRC (fsl-mc bus instance). So, the fsl-mc
bus object allocator is extended to also provide services
to allocate IRQs to DPAA2 devices, from their parent fsl-mc bus
IRQ pool.

Signed-off-by: J. German Rivera 
---
Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-allocator.c   | 199 
 drivers/staging/fsl-mc/include/mc-private.h |  15 +++
 drivers/staging/fsl-mc/include/mc.h |   9 ++
 3 files changed, 223 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c 
b/drivers/staging/fsl-mc/bus/mc-allocator.c
index 88d1857..c5fa628 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -15,6 +15,7 @@
 #include "../include/dpcon-cmd.h"
 #include "dpmcp-cmd.h"
 #include "dpmcp.h"
+#include 

 /**
  * fsl_mc_resource_pool_add_device - add allocatable device to a resource
@@ -160,6 +161,7 @@ static const char *const fsl_mc_pool_type_strings[] = {
[FSL_MC_POOL_DPMCP] = "dpmcp",
[FSL_MC_POOL_DPBP] = "dpbp",
[FSL_MC_POOL_DPCON] = "dpcon",
+   [FSL_MC_POOL_IRQ] = "irq",
 };

 static int __must_check object_type_to_pool_type(const char *object_type,
@@ -465,6 +467,203 @@ void fsl_mc_object_free(struct fsl_mc_device *mc_adev)
 }
 EXPORT_SYMBOL_GPL(fsl_mc_object_free);

+/*
+ * Initialize the interrupt pool associated with a MC bus.
+ * It allocates a block of IRQs from the GIC-ITS
+ */
+int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
+unsigned int irq_count)
+{
+   unsigned int i;
+   struct msi_desc *msi_desc;
+   struct fsl_mc_device_irq *irq_resources;
+   struct fsl_mc_device_irq *mc_dev_irq;
+   int error;
+   struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+   struct fsl_mc_resource_pool *res_pool =
+   &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
+
+   if (WARN_ON(irq_count == 0 ||
+   irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS))
+   return -EINVAL;
+
+   error = fsl_mc_msi_domain_alloc_irqs(&mc_bus_dev->dev, irq_count);
+   if (error < 0)
+   return error;
+
+   irq_resources = devm_kzalloc(&mc_bus_dev->dev,
+sizeof(*irq_resources) * irq_count,
+GFP_KERNEL);
+   if (!irq_resources) {
+   error = -ENOMEM;
+   goto cleanup_msi_irqs;
+   }
+
+   for (i = 0; i < irq_count; i++) {
+   mc_dev_irq = &irq_resources[i];
+
+   /*
+* NOTE: This mc_dev_irq's MSI addr/value pair will be set
+* by the fsl_mc_msi_write_msg() callback
+*/
+   mc_dev_irq->resource.type = res_pool->type;
+   mc_dev_irq->resource.data = mc_dev_irq;
+   mc_dev_irq->resource.parent_pool = res_pool;
+   INIT_LIST_HEAD(&mc_dev_irq->resource.node);
+   list_add_tail(&mc_dev_irq->resource.node, &res_pool->free_list);
+   }
+
+   for_each_msi_entry(msi_desc, &mc_bus_dev->dev) {
+   mc_dev_irq = &irq_resources[msi_desc->fsl_mc.msi_index];
+   mc_dev_irq->msi_desc = msi_desc;
+   mc_dev_irq->resource.id = msi_desc->irq;
+   }
+
+   res_pool->max_count = irq_count;
+   res_pool->free_count = irq_count;
+   mc_bus->irq_resources = irq_resources;
+   return 0;
+
+cleanup_msi_irqs:
+   fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
+   return error;
+}
+EXPORT_SYMBOL_GPL(fsl_mc_populate_irq_pool);
+
+/**
+ * Teardown the interrupt pool associated with an MC bus.
+ * It frees the IRQs that were allocated to the pool, back to the GIC-ITS.
+ */
+void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus)
+{
+   struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+   struct fsl_mc_resource_pool *res_pool =
+   &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
+
+   if (WARN_ON(!mc_bus->irq_resources))
+   return;
+
+   if (WARN_ON(res_pool->max_count == 0))
+   return;
+
+   if (WARN_ON(res_pool->free_count != res_pool->max_count))
+   return;
+
+   INIT_LIST_HEAD(&res_pool->free_list);
+   res_pool->max_count = 0;
+   res_pool->free_count = 0;
+   mc_bus->irq_resources = NULL;
+   fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
+}
+EXPORT_SYMBOL_GPL(fsl_mc_cleanup_irq_pool);
+
+/**
+ * It allocates the IRQs required by a giv

[PATCH v2 01/11] irqdomain: Added domain bus token DOMAIN_BUS_FSL_MC_MSI

2015-10-30 Thread J. German Rivera
Since an FSL-MC bus is a new bus type that is neither PCI nor
PLATFORM, we need a new domain bus token to disambiguate the
IRQ domain for FSL-MC MSIs.

Signed-off-by: J. German Rivera 
---
Changes in v2: none

 include/linux/irqdomain.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index d5e5c5b..c0cb5d1 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -73,6 +73,7 @@ enum irq_domain_bus_token {
DOMAIN_BUS_PCI_MSI,
DOMAIN_BUS_PLATFORM_MSI,
DOMAIN_BUS_NEXUS,
+   DOMAIN_BUS_FSL_MC_MSI,
 };

 /**
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 09/11] staging: fsl-mc: Fixed bug in dprc_probe() error path

2015-10-30 Thread J. German Rivera
Destroy mc_io in error path in dprc_probe() only if the mc_io was
created in this function.

Signed-off-by: J. German Rivera 
---
Changes in v2:
- Addressed comment from Dan Carpenter
  * Renamed goto error labels to indicate what the goto does

 drivers/staging/fsl-mc/bus/dprc-driver.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 455379d..7f1ceb5 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -401,6 +401,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
size_t region_size;
struct device *parent_dev = mc_dev->dev.parent;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   bool mc_io_created = false;
bool msi_domain_set = false;

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
@@ -413,6 +414,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
/*
 * This is a child DPRC:
 */
+   if (WARN_ON(parent_dev->bus != &fsl_mc_bus_type))
+   return -EINVAL;
+
if (WARN_ON(mc_dev->obj_desc.region_count == 0))
return -EINVAL;

@@ -427,6 +431,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 &mc_dev->mc_io);
if (error < 0)
return error;
+
+   mc_io_created = true;
+
/*
 * Inherit parent MSI domain:
 */
@@ -457,7 +464,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
  &mc_dev->mc_handle);
if (error < 0) {
dev_err(&mc_dev->dev, "dprc_open() failed: %d\n", error);
-   goto error_cleanup_mc_io;
+   goto error_cleanup_msi_domain;
}

mutex_init(&mc_bus->scan_mutex);
@@ -475,11 +482,15 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 error_cleanup_open:
(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);

-error_cleanup_mc_io:
+error_cleanup_msi_domain:
if (msi_domain_set)
dev_set_msi_domain(&mc_dev->dev, NULL);

-   fsl_destroy_mc_io(mc_dev->mc_io);
+   if (mc_io_created) {
+   fsl_destroy_mc_io(mc_dev->mc_io);
+   mc_dev->mc_io = NULL;
+   }
+
return error;
 }

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 08/11] staging: fsl-mc: set MSI domain for DPRC objects

2015-10-30 Thread J. German Rivera
THE MSI domain associated with a root DPRC object is
obtained form the device tree. Child DPRCs inherit
the parent DPRC MSI domain.

Signed-off-by: J. German Rivera 
---
Changes in v2: none

 drivers/staging/fsl-mc/bus/dprc-driver.c | 39 
 1 file changed, 39 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 3bcd161..455379d 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -13,6 +13,7 @@
 #include "../include/mc-sys.h"
 #include 
 #include 
+#include 
 #include "dprc-cmd.h"

 struct dprc_child_objs {
@@ -398,11 +399,16 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 {
int error;
size_t region_size;
+   struct device *parent_dev = mc_dev->dev.parent;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   bool msi_domain_set = false;

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
return -EINVAL;

+   if (WARN_ON(dev_get_msi_domain(&mc_dev->dev)))
+   return -EINVAL;
+
if (!mc_dev->mc_io) {
/*
 * This is a child DPRC:
@@ -421,6 +427,30 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 &mc_dev->mc_io);
if (error < 0)
return error;
+   /*
+* Inherit parent MSI domain:
+*/
+   dev_set_msi_domain(&mc_dev->dev,
+  dev_get_msi_domain(parent_dev));
+   msi_domain_set = true;
+   } else {
+   /*
+* This is a root DPRC
+*/
+   struct irq_domain *mc_msi_domain;
+
+   if (WARN_ON(parent_dev->bus == &fsl_mc_bus_type))
+   return -EINVAL;
+
+   error = fsl_mc_find_msi_domain(parent_dev->of_node,
+  &mc_msi_domain);
+   if (error < 0) {
+   dev_warn(&mc_dev->dev,
+"WARNING: MC bus without interrupt support\n");
+   } else {
+   dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
+   msi_domain_set = true;
+   }
}

error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
@@ -446,6 +476,9 @@ error_cleanup_open:
(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);

 error_cleanup_mc_io:
+   if (msi_domain_set)
+   dev_set_msi_domain(&mc_dev->dev, NULL);
+
fsl_destroy_mc_io(mc_dev->mc_io);
return error;
 }
@@ -463,6 +496,7 @@ error_cleanup_mc_io:
 static int dprc_remove(struct fsl_mc_device *mc_dev)
 {
int error;
+   struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);

if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
return -EINVAL;
@@ -475,6 +509,11 @@ static int dprc_remove(struct fsl_mc_device *mc_dev)
if (error < 0)
dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);

+   if (dev_get_msi_domain(&mc_dev->dev)) {
+   fsl_mc_cleanup_irq_pool(mc_bus);
+   dev_set_msi_domain(&mc_dev->dev, NULL);
+   }
+
dev_info(&mc_dev->dev, "DPRC device unbound from driver");
return 0;
 }
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 00/11] staging: fsl-mc: MC bus MSI support

2015-10-30 Thread J. German Rivera
This patch series addresses the following item from the TODO list
for the MC bus driver to exit staging:

* Interrupt support. For meaningful driver support we need
  interrupts, and thus need message interrupt support by the bus
  driver.

MC Bus MSI Support Architecture
===
A new IRQ domain bus token is added for the FSL-MC bus.
An MSI IRQ domain is created for each top-level (root) data-path
resource container (DPRC), based on its msi-parent in the device
tree (which is the GIC-ITS). Child DPRCs inherit the MSI IRQ
domain form their parent DPRC.

MC Bus MSI Allocation
-
Given the way in which the GIC-ITS works, we need to pre-allocate
a block of MSIs in the GIC-ITS for the IRQs of all the DPAA2 objects
in the same data-path resource container (DPRC) and for the IRQ of
the DPRC iself.

This is due to the fact that all the IRQs for DPAA2 objects in the
same DPRC (and the DPRC's own IRQ) must use the same "device Id" in
the GIC-ITS. Thus, all these IRQs must share the same ITT table in
the GIC-ITS, and therefore must be allocated in the GIC-ITS as
a block of MSIs for the same "device Id".

This is because all the DPAA2 objects in the same DPRC (and the
DPRC itself) use the DPRC's SMMU stream ID as their device Id for
the GIC-ITS.
The DPAA2 Management Complex (MC) firmware does not assign a separate
SMMU stream ID to each DPAA2 object. The MC only assigns SMMU stream
IDs to DPRCs. In MC terms, the stream ID assigned to a DPRC is known
as the DPRC's Isolation Context ID (ICID).

As a consequence of having to pre-allocate a block of MSIs in
the GIC-ITS, the object allocator of the MC bus driver needs to be
extended to provide IRQ allocation services to DPAA2 device drivers
and to the DPRC driver. For a given DPAA2 object, MSIs are allocated
from the corresponding DPRC's pool of pre-allocated MSIs. The MSI
for the DPRC itself is also allocated from this pool.

The following are the patches in this series:

Patch 1: Added domain bus token DOMAIN_BUS_FSL_MC_MSI
Patch 2: Added generic MSI support for FSL-MC devices
Patch 3: Added GICv3-ITS support for FSL-MC MSIs
Patch 4: Extended MC bus allocator to include IRQs
Patch 5: Changed DPRC built-in portal's mc_io to be atomic
Patch 6: Populate the IRQ pool for an MC bus instance
Patch 7: Set MSI domain for DPRC objects
Patch 8: Fixed bug in dprc_probe() error path
Patch 9: Added DPRC interrupt handler
Patch 10: Added MSI support to the MC bus driver

CHANGE HISTORY

Changes in v2:
- Addressed comment from Jiang Liu
  * Added a dedicated structure for FSL-MC in struct msi_desc
- Addressed comment from Dan Carpenter
  * Renamed goto error labels to indicate what the goto does

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3] arm64: dts: Added syscon-reboot node for FSL's LS2085A SoC

2015-10-30 Thread J. German Rivera
Added sys-reboot node to the FSL's LS2085A SoC DT to leverage
the ARM-generic reboot mechanism for this SoC. This mechanism
is enabled through CONFIG_POWER_RESET_SYSCON.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY:

Changes in v2:
- Addressed comment form Stuart Yoder:
  * Removed "@" from reboot node

Changes in v3:
- Addressed comment form Stuart Yoder:
  * Expose only the reset register

 arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
index e281ceb..5e3d894 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
@@ -131,6 +131,18 @@
interrupts = <1 9 0x4>;
};

+   rstcr: rstcr@1E6 {
+   compatible = "syscon";
+   reg = <0x0 0x1E6 0x0 0x4>;
+   };
+
+   reboot {
+   compatible ="syscon-reboot";
+   regmap = <&rstcr>;
+   offset = <0x0>;
+   mask = <0x2>;
+   };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] arm64: dts: Added syscon-reboot node for FSL's LS2085A SoC

2015-10-28 Thread J. German Rivera
Added sys-reboot node to the FSL's LS2085A SoC DT to leverage
the ARM-generic reboot mechanism for this SoC. This mechanism
is enabled through CONFIG_POWER_RESET_SYSCON.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v2:
- Address comment form Stuart Yoder:
  * Removed "@" from reboot node

 arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
index e281ceb..8fb3646 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
@@ -131,6 +131,18 @@
interrupts = <1 9 0x4>;
};

+   rst_ccsr: rstccsr@1E6 {
+   compatible = "syscon";
+   reg = <0x0 0x1E6 0x0 0x1>;
+   };
+
+   reboot {
+   compatible ="syscon-reboot";
+   regmap = <&rst_ccsr>;
+   offset = <0x0>;
+   mask = <0x2>;
+   };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 04/10] staging: fsl-mc: Extended MC bus allocator to include IRQs

2015-10-26 Thread J. German Rivera
All the IRQs for DPAA2 objects in the same DPRC must use
the ICID of that DPRC, as their device Id in the GIC-ITS.
Thus, all these IRQs must share the same ITT table in the GIC.
As a result, a pool of IRQs with the same device Id must be
preallocated per DPRC (fsl-mc bus instance). So, the fsl-mc
bus object allocator is extended to also provide services
to allocate IRQs to DPAA2 devices, from their parent fsl-mc bus
IRQ pool.

Signed-off-by: J. German Rivera 
---
 drivers/staging/fsl-mc/bus/mc-allocator.c   | 199 
 drivers/staging/fsl-mc/include/mc-private.h |  15 +++
 drivers/staging/fsl-mc/include/mc.h |   9 ++
 3 files changed, 223 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c 
b/drivers/staging/fsl-mc/bus/mc-allocator.c
index 88d1857..6f1049a 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -15,6 +15,7 @@
 #include "../include/dpcon-cmd.h"
 #include "dpmcp-cmd.h"
 #include "dpmcp.h"
+#include 
 
 /**
  * fsl_mc_resource_pool_add_device - add allocatable device to a resource
@@ -160,6 +161,7 @@ static const char *const fsl_mc_pool_type_strings[] = {
[FSL_MC_POOL_DPMCP] = "dpmcp",
[FSL_MC_POOL_DPBP] = "dpbp",
[FSL_MC_POOL_DPCON] = "dpcon",
+   [FSL_MC_POOL_IRQ] = "irq",
 };
 
 static int __must_check object_type_to_pool_type(const char *object_type,
@@ -465,6 +467,203 @@ void fsl_mc_object_free(struct fsl_mc_device *mc_adev)
 }
 EXPORT_SYMBOL_GPL(fsl_mc_object_free);
 
+/*
+ * Initialize the interrupt pool associated with a MC bus.
+ * It allocates a block of IRQs from the GIC-ITS
+ */
+int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
+unsigned int irq_count)
+{
+   unsigned int i;
+   struct msi_desc *msi_desc;
+   struct fsl_mc_device_irq *irq_resources;
+   struct fsl_mc_device_irq *mc_dev_irq;
+   int error;
+   struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+   struct fsl_mc_resource_pool *res_pool =
+   &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
+
+   if (WARN_ON(irq_count == 0 ||
+   irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS))
+   return -EINVAL;
+
+   error = fsl_mc_msi_domain_alloc_irqs(&mc_bus_dev->dev, irq_count);
+   if (error < 0)
+   return error;
+
+   irq_resources = devm_kzalloc(&mc_bus_dev->dev,
+sizeof(*irq_resources) * irq_count,
+GFP_KERNEL);
+   if (!irq_resources) {
+   error = -ENOMEM;
+   goto cleanup_msi_irqs;
+   }
+
+   for (i = 0; i < irq_count; i++) {
+   mc_dev_irq = &irq_resources[i];
+
+   /*
+* NOTE: This mc_dev_irq's MSI addr/value pair will be set
+* by the fsl_mc_msi_write_msg() callback
+*/
+   mc_dev_irq->resource.type = res_pool->type;
+   mc_dev_irq->resource.data = mc_dev_irq;
+   mc_dev_irq->resource.parent_pool = res_pool;
+   INIT_LIST_HEAD(&mc_dev_irq->resource.node);
+   list_add_tail(&mc_dev_irq->resource.node, &res_pool->free_list);
+   }
+
+   for_each_msi_entry(msi_desc, &mc_bus_dev->dev) {
+   mc_dev_irq = &irq_resources[msi_desc->msi_attrib.entry_nr];
+   mc_dev_irq->msi_desc = msi_desc;
+   mc_dev_irq->resource.id = msi_desc->irq;
+   }
+
+   res_pool->max_count = irq_count;
+   res_pool->free_count = irq_count;
+   mc_bus->irq_resources = irq_resources;
+   return 0;
+
+cleanup_msi_irqs:
+   fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
+   return error;
+}
+EXPORT_SYMBOL_GPL(fsl_mc_populate_irq_pool);
+
+/**
+ * Teardown the interrupt pool associated with an MC bus.
+ * It frees the IRQs that were allocated to the pool, back to the GIC-ITS.
+ */
+void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus)
+{
+   struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+   struct fsl_mc_resource_pool *res_pool =
+   &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
+
+   if (WARN_ON(!mc_bus->irq_resources))
+   return;
+
+   if (WARN_ON(res_pool->max_count == 0))
+   return;
+
+   if (WARN_ON(res_pool->free_count != res_pool->max_count))
+   return;
+
+   INIT_LIST_HEAD(&res_pool->free_list);
+   res_pool->max_count = 0;
+   res_pool->free_count = 0;
+   mc_bus->irq_resources = NULL;
+   fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
+}
+EXPORT_SYMBOL_GPL(fsl_mc_cleanup_irq_pool);
+
+/**
+ * It allocates the IRQs required by a given MC object dev

[PATCH 05/10] staging: fsl-mc: Changed DPRC built-in portal's mc_io to be atomic

2015-10-26 Thread J. German Rivera
The DPRC built-in portal's mc_io is used to send commands to the MC
to program MSIs for MC objects. This is done by the
fsl_mc_msi_write_msg() callback, which is invoked by the generic MSI
layer with interrupts disabled. As a result, the mc_io used in
fsl_mc_msi_write_msg needs to be an atomic mc_io.

Signed-off-by: J. German Rivera 
---
 drivers/staging/fsl-mc/bus/dprc-driver.c | 4 +++-
 drivers/staging/fsl-mc/bus/mc-bus.c  | 3 ++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index a9ead0d..7bb30dd 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -396,7 +396,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
error = fsl_create_mc_io(&mc_dev->dev,
 mc_dev->regions[0].start,
 region_size,
-NULL, 0, &mc_dev->mc_io);
+NULL,
+FSL_MC_IO_ATOMIC_CONTEXT_PORTAL,
+&mc_dev->mc_io);
if (error < 0)
return error;
}
diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index 84db55b..d34f1af 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -702,7 +702,8 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
mc_portal_phys_addr = res.start;
mc_portal_size = resource_size(&res);
error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
-mc_portal_size, NULL, 0, &mc_io);
+mc_portal_size, NULL,
+FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
if (error < 0)
return error;
 
-- 
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 01/10] irqdomain: Added domain bus token DOMAIN_BUS_FSL_MC_MSI

2015-10-26 Thread J. German Rivera
Since an FSL-MC bus is a new bus type that is neither PCI nor
PLATFORM, we need a new domain bus token to disambiguate the
IRQ domain for FSL-MC MSIs.

Signed-off-by: J. German Rivera 
---
 include/linux/irqdomain.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index d5e5c5b..c0cb5d1 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -73,6 +73,7 @@ enum irq_domain_bus_token {
DOMAIN_BUS_PCI_MSI,
DOMAIN_BUS_PLATFORM_MSI,
DOMAIN_BUS_NEXUS,
+   DOMAIN_BUS_FSL_MC_MSI,
 };
 
 /**
-- 
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 09/10] staging: fsl-mc: Added DPRC interrupt handler

2015-10-26 Thread J. German Rivera
The interrupt handler for DPRC IRQs is added. DPRC IRQs are
generated for hot plug events related to DPAA2 objects in a given
DPRC. These events include, creating/destroying DPAA2 objects in
the DPRC, changing the "plugged" state of DPAA2 objects and moving
objects between DPRCs.

Signed-off-by: J. German Rivera 
---
 drivers/staging/fsl-mc/bus/dprc-driver.c | 247 +++
 1 file changed, 247 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 3eeafaa..38ec2b2 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "dprc-cmd.h"
 
 struct dprc_child_objs {
@@ -386,6 +387,230 @@ error:
 EXPORT_SYMBOL_GPL(dprc_scan_container);
 
 /**
+ * dprc_irq0_handler - Regular ISR for DPRC interrupt 0
+ *
+ * @irq: IRQ number of the interrupt being handled
+ * @arg: Pointer to device structure
+ */
+static irqreturn_t dprc_irq0_handler(int irq_num, void *arg)
+{
+   return IRQ_WAKE_THREAD;
+}
+
+/**
+ * dprc_irq0_handler_thread - Handler thread function for DPRC interrupt 0
+ *
+ * @irq: IRQ number of the interrupt being handled
+ * @arg: Pointer to device structure
+ */
+static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
+{
+   int error;
+   u32 status;
+   struct device *dev = (struct device *)arg;
+   struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+   struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   struct fsl_mc_io *mc_io = mc_dev->mc_io;
+   struct msi_desc *msi_desc = mc_dev->irqs[0]->msi_desc;
+
+   dev_dbg(dev, "DPRC IRQ %d triggered on CPU %u\n",
+   irq_num, smp_processor_id());
+
+   if (WARN_ON(!(mc_dev->flags & FSL_MC_IS_DPRC)))
+   return IRQ_HANDLED;
+
+   mutex_lock(&mc_bus->scan_mutex);
+   if (WARN_ON(!msi_desc || msi_desc->irq != (u32)irq_num))
+   goto out;
+
+   error = dprc_get_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
+   &status);
+   if (error < 0) {
+   dev_err(dev,
+   "dprc_get_irq_status() failed: %d\n", error);
+   goto out;
+   }
+
+   error = dprc_clear_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
+ status);
+   if (error < 0) {
+   dev_err(dev,
+   "dprc_clear_irq_status() failed: %d\n", error);
+   goto out;
+   }
+
+   if (status & (DPRC_IRQ_EVENT_OBJ_ADDED |
+ DPRC_IRQ_EVENT_OBJ_REMOVED |
+ DPRC_IRQ_EVENT_CONTAINER_DESTROYED |
+ DPRC_IRQ_EVENT_OBJ_DESTROYED |
+ DPRC_IRQ_EVENT_OBJ_CREATED)) {
+   unsigned int irq_count;
+
+   error = dprc_scan_objects(mc_dev, &irq_count);
+   if (error < 0) {
+   /*
+* If the error is -ENXIO, we ignore it, as it indicates
+* that the object scan was aborted, as we detected that
+* an object was removed from the DPRC in the MC, while
+* we were scanning the DPRC.
+*/
+   if (error != -ENXIO) {
+   dev_err(dev, "dprc_scan_objects() failed: %d\n",
+   error);
+   }
+
+   goto out;
+   }
+
+   if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
+   dev_warn(dev,
+"IRQs needed (%u) exceed IRQs preallocated 
(%u)\n",
+irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   }
+   }
+
+out:
+   mutex_unlock(&mc_bus->scan_mutex);
+   return IRQ_HANDLED;
+}
+
+/*
+ * Disable and clear interrupt for a given DPRC object
+ */
+static int disable_dprc_irq(struct fsl_mc_device *mc_dev)
+{
+   int error;
+   struct fsl_mc_io *mc_io = mc_dev->mc_io;
+
+   WARN_ON(mc_dev->obj_desc.irq_count != 1);
+
+   /*
+* Disable generation of interrupt, while we configure it:
+*/
+   error = dprc_set_irq_enable(mc_io, 0, mc_dev->mc_handle, 0, 0);
+   if (error < 0) {
+   dev_err(&mc_dev->dev,
+   "Disabling DPRC IRQ failed: dprc_set_irq_enable() 
failed: %d\n",
+   error);
+   return error;
+   }
+
+   /*
+* Disable all interrupt causes for the interrupt:
+*/
+   error = dprc_set_irq_mask(mc_io, 0, mc_dev->mc_handle, 0, 0x0);
+   if (error < 0) {
+   de

[PATCH 08/10] staging: fsl-mc: Fixed bug in dprc_probe() error path

2015-10-26 Thread J. German Rivera
Destroy mc_io in error path in dprc_probe() only if the mc_io was
created in this function. Minor refactoring in error labels.

Signed-off-by: J. German Rivera 
---
 drivers/staging/fsl-mc/bus/dprc-driver.c | 21 -
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 455379d..3eeafaa 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -401,6 +401,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
size_t region_size;
struct device *parent_dev = mc_dev->dev.parent;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   bool mc_io_created = false;
bool msi_domain_set = false;
 
if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
@@ -413,6 +414,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
/*
 * This is a child DPRC:
 */
+   if (WARN_ON(parent_dev->bus != &fsl_mc_bus_type))
+   return -EINVAL;
+
if (WARN_ON(mc_dev->obj_desc.region_count == 0))
return -EINVAL;
 
@@ -427,6 +431,9 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 &mc_dev->mc_io);
if (error < 0)
return error;
+
+   mc_io_created = true;
+
/*
 * Inherit parent MSI domain:
 */
@@ -457,7 +464,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
  &mc_dev->mc_handle);
if (error < 0) {
dev_err(&mc_dev->dev, "dprc_open() failed: %d\n", error);
-   goto error_cleanup_mc_io;
+   goto dprc_open_error;
}
 
mutex_init(&mc_bus->scan_mutex);
@@ -467,19 +474,23 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 */
error = dprc_scan_container(mc_dev);
if (error < 0)
-   goto error_cleanup_open;
+   goto dprc_scan_container_error;
+
 
dev_info(&mc_dev->dev, "DPRC device bound to driver");
return 0;
 
-error_cleanup_open:
+dprc_scan_container_error:
(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
+dprc_open_error:
+   if (mc_io_created) {
+   fsl_destroy_mc_io(mc_dev->mc_io);
+   mc_dev->mc_io = NULL;
+   }
 
-error_cleanup_mc_io:
if (msi_domain_set)
dev_set_msi_domain(&mc_dev->dev, NULL);
 
-   fsl_destroy_mc_io(mc_dev->mc_io);
return error;
 }
 
-- 
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 06/10] staging: fsl-mc: Populate the IRQ pool for an MC bus instance

2015-10-26 Thread J. German Rivera
Scan the corresponding DPRC container to get total count
of IRQs needed by all its child DPAA2 objects. Then,
preallocate a set of MSI IRQs with the DPRC's ICID
(GIT-ITS device Id) to populate the the DPRC's IRQ pool.
Each child DPAA2 object in the DPRC and the DPRC object itself
will allocate their necessary MSI IRQs from the DPRC's IRQ pool,
in their driver probe function.

Signed-off-by: J. German Rivera 
---
 drivers/staging/fsl-mc/bus/dprc-driver.c| 24 ++--
 drivers/staging/fsl-mc/include/mc-private.h |  3 ++-
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 7bb30dd..3bcd161 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -241,6 +241,7 @@ static void dprc_cleanup_all_resource_pools(struct 
fsl_mc_device *mc_bus_dev)
  * dprc_scan_objects - Discover objects in a DPRC
  *
  * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
+ * @total_irq_count: total number of IRQs needed by objects in the DPRC.
  *
  * Detects objects added and removed from a DPRC and synchronizes the
  * state of the Linux bus driver, MC by adding and removing
@@ -254,11 +255,13 @@ static void dprc_cleanup_all_resource_pools(struct 
fsl_mc_device *mc_bus_dev)
  * populated before they can get allocation requests from probe callbacks
  * of the device drivers for the non-allocatable devices.
  */
-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+ unsigned int *total_irq_count)
 {
int num_child_objects;
int dprc_get_obj_failures;
int error;
+   unsigned int irq_count = mc_bus_dev->obj_desc.irq_count;
struct dprc_obj_desc *child_obj_desc_array = NULL;
 
error = dprc_get_obj_count(mc_bus_dev->mc_io,
@@ -307,6 +310,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
continue;
}
 
+   irq_count += obj_desc->irq_count;
dev_dbg(&mc_bus_dev->dev,
"Discovered object: type %s, id %d\n",
obj_desc->type, obj_desc->id);
@@ -319,6 +323,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
}
}
 
+   *total_irq_count = irq_count;
dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
num_child_objects);
 
@@ -344,6 +349,7 @@ EXPORT_SYMBOL_GPL(dprc_scan_objects);
 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 {
int error;
+   unsigned int irq_count;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
 
dprc_init_all_resource_pools(mc_bus_dev);
@@ -352,11 +358,25 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
 * Discover objects in the DPRC:
 */
mutex_lock(&mc_bus->scan_mutex);
-   error = dprc_scan_objects(mc_bus_dev);
+   error = dprc_scan_objects(mc_bus_dev, &irq_count);
mutex_unlock(&mc_bus->scan_mutex);
if (error < 0)
goto error;
 
+   if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) {
+   if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
+   dev_warn(&mc_bus_dev->dev,
+"IRQs needed (%u) exceed IRQs preallocated 
(%u)\n",
+irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   }
+
+   error = fsl_mc_populate_irq_pool(
+   mc_bus,
+   FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
+   if (error < 0)
+   goto error;
+   }
+
return 0;
 error:
dprc_cleanup_all_resource_pools(mc_bus_dev);
diff --git a/drivers/staging/fsl-mc/include/mc-private.h 
b/drivers/staging/fsl-mc/include/mc-private.h
index 97295f0..27834ea 100644
--- a/drivers/staging/fsl-mc/include/mc-private.h
+++ b/drivers/staging/fsl-mc/include/mc-private.h
@@ -114,7 +114,8 @@ void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);
 
 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev);
 
-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev);
+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+ unsigned int *total_irq_count);
 
 int __init dprc_driver_init(void);
 
-- 
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 07/10] staging: fsl-mc: set MSI domain for DPRC objects

2015-10-26 Thread J. German Rivera
THE MSI domain associated with a root DPRC object is
obtained form the device tree. Child DPRCs inherit
the parent DPRC MSI domain.

Signed-off-by: J. German Rivera 
---
 drivers/staging/fsl-mc/bus/dprc-driver.c | 39 
 1 file changed, 39 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c 
b/drivers/staging/fsl-mc/bus/dprc-driver.c
index 3bcd161..455379d 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -13,6 +13,7 @@
 #include "../include/mc-sys.h"
 #include 
 #include 
+#include 
 #include "dprc-cmd.h"
 
 struct dprc_child_objs {
@@ -398,11 +399,16 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 {
int error;
size_t region_size;
+   struct device *parent_dev = mc_dev->dev.parent;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+   bool msi_domain_set = false;
 
if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
return -EINVAL;
 
+   if (WARN_ON(dev_get_msi_domain(&mc_dev->dev)))
+   return -EINVAL;
+
if (!mc_dev->mc_io) {
/*
 * This is a child DPRC:
@@ -421,6 +427,30 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 &mc_dev->mc_io);
if (error < 0)
return error;
+   /*
+* Inherit parent MSI domain:
+*/
+   dev_set_msi_domain(&mc_dev->dev,
+  dev_get_msi_domain(parent_dev));
+   msi_domain_set = true;
+   } else {
+   /*
+* This is a root DPRC
+*/
+   struct irq_domain *mc_msi_domain;
+
+   if (WARN_ON(parent_dev->bus == &fsl_mc_bus_type))
+   return -EINVAL;
+
+   error = fsl_mc_find_msi_domain(parent_dev->of_node,
+  &mc_msi_domain);
+   if (error < 0) {
+   dev_warn(&mc_dev->dev,
+"WARNING: MC bus without interrupt support\n");
+   } else {
+   dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
+   msi_domain_set = true;
+   }
}
 
error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
@@ -446,6 +476,9 @@ error_cleanup_open:
(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
 
 error_cleanup_mc_io:
+   if (msi_domain_set)
+   dev_set_msi_domain(&mc_dev->dev, NULL);
+
fsl_destroy_mc_io(mc_dev->mc_io);
return error;
 }
@@ -463,6 +496,7 @@ error_cleanup_mc_io:
 static int dprc_remove(struct fsl_mc_device *mc_dev)
 {
int error;
+   struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
 
if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
return -EINVAL;
@@ -475,6 +509,11 @@ static int dprc_remove(struct fsl_mc_device *mc_dev)
if (error < 0)
dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);
 
+   if (dev_get_msi_domain(&mc_dev->dev)) {
+   fsl_mc_cleanup_irq_pool(mc_bus);
+   dev_set_msi_domain(&mc_dev->dev, NULL);
+   }
+
dev_info(&mc_dev->dev, "DPRC device unbound from driver");
return 0;
 }
-- 
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 10/10] staging: fsl-mc: Added MSI support to the MC bus driver

2015-10-26 Thread J. German Rivera
Initialize/Cleanup ITS-MSI support for the MC bus driver at driver
init/exit time. Associate an MSI domain with each DPAA2 child device.

Signed-off-by: J. German Rivera 
---
 drivers/staging/fsl-mc/bus/mc-bus.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index d34f1af..9317561 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -16,6 +16,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include "../include/dpmng.h"
 #include "../include/mc-sys.h"
 #include "dprc-cmd.h"
@@ -472,6 +474,8 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
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;
+   dev_set_msi_domain(&mc_dev->dev,
+  dev_get_msi_domain(&parent_mc_dev->dev));
}
 
/*
@@ -833,8 +837,15 @@ static int __init fsl_mc_bus_driver_init(void)
if (error < 0)
goto error_cleanup_dprc_driver;
 
+   error = its_fsl_mc_msi_init();
+   if (error < 0)
+   goto error_cleanup_mc_allocator;
+
return 0;
 
+error_cleanup_mc_allocator:
+   fsl_mc_allocator_driver_exit();
+
 error_cleanup_dprc_driver:
dprc_driver_exit();
 
@@ -856,6 +867,7 @@ static void __exit fsl_mc_bus_driver_exit(void)
if (WARN_ON(!mc_dev_cache))
return;
 
+   its_fsl_mc_msi_cleanup();
fsl_mc_allocator_driver_exit();
dprc_driver_exit();
platform_driver_unregister(&fsl_mc_bus_driver);
-- 
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 00/10] staging: fsl-mc: MC bus MSI support

2015-10-26 Thread J. German Rivera
This patch series addresses the following item from the TODO list
for the MC bus driver to exit staging:

* Interrupt support. For meaningful driver support we need
  interrupts, and thus need message interrupt support by the bus
  driver.

MC Bus MSI Support Architecture
===
A new IRQ domain bus token is added for the FSL-MC bus.
An MSI IRQ domain is created for each top-level (root) data-path
resource container (DPRC), based on its msi-parent in the device
tree (which is the GIC-ITS). Child DPRCs inherit the MSI IRQ
domain form their parent DPRC.

MC Bus MSI Allocation
-
Given the way in which the GIC-ITS works, we need to pre-allocate
a block of MSIs in the GIC-ITS for the IRQs of all the DPAA2 objects
in the same data-path resource container (DPRC) and for the IRQ of
the DPRC iself.

This is due to the fact that all the IRQs for DPAA2 objects in the
same DPRC (and the DPRC's own IRQ) must use the same "device Id" in
the GIC-ITS. Thus, all these IRQs must share the same ITT table in
the GIC-ITS, and therefore must be allocated in the GIC-ITS as
a block of MSIs for the same "device Id".

This is because all the DPAA2 objects in the same DPRC (and the
DPRC itself) use the DPRC's SMMU stream ID as their device Id for
the GIC-ITS.
The DPAA2 Management Complex (MC) firmware does not assign a separate
SMMU stream ID to each DPAA2 object. The MC only assigns SMMU stream
IDs to DPRCs. In MC terms, the stream ID assigned to a DPRC is known
as the DPRC's Isolation Context ID (ICID).

As a consequence of having to pre-allocate a block of MSIs in
the GIC-ITS, the object allocator of the MC bus driver needs to be
extended to provide IRQ allocation services to DPAA2 device drivers
and to the DPRC driver. For a given DPAA2 object, MSIs are allocated
from the corresponding DPRC's pool of pre-allocated MSIs. The MSI
for the DPRC itself is also allocated from this pool.

The following are the patches in this series:

Patch 1: Added domain bus token DOMAIN_BUS_FSL_MC_MSI
Patch 2: Added generic MSI support for FSL-MC devices
Patch 3: Added GICv3-ITS support for FSL-MC MSIs
Patch 4: Extended MC bus allocator to include IRQs
Patch 5: Changed DPRC built-in portal's mc_io to be atomic
Patch 6: Populate the IRQ pool for an MC bus instance
Patch 7: Set MSI domain for DPRC objects
Patch 8: Fixed bug in dprc_probe() error path
Patch 9: Added DPRC interrupt handler
Patch 10: Added MSI support to the MC bus driver

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 02/10] staging: fsl-mc: Added generic MSI support for FSL-MC devices

2015-10-26 Thread J. German Rivera
Created an MSI domain for the fsl-mc bus-- including functions
to create a domain, find a domain, alloc/free domain irqs, and
bus specific overrides for domain and irq_chip ops.

Signed-off-by: J. German Rivera 
---
 drivers/staging/fsl-mc/bus/Kconfig  |   1 +
 drivers/staging/fsl-mc/bus/Makefile |   1 +
 drivers/staging/fsl-mc/bus/mc-msi.c | 278 
 drivers/staging/fsl-mc/include/mc-private.h |  17 ++
 drivers/staging/fsl-mc/include/mc.h |  17 ++
 5 files changed, 314 insertions(+)
 create mode 100644 drivers/staging/fsl-mc/bus/mc-msi.c

diff --git a/drivers/staging/fsl-mc/bus/Kconfig 
b/drivers/staging/fsl-mc/bus/Kconfig
index 0d779d9..c498ac6 100644
--- a/drivers/staging/fsl-mc/bus/Kconfig
+++ b/drivers/staging/fsl-mc/bus/Kconfig
@@ -9,6 +9,7 @@
 config FSL_MC_BUS
tristate "Freescale Management Complex (MC) bus driver"
depends on OF && ARM64
+   select GENERIC_MSI_IRQ_DOMAIN
help
  Driver to enable the bus infrastructure for the Freescale
   QorIQ Management Complex (fsl-mc). The fsl-mc is a hardware
diff --git a/drivers/staging/fsl-mc/bus/Makefile 
b/drivers/staging/fsl-mc/bus/Makefile
index 25433a9..a5f2ba4 100644
--- a/drivers/staging/fsl-mc/bus/Makefile
+++ b/drivers/staging/fsl-mc/bus/Makefile
@@ -13,5 +13,6 @@ mc-bus-driver-objs := mc-bus.o \
  dpmng.o \
  dprc-driver.o \
  mc-allocator.o \
+ mc-msi.o \
  dpmcp.o \
  dpbp.o
diff --git a/drivers/staging/fsl-mc/bus/mc-msi.c 
b/drivers/staging/fsl-mc/bus/mc-msi.c
new file mode 100644
index 000..dfe8016
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/mc-msi.c
@@ -0,0 +1,278 @@
+/*
+ * Freescale Management Complex (MC) bus driver MSI support
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera 
+ *
+ * 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 "../include/mc-private.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../include/mc-sys.h"
+#include "dprc-cmd.h"
+
+static void fsl_mc_msi_set_desc(msi_alloc_info_t *arg,
+   struct msi_desc *desc)
+{
+   arg->desc = desc;
+   arg->hwirq = (irq_hw_number_t)desc->msi_attrib.entry_nr;
+}
+
+static void fsl_mc_msi_update_dom_ops(struct msi_domain_info *info)
+{
+   struct msi_domain_ops *ops = info->ops;
+
+   if (WARN_ON(!ops))
+   return;
+
+   if (!ops->set_desc)
+   ops->set_desc = fsl_mc_msi_set_desc;
+}
+
+static void __fsl_mc_msi_write_msg(struct fsl_mc_device *mc_bus_dev,
+  struct fsl_mc_device_irq *mc_dev_irq)
+{
+   int error;
+   struct fsl_mc_device *owner_mc_dev = mc_dev_irq->mc_dev;
+   struct msi_desc *msi_desc = mc_dev_irq->msi_desc;
+   struct dprc_irq_cfg irq_cfg;
+
+   /*
+* msi_desc->msg.address is 0x0 when this function is invoked in
+* the free_irq() code path. In this case, for the MC, we don't
+* really need to "unprogram" the MSI, so we just return.
+*/
+   if (msi_desc->msg.address_lo == 0x0 && msi_desc->msg.address_hi == 0x0)
+   return;
+
+   if (WARN_ON(!owner_mc_dev))
+   return;
+
+   irq_cfg.paddr = ((u64)msi_desc->msg.address_hi << 32) |
+   msi_desc->msg.address_lo;
+   irq_cfg.val = msi_desc->msg.data;
+   irq_cfg.user_irq_id = msi_desc->irq;
+
+   /*
+* DPRCs and other objects use different commands to set up IRQs,
+* so we have to differentiate them here.
+*/
+   if (owner_mc_dev == mc_bus_dev) {
+   /*
+* IRQ is for the mc_bus_dev's DPRC itself
+*/
+   error = dprc_set_irq(mc_bus_dev->mc_io,
+MC_CMD_FLAG_INTR_DIS | MC_CMD_FLAG_PRI,
+mc_bus_dev->mc_handle,
+mc_dev_irq->dev_irq_index,
+&irq_cfg);
+   if (error < 0) {
+   dev_err(&owner_mc_dev->dev,
+   "dprc_set_irq() failed: %d\n", error);
+   }
+   } else {
+   error = dprc_set_obj_irq(mc_bus_dev->mc_io,
+MC_CMD_FLAG_INTR_DIS | MC_CMD_FLAG_PRI,
+mc_bus_dev->mc_handle,
+owner_mc_dev->obj_desc.type,
+ 

[PATCH 03/10] staging: fsl-mc: Added GICv3-ITS support for FSL-MC MSIs

2015-10-26 Thread J. German Rivera
Added platform-specific MSI support layer for FSL-MC devices.

Signed-off-by: J. German Rivera 
---
 drivers/staging/fsl-mc/bus/Makefile|   1 +
 .../staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c | 127 +
 drivers/staging/fsl-mc/include/mc-private.h|   4 +
 3 files changed, 132 insertions(+)
 create mode 100644 drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c

diff --git a/drivers/staging/fsl-mc/bus/Makefile 
b/drivers/staging/fsl-mc/bus/Makefile
index a5f2ba4..e731517 100644
--- a/drivers/staging/fsl-mc/bus/Makefile
+++ b/drivers/staging/fsl-mc/bus/Makefile
@@ -14,5 +14,6 @@ mc-bus-driver-objs := mc-bus.o \
  dprc-driver.o \
  mc-allocator.o \
  mc-msi.o \
+ irq-gic-v3-its-fsl-mc-msi.o \
  dpmcp.o \
  dpbp.o
diff --git a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c 
b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
new file mode 100644
index 000..5319afa
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
@@ -0,0 +1,127 @@
+/*
+ * Freescale Management Complex (MC) bus driver MSI support
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera 
+ *
+ * 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 "../include/mc-private.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../include/mc-sys.h"
+#include "dprc-cmd.h"
+
+static struct irq_chip its_msi_irq_chip = {
+   .name = "fsl-mc-bus-msi",
+   .irq_mask = irq_chip_mask_parent,
+   .irq_unmask = irq_chip_unmask_parent,
+   .irq_eoi = irq_chip_eoi_parent,
+   .irq_set_affinity = msi_domain_set_affinity
+};
+
+static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
+ struct device *dev,
+ int nvec, msi_alloc_info_t *info)
+{
+   u32 its_dev_id;
+   struct fsl_mc_device *mc_bus_dev = to_fsl_mc_device(dev);
+   struct msi_domain_info *msi_info;
+
+   if (WARN_ON(dev->bus != &fsl_mc_bus_type))
+   return -EINVAL;
+
+   if (WARN_ON(!(mc_bus_dev->flags & FSL_MC_IS_DPRC)))
+   return -EINVAL;
+
+   /*
+* Set the device Id to be passed to the GIC-ITS:
+*
+* NOTE: This device id corresponds to the IOMMU stream ID
+* associated with the DPRC object (ICID).
+*/
+   its_dev_id = mc_bus_dev->icid;
+   info->scratchpad[0].ul = its_dev_id;
+   msi_info = msi_get_domain_info(msi_domain->parent);
+   return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info);
+}
+
+static struct msi_domain_ops its_fsl_mc_msi_ops = {
+   .msi_prepare = its_fsl_mc_msi_prepare,
+};
+
+static struct msi_domain_info its_fsl_mc_msi_domain_info = {
+   .flags  = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
+   .ops= &its_fsl_mc_msi_ops,
+   .chip   = &its_msi_irq_chip,
+};
+
+static const struct of_device_id its_device_id[] = {
+   {   .compatible = "arm,gic-v3-its", },
+   {},
+};
+
+int __init its_fsl_mc_msi_init(void)
+{
+   struct device_node *np;
+   struct irq_domain *parent;
+   struct irq_domain *mc_msi_domain;
+
+   for (np = of_find_matching_node(NULL, its_device_id); np;
+np = of_find_matching_node(np, its_device_id)) {
+   if (!of_property_read_bool(np, "msi-controller"))
+   continue;
+
+   parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
+   if (!parent || !msi_get_domain_info(parent)) {
+   pr_err("%s: unable to locate ITS domain\n",
+  np->full_name);
+   continue;
+   }
+
+   mc_msi_domain =
+   fsl_mc_msi_create_irq_domain(of_node_to_fwnode(np),
+&its_fsl_mc_msi_domain_info,
+parent);
+   if (!mc_msi_domain) {
+   pr_err("%s: unable to create fsl-mc domain\n",
+  np->full_name);
+   continue;
+   }
+
+   WARN_ON(mc_msi_domain->host_data !=
+   &its_fsl_mc_msi_domain_info);
+
+   pr_info("fsl-mc MSI: %s domain created\n", np->full_name);
+   }
+
+   return 0;
+}
+
+void its_fsl_mc_msi_cleanup(void)
+{
+   struct device_node *np;
+
+   for (np = of_find_matching_node(NULL, its_device_id); np;
+ 

[PATCH] arm64: dts: Added syscon-reboot node for FSL's LS2085A SoC

2015-10-23 Thread J. German Rivera
Added sys-reboot node to the FSL's LS2085A SoC DT to leverage
the ARM-generic reboot mechanism for this SoC. This mechanism
is enabled through CONFIG_POWER_RESET_SYSCON.

Signed-off-by: J. German Rivera 
---
 arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
index e281ceb..6f82163 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
@@ -131,6 +131,18 @@
interrupts = <1 9 0x4>;
};
 
+   rst_ccsr: rstccsr@1E6 {
+   compatible = "syscon";
+   reg = <0x0 0x1E6 0x0 0x1>;
+   };
+
+   reboot@65024000 {
+   compatible ="syscon-reboot";
+   regmap = <&rst_ccsr>;
+   offset = <0x0>;
+   mask = <0x2>;
+   };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
-- 
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 0/4] staging: fsl-mc: MC command serialization

2015-10-17 Thread J. German Rivera
This patch series depends on the patch series posted
at http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg999081.html

This patch series addresses the following item from the TODO list
for the MC bus driver to exit staging:

* Management Complex (MC) command serialization. Locking mechanisms
  are needed by drivers to serialize commands sent to the MC, including
  from atomic context.

CHANGE HISTORY

Changes in v2:
- Updated link to patch series this patch series depends on.
- Added missing Signed-off-by entries.

Patch 1: Changed timeout units for MC cmd completion
Patch 2: Refactored mc_send_command()
Patch 3: Added support for atomic portals
Patch 4: Added serialization to mc_send_command()

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 4/4] staging: fsl-mc: Added serialization to mc_send_command()

2015-10-17 Thread J. German Rivera
When the same portal is used to call mc_send_command() from two
different threads or a thread and an interrupt handler, serialization
is required, as the MC only supports one outstanding command per MC
portal. Thus, a new command should not be sent to the MC until the
last command sent has been responded by the MC.

Signed-off-by: J. German Rivera 
---
Changes in v2:
- Added missing Signed-off-by entry

 drivers/staging/fsl-mc/bus/mc-sys.c | 25 ++---
 drivers/staging/fsl-mc/include/mc-sys.h | 29 +
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c 
b/drivers/staging/fsl-mc/bus/mc-sys.c
index 6eeb9fa..6e14892 100644
--- a/drivers/staging/fsl-mc/bus/mc-sys.c
+++ b/drivers/staging/fsl-mc/bus/mc-sys.c
@@ -88,6 +88,11 @@ int __must_check fsl_create_mc_io(struct device *dev,
mc_io->flags = flags;
mc_io->portal_phys_addr = mc_portal_phys_addr;
mc_io->portal_size = mc_portal_size;
+   if (flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)
+   spin_lock_init(&mc_io->spinlock);
+   else
+   mutex_init(&mc_io->mutex);
+
res = devm_request_mem_region(dev,
  mc_portal_phys_addr,
  mc_portal_size,
@@ -391,11 +396,17 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct 
mc_command *cmd)
 {
int error;
enum mc_cmd_status status;
+   unsigned long irq_flags = 0;

if (WARN_ON(in_irq() &&
!(mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)))
return -EINVAL;

+   if (mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)
+   spin_lock_irqsave(&mc_io->spinlock, irq_flags);
+   else
+   mutex_lock(&mc_io->mutex);
+
/*
 * Send command to the MC hardware:
 */
@@ -410,7 +421,7 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct 
mc_command *cmd)
error = mc_polling_wait_atomic(mc_io, cmd, &status);

if (error < 0)
-   return error;
+   goto common_exit;

if (status != MC_CMD_STATUS_OK) {
pr_debug("MC command failed: portal: %#llx, obj handle: %#x, 
command: %#x, status: %s (%#x)\n",
@@ -420,9 +431,17 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct 
mc_command *cmd)
 mc_status_to_string(status),
 (unsigned int)status);

-   return mc_status_to_error(status);
+   error = mc_status_to_error(status);
+   goto common_exit;
}

-   return 0;
+   error = 0;
+common_exit:
+   if (mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)
+   spin_unlock_irqrestore(&mc_io->spinlock, irq_flags);
+   else
+   mutex_unlock(&mc_io->mutex);
+
+   return error;
 }
 EXPORT_SYMBOL(mc_send_command);
diff --git a/drivers/staging/fsl-mc/include/mc-sys.h 
b/drivers/staging/fsl-mc/include/mc-sys.h
index 15e19af..c5038cc 100644
--- a/drivers/staging/fsl-mc/include/mc-sys.h
+++ b/drivers/staging/fsl-mc/include/mc-sys.h
@@ -39,6 +39,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 

 /**
  * Bit masks for a MC I/O object (struct fsl_mc_io) flags
@@ -56,6 +58,20 @@ struct mc_command;
  * @portal_phys_addr: MC command portal physical address
  * @portal_virt_addr: MC command portal virtual address
  * @dpmcp_dev: pointer to the DPMCP device associated with the MC portal.
+ *
+ * Fields are only meaningful if the FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag is 
not
+ * set:
+ * @mutex: Mutex to serialize mc_send_command() calls that use the same MC
+ * portal, if the fsl_mc_io object was created with the
+ * FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag off. mc_send_command() calls for this
+ * fsl_mc_io object must be made only from non-atomic context.
+ *
+ * Fields are only meaningful if the FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag is
+ * set:
+ * @spinlock: Spinlock to serialize mc_send_command() calls that use the same 
MC
+ * portal, if the fsl_mc_io object was created with the
+ * FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag on. mc_send_command() calls for this
+ * fsl_mc_io object can be made from atomic or non-atomic context.
  */
 struct fsl_mc_io {
struct device *dev;
@@ -64,6 +80,19 @@ struct fsl_mc_io {
phys_addr_t portal_phys_addr;
void __iomem *portal_virt_addr;
struct fsl_mc_device *dpmcp_dev;
+   union {
+   /*
+* This field is only meaningful if the
+* FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag is not set
+*/
+   struct mutex mutex; /* serializes mc_send_command() */
+
+   /*
+* This field is only meaningful if the
+* FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag is set
+ 

[PATCH v2 1/4] staging: fsl-mc: changed timeout units for MC cmd completion

2015-10-17 Thread J. German Rivera
Changed units for the timeout to wait for completion
of MC command, from jiffies to milliseconds.

Signed-off-by: J. German Rivera 
---
Changes in v2:
- Added missing Signed-off-by entry

 drivers/staging/fsl-mc/bus/mc-sys.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c 
b/drivers/staging/fsl-mc/bus/mc-sys.c
index 07848a0..2c5f109 100644
--- a/drivers/staging/fsl-mc/bus/mc-sys.c
+++ b/drivers/staging/fsl-mc/bus/mc-sys.c
@@ -42,9 +42,9 @@
 #include "dpmcp.h"

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

 /*
  * usleep_range() min and max values used to throttle down polling
@@ -305,7 +305,7 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct 
mc_command *cmd)
 {
enum mc_cmd_status status;
unsigned long jiffies_until_timeout =
-   jiffies + MC_CMD_COMPLETION_TIMEOUT_JIFFIES;
+   jiffies + msecs_to_jiffies(MC_CMD_COMPLETION_TIMEOUT_MS);

/*
 * Send command to the MC hardware:
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 3/4] staging: fsl-mc:Added support for atomic portals

2015-10-17 Thread J. German Rivera
Refactored mc_send_command() to support two flavors of polling:
- preemptible (for non-atomic portals), which was already supported.
  It calls usleep_range() between polling iterations.
- non-preemptible (for atomic portals), which is needed when
  mc_send_command() is called with interrupts disabled.
  It calls udelay() between polling iterations.

Signed-off-by: J. German Rivera 
---
Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-sys.c | 53 +++--
 drivers/staging/fsl-mc/include/mc-sys.h |  5 
 2 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c 
b/drivers/staging/fsl-mc/bus/mc-sys.c
index c4f5bdd..6eeb9fa 100644
--- a/drivers/staging/fsl-mc/bus/mc-sys.c
+++ b/drivers/staging/fsl-mc/bus/mc-sys.c
@@ -339,20 +339,63 @@ static int mc_polling_wait_preemptible(struct fsl_mc_io 
*mc_io,
 }

 /**
+ * Waits for the completion of an MC command doing atomic polling.
+ * udelay() is called between polling iterations.
+ *
+ * @mc_io: MC I/O object to be used
+ * @cmd: command buffer to receive MC response
+ * @mc_status: MC command completion status
+ */
+static int mc_polling_wait_atomic(struct fsl_mc_io *mc_io,
+ struct mc_command *cmd,
+ enum mc_cmd_status *mc_status)
+{
+   enum mc_cmd_status status;
+   unsigned long timeout_usecs = MC_CMD_COMPLETION_TIMEOUT_MS * 1000;
+
+   BUILD_BUG_ON((MC_CMD_COMPLETION_TIMEOUT_MS * 1000) %
+MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS != 0);
+
+   for (;;) {
+   status = mc_read_response(mc_io->portal_virt_addr, cmd);
+   if (status != MC_CMD_STATUS_READY)
+   break;
+
+   udelay(MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS);
+   timeout_usecs -= MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS;
+   if (timeout_usecs == 0) {
+   pr_debug("MC command timed out (portal: %#llx, obj 
handle: %#x, command: %#x)\n",
+mc_io->portal_phys_addr,
+(unsigned int)
+   MC_CMD_HDR_READ_TOKEN(cmd->header),
+(unsigned int)
+   MC_CMD_HDR_READ_CMDID(cmd->header));
+
+   return -ETIMEDOUT;
+   }
+   }
+
+   *mc_status = status;
+   return 0;
+}
+
+/**
  * Sends a command to the MC device using the given MC I/O object
  *
  * @mc_io: MC I/O object to be used
  * @cmd: command to be sent
  *
  * Returns '0' on Success; Error code otherwise.
- *
- * NOTE: This function cannot be invoked from from atomic contexts.
  */
 int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
 {
int error;
enum mc_cmd_status status;

+   if (WARN_ON(in_irq() &&
+   !(mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)))
+   return -EINVAL;
+
/*
 * Send command to the MC hardware:
 */
@@ -361,7 +404,11 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct 
mc_command *cmd)
/*
 * Wait for response from the MC hardware:
 */
-   error = mc_polling_wait_preemptible(mc_io, cmd, &status);
+   if (!(mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL))
+   error = mc_polling_wait_preemptible(mc_io, cmd, &status);
+   else
+   error = mc_polling_wait_atomic(mc_io, cmd, &status);
+
if (error < 0)
return error;

diff --git a/drivers/staging/fsl-mc/include/mc-sys.h 
b/drivers/staging/fsl-mc/include/mc-sys.h
index 7d44d8c..15e19af 100644
--- a/drivers/staging/fsl-mc/include/mc-sys.h
+++ b/drivers/staging/fsl-mc/include/mc-sys.h
@@ -40,6 +40,11 @@
 #include 
 #include 

+/**
+ * Bit masks for a MC I/O object (struct fsl_mc_io) flags
+ */
+#define FSL_MC_IO_ATOMIC_CONTEXT_PORTAL0x0001
+
 struct fsl_mc_resource;
 struct mc_command;

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 2/4] staging: fsl-mc: refactored mc_send_command()

2015-10-17 Thread J. German Rivera
Moved wait logic in mc_send_command() to its own function

Signed-off-by: J. German Rivera 
---
Changes in v2:
- Added missing Signed-off-by entry

 drivers/staging/fsl-mc/bus/mc-sys.c | 50 -
 1 file changed, 38 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c 
b/drivers/staging/fsl-mc/bus/mc-sys.c
index 2c5f109..c4f5bdd 100644
--- a/drivers/staging/fsl-mc/bus/mc-sys.c
+++ b/drivers/staging/fsl-mc/bus/mc-sys.c
@@ -292,27 +292,22 @@ static inline enum mc_cmd_status mc_read_response(struct 
mc_command __iomem *
 }

 /**
- * Sends an command to the MC device using the given MC I/O object
+ * Waits for the completion of an MC command doing preemptible polling.
+ * uslepp_range() is called between polling iterations.
  *
  * @mc_io: MC I/O object to be used
- * @cmd: command to be sent
- *
- * Returns '0' on Success; Error code otherwise.
- *
- * NOTE: This function cannot be invoked from from atomic contexts.
+ * @cmd: command buffer to receive MC response
+ * @mc_status: MC command completion status
  */
-int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
+static int mc_polling_wait_preemptible(struct fsl_mc_io *mc_io,
+  struct mc_command *cmd,
+  enum mc_cmd_status *mc_status)
 {
enum mc_cmd_status status;
unsigned long jiffies_until_timeout =
jiffies + msecs_to_jiffies(MC_CMD_COMPLETION_TIMEOUT_MS);

/*
-* Send command to the MC hardware:
-*/
-   mc_write_command(mc_io->portal_virt_addr, cmd);
-
-   /*
 * Wait for response from the MC hardware:
 */
for (;;) {
@@ -339,6 +334,37 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct 
mc_command *cmd)
}
}

+   *mc_status = status;
+   return 0;
+}
+
+/**
+ * Sends a command to the MC device using the given MC I/O object
+ *
+ * @mc_io: MC I/O object to be used
+ * @cmd: command to be sent
+ *
+ * Returns '0' on Success; Error code otherwise.
+ *
+ * NOTE: This function cannot be invoked from from atomic contexts.
+ */
+int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
+{
+   int error;
+   enum mc_cmd_status status;
+
+   /*
+* Send command to the MC hardware:
+*/
+   mc_write_command(mc_io->portal_virt_addr, cmd);
+
+   /*
+* Wait for response from the MC hardware:
+*/
+   error = mc_polling_wait_preemptible(mc_io, cmd, &status);
+   if (error < 0)
+   return error;
+
if (status != MC_CMD_STATUS_OK) {
pr_debug("MC command failed: portal: %#llx, obj handle: %#x, 
command: %#x, status: %s (%#x)\n",
 mc_io->portal_phys_addr,
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 07/12] staging: fsl-mc: Fixed alignment of copyright comment

2015-10-17 Thread J. German Rivera
Whitespace cleanup-- add missing spaces in column 1 of copyright

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3:
- Added missing signed-off-by

Changes in v2: none

 drivers/staging/fsl-mc/include/dpcon-cmd.h | 60 +++---
 1 file changed, 30 insertions(+), 30 deletions(-)

diff --git a/drivers/staging/fsl-mc/include/dpcon-cmd.h 
b/drivers/staging/fsl-mc/include/dpcon-cmd.h
index 2617024..536b2ef 100644
--- a/drivers/staging/fsl-mc/include/dpcon-cmd.h
+++ b/drivers/staging/fsl-mc/include/dpcon-cmd.h
@@ -1,34 +1,34 @@
 /* Copyright 2013-2015 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 the above-listed copyright holders nor the
-* names of any 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS OR CONTRIBUTORS 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.
-*/
+ *
+ * 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 the above-listed copyright holders nor the
+ * names of any 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS OR CONTRIBUTORS 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_DPCON_CMD_H
 #define _FSL_DPCON_CMD_H

--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 10/12] staging: fsl-mc: Fixed WARN_ON() in fsl_mc_resource_pool_remove_device

2015-10-17 Thread J. German Rivera
Check that resource is not NULL before de-referencing it.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3:
- Added missing signed-off-by

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-allocator.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c 
b/drivers/staging/fsl-mc/bus/mc-allocator.c
index a45293b..88d1857 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -111,7 +111,7 @@ static int __must_check 
fsl_mc_resource_pool_remove_device(struct fsl_mc_device
goto out;

resource = mc_dev->resource;
-   if (WARN_ON(resource->data != mc_dev))
+   if (WARN_ON(!resource || resource->data != mc_dev))
goto out;

mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 03/12] staging: fsl-mc: dpmcp opening/closing refactoring

2015-10-17 Thread J. German Rivera
Before, we were opening and closing a mc_io's dpmcp object
in fsl_mc_portal_reset(), since that was the only function that was
calling dpmcp MC operations. However, it is better for maintainability
to open the dpmcp object when it gets associated with an mc_io object,
and close it when this association is terminated. This way, we are free
to call dpmcp operations on a mc_io's dpmcp object at any time, without
having to check if the dpmcp object is opened or not.

Consequently, the creation/teardown of the association between
an mc_io object and a dpmcp is now encapsulated in two functions:
fsl_mc_io_set_dpmcp()/fsl_mc_io_unset_dpmcp(). Besides, setting
the corresponding pointers for the association, these functions
open and close the dpmcp object respectively.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3:
- Added missing signed-off-by

Changes in v2:
- Removed leftover code that needed to be removed as part of
  the refactoring done in this patch

 drivers/staging/fsl-mc/bus/mc-allocator.c | 15 +--
 drivers/staging/fsl-mc/bus/mc-sys.c   | 74 ---
 drivers/staging/fsl-mc/include/mc-sys.h   |  5 +++
 3 files changed, 73 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c 
b/drivers/staging/fsl-mc/bus/mc-allocator.c
index c3222c6..33f5de4 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -373,30 +373,17 @@ EXPORT_SYMBOL_GPL(fsl_mc_portal_free);
 int fsl_mc_portal_reset(struct fsl_mc_io *mc_io)
 {
int error;
-   u16 token;
struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;

if (WARN_ON(!dpmcp_dev))
return -EINVAL;

-   error = dpmcp_open(mc_io, 0, dpmcp_dev->obj_desc.id, &token);
-   if (error < 0) {
-   dev_err(&dpmcp_dev->dev, "dpmcp_open() failed: %d\n", error);
-   return error;
-   }
-
-   error = dpmcp_reset(mc_io, 0, token);
+   error = dpmcp_reset(mc_io, 0, dpmcp_dev->mc_handle);
if (error < 0) {
dev_err(&dpmcp_dev->dev, "dpmcp_reset() failed: %d\n", error);
return error;
}

-   error = dpmcp_close(mc_io, 0, token);
-   if (error < 0) {
-   dev_err(&dpmcp_dev->dev, "dpmcp_close() failed: %d\n", error);
-   return error;
-   }
-
return 0;
 }
 EXPORT_SYMBOL_GPL(fsl_mc_portal_reset);
diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c 
b/drivers/staging/fsl-mc/bus/mc-sys.c
index e53acfa..07848a0 100644
--- a/drivers/staging/fsl-mc/bus/mc-sys.c
+++ b/drivers/staging/fsl-mc/bus/mc-sys.c
@@ -75,6 +75,7 @@ int __must_check fsl_create_mc_io(struct device *dev,
  struct fsl_mc_device *dpmcp_dev,
  u32 flags, struct fsl_mc_io **new_mc_io)
 {
+   int error;
struct fsl_mc_io *mc_io;
void __iomem *mc_portal_virt_addr;
struct resource *res;
@@ -87,8 +88,6 @@ int __must_check fsl_create_mc_io(struct device *dev,
mc_io->flags = flags;
mc_io->portal_phys_addr = mc_portal_phys_addr;
mc_io->portal_size = mc_portal_size;
-   mc_io->dpmcp_dev = dpmcp_dev;
-   dpmcp_dev->mc_io = mc_io;
res = devm_request_mem_region(dev,
  mc_portal_phys_addr,
  mc_portal_size,
@@ -111,8 +110,18 @@ int __must_check fsl_create_mc_io(struct device *dev,
}

mc_io->portal_virt_addr = mc_portal_virt_addr;
+   if (dpmcp_dev) {
+   error = fsl_mc_io_set_dpmcp(mc_io, dpmcp_dev);
+   if (error < 0)
+   goto error_destroy_mc_io;
+   }
+
*new_mc_io = mc_io;
return 0;
+
+error_destroy_mc_io:
+   fsl_destroy_mc_io(mc_io);
+   return error;
 }
 EXPORT_SYMBOL_GPL(fsl_create_mc_io);

@@ -123,21 +132,72 @@ EXPORT_SYMBOL_GPL(fsl_create_mc_io);
  */
 void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
 {
+   struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
+
+   if (dpmcp_dev)
+   fsl_mc_io_unset_dpmcp(mc_io);
+
devm_iounmap(mc_io->dev, mc_io->portal_virt_addr);
devm_release_mem_region(mc_io->dev,
mc_io->portal_phys_addr,
mc_io->portal_size);

mc_io->portal_virt_addr = NULL;
-   if (mc_io->dpmcp_dev) {
-   WARN_ON(mc_io->dpmcp_dev->mc_io != mc_io);
-   mc_io->dpmcp_dev->mc_io = NULL;
-   }
-
devm_kfree(mc_io->dev, mc_io);
 }
 EXPORT_SYMBOL_GPL(fsl_destroy_mc_io);

+int fsl_mc_io_set_dpmcp(struct fsl_mc_io *mc_io,
+   struct fsl_mc_device *dpmcp_dev)
+{
+   int error;
+
+   if (WARN_ON(!dpmcp_dev))
+   return -EINVAL;
+

[PATCH v3 08/12] staging: fsl-mc: Fixed bug in fsl_mc_allocator_remove

2015-10-17 Thread J. German Rivera
Call fsl_mc_resource_pool_remove_device() only if mc_dev->resource
is not NULL.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3:
- Added missing signed-off-by

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-allocator.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c 
b/drivers/staging/fsl-mc/bus/mc-allocator.c
index 527cb4b..e9c3dec 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -511,9 +511,11 @@ static int fsl_mc_allocator_remove(struct fsl_mc_device 
*mc_dev)
if (WARN_ON(!FSL_MC_IS_ALLOCATABLE(mc_dev->obj_desc.type)))
goto out;

-   error = fsl_mc_resource_pool_remove_device(mc_dev);
-   if (error < 0)
-   goto out;
+   if (mc_dev->resource) {
+   error = fsl_mc_resource_pool_remove_device(mc_dev);
+   if (error < 0)
+   goto out;
+   }

dev_dbg(&mc_dev->dev,
"Allocatable MC object device unbound from fsl_mc_allocator 
driver");
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 06/12] staging: fsl-mc: Removed unused DPMCP macros

2015-10-17 Thread J. German Rivera
The macros were a left-over from a previous implementation
of the dpmcp APIs and are no longer used.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3:
- Added missing signed-off-by

Changes in v2: none

 drivers/staging/fsl-mc/bus/dpmcp-cmd.h | 79 --
 1 file changed, 79 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h 
b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h
index 6cc0fed..a87e9f8 100644
--- a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h
+++ b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h
@@ -54,83 +54,4 @@
 #define DPMCP_CMDID_GET_IRQ_STATUS 0x016
 #define DPMCP_CMDID_CLEAR_IRQ_STATUS   0x017

-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_CREATE(cmd, cfg) \
-   MC_CMD_OP(cmd, 0, 0,  32, int,  cfg->portal_id)
-
-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_SET_IRQ(cmd, irq_index, irq_addr, irq_val, user_irq_id) \
-do { \
-   MC_CMD_OP(cmd, 0, 0,  8,  uint8_t,  irq_index);\
-   MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_val);\
-   MC_CMD_OP(cmd, 1, 0,  64, uint64_t, irq_addr); \
-   MC_CMD_OP(cmd, 2, 0,  32, int,  user_irq_id); \
-} while (0)
-
-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_GET_IRQ(cmd, irq_index) \
-   MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index)
-
-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_RSP_GET_IRQ(cmd, type, irq_addr, irq_val, user_irq_id) \
-do { \
-   MC_RSP_OP(cmd, 0, 0,  32, uint32_t, irq_val); \
-   MC_RSP_OP(cmd, 1, 0,  64, uint64_t, irq_addr); \
-   MC_RSP_OP(cmd, 2, 0,  32, int,  user_irq_id); \
-   MC_RSP_OP(cmd, 2, 32, 32, int,  type); \
-} while (0)
-
-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_SET_IRQ_ENABLE(cmd, irq_index, en) \
-do { \
-   MC_CMD_OP(cmd, 0, 0,  8,  uint8_t,  en); \
-   MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index);\
-} while (0)
-
-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_GET_IRQ_ENABLE(cmd, irq_index) \
-   MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index)
-
-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_RSP_GET_IRQ_ENABLE(cmd, en) \
-   MC_RSP_OP(cmd, 0, 0,  8,  uint8_t,  en)
-
-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \
-do { \
-   MC_CMD_OP(cmd, 0, 0,  32, uint32_t, mask);\
-   MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index);\
-} while (0)
-
-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_GET_IRQ_MASK(cmd, irq_index) \
-   MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index)
-
-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_RSP_GET_IRQ_MASK(cmd, mask) \
-   MC_RSP_OP(cmd, 0, 0,  32, uint32_t, mask)
-
-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_GET_IRQ_STATUS(cmd, irq_index) \
-   MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index)
-
-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_RSP_GET_IRQ_STATUS(cmd, status) \
-   MC_RSP_OP(cmd, 0, 0,  32, uint32_t, status)
-
-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \
-do { \
-   MC_CMD_OP(cmd, 0, 0,  32, uint32_t, status); \
-   MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  irq_index);\
-} while (0)
-
-/*cmd, param, offset, width, type, arg_name */
-#define DPMCP_RSP_GET_ATTRIBUTES(cmd, attr) \
-do { \
-   MC_RSP_OP(cmd, 0, 32, 32, int,  attr->id);\
-   MC_RSP_OP(cmd, 1, 0,  16, uint16_t, attr->version.major);\
-   MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->version.minor);\
-} while (0)
-
 #endif /* _FSL_DPMCP_CMD_H */
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 02/12] staging: fsl-mc: fsl_mc_io object refactoring

2015-10-17 Thread J. German Rivera
Each fsl_mc_io object is associated with an fsl_mc_device object
of type "dpmcp" representing the MC portal associated with the
fsl_mc_io object. Before, we were representing this association with
an fsl_mc_resource pointer. To enhance code clarity, it is more
straight forward to use an fsl_mc_device pointer instead.
So, this change replaces the 'resource' field in the fsl_mc_io
object with 'dpmcp_dev'. Also, it changes parameter 'resource' of
fsl_create_mc_io() to be an fsl_mc_device pointer instead.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3:
- Added missing signed-off-by

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-allocator.c | 34 ++-
 drivers/staging/fsl-mc/bus/mc-sys.c   | 16 +++
 drivers/staging/fsl-mc/include/mc-sys.h   |  8 +++-
 3 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c 
b/drivers/staging/fsl-mc/bus/mc-allocator.c
index a4aa859..c3222c6 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -320,7 +320,7 @@ int __must_check fsl_mc_portal_allocate(struct 
fsl_mc_device *mc_dev,

error = fsl_create_mc_io(&mc_bus_dev->dev,
 mc_portal_phys_addr,
-mc_portal_size, resource,
+mc_portal_size, dpmcp_dev,
 mc_io_flags, &mc_io);
if (error < 0)
goto error_cleanup_resource;
@@ -342,12 +342,22 @@ EXPORT_SYMBOL_GPL(fsl_mc_portal_allocate);
  */
 void fsl_mc_portal_free(struct fsl_mc_io *mc_io)
 {
+   struct fsl_mc_device *dpmcp_dev;
struct fsl_mc_resource *resource;

-   resource = mc_io->resource;
-   if (WARN_ON(resource->type != FSL_MC_POOL_DPMCP))
+   /*
+* Every mc_io obtained by calling fsl_mc_portal_allocate() is supposed
+* to have a DPMCP object associated with.
+*/
+   dpmcp_dev = mc_io->dpmcp_dev;
+   if (WARN_ON(!dpmcp_dev))
+   return;
+
+   resource = dpmcp_dev->resource;
+   if (WARN_ON(!resource || resource->type != FSL_MC_POOL_DPMCP))
return;
-   if (WARN_ON(!resource->data))
+
+   if (WARN_ON(resource->data != dpmcp_dev))
return;

fsl_destroy_mc_io(mc_io);
@@ -364,30 +374,26 @@ int fsl_mc_portal_reset(struct fsl_mc_io *mc_io)
 {
int error;
u16 token;
-   struct fsl_mc_resource *resource = mc_io->resource;
-   struct fsl_mc_device *mc_dev = resource->data;
+   struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;

-   if (WARN_ON(resource->type != FSL_MC_POOL_DPMCP))
-   return -EINVAL;
-
-   if (WARN_ON(!mc_dev))
+   if (WARN_ON(!dpmcp_dev))
return -EINVAL;

-   error = dpmcp_open(mc_io, 0, mc_dev->obj_desc.id, &token);
+   error = dpmcp_open(mc_io, 0, dpmcp_dev->obj_desc.id, &token);
if (error < 0) {
-   dev_err(&mc_dev->dev, "dpmcp_open() failed: %d\n", error);
+   dev_err(&dpmcp_dev->dev, "dpmcp_open() failed: %d\n", error);
return error;
}

error = dpmcp_reset(mc_io, 0, token);
if (error < 0) {
-   dev_err(&mc_dev->dev, "dpmcp_reset() failed: %d\n", error);
+   dev_err(&dpmcp_dev->dev, "dpmcp_reset() failed: %d\n", error);
return error;
}

error = dpmcp_close(mc_io, 0, token);
if (error < 0) {
-   dev_err(&mc_dev->dev, "dpmcp_close() failed: %d\n", error);
+   dev_err(&dpmcp_dev->dev, "dpmcp_close() failed: %d\n", error);
return error;
}

diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c 
b/drivers/staging/fsl-mc/bus/mc-sys.c
index b58b53f..e53acfa 100644
--- a/drivers/staging/fsl-mc/bus/mc-sys.c
+++ b/drivers/staging/fsl-mc/bus/mc-sys.c
@@ -34,10 +34,12 @@

 #include "../include/mc-sys.h"
 #include "../include/mc-cmd.h"
+#include "../include/mc.h"
 #include 
 #include 
 #include 
 #include 
+#include "dpmcp.h"

 /**
  * Timeout in jiffies to wait for the completion of an MC command
@@ -60,8 +62,8 @@
  * @dev: device to be associated with the MC I/O object
  * @mc_portal_phys_addr: physical address of the MC portal to use
  * @mc_portal_size: size in bytes of the MC portal
- * @resource: Pointer to MC bus object allocator resource associated
- * with this MC I/O object or NULL if none.
+ * @dpmcp-dev: Pointer to the DPMCP object associated with this MC I/O
+ * object or NULL if none.
  * @flags: flags for the new MC I/O object
  * @new_mc_io: Area to return pointer to newly created MC I/O object
  *
@@ -70,7

[PATCH v3 01/12] staging: fsl-mc: Naming cleanup in fsl_mc-portal_allocate

2015-10-17 Thread J. German Rivera
mc_adev is a local variable for the allocated dpmcp object.
Renamed mc_adev as dpmcp_dev for clarity.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3:
- Added missing signed-off-by

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-allocator.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c 
b/drivers/staging/fsl-mc/bus/mc-allocator.c
index d087b4c..a4aa859 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -284,7 +284,7 @@ int __must_check fsl_mc_portal_allocate(struct 
fsl_mc_device *mc_dev,
struct fsl_mc_bus *mc_bus;
phys_addr_t mc_portal_phys_addr;
size_t mc_portal_size;
-   struct fsl_mc_device *mc_adev;
+   struct fsl_mc_device *dpmcp_dev;
int error = -EINVAL;
struct fsl_mc_resource *resource = NULL;
struct fsl_mc_io *mc_io = NULL;
@@ -304,16 +304,16 @@ int __must_check fsl_mc_portal_allocate(struct 
fsl_mc_device *mc_dev,
if (error < 0)
return error;

-   mc_adev = resource->data;
-   if (WARN_ON(!mc_adev))
+   dpmcp_dev = resource->data;
+   if (WARN_ON(!dpmcp_dev))
goto error_cleanup_resource;

-   if (WARN_ON(mc_adev->obj_desc.region_count == 0))
+   if (WARN_ON(dpmcp_dev->obj_desc.region_count == 0))
goto error_cleanup_resource;

-   mc_portal_phys_addr = mc_adev->regions[0].start;
-   mc_portal_size = mc_adev->regions[0].end -
-mc_adev->regions[0].start + 1;
+   mc_portal_phys_addr = dpmcp_dev->regions[0].start;
+   mc_portal_size = dpmcp_dev->regions[0].end -
+dpmcp_dev->regions[0].start + 1;

if (WARN_ON(mc_portal_size != mc_bus_dev->mc_io->portal_size))
goto error_cleanup_resource;
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 04/12] staging: fsl-mc: Changed dev_info() calls to dev_dbg()

2015-10-17 Thread J. German Rivera
Changed dev_info() calls to dev_dbg() in
fsl_mc_allocator_probe/fsl_mc_allocator_remove, as they
are useful only for debugging.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3:
- Added missing signed-off-by

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-allocator.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c 
b/drivers/staging/fsl-mc/bus/mc-allocator.c
index 33f5de4..527cb4b 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -492,8 +492,8 @@ static int fsl_mc_allocator_probe(struct fsl_mc_device 
*mc_dev)
if (error < 0)
goto error;

-   dev_info(&mc_dev->dev,
-"Allocatable MC object device bound to fsl_mc_allocator 
driver");
+   dev_dbg(&mc_dev->dev,
+   "Allocatable MC object device bound to fsl_mc_allocator 
driver");
return 0;
 error:

@@ -515,8 +515,8 @@ static int fsl_mc_allocator_remove(struct fsl_mc_device 
*mc_dev)
if (error < 0)
goto out;

-   dev_info(&mc_dev->dev,
-"Allocatable MC object device unbound from fsl_mc_allocator 
driver");
+   dev_dbg(&mc_dev->dev,
+   "Allocatable MC object device unbound from fsl_mc_allocator 
driver");
error = 0;
 out:
return error;
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 05/12] staging_fsl-mc: Changed types of flags, portal size in

2015-10-17 Thread J. German Rivera
Changed these two fields from 32-bit integers to 16-bit integers in
struct fsl_mc_io, as 32 bits is too much for these fields. This
change does not affect other components since fsl_mc_io is an opaque
type.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3:
- Added missing signed-off-by

Changes in v2: none

 drivers/staging/fsl-mc/include/mc-sys.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fsl-mc/include/mc-sys.h 
b/drivers/staging/fsl-mc/include/mc-sys.h
index d4fb602..7d44d8c 100644
--- a/drivers/staging/fsl-mc/include/mc-sys.h
+++ b/drivers/staging/fsl-mc/include/mc-sys.h
@@ -54,8 +54,8 @@ struct mc_command;
  */
 struct fsl_mc_io {
struct device *dev;
-   u32 flags;
-   u32 portal_size;
+   u16 flags;
+   u16 portal_size;
phys_addr_t portal_phys_addr;
void __iomem *portal_virt_addr;
struct fsl_mc_device *dpmcp_dev;
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 12/12] staging: fsl-mc: Added missing initializer in fsl_mc_bus_driver

2015-10-17 Thread J. German Rivera
owner needs to be initialized as THIS_MOUDLE.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3:
- Added missing signed-off-by

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-bus.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index 4ac3d07..84db55b 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -790,6 +790,7 @@ 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,
   },
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 09/12] staging: fsl-mc: refactored error exit in allocator probe/remove

2015-10-17 Thread J. German Rivera
Replaced error gotos with direct returns in fsl_mc_allocator_probe()
and fsl_mc_allocator_remove(), since the only error handling done
in those functions is to exit.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3: none

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-allocator.c | 23 +--
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c 
b/drivers/staging/fsl-mc/bus/mc-allocator.c
index e9c3dec..a45293b 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
@@ -474,30 +474,27 @@ static int fsl_mc_allocator_probe(struct fsl_mc_device 
*mc_dev)
enum fsl_mc_pool_type pool_type;
struct fsl_mc_device *mc_bus_dev;
struct fsl_mc_bus *mc_bus;
-   int error = -EINVAL;
+   int error;

if (WARN_ON(!FSL_MC_IS_ALLOCATABLE(mc_dev->obj_desc.type)))
-   goto error;
+   return -EINVAL;

mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
if (WARN_ON(mc_bus_dev->dev.bus != &fsl_mc_bus_type))
-   goto error;
+   return -EINVAL;

mc_bus = to_fsl_mc_bus(mc_bus_dev);
error = object_type_to_pool_type(mc_dev->obj_desc.type, &pool_type);
if (error < 0)
-   goto error;
+   return error;

error = fsl_mc_resource_pool_add_device(mc_bus, pool_type, mc_dev);
if (error < 0)
-   goto error;
+   return error;

dev_dbg(&mc_dev->dev,
"Allocatable MC object device bound to fsl_mc_allocator 
driver");
return 0;
-error:
-
-   return error;
 }

 /**
@@ -506,22 +503,20 @@ error:
  */
 static int fsl_mc_allocator_remove(struct fsl_mc_device *mc_dev)
 {
-   int error = -EINVAL;
+   int error;

if (WARN_ON(!FSL_MC_IS_ALLOCATABLE(mc_dev->obj_desc.type)))
-   goto out;
+   return -EINVAL;

if (mc_dev->resource) {
error = fsl_mc_resource_pool_remove_device(mc_dev);
if (error < 0)
-   goto out;
+   return error;
}

dev_dbg(&mc_dev->dev,
"Allocatable MC object device unbound from fsl_mc_allocator 
driver");
-   error = 0;
-out:
-   return error;
+   return 0;
 }

 static const struct fsl_mc_device_match_id match_id_table[] = {
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 11/12] staging: fsl-mc: fixed bug in uninitialized root dprc irq count

2015-10-17 Thread J. German Rivera
When initializing the object attributes for the root dprc, the
irq_count was uninitialized. Initialize it to 1.

Signed-off-by: J. German Rivera 
---
CHANGE HISTORY

Changes in v3:
- Added missing signed-off-by

Changes in v2: none

 drivers/staging/fsl-mc/bus/mc-bus.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c 
b/drivers/staging/fsl-mc/bus/mc-bus.c
index fd13053..4ac3d07 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -749,6 +749,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
obj_desc.id = container_id;
obj_desc.ver_major = DPRC_VER_MAJOR;
obj_desc.ver_minor = DPRC_VER_MINOR;
+   obj_desc.irq_count = 1;
obj_desc.region_count = 0;

error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, &mc_bus_dev);
--
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 0/12] staging: fsl-mc: Cleanup and bug fixes

2015-10-17 Thread J. German Rivera
This patch series includes the following code cleanup and
bug fixes for the fsl-mc bus driver:

Patch 1: Naming cleanup in fsl_mc-portal_allocate
Patch 2: fsl_mc_io object refactoring
Patch 3: dpmcp opening/closing refactoring
Patch 4: Changed dev_info() calls to dev_dbg()
Patch 5: Changed types of flags, portal size in
Patch 6: Removed unused DPMCP macros
Patch 7: Fixed alignment of copyright comment
Patch 8: Fixed bug in fsl_mc_allocator_remove
Patch 9: Refactored error exit in allocator probe/remove
Patch 10: Fixed WARN_ON() in fsl_mc_resource_pool_remove_device
Patch 11: Fixed bug in uninitialized root dprc irq count
Patch 12: Added missing initializer in fsl_mc_bus_driver

CHANGE HISTORY

Changes in v3
- Added missing signed-off-by entries.

Changes in v2
- Updated only patch 3. There was some leftover code that
  needed to be removed as part of the refactoring done
  in that patch.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/4] staging: fsl-mc: changed timeout units for MC cmd completion

2015-10-14 Thread J. German Rivera
Changed units for the timeout to wait for completion
of MC command, from jiffies to milliseconds.
---
 drivers/staging/fsl-mc/bus/mc-sys.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c 
b/drivers/staging/fsl-mc/bus/mc-sys.c
index 07848a0..2c5f109 100644
--- a/drivers/staging/fsl-mc/bus/mc-sys.c
+++ b/drivers/staging/fsl-mc/bus/mc-sys.c
@@ -42,9 +42,9 @@
 #include "dpmcp.h"
 
 /**
- * Timeout in jiffies to wait for the completion of an MC command
+ * Timeout in milliseconds to wait for the completion of an MC command
  */
-#define MC_CMD_COMPLETION_TIMEOUT_JIFFIES   (HZ / 2)   /* 500 ms */
+#define MC_CMD_COMPLETION_TIMEOUT_MS   500
 
 /*
  * usleep_range() min and max values used to throttle down polling
@@ -305,7 +305,7 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct 
mc_command *cmd)
 {
enum mc_cmd_status status;
unsigned long jiffies_until_timeout =
-   jiffies + MC_CMD_COMPLETION_TIMEOUT_JIFFIES;
+   jiffies + msecs_to_jiffies(MC_CMD_COMPLETION_TIMEOUT_MS);
 
/*
 * Send command to the MC hardware:
-- 
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/4] staging: fsl-mc: refactored mc_send_command()

2015-10-14 Thread J. German Rivera
Moved wait logic in mc_send_command() to its own function
---
 drivers/staging/fsl-mc/bus/mc-sys.c | 50 -
 1 file changed, 38 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c 
b/drivers/staging/fsl-mc/bus/mc-sys.c
index 2c5f109..c4f5bdd 100644
--- a/drivers/staging/fsl-mc/bus/mc-sys.c
+++ b/drivers/staging/fsl-mc/bus/mc-sys.c
@@ -292,27 +292,22 @@ static inline enum mc_cmd_status mc_read_response(struct 
mc_command __iomem *
 }
 
 /**
- * Sends an command to the MC device using the given MC I/O object
+ * Waits for the completion of an MC command doing preemptible polling.
+ * uslepp_range() is called between polling iterations.
  *
  * @mc_io: MC I/O object to be used
- * @cmd: command to be sent
- *
- * Returns '0' on Success; Error code otherwise.
- *
- * NOTE: This function cannot be invoked from from atomic contexts.
+ * @cmd: command buffer to receive MC response
+ * @mc_status: MC command completion status
  */
-int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
+static int mc_polling_wait_preemptible(struct fsl_mc_io *mc_io,
+  struct mc_command *cmd,
+  enum mc_cmd_status *mc_status)
 {
enum mc_cmd_status status;
unsigned long jiffies_until_timeout =
jiffies + msecs_to_jiffies(MC_CMD_COMPLETION_TIMEOUT_MS);
 
/*
-* Send command to the MC hardware:
-*/
-   mc_write_command(mc_io->portal_virt_addr, cmd);
-
-   /*
 * Wait for response from the MC hardware:
 */
for (;;) {
@@ -339,6 +334,37 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct 
mc_command *cmd)
}
}
 
+   *mc_status = status;
+   return 0;
+}
+
+/**
+ * Sends a command to the MC device using the given MC I/O object
+ *
+ * @mc_io: MC I/O object to be used
+ * @cmd: command to be sent
+ *
+ * Returns '0' on Success; Error code otherwise.
+ *
+ * NOTE: This function cannot be invoked from from atomic contexts.
+ */
+int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
+{
+   int error;
+   enum mc_cmd_status status;
+
+   /*
+* Send command to the MC hardware:
+*/
+   mc_write_command(mc_io->portal_virt_addr, cmd);
+
+   /*
+* Wait for response from the MC hardware:
+*/
+   error = mc_polling_wait_preemptible(mc_io, cmd, &status);
+   if (error < 0)
+   return error;
+
if (status != MC_CMD_STATUS_OK) {
pr_debug("MC command failed: portal: %#llx, obj handle: %#x, 
command: %#x, status: %s (%#x)\n",
 mc_io->portal_phys_addr,
-- 
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/4] staging: fsl-mc: MC command serialization

2015-10-14 Thread J. German Rivera
This patch series depends on the patch series posted
at http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg996780.html

This patch series addresses the following item from the TODO list
for the MC bus driver to exit staging:

* Management Complex (MC) command serialization. Locking mechanisms
  are needed by drivers to serialize commands sent to the MC, including
  from atomic context.

Patch 1: Changed timeout units for MC cmd completion
Patch 2: Refactored mc_send_command()
Patch 3: Added support for atomic portals
Patch 4: Added serialization to mc_send_command()

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 4/4] staging: fsl-mc: Added serialization to mc_send_command()

2015-10-14 Thread J. German Rivera
When the same portal is used to call mc_send_command() from two
different threads or a thread and an interrupt handler, serialization
is required, as the MC only supports one outstanding command per MC
portal. Thus, a new command should not be sent to the MC until the
last command sent has been responded by the MC.

Signed-off-by: J. German Rivera 
---
 drivers/staging/fsl-mc/bus/mc-sys.c | 25 ++---
 drivers/staging/fsl-mc/include/mc-sys.h | 29 +
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c 
b/drivers/staging/fsl-mc/bus/mc-sys.c
index 6eeb9fa..6e14892 100644
--- a/drivers/staging/fsl-mc/bus/mc-sys.c
+++ b/drivers/staging/fsl-mc/bus/mc-sys.c
@@ -88,6 +88,11 @@ int __must_check fsl_create_mc_io(struct device *dev,
mc_io->flags = flags;
mc_io->portal_phys_addr = mc_portal_phys_addr;
mc_io->portal_size = mc_portal_size;
+   if (flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)
+   spin_lock_init(&mc_io->spinlock);
+   else
+   mutex_init(&mc_io->mutex);
+
res = devm_request_mem_region(dev,
  mc_portal_phys_addr,
  mc_portal_size,
@@ -391,11 +396,17 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct 
mc_command *cmd)
 {
int error;
enum mc_cmd_status status;
+   unsigned long irq_flags = 0;
 
if (WARN_ON(in_irq() &&
!(mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)))
return -EINVAL;
 
+   if (mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)
+   spin_lock_irqsave(&mc_io->spinlock, irq_flags);
+   else
+   mutex_lock(&mc_io->mutex);
+
/*
 * Send command to the MC hardware:
 */
@@ -410,7 +421,7 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct 
mc_command *cmd)
error = mc_polling_wait_atomic(mc_io, cmd, &status);
 
if (error < 0)
-   return error;
+   goto common_exit;
 
if (status != MC_CMD_STATUS_OK) {
pr_debug("MC command failed: portal: %#llx, obj handle: %#x, 
command: %#x, status: %s (%#x)\n",
@@ -420,9 +431,17 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct 
mc_command *cmd)
 mc_status_to_string(status),
 (unsigned int)status);
 
-   return mc_status_to_error(status);
+   error = mc_status_to_error(status);
+   goto common_exit;
}
 
-   return 0;
+   error = 0;
+common_exit:
+   if (mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)
+   spin_unlock_irqrestore(&mc_io->spinlock, irq_flags);
+   else
+   mutex_unlock(&mc_io->mutex);
+
+   return error;
 }
 EXPORT_SYMBOL(mc_send_command);
diff --git a/drivers/staging/fsl-mc/include/mc-sys.h 
b/drivers/staging/fsl-mc/include/mc-sys.h
index 15e19af..c5038cc 100644
--- a/drivers/staging/fsl-mc/include/mc-sys.h
+++ b/drivers/staging/fsl-mc/include/mc-sys.h
@@ -39,6 +39,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 /**
  * Bit masks for a MC I/O object (struct fsl_mc_io) flags
@@ -56,6 +58,20 @@ struct mc_command;
  * @portal_phys_addr: MC command portal physical address
  * @portal_virt_addr: MC command portal virtual address
  * @dpmcp_dev: pointer to the DPMCP device associated with the MC portal.
+ *
+ * Fields are only meaningful if the FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag is 
not
+ * set:
+ * @mutex: Mutex to serialize mc_send_command() calls that use the same MC
+ * portal, if the fsl_mc_io object was created with the
+ * FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag off. mc_send_command() calls for this
+ * fsl_mc_io object must be made only from non-atomic context.
+ *
+ * Fields are only meaningful if the FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag is
+ * set:
+ * @spinlock: Spinlock to serialize mc_send_command() calls that use the same 
MC
+ * portal, if the fsl_mc_io object was created with the
+ * FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag on. mc_send_command() calls for this
+ * fsl_mc_io object can be made from atomic or non-atomic context.
  */
 struct fsl_mc_io {
struct device *dev;
@@ -64,6 +80,19 @@ struct fsl_mc_io {
phys_addr_t portal_phys_addr;
void __iomem *portal_virt_addr;
struct fsl_mc_device *dpmcp_dev;
+   union {
+   /*
+* This field is only meaningful if the
+* FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag is not set
+*/
+   struct mutex mutex; /* serializes mc_send_command() */
+
+   /*
+* This field is only meaningful if the
+* FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag is set
+*/
+   spinlock_t spinlock;/* s

[PATCH 3/4] staging: fsl-mc:Added support for atomic portals

2015-10-14 Thread J. German Rivera
Refactored mc_send_command() to support two flavors of polling:
- preemptible (for non-atomic portals), which was already supported.
  It calls usleep_range() between polling iterations.
- non-preemptible (for atomic portals), which is needed when
  mc_send_command() is called with interrupts disabled.
  It calls udelay() between polling iterations.

Signed-off-by: J. German Rivera 
---
 drivers/staging/fsl-mc/bus/mc-sys.c | 53 +++--
 drivers/staging/fsl-mc/include/mc-sys.h |  5 
 2 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c 
b/drivers/staging/fsl-mc/bus/mc-sys.c
index c4f5bdd..6eeb9fa 100644
--- a/drivers/staging/fsl-mc/bus/mc-sys.c
+++ b/drivers/staging/fsl-mc/bus/mc-sys.c
@@ -339,20 +339,63 @@ static int mc_polling_wait_preemptible(struct fsl_mc_io 
*mc_io,
 }
 
 /**
+ * Waits for the completion of an MC command doing atomic polling.
+ * udelay() is called between polling iterations.
+ *
+ * @mc_io: MC I/O object to be used
+ * @cmd: command buffer to receive MC response
+ * @mc_status: MC command completion status
+ */
+static int mc_polling_wait_atomic(struct fsl_mc_io *mc_io,
+ struct mc_command *cmd,
+ enum mc_cmd_status *mc_status)
+{
+   enum mc_cmd_status status;
+   unsigned long timeout_usecs = MC_CMD_COMPLETION_TIMEOUT_MS * 1000;
+
+   BUILD_BUG_ON((MC_CMD_COMPLETION_TIMEOUT_MS * 1000) %
+MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS != 0);
+
+   for (;;) {
+   status = mc_read_response(mc_io->portal_virt_addr, cmd);
+   if (status != MC_CMD_STATUS_READY)
+   break;
+
+   udelay(MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS);
+   timeout_usecs -= MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS;
+   if (timeout_usecs == 0) {
+   pr_debug("MC command timed out (portal: %#llx, obj 
handle: %#x, command: %#x)\n",
+mc_io->portal_phys_addr,
+(unsigned int)
+   MC_CMD_HDR_READ_TOKEN(cmd->header),
+(unsigned int)
+   MC_CMD_HDR_READ_CMDID(cmd->header));
+
+   return -ETIMEDOUT;
+   }
+   }
+
+   *mc_status = status;
+   return 0;
+}
+
+/**
  * Sends a command to the MC device using the given MC I/O object
  *
  * @mc_io: MC I/O object to be used
  * @cmd: command to be sent
  *
  * Returns '0' on Success; Error code otherwise.
- *
- * NOTE: This function cannot be invoked from from atomic contexts.
  */
 int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
 {
int error;
enum mc_cmd_status status;
 
+   if (WARN_ON(in_irq() &&
+   !(mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)))
+   return -EINVAL;
+
/*
 * Send command to the MC hardware:
 */
@@ -361,7 +404,11 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct 
mc_command *cmd)
/*
 * Wait for response from the MC hardware:
 */
-   error = mc_polling_wait_preemptible(mc_io, cmd, &status);
+   if (!(mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL))
+   error = mc_polling_wait_preemptible(mc_io, cmd, &status);
+   else
+   error = mc_polling_wait_atomic(mc_io, cmd, &status);
+
if (error < 0)
return error;
 
diff --git a/drivers/staging/fsl-mc/include/mc-sys.h 
b/drivers/staging/fsl-mc/include/mc-sys.h
index 7d44d8c..15e19af 100644
--- a/drivers/staging/fsl-mc/include/mc-sys.h
+++ b/drivers/staging/fsl-mc/include/mc-sys.h
@@ -40,6 +40,11 @@
 #include 
 #include 
 
+/**
+ * Bit masks for a MC I/O object (struct fsl_mc_io) flags
+ */
+#define FSL_MC_IO_ATOMIC_CONTEXT_PORTAL0x0001
+
 struct fsl_mc_resource;
 struct mc_command;
 
-- 
2.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


  1   2   3   >