ARM: cpu topology: Add debugfs interface for cpu_power
[cmplus.git] / drivers / rpmsg / rpmsg_resmgr.c
bloba13094dc3b26d3efc5322d9fd8c28569e97b418d
1 /*
2 * Remote processor resource manager
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Copyright (C) 2011 Google, Inc.
7 * Fernando Guzman Lugo <fernando.lugo@ti.com>
8 * Miguel Vadillo <vadillo@ti.com>
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/virtio.h>
19 #include <linux/slab.h>
20 #include <linux/rpmsg.h>
21 #include <linux/delay.h>
22 #include <linux/idr.h>
23 #include <linux/remoteproc.h>
24 #include <linux/clk.h>
25 #include <linux/regulator/consumer.h>
26 #include <linux/regulator/driver.h>
27 #include <linux/regulator/machine.h>
28 #include <linux/gpio.h>
29 #include <linux/err.h>
30 #include <linux/list.h>
31 #include <linux/debugfs.h>
32 #include <linux/rpmsg_resmgr.h>
33 #include <linux/pm_runtime.h>
34 #include <plat/dmtimer.h>
35 #include <plat/rpres.h>
36 #include <plat/clock.h>
37 #include <plat/dma.h>
38 #include <plat/i2c.h>
39 #include <plat/omap_hwmod.h>
41 #define NAME_SIZE 50
42 #define REGULATOR_MAX 1
43 #define NUM_SRC_CLK 3
44 #define AUX_CLK_MIN 0
45 #define AUX_CLK_MAX 5
46 #define GPTIMERS_MAX 11
47 #define MHZ 1000000
48 #define MAX_MSG (sizeof(struct rprm_ack) + sizeof(struct rprm_sdma))
50 static struct dentry *rprm_dbg;
52 static char *regulator_name[] = {
53 "cam2pwr"
56 static char *clk_src_name[] = {
57 "sys_clkin_ck",
58 "dpll_core_m3x2_ck",
59 "dpll_per_m3x2_ck",
62 static const char const *rnames[] = {
63 [RPRM_GPTIMER] = "GP Timer",
64 [RPRM_L3BUS] = "L3 bus",
65 [RPRM_IVAHD] = "IVA HD",
66 [RPRM_IVASEQ0] = "IVA SEQ0",
67 [RPRM_IVASEQ1] = "IVA SEQ1",
68 [RPRM_ISS] = "ISS",
69 [RPRM_SL2IF] = "SL2IF",
70 [RPRM_FDIF] = "FDIF",
71 [RPRM_AUXCLK] = "AUXCLK",
72 [RPRM_REGULATOR] = "REGULATOR",
73 [RPRM_GPIO] = "GPIO",
74 [RPRM_SDMA] = "SDMA",
75 [RPRM_IPU] = "IPU",
76 [RPRM_DSP] = "DSP",
77 [RPRM_I2C] = "I2C",
80 static const char *rname(u32 type) {
81 if (type >= RPRM_MAX)
82 return "(invalid)";
83 return rnames[type];
86 struct rprm_elem {
87 struct list_head next;
88 u32 src;
89 u32 type;
90 u32 id;
91 void *handle;
92 u32 base;
93 struct rprm_constraints_data *constraints;
94 char res[];
97 struct rprm {
98 struct list_head res_list;
99 struct idr conn_list;
100 struct idr id_list;
101 struct mutex lock;
102 struct dentry *dbg_dir;
105 struct rprm_auxclk_depot {
106 struct clk *aux_clk;
107 struct clk *src;
110 struct rprm_regulator_depot {
111 struct regulator *reg_p;
112 u32 orig_uv;
115 static struct rprm_constraints_data def_data = {
116 .frequency = 0,
117 .bandwidth = -1,
118 .latency = -1,
121 static int _get_rprm_size(u32 type)
123 switch (type) {
124 case RPRM_GPTIMER:
125 return sizeof(struct rprm_gpt);
126 case RPRM_AUXCLK:
127 return sizeof(struct rprm_auxclk);
128 case RPRM_REGULATOR:
129 return sizeof(struct rprm_regulator);
130 case RPRM_GPIO:
131 return sizeof(struct rprm_gpio);
132 case RPRM_SDMA:
133 return sizeof(struct rprm_sdma);
134 case RPRM_I2C:
135 return sizeof(struct rprm_i2c);
137 return 0;
140 static int rprm_gptimer_request(struct rprm_elem *e, struct rprm_gpt *obj)
142 int ret;
143 struct omap_dm_timer *gpt;
145 if (obj->id > GPTIMERS_MAX) {
146 pr_err("Invalid gptimer %u\n", obj->id);
147 return -EINVAL;
150 gpt = omap_dm_timer_request_specific(obj->id);
151 if (!gpt)
152 return -EBUSY;
154 ret = omap_dm_timer_set_source(gpt, obj->src_clk);
155 if (!ret)
156 e->handle = gpt;
157 else
158 omap_dm_timer_free(gpt);
160 return ret;
163 static void rprm_gptimer_release(struct omap_dm_timer *obj)
165 omap_dm_timer_free(obj);
168 static int rprm_auxclk_request(struct rprm_elem *e, struct rprm_auxclk *obj)
170 int ret;
171 char clk_name[NAME_SIZE];
172 char src_clk_name[NAME_SIZE];
173 struct rprm_auxclk_depot *acd;
174 struct clk *src_parent;
176 if ((obj->id < AUX_CLK_MIN) || (obj->id > AUX_CLK_MAX)) {
177 pr_err("Invalid aux_clk %d\n", obj->id);
178 return -EINVAL;
181 /* Create auxclks depot */
182 acd = kmalloc(sizeof(*acd), GFP_KERNEL);
183 if (!acd)
184 return -ENOMEM;
186 sprintf(clk_name, "auxclk%d_ck", obj->id);
187 acd->aux_clk = clk_get(NULL, clk_name);
188 if (!acd->aux_clk) {
189 pr_err("%s: unable to get clock %s\n", __func__, clk_name);
190 ret = -EIO;
191 goto error;
194 if (unlikely(acd->aux_clk->usecount))
195 pr_warn("There are other users of %d clk\n", obj->id);
197 sprintf(src_clk_name, "auxclk%d_src_ck", obj->id);
198 acd->src = clk_get(NULL, src_clk_name);
199 if (!acd->src) {
200 pr_err("%s: unable to get clock %s\n", __func__, src_clk_name);
201 ret = -EIO;
202 goto error_aux;
205 src_parent = clk_get(NULL, clk_src_name[obj->parent_src_clk]);
206 if (!src_parent) {
207 pr_err("%s: unable to get parent clock %s\n", __func__,
208 clk_src_name[obj->parent_src_clk]);
209 ret = -EIO;
210 goto error_aux_src;
213 ret = clk_set_rate(src_parent, (obj->parent_src_clk_rate * MHZ));
214 if (ret) {
215 pr_err("%s: rate not supported by %s\n", __func__,
216 clk_src_name[obj->parent_src_clk]);
217 ret = -EINVAL;
218 goto error_aux_src_parent;
221 ret = clk_set_parent(acd->src, src_parent);
222 if (ret) {
223 pr_err("%s: unable to set clk %s as parent of aux_clk %s\n",
224 __func__,
225 clk_src_name[obj->parent_src_clk],
226 src_clk_name);
227 goto error_aux_src_parent;
230 ret = clk_enable(acd->src);
231 if (ret) {
232 pr_err("%s: error enabling %s\n", __func__, src_clk_name);
233 goto error_aux_src_parent;
236 ret = clk_set_rate(acd->aux_clk, (obj->clk_rate * MHZ));
237 if (ret) {
238 pr_err("%s: rate not supported by %s\n", __func__, clk_name);
239 goto error_aux_src_parent;
242 ret = clk_enable(acd->aux_clk);
243 if (ret) {
244 pr_err("%s: error enabling %s\n", __func__, clk_name);
245 goto error_aux_enable;
247 clk_put(src_parent);
249 e->handle = acd;
251 return 0;
252 error_aux_enable:
253 clk_disable(acd->src);
254 error_aux_src_parent:
255 clk_put(src_parent);
256 error_aux_src:
257 clk_put(acd->src);
258 error_aux:
259 clk_put(acd->aux_clk);
260 error:
261 kfree(acd);
263 return ret;
266 static void rprm_auxclk_release(struct rprm_auxclk_depot *obj)
268 clk_disable((struct clk *)obj->aux_clk);
269 clk_put((struct clk *)obj->aux_clk);
270 clk_disable((struct clk *)obj->src);
271 clk_put((struct clk *)obj->src);
273 kfree(obj);
276 static
277 int rprm_regulator_request(struct rprm_elem *e, struct rprm_regulator *obj)
279 int ret;
280 struct rprm_regulator_depot *rd;
281 char *reg_name;
283 if (obj->id > REGULATOR_MAX) {
284 pr_err("Invalid regulator %d\n", obj->id);
285 return -EINVAL;
288 /* Create regulator depot */
289 rd = kmalloc(sizeof(*rd), GFP_KERNEL);
290 if (!rd)
291 return -ENOMEM;
293 reg_name = regulator_name[obj->id - 1];
294 rd->reg_p = regulator_get_exclusive(NULL, reg_name);
295 if (IS_ERR_OR_NULL(rd->reg_p)) {
296 pr_err("%s: error providing regulator %s\n", __func__, reg_name);
297 ret = -EINVAL;
298 goto error;
301 rd->orig_uv = regulator_get_voltage(rd->reg_p);
303 ret = regulator_set_voltage(rd->reg_p, obj->min_uv, obj->max_uv);
304 if (ret) {
305 pr_err("%s: error setting %s voltage\n", __func__, reg_name);
306 goto error_reg;
309 ret = regulator_enable(rd->reg_p);
310 if (ret) {
311 pr_err("%s: error enabling %s ldo\n", __func__, reg_name);
312 goto error_reg;
315 e->handle = rd;
317 return 0;
319 error_reg:
320 regulator_put(rd->reg_p);
321 error:
322 kfree(rd);
324 return ret;
327 static void rprm_regulator_release(struct rprm_regulator_depot *obj)
329 int ret;
331 ret = regulator_disable(obj->reg_p);
332 if (ret) {
333 pr_err("%s: error disabling ldo\n", __func__);
334 return;
337 /* Restore orginal voltage */
338 ret = regulator_set_voltage(obj->reg_p, obj->orig_uv, obj->orig_uv);
339 if (ret) {
340 pr_err("%s: error restoring voltage\n", __func__);
341 return;
344 regulator_put(obj->reg_p);
345 kfree(obj);
348 static int rprm_gpio_request(struct rprm_elem *e, struct rprm_gpio *obj)
350 int ret;
351 struct rprm_gpio *gd;
353 /* Create gpio depot */
354 gd = kmalloc(sizeof(*gd), GFP_KERNEL);
355 if (!gd)
356 return -ENOMEM;
358 ret = gpio_request(obj->id , "rpmsg_resmgr");
359 if (ret) {
360 pr_err("%s: error providing gpio %d\n", __func__, obj->id);
361 return ret;
364 e->handle = memcpy(gd, obj, sizeof(*obj));
366 return ret;
369 static void rprm_gpio_release(struct rprm_gpio *obj)
371 gpio_free(obj->id);
372 kfree(obj);
375 static int rprm_sdma_request(struct rprm_elem *e, struct rprm_sdma *obj)
377 int ret;
378 int sdma;
379 int i;
380 struct rprm_sdma *sd;
382 /* Create sdma depot */
383 sd = kmalloc(sizeof(*sd), GFP_KERNEL);
384 if (!sd)
385 return -ENOMEM;
387 if (obj->num_chs > MAX_NUM_SDMA_CHANNELS) {
388 pr_err("Not able to provide %u channels\n", obj->num_chs);
389 return -EINVAL;
392 for (i = 0; i < obj->num_chs; i++) {
393 ret = omap_request_dma(0, "rpmsg_resmgr", NULL, NULL, &sdma);
394 if (ret) {
395 pr_err("Error providing sdma channel %d\n", ret);
396 goto err;
398 obj->channels[i] = sdma;
399 pr_debug("Providing sdma ch %d\n", sdma);
402 e->handle = memcpy(sd, obj, sizeof(*obj));
404 return 0;
405 err:
406 while (i--)
407 omap_free_dma(obj->channels[i]);
408 kfree(sd);
409 return ret;
412 static void rprm_sdma_release(struct rprm_sdma *obj)
414 int i = obj->num_chs;
416 while (i--) {
417 omap_free_dma(obj->channels[i]);
418 pr_debug("Releasing sdma ch %d\n", obj->channels[i]);
420 kfree(obj);
423 static int rprm_i2c_request(struct rprm_elem *e, struct rprm_i2c *obj)
425 struct device *i2c_dev;
426 struct i2c_adapter *adapter;
427 char i2c_name[NAME_SIZE];
428 int ret = -EINVAL;
430 sprintf(i2c_name, "i2c%d", obj->id);
431 i2c_dev = omap_hwmod_name_get_dev(i2c_name);
432 if (IS_ERR_OR_NULL(i2c_dev)) {
433 pr_err("%s: unable to lookup %s\n", __func__, i2c_name);
434 return ret;
437 adapter = i2c_get_adapter(obj->id);
438 if (!adapter) {
439 pr_err("%s: could not get i2c%d adapter\n", __func__, obj->id);
440 return -EINVAL;
442 i2c_detect_ext_master(adapter);
443 i2c_put_adapter(adapter);
445 ret = pm_runtime_get_sync(i2c_dev);
447 * pm_runtime_get_sync can return 1 in case it is already active,
448 * change it to 0 to indicate success.
450 ret -= ret == 1;
451 if (!ret)
452 e->handle = i2c_dev;
453 else
454 dev_warn(i2c_dev, "%s: failed get sync %d\n", __func__, ret);
456 return ret;
459 static int rprm_i2c_release(struct device *i2c_dev)
461 int ret = -EINVAL;
463 if (IS_ERR_OR_NULL(i2c_dev)) {
464 pr_err("%s: invalid device passed\n", __func__);
465 return ret;
468 ret = pm_runtime_put_sync(i2c_dev);
469 if (ret)
470 dev_warn(i2c_dev, "%s: failed put sync %d\n", __func__, ret);
472 return ret;
476 static const char *_get_rpres_name(int type)
478 switch (type) {
479 case RPRM_IVAHD:
480 return "rpres_iva";
481 case RPRM_IVASEQ0:
482 return "rpres_iva_seq0";
483 case RPRM_IVASEQ1:
484 return "rpres_iva_seq1";
485 case RPRM_ISS:
486 return "rpres_iss";
487 case RPRM_FDIF:
488 return "rpres_fdif";
489 case RPRM_SL2IF:
490 return "rpres_sl2if";
492 return "";
495 static int _rpres_set_constraints(struct rprm_elem *e, u32 type, long val)
497 switch (type) {
498 case RPRM_SCALE:
499 return rpres_set_constraints(e->handle,
500 RPRES_CONSTRAINT_SCALE,
501 val);
502 case RPRM_LATENCY:
503 return rpres_set_constraints(e->handle,
504 RPRES_CONSTRAINT_LATENCY,
505 val);
506 case RPRM_BANDWIDTH:
507 return rpres_set_constraints(e->handle,
508 RPRES_CONSTRAINT_BANDWIDTH,
509 val);
511 pr_err("Invalid constraint\n");
512 return -EINVAL;
515 static int _rproc_set_constraints(struct rprm_elem *e, u32 type, long val)
517 switch (type) {
518 case RPRM_SCALE:
519 return rproc_set_constraints(e->handle,
520 RPROC_CONSTRAINT_SCALE,
521 val);
522 case RPRM_LATENCY:
523 return rproc_set_constraints(e->handle,
524 RPROC_CONSTRAINT_LATENCY,
525 val);
526 case RPRM_BANDWIDTH:
527 return rproc_set_constraints(e->handle,
528 RPROC_CONSTRAINT_BANDWIDTH,
529 val);
531 pr_err("Invalid constraint\n");
532 return -EINVAL;
535 static
536 int _set_constraints(struct rprm_elem *e, struct rprm_constraints_data *c)
538 int ret = -EINVAL;
539 u32 mask = 0;
540 int (*_set_constraints_func)(struct rprm_elem *, u32 type, long val);
542 switch (e->type) {
543 case RPRM_IVAHD:
544 case RPRM_ISS:
545 case RPRM_FDIF:
546 _set_constraints_func = _rpres_set_constraints;
547 break;
548 case RPRM_IPU:
549 _set_constraints_func = _rproc_set_constraints;
550 break;
551 default:
552 return -EINVAL;
555 if (c->mask & RPRM_SCALE) {
556 ret = _set_constraints_func(e, RPRM_SCALE, c->frequency);
557 if (ret)
558 goto err;
559 mask |= RPRM_SCALE;
560 e->constraints->frequency = c->frequency;
563 if (c->mask & RPRM_LATENCY) {
564 ret = _set_constraints_func(e, RPRM_LATENCY, c->latency);
565 if (ret)
566 goto err;
567 mask |= RPRM_LATENCY;
568 e->constraints->latency = c->latency;
571 if (c->mask & RPRM_BANDWIDTH) {
572 ret = _set_constraints_func(e, RPRM_BANDWIDTH, c->bandwidth);
573 if (ret)
574 goto err;
575 mask |= RPRM_BANDWIDTH;
576 e->constraints->bandwidth = c->bandwidth;
578 err:
579 c->mask = mask;
580 return ret;
583 static int rprm_set_constraints(struct rprm *rprm, u32 addr, int res_id,
584 void *data, bool set)
586 int ret = 0;
587 struct rprm_elem *e;
589 mutex_lock(&rprm->lock);
590 if (!idr_find(&rprm->conn_list, addr)) {
591 ret = -ENOTCONN;
592 goto out;
595 e = idr_find(&rprm->id_list, res_id);
596 if (!e || e->src != addr) {
597 ret = -ENOENT;
598 goto out;
601 if (!e->constraints) {
602 pr_warn("No constraints\n");
603 ret = -EINVAL;
604 goto out;
607 if (set) {
608 ret = _set_constraints(e, data);
609 if (!ret) {
610 e->constraints->mask |=
611 ((struct rprm_constraints_data *)data)->mask;
612 goto out;
615 def_data.mask = ((struct rprm_constraints_data *)data)->mask;
616 if (def_data.mask) {
617 _set_constraints(e, &def_data);
618 e->constraints->mask &=
619 ~((struct rprm_constraints_data *)data)->mask;
621 out:
622 mutex_unlock(&rprm->lock);
623 return ret;
627 static int rprm_rpres_request(struct rprm_elem *e, int type)
629 const char *res_name = _get_rpres_name(type);
630 struct rpres *res;
632 e->constraints = kzalloc(sizeof(*(e->constraints)), GFP_KERNEL);
633 if (!(e->constraints))
634 return -ENOMEM;
636 res = rpres_get(res_name);
638 if (IS_ERR(res)) {
639 pr_err("%s: error requesting %s\n", __func__, res_name);
640 kfree(e->constraints);
641 return PTR_ERR(res);
643 e->handle = res;
645 return 0;
648 static void rprm_rpres_release(struct rpres *res)
650 rpres_put(res);
653 static int rprm_rproc_request(struct rprm_elem *e, char *name)
655 struct rproc *rp;
657 e->constraints = kzalloc(sizeof(*(e->constraints)), GFP_KERNEL);
658 if (!(e->constraints))
659 return -ENOMEM;
661 rp = rproc_get(name);
662 if (IS_ERR(rp)) {
663 pr_debug("Error requesting %s\n", name);
664 kfree(e->constraints);
665 return PTR_ERR(rp);
667 e->handle = rp;
669 return 0;
672 static void rprm_rproc_release(struct rproc *rp)
674 rproc_put(rp);
677 static int _resource_free(struct rprm_elem *e)
679 int ret = 0;
680 if (e->constraints && e->constraints->mask) {
681 def_data.mask = e->constraints->mask;
682 _set_constraints(e, &def_data);
684 kfree(e->constraints);
686 switch (e->type) {
687 case RPRM_GPTIMER:
688 rprm_gptimer_release(e->handle);
689 break;
690 case RPRM_IVAHD:
691 case RPRM_IVASEQ0:
692 case RPRM_IVASEQ1:
693 case RPRM_ISS:
694 case RPRM_SL2IF:
695 case RPRM_FDIF:
696 rprm_rpres_release(e->handle);
697 break;
698 case RPRM_IPU:
699 case RPRM_DSP:
700 rprm_rproc_release(e->handle);
701 break;
702 case RPRM_AUXCLK:
703 rprm_auxclk_release(e->handle);
704 break;
705 case RPRM_I2C:
706 ret = rprm_i2c_release(e->handle);
707 break;
708 case RPRM_REGULATOR:
709 rprm_regulator_release(e->handle);
710 break;
711 case RPRM_GPIO:
712 rprm_gpio_release(e->handle);
713 break;
714 case RPRM_SDMA:
715 rprm_sdma_release(e->handle);
716 break;
717 case RPRM_L3BUS:
718 /* ignore silently */
719 break;
720 default:
721 return -EINVAL;
724 return ret;
727 static int rprm_resource_free(struct rprm *rprm, u32 addr, int res_id)
729 int ret = 0;
730 struct rprm_elem *e;
732 mutex_lock(&rprm->lock);
733 if (!idr_find(&rprm->conn_list, addr)) {
734 ret = -ENOTCONN;
735 goto out;
738 e = idr_find(&rprm->id_list, res_id);
739 if (!e || e->src != addr) {
740 ret = -ENOENT;
741 goto out;
743 idr_remove(&rprm->id_list, res_id);
744 list_del(&e->next);
745 out:
746 mutex_unlock(&rprm->lock);
748 if (!ret) {
749 ret = _resource_free(e);
750 kfree(e);
753 return ret;
756 static int _resource_alloc(struct rprm_elem *e, int type, void *data)
758 int ret = 0;
760 switch (type) {
761 case RPRM_GPTIMER:
762 ret = rprm_gptimer_request(e, data);
763 break;
764 case RPRM_IVAHD:
765 case RPRM_IVASEQ0:
766 case RPRM_IVASEQ1:
767 case RPRM_ISS:
768 case RPRM_SL2IF:
769 case RPRM_FDIF:
770 ret = rprm_rpres_request(e, type);
771 break;
772 case RPRM_IPU:
773 ret = rprm_rproc_request(e, "ipu");
774 break;
775 case RPRM_DSP:
776 ret = rprm_rproc_request(e, "dsp");
777 break;
778 case RPRM_AUXCLK:
779 ret = rprm_auxclk_request(e, data);
780 break;
781 case RPRM_I2C:
782 ret = rprm_i2c_request(e, data);
783 break;
784 case RPRM_REGULATOR:
785 ret = rprm_regulator_request(e, data);
786 break;
787 case RPRM_GPIO:
788 ret = rprm_gpio_request(e, data);
789 break;
790 case RPRM_SDMA:
791 ret = rprm_sdma_request(e, data);
792 break;
793 case RPRM_L3BUS:
794 /* ignore silently; */
795 break;
796 default:
797 pr_err("%s: invalid source %d!\n", __func__, type);
798 ret = -EINVAL;
801 return ret;
804 static int rprm_resource_alloc(struct rprm *rprm, u32 addr, int *res_id,
805 int type, void *data)
807 struct rprm_elem *e;
808 int ret;
809 int rlen = _get_rprm_size(type);
811 e = kzalloc(sizeof(*e) + rlen, GFP_KERNEL);
812 if (!e)
813 return -ENOMEM;
815 ret = _resource_alloc(e, type, data);
816 if (ret) {
817 pr_err("%s: request for %d (%s) failed: %d\n", __func__,
818 type, rname(type), ret);
819 goto err_res_alloc;
822 mutex_lock(&rprm->lock);
823 if (!idr_find(&rprm->conn_list, addr)) {
824 pr_err("%s: addr %d not connected!\n", __func__, addr);
825 ret = -ENOTCONN;
826 goto err;
829 * Create a resource id to avoid sending kernel address to the
830 * remote processor.
832 if (!idr_pre_get(&rprm->id_list, GFP_KERNEL)) {
833 ret = -ENOMEM;
834 goto err;
836 ret = idr_get_new(&rprm->id_list, e, res_id);
837 if (ret)
838 goto err;
840 e->type = type;
841 e->src = addr;
842 e->id = *res_id;
843 memcpy(e->res, data, rlen);
844 list_add(&e->next, &rprm->res_list);
845 mutex_unlock(&rprm->lock);
847 return 0;
848 err:
849 mutex_unlock(&rprm->lock);
850 _resource_free(e);
851 err_res_alloc:
852 kfree(e);
854 return ret;
857 static int rprm_disconnect_client(struct rprm *rprm, u32 addr)
859 struct rprm_elem *e, *tmp;
860 int ret;
862 mutex_lock(&rprm->lock);
863 if (!idr_find(&rprm->conn_list, addr)) {
864 ret = -ENOTCONN;
865 goto out;
867 list_for_each_entry_safe(e, tmp, &rprm->res_list, next) {
868 if (e->src == addr) {
869 _resource_free(e);
870 idr_remove(&rprm->id_list, e->id);
871 list_del(&e->next);
872 kfree(e);
876 idr_remove(&rprm->conn_list, addr);
877 out:
878 mutex_unlock(&rprm->lock);
880 return 0;
883 static int rpmsg_connect_client(struct rprm *rprm, u32 addr)
885 int ret;
886 int tid;
888 mutex_lock(&rprm->lock);
889 if (idr_find(&rprm->conn_list, addr)) {
890 pr_err("Connection already opened\n");
891 ret = -EISCONN;
892 goto out;
894 if (!idr_pre_get(&rprm->conn_list, GFP_KERNEL)) {
895 ret = -ENOMEM;
896 goto out;
898 ret = idr_get_new_above(&rprm->conn_list, &rprm->res_list, addr, &tid);
899 BUG_ON(addr != tid);
900 out:
901 mutex_unlock(&rprm->lock);
903 return ret;
906 static void rprm_cb(struct rpmsg_channel *rpdev, void *data, int len,
907 void *priv, u32 src)
909 int ret;
910 struct device *dev = &rpdev->dev;
911 struct rprm *rprm = dev_get_drvdata(dev);
912 struct rprm_request *req = data;
913 char ack_msg[MAX_MSG];
914 struct rprm_ack *ack = (void *)ack_msg;
915 int r_sz = 0;
917 if (len < sizeof(*req)) {
918 dev_err(dev, "Bad message\n");
919 return;
922 dev_dbg(dev, "resource type %d\n"
923 "request type %d\n"
924 "res_id %d",
925 req->res_type, req->acquire, req->res_id);
927 switch (req->acquire) {
928 case RPRM_CONNECT:
929 ret = rpmsg_connect_client(rprm, src);
930 if (ret)
931 dev_err(dev, "connection failed! ret %d\n", ret);
932 break;
933 case RPRM_REQ_ALLOC:
934 r_sz = len - sizeof(*req);
935 if (r_sz != _get_rprm_size(req->res_type)) {
936 r_sz = 0;
937 ret = -EINVAL;
938 break;
940 ret = rprm_resource_alloc(rprm, src, &req->res_id,
941 req->res_type, req->data);
942 if (ret)
943 dev_err(dev, "resource allocation failed! ret %d\n",
944 ret);
945 break;
946 case RPRM_REQ_FREE:
947 ret = rprm_resource_free(rprm, src, req->res_id);
948 if (ret)
949 dev_err(dev, "resource release failed! ret %d\n", ret);
950 return;
951 case RPRM_DISCONNECT:
952 ret = rprm_disconnect_client(rprm, src);
953 if (ret)
954 dev_err(dev, "disconnection failed ret %d\n", ret);
955 return;
956 case RPRM_REQ_CONSTRAINTS:
957 r_sz = len - sizeof(*req);
958 if (r_sz != sizeof(struct rprm_constraints_data)) {
959 r_sz = 0;
960 ret = -EINVAL;
961 break;
963 ret = rprm_set_constraints(rprm, src, req->res_id,
964 req->data, true);
965 if (ret)
966 dev_err(dev, "set constraints failed! ret %d\n", ret);
967 break;
968 case RPRM_REL_CONSTRAINTS:
969 ret = rprm_set_constraints(rprm, src, req->res_id,
970 req->data, false);
971 if (ret)
972 dev_err(dev, "rel constraints failed! ret %d\n", ret);
973 return;
974 default:
975 dev_err(dev, "Unknow request\n");
976 ret = -EINVAL;
979 ack->ret = ret;
980 ack->res_type = req->res_type;
981 ack->res_id = req->res_id;
982 memcpy(ack->data, req->data, r_sz);
984 ret = rpmsg_sendto(rpdev, ack, sizeof(*ack) + r_sz, src);
985 if (ret)
986 dev_err(dev, "rprm ack failed: %d\n", ret);
989 static int _printf_gptimer_args(char *buf, struct rprm_gpt *obj)
991 return sprintf(buf,
992 "Id:%d\n"
993 "Source:%d\n",
994 obj->id, obj->src_clk);
997 static int _printf_auxclk_args(char *buf, struct rprm_auxclk *obj)
999 return sprintf(buf,
1000 "Id:%d\n"
1001 "Rate:%2d\n"
1002 "ParentSrc:%d\n"
1003 "ParentSrcRate:%d\n",
1004 obj->id, obj->clk_rate, obj->parent_src_clk,
1005 obj->parent_src_clk_rate);
1008 static int _printf_regulator_args(char *buf, struct rprm_regulator *obj)
1010 return sprintf(buf,
1011 "Id:%d\n"
1012 "min_uV:%d\n"
1013 "max_uV:%d\n",
1014 obj->id, obj->min_uv, obj->max_uv);
1017 static int _printf_gpio_args(char *buf, struct rprm_gpio *obj)
1019 return sprintf(buf, "Id:%d\n", obj->id);
1022 static int _printf_i2c_args(char *buf, struct rprm_i2c *obj)
1024 return sprintf(buf, "Id:%d\n", obj->id);
1027 static int _printf_sdma_args(char *buf, struct rprm_sdma *obj)
1029 int i, ret = 0;
1030 ret += sprintf(buf, "NumChannels:%d\n", obj->num_chs);
1031 for (i = 0 ; i < obj->num_chs; i++)
1032 ret += sprintf(buf + ret, "Channel[%d]:%d\n", i,
1033 obj->channels[i]);
1034 return ret;
1037 static int _print_res_args(char *buf, struct rprm_elem *e)
1039 void *res = (void *)e->res;
1041 switch (e->type) {
1042 case RPRM_GPTIMER:
1043 return _printf_gptimer_args(buf, res);
1044 case RPRM_AUXCLK:
1045 return _printf_auxclk_args(buf, res);
1046 case RPRM_I2C:
1047 return _printf_i2c_args(buf, res);
1048 case RPRM_REGULATOR:
1049 return _printf_regulator_args(buf, res);
1050 case RPRM_GPIO:
1051 return _printf_gpio_args(buf, res);
1052 case RPRM_SDMA:
1053 return _printf_sdma_args(buf, res);
1055 return 0;
1058 static int _printf_constraints_args(char *buf, struct rprm_elem *e)
1060 return sprintf(buf,
1061 "Mask:0x%x\n"
1062 "Frequency:%ld\n"
1063 "Latency:%ld\n"
1064 "Bandwidth:%ld\n",
1065 e->constraints->mask, e->constraints->frequency,
1066 e->constraints->latency, e->constraints->bandwidth);
1069 static ssize_t rprm_dbg_read(struct file *filp, char __user *userbuf,
1070 size_t count, loff_t *ppos)
1072 struct rprm *rprm = filp->private_data;
1073 struct rprm_elem *e;
1074 char res[512];
1075 int total = 0, c, tmp;
1076 loff_t p = 0, pt;
1078 list_for_each_entry(e, &rprm->res_list, next) {
1079 c = sprintf(res,
1080 "\nResource Name:%s\n"
1081 "Source address:%d\n",
1082 rnames[e->type], e->src);
1084 if (_get_rprm_size(e->type))
1085 c += _print_res_args(res + c, e);
1087 if (e->constraints && e->constraints->mask)
1088 c += _printf_constraints_args(res + c, e);
1090 p += c;
1091 if (*ppos >= p)
1092 continue;
1093 pt = c - p + *ppos;
1094 tmp = simple_read_from_buffer(userbuf + total, count, &pt,
1095 res, c);
1096 total += tmp;
1097 *ppos += tmp;
1098 if (tmp - c)
1099 break;
1102 return total;
1105 static int rprm_dbg_open(struct inode *inode, struct file *file)
1107 file->private_data = inode->i_private;
1108 return 0;
1111 static const struct file_operations rprm_dbg_ops = {
1112 .read = rprm_dbg_read,
1113 .open = rprm_dbg_open,
1114 .llseek = generic_file_llseek,
1117 static int rprm_probe(struct rpmsg_channel *rpdev)
1119 struct rprm *rprm;
1121 rprm = kmalloc(sizeof(*rprm), GFP_KERNEL);
1122 if (!rprm)
1123 return -ENOMEM;
1125 mutex_init(&rprm->lock);
1126 INIT_LIST_HEAD(&rprm->res_list);
1127 idr_init(&rprm->conn_list);
1128 idr_init(&rprm->id_list);
1129 dev_set_drvdata(&rpdev->dev, rprm);
1131 rprm->dbg_dir = debugfs_create_dir(dev_name(&rpdev->dev), rprm_dbg);
1132 if (!rprm->dbg_dir)
1133 dev_err(&rpdev->dev, "can't create debugfs dir\n");
1135 debugfs_create_file("resources", 0400, rprm->dbg_dir, rprm,
1136 &rprm_dbg_ops);
1138 return 0;
1141 static void __devexit rprm_remove(struct rpmsg_channel *rpdev)
1143 struct rprm *rprm = dev_get_drvdata(&rpdev->dev);
1144 struct rprm_elem *e, *tmp;
1146 dev_info(&rpdev->dev, "Enter %s\n", __func__);
1148 if (rprm->dbg_dir)
1149 debugfs_remove_recursive(rprm->dbg_dir);
1151 mutex_lock(&rprm->lock);
1153 /* clean up remaining resources */
1154 list_for_each_entry_safe(e, tmp, &rprm->res_list, next) {
1155 _resource_free(e);
1156 list_del(&e->next);
1157 kfree(e);
1159 idr_remove_all(&rprm->id_list);
1160 idr_destroy(&rprm->id_list);
1161 idr_remove_all(&rprm->conn_list);
1162 idr_destroy(&rprm->conn_list);
1164 mutex_unlock(&rprm->lock);
1166 kfree(rprm);
1169 static struct rpmsg_device_id rprm_id_table[] = {
1171 .name = "rpmsg-resmgr",
1173 { },
1175 MODULE_DEVICE_TABLE(platform, rprm_id_table);
1177 static struct rpmsg_driver rprm_driver = {
1178 .drv.name = KBUILD_MODNAME,
1179 .drv.owner = THIS_MODULE,
1180 .id_table = rprm_id_table,
1181 .probe = rprm_probe,
1182 .callback = rprm_cb,
1183 .remove = __devexit_p(rprm_remove),
1186 static int __init init(void)
1188 int r;
1190 if (debugfs_initialized()) {
1191 rprm_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
1192 if (!rprm_dbg)
1193 pr_err("Error creating rprm debug directory\n");
1195 r = register_rpmsg_driver(&rprm_driver);
1196 if (r && rprm_dbg)
1197 debugfs_remove_recursive(rprm_dbg);
1199 return r;
1202 static void __exit fini(void)
1204 if (rprm_dbg)
1205 debugfs_remove_recursive(rprm_dbg);
1206 unregister_rpmsg_driver(&rprm_driver);
1208 module_init(init);
1209 module_exit(fini);
1211 MODULE_DESCRIPTION("Remote Processor Resource Manager");
1212 MODULE_LICENSE("GPL v2");