diff options
author | Juan Gutierrez <jgutierrez@ti.com> | 2012-07-18 11:35:30 -0500 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-01 12:58:54 +0200 |
commit | a5218624aba8105363aaeba30e1abcc9c8961dc6 (patch) | |
tree | 5673e9e7d0acda03af158c95ef4e92f9dcb79b31 /drivers/rpmsg | |
parent | 042c5a29f894a84bae794a44532bed4afa949d92 (diff) | |
download | kernel_samsung_tuna-a5218624aba8105363aaeba30e1abcc9c8961dc6.zip kernel_samsung_tuna-a5218624aba8105363aaeba30e1abcc9c8961dc6.tar.gz kernel_samsung_tuna-a5218624aba8105363aaeba30e1abcc9c8961dc6.tar.bz2 |
rpmsg: resmgr: add support for resource-data requests from rproc
Support has been added to the remote processor resource manager layer
to allow the remote processor to query for certain data associated
with a remote resource.
A request to query the maximum frequency for IVAHD and FDIF is
currently the only supported resource-data request. This information
is to be used to help the remote processor application code make power
and performance related policy decisions for different usecases.
Change-Id: I644a7603d3e493de4d5669e8994b9809e808e8a0
Signed-off-by: Juan Gutierrez <jgutierrez@ti.com>
Signed-off-by: Paul Hunt <hunt@ti.com>
Signed-off-by: Fernando Guzman Lugo <fernando.lugo@ti.com>
Signed-off-by: Suman Anna <s-anna@ti.com>
Diffstat (limited to 'drivers/rpmsg')
-rw-r--r-- | drivers/rpmsg/rpmsg_resmgr.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/drivers/rpmsg/rpmsg_resmgr.c b/drivers/rpmsg/rpmsg_resmgr.c index d945a4b..94738d0 100644 --- a/drivers/rpmsg/rpmsg_resmgr.c +++ b/drivers/rpmsg/rpmsg_resmgr.c @@ -897,6 +897,71 @@ out: return ret; } +static int _request_max_freq(struct rprm_elem *e, unsigned long *freq) +{ + int ret = 0; + + switch (e->type) { + case RPRM_IVAHD: + case RPRM_FDIF: + *freq = rpres_get_max_freq(e->handle); + break; + default: + pr_err("%s: not supported for resource type %d!\n", + __func__, e->type); + ret = -EINVAL; + break; + } + + return ret; +} + +static int _request_data(struct rprm_elem *e, int type, void *data, int len) +{ + int ret = 0; + + switch (type) { + case RPRM_MAX_FREQ: + if (len != sizeof(unsigned long)) { + ret = -EINVAL; + break; + } + ret = _request_max_freq(e, data); + break; + default: + pr_err("%s: invalid data request %d!\n", __func__, type); + ret = -EINVAL; + break; + } + + return ret; +} + +static int rprm_req_data(struct rprm *rprm, u32 addr, int res_id, + void *data, int len) +{ + int ret = 0; + struct rprm_elem *e; + struct rprm_request_data *rd = data; + + mutex_lock(&rprm->lock); + if (!idr_find(&rprm->conn_list, addr)) { + ret = -ENOTCONN; + goto out; + } + + e = idr_find(&rprm->id_list, res_id); + if (!e || e->src != addr) { + ret = -ENOENT; + goto out; + } + + ret = _request_data(e, rd->type, rd->data, len - sizeof(*rd)); +out: + mutex_unlock(&rprm->lock); + return ret; +} + static void rprm_cb(struct rpmsg_channel *rpdev, void *data, int len, void *priv, u32 src) { @@ -965,6 +1030,17 @@ static void rprm_cb(struct rpmsg_channel *rpdev, void *data, int len, if (ret) dev_err(dev, "rel constraints failed! ret %d\n", ret); return; + case RPRM_REQ_DATA: + r_sz = len - sizeof(*req); + if (r_sz < 0) { + r_sz = 0; + ret = -EINVAL; + break; + } + ret = rprm_req_data(rprm, src, req->res_id, req->data, r_sz); + if (ret) + dev_err(dev, "request data failed! ret %d\n", ret); + break; default: dev_err(dev, "Unknow request\n"); ret = -EINVAL; |