]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - rpmsg/rpmsg.git/commitdiff
soc: ti: pruss: add pruss_{request,release}_mem_region() API
authorAndrew F. Davis <afd@ti.com>
Mon, 11 Jan 2016 22:18:38 +0000 (16:18 -0600)
committerSuman 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>
drivers/soc/ti/pruss.c
include/linux/pruss.h
include/linux/pruss_driver.h

index b0ab89af64261dfb762f9ae5e7092994255c91f2..e80d1ad68aa2ce6027f569a75c6b29661438de7f 100644 (file)
@@ -93,6 +93,85 @@ void pruss_put(struct pruss *pruss)
 }
 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)
 {
@@ -143,6 +222,7 @@ static int pruss_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        pruss->dev = dev;
+       mutex_init(&pruss->lock);
 
        np = of_get_child_by_name(node, "cfg");
        if (!np) {
index 8bf0a4b751ceeb3b99744e59eef8f8f4fd39d5d2..5d0642f7abd96e0dc63d1bad88f62f45b74c9186 100644 (file)
@@ -33,6 +33,28 @@ enum pru_ctable_idx {
        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;
 
@@ -40,6 +62,10 @@ 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
@@ -51,6 +77,19 @@ static inline struct pruss *pruss_get(struct rproc *rproc)
 
 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)
@@ -9,6 +9,8 @@
 #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
@@ -60,6 +40,8 @@ struct pruss_intc_config {
  * @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;
@@ -67,6 +49,8 @@ struct pruss {
        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,