summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9b0caab)
raw | patch | inline | side by side (parent: 9b0caab)
author | Andrew F. Davis <afd@ti.com> | |
Mon, 11 Jan 2016 22:18:38 +0000 (16:18 -0600) | ||
committer | Suman Anna <s-anna@ti.com> | |
Sun, 24 Feb 2019 01:20:52 +0000 (19:20 -0600) |
Add two new API - pruss_request_mem_region() & pruss_release_mem_region(),
to the PRUSS platform driver to allow client drivers to acquire and release
the common memory resources present within a PRU-ICSS subsystem. This
allows the client drivers to directly manipulate the respective memories,
as per their design contract with the associated firmware.
Signed-off-by: Andrew F. Davis <afd@ti.com>
[s-anna@ti.com: rename functions, add error checking, comments]
Signed-off-by: Suman Anna <s-anna@ti.com>
to the PRUSS platform driver to allow client drivers to acquire and release
the common memory resources present within a PRU-ICSS subsystem. This
allows the client drivers to directly manipulate the respective memories,
as per their design contract with the associated firmware.
Signed-off-by: Andrew F. Davis <afd@ti.com>
[s-anna@ti.com: rename functions, add error checking, comments]
Signed-off-by: Suman Anna <s-anna@ti.com>
drivers/soc/ti/pruss.c | patch | blob | history | |
include/linux/pruss.h | patch | blob | history | |
include/linux/pruss_driver.h | patch | blob | history |
diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c
index b0ab89af64261dfb762f9ae5e7092994255c91f2..e80d1ad68aa2ce6027f569a75c6b29661438de7f 100644 (file)
--- a/drivers/soc/ti/pruss.c
+++ b/drivers/soc/ti/pruss.c
}
EXPORT_SYMBOL_GPL(pruss_put);
+/**
+ * pruss_request_mem_region() - request a memory resource
+ * @pruss: the pruss instance
+ * @mem_id: the memory resource id
+ * @region: pointer to memory region structure to be filled in
+ *
+ * This function allows a client driver to request a memory resource,
+ * and if successful, will let the client driver own the particular
+ * memory region until released using the pruss_release_mem_region()
+ * API.
+ *
+ * Returns the memory region if requested resource is available, an
+ * error otherwise
+ */
+int pruss_request_mem_region(struct pruss *pruss, enum pruss_mem mem_id,
+ struct pruss_mem_region *region)
+{
+ if (!pruss || !region)
+ return -EINVAL;
+
+ if (mem_id >= PRUSS_MEM_MAX)
+ return -EINVAL;
+
+ mutex_lock(&pruss->lock);
+
+ if (pruss->mem_in_use[mem_id]) {
+ mutex_unlock(&pruss->lock);
+ return -EBUSY;
+ }
+
+ *region = pruss->mem_regions[mem_id];
+ pruss->mem_in_use[mem_id] = region;
+
+ mutex_unlock(&pruss->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pruss_request_mem_region);
+
+/**
+ * pruss_release_mem_region() - release a memory resource
+ * @pruss: the pruss instance
+ * @region: the memory region to release
+ *
+ * This function is the complimentary function to
+ * pruss_request_mem_region(), and allows the client drivers to
+ * release back a memory resource.
+ *
+ * Returns 0 on success, an error code otherwise
+ */
+int pruss_release_mem_region(struct pruss *pruss,
+ struct pruss_mem_region *region)
+{
+ int id;
+
+ if (!pruss || !region)
+ return -EINVAL;
+
+ mutex_lock(&pruss->lock);
+
+ /* find out the memory region being released */
+ for (id = 0; id < PRUSS_MEM_MAX; id++) {
+ if (pruss->mem_in_use[id] == region)
+ break;
+ }
+
+ if (id == PRUSS_MEM_MAX) {
+ mutex_unlock(&pruss->lock);
+ return -EINVAL;
+ }
+
+ pruss->mem_in_use[id] = NULL;
+
+ mutex_unlock(&pruss->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pruss_release_mem_region);
+
static const
struct pruss_private_data *pruss_get_private_data(struct platform_device *pdev)
{
return -ENOMEM;
pruss->dev = dev;
+ mutex_init(&pruss->lock);
np = of_get_child_by_name(node, "cfg");
if (!np) {
diff --git a/include/linux/pruss.h b/include/linux/pruss.h
index 8bf0a4b751ceeb3b99744e59eef8f8f4fd39d5d2..5d0642f7abd96e0dc63d1bad88f62f45b74c9186 100644 (file)
--- a/include/linux/pruss.h
+++ b/include/linux/pruss.h
PRU_C31,
};
+/**
+ * enum pruss_mem - PRUSS memory range identifiers
+ */
+enum pruss_mem {
+ PRUSS_MEM_DRAM0 = 0,
+ PRUSS_MEM_DRAM1,
+ PRUSS_MEM_SHRD_RAM2,
+ PRUSS_MEM_MAX,
+};
+
+/**
+ * struct pruss_mem_region - PRUSS memory region structure
+ * @va: kernel virtual address of the PRUSS memory region
+ * @pa: physical (bus) address of the PRUSS memory region
+ * @size: size of the PRUSS memory region
+ */
+struct pruss_mem_region {
+ void __iomem *va;
+ phys_addr_t pa;
+ size_t size;
+};
+
struct rproc;
struct pruss;
struct pruss *pruss_get(struct rproc *rproc);
void pruss_put(struct pruss *pruss);
+int pruss_request_mem_region(struct pruss *pruss, enum pruss_mem mem_id,
+ struct pruss_mem_region *region);
+int pruss_release_mem_region(struct pruss *pruss,
+ struct pruss_mem_region *region);
int pruss_intc_trigger(unsigned int irq);
#else
static inline void pruss_put(struct pruss *pruss) { }
+static inline int pruss_request_mem_region(struct pruss *pruss,
+ enum pruss_mem mem_id,
+ struct pruss_mem_region *region)
+{
+ return -ENOTSUPP;
+}
+
+static inline int pruss_release_mem_region(struct pruss *pruss,
+ struct pruss_mem_region *region)
+{
+ return -ENOTSUPP;
+}
+
static inline int pruss_intc_trigger(unsigned int irq)
{
return -ENOTSUPP;
index fe7d513ea8e7322abc16aef070d3de342b64e291..318ae77df37ddcfda223aa94619df10d2fe12040 100644 (file)
#ifndef _PRUSS_DRIVER_H_
#define _PRUSS_DRIVER_H_
+#include <linux/pruss.h>
+
/* maximum number of system events */
#define MAX_PRU_SYS_EVENTS 64
/* maximum number of host interrupts */
#define MAX_PRU_HOST_INT 10
-/**
- * enum pruss_mem - PRUSS memory range identifiers
- */
-enum pruss_mem {
- PRUSS_MEM_DRAM0 = 0,
- PRUSS_MEM_DRAM1,
- PRUSS_MEM_SHRD_RAM2,
- PRUSS_MEM_MAX,
-};
-
-/**
- * struct pruss_mem_region - PRUSS memory region structure
- * @va: kernel virtual address of the PRUSS memory region
- * @pa: physical (bus) address of the PRUSS memory region
- * @size: size of the PRUSS memory region
- */
-struct pruss_mem_region {
- void __iomem *va;
- phys_addr_t pa;
- size_t size;
-};
-
/**
* struct pruss_intc_config - INTC configuration info
* @sysev_to_ch: system events to channel mapping information
* @iep: regmap for IEP sub-module
* @mii_rt: regmap for MII_RT sub-module
* @mem_regions: data for each of the PRUSS memory regions
+ * @mem_in_use: to indicate if memory resource is in use
+ * @lock: mutex to serialize access to resources
*/
struct pruss {
struct device *dev;
struct regmap *iep;
struct regmap *mii_rt;
struct pruss_mem_region mem_regions[PRUSS_MEM_MAX];
+ struct pruss_mem_region *mem_in_use[PRUSS_MEM_MAX];
+ struct mutex lock; /* PRU resource lock */
};
int pruss_intc_configure(struct pruss *pruss,