aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.4/7147-staging-fsl-mc-Extended-MC-bus-allocator-to-include-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.4/7147-staging-fsl-mc-Extended-MC-bus-allocator-to-include-.patch')
-rw-r--r--target/linux/layerscape/patches-4.4/7147-staging-fsl-mc-Extended-MC-bus-allocator-to-include-.patch326
1 files changed, 0 insertions, 326 deletions
diff --git a/target/linux/layerscape/patches-4.4/7147-staging-fsl-mc-Extended-MC-bus-allocator-to-include-.patch b/target/linux/layerscape/patches-4.4/7147-staging-fsl-mc-Extended-MC-bus-allocator-to-include-.patch
deleted file mode 100644
index c02c892b21..0000000000
--- a/target/linux/layerscape/patches-4.4/7147-staging-fsl-mc-Extended-MC-bus-allocator-to-include-.patch
+++ /dev/null
@@ -1,326 +0,0 @@
-From 23b09c6b4162a8264b600f35d7048256a7afc0cd Mon Sep 17 00:00:00 2001
-From: "J. German Rivera" <German.Rivera@freescale.com>
-Date: Wed, 6 Jan 2016 16:03:23 -0600
-Subject: [PATCH 147/226] staging: fsl-mc: Extended MC bus allocator to
- include IRQs
-
-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 <German.Rivera@freescale.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- 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(+)
-
---- 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 <linux/msi.h>
-
- /**
- * fsl_mc_resource_pool_add_device - add allocatable device to a resource
-@@ -160,6 +161,7 @@ static const char *const fsl_mc_pool_typ
- [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_de
- }
- 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 given MC object device. The
-+ * IRQs are allocated from the interrupt pool associated with the
-+ * MC bus that contains the device, if the device is not a DPRC device.
-+ * Otherwise, the IRQs are allocated from the interrupt pool associated
-+ * with the MC bus that represents the DPRC device itself.
-+ */
-+int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev)
-+{
-+ int i;
-+ int irq_count;
-+ int res_allocated_count = 0;
-+ int error = -EINVAL;
-+ struct fsl_mc_device_irq **irqs = NULL;
-+ struct fsl_mc_bus *mc_bus;
-+ struct fsl_mc_resource_pool *res_pool;
-+
-+ if (WARN_ON(mc_dev->irqs))
-+ return -EINVAL;
-+
-+ irq_count = mc_dev->obj_desc.irq_count;
-+ if (WARN_ON(irq_count == 0))
-+ return -EINVAL;
-+
-+ if (strcmp(mc_dev->obj_desc.type, "dprc") == 0)
-+ mc_bus = to_fsl_mc_bus(mc_dev);
-+ else
-+ mc_bus = to_fsl_mc_bus(to_fsl_mc_device(mc_dev->dev.parent));
-+
-+ if (WARN_ON(!mc_bus->irq_resources))
-+ return -EINVAL;
-+
-+ res_pool = &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
-+ if (res_pool->free_count < irq_count) {
-+ dev_err(&mc_dev->dev,
-+ "Not able to allocate %u irqs for device\n", irq_count);
-+ return -ENOSPC;
-+ }
-+
-+ irqs = devm_kzalloc(&mc_dev->dev, irq_count * sizeof(irqs[0]),
-+ GFP_KERNEL);
-+ if (!irqs)
-+ return -ENOMEM;
-+
-+ for (i = 0; i < irq_count; i++) {
-+ struct fsl_mc_resource *resource;
-+
-+ error = fsl_mc_resource_allocate(mc_bus, FSL_MC_POOL_IRQ,
-+ &resource);
-+ if (error < 0)
-+ goto error_resource_alloc;
-+
-+ irqs[i] = to_fsl_mc_irq(resource);
-+ res_allocated_count++;
-+
-+ WARN_ON(irqs[i]->mc_dev);
-+ irqs[i]->mc_dev = mc_dev;
-+ irqs[i]->dev_irq_index = i;
-+ }
-+
-+ mc_dev->irqs = irqs;
-+ return 0;
-+
-+error_resource_alloc:
-+ for (i = 0; i < res_allocated_count; i++) {
-+ irqs[i]->mc_dev = NULL;
-+ fsl_mc_resource_free(&irqs[i]->resource);
-+ }
-+
-+ return error;
-+}
-+EXPORT_SYMBOL_GPL(fsl_mc_allocate_irqs);
-+
-+/*
-+ * It frees the IRQs that were allocated for a MC object device, by
-+ * returning them to the corresponding interrupt pool.
-+ */
-+void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev)
-+{
-+ int i;
-+ int irq_count;
-+ struct fsl_mc_bus *mc_bus;
-+ struct fsl_mc_device_irq **irqs = mc_dev->irqs;
-+
-+ if (WARN_ON(!irqs))
-+ return;
-+
-+ irq_count = mc_dev->obj_desc.irq_count;
-+
-+ if (strcmp(mc_dev->obj_desc.type, "dprc") == 0)
-+ mc_bus = to_fsl_mc_bus(mc_dev);
-+ else
-+ mc_bus = to_fsl_mc_bus(to_fsl_mc_device(mc_dev->dev.parent));
-+
-+ if (WARN_ON(!mc_bus->irq_resources))
-+ return;
-+
-+ for (i = 0; i < irq_count; i++) {
-+ WARN_ON(!irqs[i]->mc_dev);
-+ irqs[i]->mc_dev = NULL;
-+ fsl_mc_resource_free(&irqs[i]->resource);
-+ }
-+
-+ mc_dev->irqs = NULL;
-+}
-+EXPORT_SYMBOL_GPL(fsl_mc_free_irqs);
-+
- /**
- * fsl_mc_allocator_probe - callback invoked when an allocatable device is
- * being added to the system
---- a/drivers/staging/fsl-mc/include/mc-private.h
-+++ b/drivers/staging/fsl-mc/include/mc-private.h
-@@ -30,6 +30,16 @@ struct irq_domain;
- struct msi_domain_info;
-
- /**
-+ * Maximum number of total IRQs that can be pre-allocated for an MC bus'
-+ * IRQ pool
-+ */
-+#define FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS 256
-+
-+struct device_node;
-+struct irq_domain;
-+struct msi_domain_info;
-+
-+/**
- * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device
- * @root_mc_bus_dev: MC object device representing the root DPRC
- * @num_translation_ranges: number of entries in addr_translation_ranges
-@@ -137,4 +147,9 @@ int __init its_fsl_mc_msi_init(void);
-
- void its_fsl_mc_msi_cleanup(void);
-
-+int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
-+ unsigned int irq_count);
-+
-+void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus);
-+
- #endif /* _FSL_MC_PRIVATE_H_ */
---- a/drivers/staging/fsl-mc/include/mc.h
-+++ b/drivers/staging/fsl-mc/include/mc.h
-@@ -14,12 +14,14 @@
- #include <linux/device.h>
- #include <linux/mod_devicetable.h>
- #include <linux/list.h>
-+#include <linux/interrupt.h>
- #include "../include/dprc.h"
-
- #define FSL_MC_VENDOR_FREESCALE 0x1957
-
- struct fsl_mc_device;
- struct fsl_mc_io;
-+struct fsl_mc_bus;
-
- /**
- * struct fsl_mc_driver - MC object device driver object
-@@ -75,6 +77,7 @@ enum fsl_mc_pool_type {
- FSL_MC_POOL_DPMCP = 0x0, /* corresponds to "dpmcp" in the MC */
- FSL_MC_POOL_DPBP, /* corresponds to "dpbp" in the MC */
- FSL_MC_POOL_DPCON, /* corresponds to "dpcon" in the MC */
-+ FSL_MC_POOL_IRQ,
-
- /*
- * NOTE: New resource pool types must be added before this entry
-@@ -141,6 +144,7 @@ struct fsl_mc_device_irq {
- * NULL if none.
- * @obj_desc: MC description of the DPAA device
- * @regions: pointer to array of MMIO region entries
-+ * @irqs: pointer to array of pointers to interrupts allocated to this device
- * @resource: generic resource associated with this MC object device, if any.
- *
- * Generic device object for MC object devices that are "attached" to a
-@@ -172,6 +176,7 @@ struct fsl_mc_device {
- struct fsl_mc_io *mc_io;
- struct dprc_obj_desc obj_desc;
- struct resource *regions;
-+ struct fsl_mc_device_irq **irqs;
- struct fsl_mc_resource *resource;
- };
-
-@@ -215,6 +220,10 @@ int __must_check fsl_mc_object_allocate(
-
- void fsl_mc_object_free(struct fsl_mc_device *mc_adev);
-
-+int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev);
-+
-+void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev);
-+
- extern struct bus_type fsl_mc_bus_type;
-
- #endif /* _FSL_MC_H_ */