mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 06:31:52 +00:00
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>
This commit is contained in:
parent
67d1b0a103
commit
b789ca1e33
@ -92,6 +92,82 @@ 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.
|
||||
*
|
||||
* Return: 0 if requested memory region is available (in such case pointer to
|
||||
* memory region is returned via @region), an error otherwise
|
||||
*/
|
||||
int pruss_request_mem_region(struct pruss *pruss, enum pruss_mem mem_id,
|
||||
struct pruss_mem_region *region)
|
||||
{
|
||||
if (!pruss || !region || 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.
|
||||
*
|
||||
* Return: 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 void pruss_of_free_clk_provider(void *data)
|
||||
{
|
||||
struct device_node *clk_mux_np = data;
|
||||
@ -298,6 +374,7 @@ static int pruss_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
pruss->dev = dev;
|
||||
mutex_init(&pruss->lock);
|
||||
|
||||
child = of_get_child_by_name(np, "memories");
|
||||
if (!child) {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#ifndef _PRUSS_DRIVER_H_
|
||||
#define _PRUSS_DRIVER_H_
|
||||
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/remoteproc/pruss.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/err.h>
|
||||
@ -41,6 +42,8 @@ struct pruss_mem_region {
|
||||
* @cfg_base: base iomap for CFG region
|
||||
* @cfg_regmap: regmap for config region
|
||||
* @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
|
||||
* @core_clk_mux: clk handle for PRUSS CORE_CLK_MUX
|
||||
* @iep_clk_mux: clk handle for PRUSS IEP_CLK_MUX
|
||||
*/
|
||||
@ -49,6 +52,8 @@ struct pruss {
|
||||
void __iomem *cfg_base;
|
||||
struct regmap *cfg_regmap;
|
||||
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 */
|
||||
struct clk *core_clk_mux;
|
||||
struct clk *iep_clk_mux;
|
||||
};
|
||||
@ -57,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);
|
||||
|
||||
#else
|
||||
|
||||
@ -67,6 +76,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 -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int pruss_release_mem_region(struct pruss *pruss,
|
||||
struct pruss_mem_region *region)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TI_PRUSS */
|
||||
|
||||
#endif /* _PRUSS_DRIVER_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user