Skip to content

Commit b789ca1

Browse files
glneonmenon
authored andcommitted
soc: ti: pruss: Add pruss_{request,release}_mem_region() API
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. Co-developed-by: Suman Anna <s-anna@ti.com> Signed-off-by: Suman Anna <s-anna@ti.com> Signed-off-by: Andrew F. Davis <afd@ti.com> Co-developed-by: Grzegorz Jaszczyk <grzegorz.jaszczyk@linaro.org> Signed-off-by: Grzegorz Jaszczyk <grzegorz.jaszczyk@linaro.org> Reviewed-by: Roger Quadros <rogerq@kernel.org> Acked-by: Mathieu Poirier <mathieu.poirier@linaro.org> Reviewed-by: Tony Lindgren <tony@atomide.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: MD Danish Anwar <danishanwar@ti.com> Link: https://lore.kernel.org/r/20230414045542.3249939-3-danishanwar@ti.com Signed-off-by: Nishanth Menon <nm@ti.com>
1 parent 67d1b0a commit b789ca1

2 files changed

Lines changed: 99 additions & 0 deletions

File tree

drivers/soc/ti/pruss.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,82 @@ void pruss_put(struct pruss *pruss)
9292
}
9393
EXPORT_SYMBOL_GPL(pruss_put);
9494

95+
/**
96+
* pruss_request_mem_region() - request a memory resource
97+
* @pruss: the pruss instance
98+
* @mem_id: the memory resource id
99+
* @region: pointer to memory region structure to be filled in
100+
*
101+
* This function allows a client driver to request a memory resource,
102+
* and if successful, will let the client driver own the particular
103+
* memory region until released using the pruss_release_mem_region()
104+
* API.
105+
*
106+
* Return: 0 if requested memory region is available (in such case pointer to
107+
* memory region is returned via @region), an error otherwise
108+
*/
109+
int pruss_request_mem_region(struct pruss *pruss, enum pruss_mem mem_id,
110+
struct pruss_mem_region *region)
111+
{
112+
if (!pruss || !region || mem_id >= PRUSS_MEM_MAX)
113+
return -EINVAL;
114+
115+
mutex_lock(&pruss->lock);
116+
117+
if (pruss->mem_in_use[mem_id]) {
118+
mutex_unlock(&pruss->lock);
119+
return -EBUSY;
120+
}
121+
122+
*region = pruss->mem_regions[mem_id];
123+
pruss->mem_in_use[mem_id] = region;
124+
125+
mutex_unlock(&pruss->lock);
126+
127+
return 0;
128+
}
129+
EXPORT_SYMBOL_GPL(pruss_request_mem_region);
130+
131+
/**
132+
* pruss_release_mem_region() - release a memory resource
133+
* @pruss: the pruss instance
134+
* @region: the memory region to release
135+
*
136+
* This function is the complimentary function to
137+
* pruss_request_mem_region(), and allows the client drivers to
138+
* release back a memory resource.
139+
*
140+
* Return: 0 on success, an error code otherwise
141+
*/
142+
int pruss_release_mem_region(struct pruss *pruss,
143+
struct pruss_mem_region *region)
144+
{
145+
int id;
146+
147+
if (!pruss || !region)
148+
return -EINVAL;
149+
150+
mutex_lock(&pruss->lock);
151+
152+
/* find out the memory region being released */
153+
for (id = 0; id < PRUSS_MEM_MAX; id++) {
154+
if (pruss->mem_in_use[id] == region)
155+
break;
156+
}
157+
158+
if (id == PRUSS_MEM_MAX) {
159+
mutex_unlock(&pruss->lock);
160+
return -EINVAL;
161+
}
162+
163+
pruss->mem_in_use[id] = NULL;
164+
165+
mutex_unlock(&pruss->lock);
166+
167+
return 0;
168+
}
169+
EXPORT_SYMBOL_GPL(pruss_release_mem_region);
170+
95171
static void pruss_of_free_clk_provider(void *data)
96172
{
97173
struct device_node *clk_mux_np = data;
@@ -298,6 +374,7 @@ static int pruss_probe(struct platform_device *pdev)
298374
return -ENOMEM;
299375

300376
pruss->dev = dev;
377+
mutex_init(&pruss->lock);
301378

302379
child = of_get_child_by_name(np, "memories");
303380
if (!child) {

include/linux/pruss_driver.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef _PRUSS_DRIVER_H_
1010
#define _PRUSS_DRIVER_H_
1111

12+
#include <linux/mutex.h>
1213
#include <linux/remoteproc/pruss.h>
1314
#include <linux/types.h>
1415
#include <linux/err.h>
@@ -41,6 +42,8 @@ struct pruss_mem_region {
4142
* @cfg_base: base iomap for CFG region
4243
* @cfg_regmap: regmap for config region
4344
* @mem_regions: data for each of the PRUSS memory regions
45+
* @mem_in_use: to indicate if memory resource is in use
46+
* @lock: mutex to serialize access to resources
4447
* @core_clk_mux: clk handle for PRUSS CORE_CLK_MUX
4548
* @iep_clk_mux: clk handle for PRUSS IEP_CLK_MUX
4649
*/
@@ -49,6 +52,8 @@ struct pruss {
4952
void __iomem *cfg_base;
5053
struct regmap *cfg_regmap;
5154
struct pruss_mem_region mem_regions[PRUSS_MEM_MAX];
55+
struct pruss_mem_region *mem_in_use[PRUSS_MEM_MAX];
56+
struct mutex lock; /* PRU resource lock */
5257
struct clk *core_clk_mux;
5358
struct clk *iep_clk_mux;
5459
};
@@ -57,6 +62,10 @@ struct pruss {
5762

5863
struct pruss *pruss_get(struct rproc *rproc);
5964
void pruss_put(struct pruss *pruss);
65+
int pruss_request_mem_region(struct pruss *pruss, enum pruss_mem mem_id,
66+
struct pruss_mem_region *region);
67+
int pruss_release_mem_region(struct pruss *pruss,
68+
struct pruss_mem_region *region);
6069

6170
#else
6271

@@ -67,6 +76,19 @@ static inline struct pruss *pruss_get(struct rproc *rproc)
6776

6877
static inline void pruss_put(struct pruss *pruss) { }
6978

79+
static inline int pruss_request_mem_region(struct pruss *pruss,
80+
enum pruss_mem mem_id,
81+
struct pruss_mem_region *region)
82+
{
83+
return -EOPNOTSUPP;
84+
}
85+
86+
static inline int pruss_release_mem_region(struct pruss *pruss,
87+
struct pruss_mem_region *region)
88+
{
89+
return -EOPNOTSUPP;
90+
}
91+
7092
#endif /* CONFIG_TI_PRUSS */
7193

7294
#endif /* _PRUSS_DRIVER_H_ */

0 commit comments

Comments
 (0)