aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rpmsg
diff options
context:
space:
mode:
authorJuan Gutierrez <jgutierrez@ti.com>2012-07-18 11:35:30 -0500
committerZiyann <jaraidaniel@gmail.com>2014-10-01 12:58:54 +0200
commita5218624aba8105363aaeba30e1abcc9c8961dc6 (patch)
tree5673e9e7d0acda03af158c95ef4e92f9dcb79b31 /drivers/rpmsg
parent042c5a29f894a84bae794a44532bed4afa949d92 (diff)
downloadkernel_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.c76
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;