diff options
author | Miguel Vadillo <vadillo@ti.com> | 2011-06-30 18:40:19 -0500 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2011-07-20 17:34:33 -0700 |
commit | dbf3f62c5761f298cce9991b30a60dd08f76656f (patch) | |
tree | e04b5ee1b359493eee0f869727b9c8b18db462d8 | |
parent | 5efcea64f6ec141bad475535572765678a9b2631 (diff) | |
download | kernel_samsung_tuna-dbf3f62c5761f298cce9991b30a60dd08f76656f.zip kernel_samsung_tuna-dbf3f62c5761f298cce9991b30a60dd08f76656f.tar.gz kernel_samsung_tuna-dbf3f62c5761f298cce9991b30a60dd08f76656f.tar.bz2 |
remoteproc: add constraints framework
Add constraints api to remoteproc framework
supporting:
- Latency (Using pm_qos framework)
- Frequency
- Bandwidth
Each of them should be provided by the specific
architecture if supported.
Change-Id: Icddd9a8ee3c6c781e1a30817a2db8716428089ad
Signed-off-by: Miguel Vadillo <vadillo@ti.com>
Signed-off-by: Fernando Guzman Lugo <fernando.lugo@ti.com>
Signed-off-by: Suman Anna <s-anna@ti.com>
-rw-r--r-- | arch/arm/mach-omap2/remoteproc.c | 1 | ||||
-rw-r--r-- | drivers/remoteproc/remoteproc.c | 56 | ||||
-rw-r--r-- | include/linux/remoteproc.h | 12 |
3 files changed, 68 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/remoteproc.c b/arch/arm/mach-omap2/remoteproc.c index b9b4c35..5f5cec1 100644 --- a/arch/arm/mach-omap2/remoteproc.c +++ b/arch/arm/mach-omap2/remoteproc.c @@ -19,7 +19,6 @@ #include <linux/err.h> #include <linux/remoteproc.h> #include <linux/memblock.h> - #include <plat/omap_device.h> #include <plat/omap_hwmod.h> #include <plat/remoteproc.h> diff --git a/drivers/remoteproc/remoteproc.c b/drivers/remoteproc/remoteproc.c index 7753c92..cd03896 100644 --- a/drivers/remoteproc/remoteproc.c +++ b/drivers/remoteproc/remoteproc.c @@ -828,6 +828,50 @@ const struct dev_pm_ops rproc_gen_pm_ops = { SET_RUNTIME_PM_OPS(rproc_runtime_suspend, rproc_runtime_resume, NULL) }; #endif +int +rproc_set_constraints(struct rproc *rproc, enum rproc_constraint type, long v) +{ + int ret; + char *cname[] = {"scale", "latency", "bandwidth"}; + int (*func)(struct rproc *, long); + + switch (type) { + case RPROC_CONSTRAINT_SCALE: + func = rproc->ops->scale; + break; + case RPROC_CONSTRAINT_LATENCY: + func = rproc->ops->set_lat; + break; + case RPROC_CONSTRAINT_BANDWIDTH: + func = rproc->ops->set_bw; + break; + default: + dev_err(rproc->dev, "invalid constraint\n"); + return -EINVAL; + } + + if (!func) { + dev_err(rproc->dev, "%s: no %s constraint\n", + __func__, cname[type]); + return -EINVAL; + } + + mutex_lock(&rproc->lock); + if (rproc->state == RPROC_OFFLINE) { + pr_err("%s: rproc inactive\n", __func__); + mutex_unlock(&rproc->lock); + return -EPERM; + } + + dev_dbg(rproc->dev, "set %s constraint %ld\n", cname[type], v); + ret = func(rproc, v); + if (ret) + dev_err(rproc->dev, "error %s constraint\n", cname[type]); + mutex_unlock(&rproc->lock); + + return ret; +} +EXPORT_SYMBOL(rproc_set_constraints); int rproc_register(struct device *dev, const char *name, const struct rproc_ops *ops, @@ -864,6 +908,16 @@ int rproc_register(struct device *dev, const char *name, rproc->state = RPROC_OFFLINE; + rproc->qos_request = kzalloc(sizeof(*rproc->qos_request), + GFP_KERNEL); + if (!rproc->qos_request) { + kfree(rproc); + return -ENOMEM; + } + + pm_qos_add_request(rproc->qos_request, PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); + spin_lock(&rprocs_lock); list_add_tail(&rproc->next, &rprocs); spin_unlock(&rprocs_lock); @@ -914,6 +968,8 @@ int rproc_unregister(const char *name) list_del(&rproc->next); spin_unlock(&rprocs_lock); + pm_qos_remove_request(rproc->qos_request); + kfree(rproc->qos_request); kfree(rproc); return 0; diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 2dc9ec1..9fe9f0b 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -37,6 +37,7 @@ #include <linux/completion.h> #include <linux/workqueue.h> #include <linux/notifier.h> +#include <linux/pm_qos_params.h> /** * The following enums and structures define the binary format of the images @@ -108,6 +109,12 @@ struct rproc_mem_entry { u32 size; }; +enum rproc_constraint { + RPROC_CONSTRAINT_SCALE, + RPROC_CONSTRAINT_LATENCY, + RPROC_CONSTRAINT_BANDWIDTH, +}; + struct rproc; struct rproc_ops { @@ -117,6 +124,9 @@ struct rproc_ops { int (*resume)(struct rproc *rproc); int (*iommu_init)(struct rproc *, int (*)(struct rproc *, u64, u32)); int (*iommu_exit)(struct rproc *); + int (*set_lat)(struct rproc *rproc, long v); + int (*set_bw)(struct rproc *rproc, long v); + int (*scale)(struct rproc *rproc, long v); }; /* @@ -217,6 +227,7 @@ struct rproc { struct blocking_notifier_head nb_resume; struct mutex pm_lock; #endif + struct pm_qos_request_list *qos_request; }; struct rproc *rproc_get(const char *); @@ -234,5 +245,6 @@ extern const struct dev_pm_ops rproc_gen_pm_ops; #else #define GENERIC_RPROC_PM_OPS NULL #endif +int rproc_set_constraints(struct rproc *, enum rproc_constraint type, long v); #endif /* REMOTEPROC_H */ |