]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - qnx/src/ipc3x_dev/ti/syslink/rpmsg-resmgr/hlos/knl/Qnx/rpmsg-resmgrdrv.c
c023cb40e11d42698ebc04a94b0cd121d35be1a1
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / rpmsg-resmgr / hlos / knl / Qnx / rpmsg-resmgrdrv.c
1 /*
2  *  @file       rpmsg-resmgrdrv.c
3  *
4  *  @brief      driver for resmgr component.
5  *
6  *  ============================================================================
7  *
8  *  Copyright (c) 2011, Texas Instruments Incorporated
9  *
10  *  Redistribution and use in source and binary forms, with or without
11  *  modification, are permitted provided that the following conditions
12  *  are met:
13  *
14  *  *  Redistributions of source code must retain the above copyright
15  *     notice, this list of conditions and the following disclaimer.
16  *
17  *  *  Redistributions in binary form must reproduce the above copyright
18  *     notice, this list of conditions and the following disclaimer in the
19  *     documentation and/or other materials provided with the distribution.
20  *
21  *  *  Neither the name of Texas Instruments Incorporated nor the names of
22  *     its contributors may be used to endorse or promote products derived
23  *     from this software without specific prior written permission.
24  *
25  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27  *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32  *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34  *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
35  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *  Contact information for paper mail:
37  *  Texas Instruments
38  *  Post Office Box 655303
39  *  Dallas, Texas 75265
40  *  Contact information:
41  *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
42  *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
43  *  ============================================================================
44  *
45  */
48 /* Standard headers */
49 #include <ti/syslink/Std.h>
51 /* OSAL & Utils headers */
52 #include <ti/syslink/utils/List.h>
53 #include <ti/syslink/utils/String.h>
54 #include <ti/syslink/utils/Trace.h>
55 #include <ti/syslink/utils/Memory.h>
56 #include <ti/syslink/utils/IGateProvider.h>
57 #include <ti/syslink/utils/GateSpinlock.h>
58 #include <ti/ipc/MultiProc.h>
59 #include <_MultiProc.h>
61 /*QNX specific header include */
62 #include <errno.h>
63 #include <unistd.h>
64 #include <sys/iofunc.h>
65 #include <sys/dispatch.h>
66 #include <sys/netmgr.h>
68 /* Module headers */
69 #include <ti/ipc/MessageQCopy.h>
70 #include <_MessageQCopy.h>
71 #include <_MessageQCopyDefs.h>
72 #include "OsalSemaphore.h"
73 #include "std_qnx.h"
74 #include <pthread.h>
76 #include "rpmsg_resmgr.h"
77 #if defined(SYSLINK_USE_IPU_PM)
78 #include "ipu_pm.h"
79 #endif
80 #include <SysLinkMemUtils.h>
82 #define  MAX_PROCESSES          32u
84 /*!
85  *  @brief  Remote connection object
86  */
87 typedef struct rpmsg_resmgr_conn_object {
88     UInt32                  addr;
89     /*!< Address of this remote connection */
90     UInt16                  procId;
91     /*!< Remote procId */
92     List_Handle             clients;
93     /*!< List of clients on this connection/remote proc */
94     UInt32                  resRefCount;
95     /*!< Reference count for requested resources */
96 #if defined(USE_MEMMGR)
97     List_Handle             tilerBufs;
98     /*!< List of tiler buffers allocated on behalf of remote proc */
99 #endif
100 } rpmsg_resmgr_conn_object;
103 /*!
104  *  @brief  rpmsg-resmgr Module state object
105  */
106 typedef struct rpmsg_resmgr_ModuleObject_tag {
107     Bool                 isSetup;
108     /*!< Indicates whether the module has been already setup */
109     IGateProvider_Handle gateHandle;
110     /*!< Handle of gate to be used for local thread safety */
111     rpmsg_resmgr_conn_object * objects [MultiProc_MAXPROCESSORS];
112     /*!< List of all remote connections. */
113     MessageQCopy_Handle mqHandle;
114     /*!< Local mq handle associated with this module */
115     UInt32 endpoint;
116 #if defined(USE_MEMMGR)
117     /*!< Local endpoint associated with the mq handle */
118     MessageQCopy_Handle mqMemHandle;
119     /*!< Local mq handle associated with this module */
120     UInt32 memEndpoint;
121     /*!< Local memMgr endpoint associated with the mq handle */
122 #endif
123 } rpmsg_resmgr_ModuleObject;
125 /*!
126  *  @brief  Structure of resource manager client information.
127  */
128 typedef struct rpmsg_resmgr_client_tag {
129     List_Elem          element;
130     /*!< List element header */
131     UInt32             addr;
132     /*!< Remote addr for the client */
133     List_Handle        resources;
134     /*!< List of acquired resources */
135 } rpmsg_resmgr_client ;
137 /*!
138  *  @brief  Structure of resource information.
139  */
140 typedef struct rpmsg_resmgr_res_tag {
141     List_Elem          element;
142     /*!< List element header */
143     UInt32             res_type;
144     /* Type of resource */
145     Char               data[];
146     /* Resource-specific request info */
147 } rpmsg_resmgr_res ;
149 /*!
150  *  @brief  Structure of resource information.
151  */
152 typedef struct rpmsg_resmgr_tiler_res_tag {
153     List_Elem          element;
154     /*!< List element header */
155     UInt32             buf;
156     /* Allocated tiler address */
157 } rpmsg_resmgr_tiler_res ;
159 #if defined(SYSLINK_USE_IPU_PM)
160 #define IPU_PM_SELF     100
161 #define IPU_PM_MPU      101
162 #define IPU_PM_CORE     102
163 #endif
165 int rpmsg_resmgr_free(rpmsg_resmgr_conn_object * resmgr, UInt32 addr, struct rprm_request * request);
167 /** ============================================================================
168  *  Globals
169  *  ============================================================================
170  */
171 /*!
172  *  @var    rpmsg_resmgr_state
173  *
174  *  @brief  rpmsg-resmgr state object variable
175  */
176 static rpmsg_resmgr_ModuleObject rpmsg_resmgr_state =
178     .gateHandle = NULL,
179     .isSetup = FALSE,
180 };
182 extern dispatch_t * syslink_dpp;
184 rpmsg_resmgr_res * find_resource(rpmsg_resmgr_client * client, UInt32 handle)
186     List_Elem * elem = NULL;
187     rpmsg_resmgr_res * res = NULL;
189     /* Search the client list for this addr */
190     List_traverse(elem, client->resources) {
191         if ((UInt32)elem == handle) {
192             res = (rpmsg_resmgr_res *)elem;
193             break;
194         }
195     }
197     return res;
200 rpmsg_resmgr_client * find_client(List_Handle client_list, UInt32 addr)
202     List_Elem * elem = NULL;
203     rpmsg_resmgr_client * client = NULL;
205     /* Search the client list for this addr */
206     List_traverse(elem, client_list) {
207         if (((rpmsg_resmgr_client *)elem)->addr == addr) {
208             client = (rpmsg_resmgr_client *)elem;
209             break;
210         }
211     }
213     return client;
216 int rpmsg_resmgr_disconnect(rpmsg_resmgr_conn_object * resmgr, UInt32 addr)
218     int status = EOK;
219     IArg key = NULL;
220     rpmsg_resmgr_client * client = NULL;
222     /* Grab the gate */
223     key = IGateProvider_enter (rpmsg_resmgr_state.gateHandle);
224     /* Check if this addr already connected */
225     client = find_client(resmgr->clients, addr);
227     /* If found, remove from the list */
228     if (client) {
229         List_Elem * elem = NULL, * temp = NULL;
230         rpmsg_resmgr_res * res = NULL;
231         char msg[MessageQCopy_BUFSIZE];
232         struct rprm_request * req = (struct rprm_request *)msg;
233         struct rprm_free_data * fdata = (struct rprm_free_data *)req->data;
235         /* Free up resources that weren't properly freed */
236         List_traverse_safe(elem, temp, client->resources) {
237             res = (rpmsg_resmgr_res *)elem;
238             fdata->res_id = (uint32_t)res;
239             rpmsg_resmgr_free(resmgr, addr, req);
240         }
242         /* Delete the resource list */
243         List_delete(&client->resources);
244         List_remove(resmgr->clients, (List_Elem *)client);
245         Memory_free (NULL, client, sizeof(*client));
246         status = 0;
247     }
248     else {
249         status = -ENOTCONN;
250     }
252     /* Release the gate */
253     IGateProvider_leave (rpmsg_resmgr_state.gateHandle, key);
255     return status;
258 int rpmsg_resmgr_constraints_rel(rpmsg_resmgr_conn_object * resmgr, UInt32 addr, struct rprm_request * request)
260     int status = EOK;
261     IArg key = NULL;
262     UInt32 tmp_rsrc;
263     rpmsg_resmgr_client * client = NULL;
264     struct rprm_constraint * cdata = (struct rprm_constraint *)(request->data);
265 #if defined(SYSLINK_USE_IPU_PM)
266     struct ipu_pm_const_req req;
267 #endif
269     /* Grab the gate */
270     key = IGateProvider_enter (rpmsg_resmgr_state.gateHandle);
271     /* Check if this client is connected */
272     client = find_client(resmgr->clients, addr);
274     /* If client found, handle the request */
275     if (client) {
276         /* Find this resource in the resource list */
277         rpmsg_resmgr_res * resource = find_resource(client, cdata->res_id);
278         if (resource) {
279             if (cdata->data.mask & RPRM_SCALE) {
280                 /* This is a frequency request */
281                 switch (resource->res_type) {
282                     case RPRM_IPU:
283                     case RPRM_ISS:
284                     case RPRM_FDIF:
285 #if defined(SYSLINK_USE_IPU_PM)
286                         tmp_rsrc = IPU_PM_CORE;
287 #endif
288                         break;
289                     default:
290                         tmp_rsrc = resource->res_type;
291                         break;
292                 }
293 #if defined(SYSLINK_USE_IPU_PM)
294                 req.rsrc = resource->res_type;
295                 req.target_rsrc = tmp_rsrc;
296                 req.rate = NO_FREQ_CONSTRAINT;
297                 status = ipu_pm_set_rate(&req);
298 #endif
299             }
300             if (cdata->data.mask & RPRM_LATENCY) {
301                 /* This is a latency request */
302                 /* TODO: handle the latency request */
303             }
304             if (cdata->data.mask & RPRM_BANDWIDTH) {
305                 /* This is a bandwidth request */
306                 if(resource->res_type == RPRM_IPU) {
307                     GT_1trace(curTrace, GT_3CLASS, "###L3 BANDWIDTH CONSTRAINTS release(%d)", cdata->data.bandwidth);
308 #if defined(SYSLINK_USE_IPU_PM)
309                     ipu_pm_set_bandwidth(0);
310 #endif
311                 }
312             }
313         }
314         else {
315             status = -ENOENT;
316         }
317     }
318     else {
319         status = -ENOTCONN;
320     }
322     /* Release the gate */
323     IGateProvider_leave (rpmsg_resmgr_state.gateHandle, key);
324     return status;
327 int rpmsg_resmgr_constraints_req(rpmsg_resmgr_conn_object * resmgr, UInt32 addr, struct rprm_request * request)
329     int status = EOK;
330     IArg key = NULL;
331     UInt32 tmp_rsrc;
332     rpmsg_resmgr_client * client = NULL;
333     struct rprm_constraint * cdata = (struct rprm_constraint *)(request->data);
334 #if defined(SYSLINK_USE_IPU_PM)
335     struct ipu_pm_const_req req;
336 #endif
338     /* Grab the gate */
339     key = IGateProvider_enter (rpmsg_resmgr_state.gateHandle);
340     /* Check if this client is connected */
341     client = find_client(resmgr->clients, addr);
343     /* If client found, handle the request */
344     if (client) {
345         /* Find this resource in the resource list */
346         rpmsg_resmgr_res * resource = find_resource(client, cdata->res_id);
347         if (resource) {
348             if (cdata->data.mask & RPRM_SCALE) {
349                 /* This is a frequency request */
350                 switch (resource->res_type) {
351                     case RPRM_IPU:
352                     case RPRM_ISS:
353                     case RPRM_FDIF:
354 #if defined(SYSLINK_USE_IPU_PM)
355                         tmp_rsrc = IPU_PM_CORE;
356 #endif
357                         break;
358                     default:
359                         tmp_rsrc = resource->res_type;
360                         break;
361                 }
362 #if defined(SYSLINK_USE_IPU_PM)
363                 req.rsrc = resource->res_type;
364                 req.target_rsrc = tmp_rsrc;
365                 req.rate = cdata->data.frequency;
366                 status = ipu_pm_set_rate(&req);
367 #endif
368             }
369             if (cdata->data.mask & RPRM_LATENCY) {
370                 /* This is a latency request */
371                 /* TODO: handle the latency request */
372             }
373             if (cdata->data.mask & RPRM_BANDWIDTH) {
374                 /* This is a bandwidth request */
375                 if(resource->res_type == RPRM_IPU) {
376                     GT_1trace(curTrace, GT_3CLASS, "###L3 BANDWIDTH CONSTRAINTS req(%d)", cdata->data.bandwidth);
377 #if defined(SYSLINK_USE_IPU_PM)
378                     ipu_pm_set_bandwidth(cdata->data.bandwidth);
379 #endif
380                 }
381             }
382         }
383         else {
384             status = -ENOENT;
385         }
386     }
387     else {
388         status = -ENOTCONN;
389     }
391     /* Release the gate */
392     IGateProvider_leave (rpmsg_resmgr_state.gateHandle, key);
393     return status;
398 int rpmsg_resmgr_req_data(rpmsg_resmgr_conn_object * resmgr, UInt32 addr, struct rprm_request * request)
400     int status = EOK;
401     IArg key = NULL;
402     rpmsg_resmgr_client * client = NULL;
403     struct rprm_reqdata * rdata = (struct rprm_reqdata *)request->data;
405     /* Grab the gate */
406     key = IGateProvider_enter (rpmsg_resmgr_state.gateHandle);
407     /* Check if this client is connected */
408     client = find_client(resmgr->clients, addr);
410     /* If client found, alloc the resource */
411     if (client) {
412         rpmsg_resmgr_res * resource = find_resource(client, rdata->res_id);
413         if (resource) {
414             switch (rdata->type) {
415                 case RPRM_REQTYPE_MAXFREQ:
416                 {
417 #if defined(SYSLINK_USE_IPU_PM)
418                     struct rprm_freq * fdata = (struct rprm_freq *)rdata->data;
419                     status = ipu_pm_get_max_freq(resource->res_type, &fdata->value);
420 #else
421                     status = -ENOENT;
422 #endif
423                 }
424                 break;
425                 default:
426                     status = -ENOENT;
427                 break;
428             }
429         }
430         else {
431             status = -ENOENT;
432         }
433     }
434     else {
435         status = -ENOTCONN;
436     }
438     /* Release the gate */
439     IGateProvider_leave (rpmsg_resmgr_state.gateHandle, key);
440     return status;
443 /* Must be holding gate when calling this function */
444 int rpmsg_resmgr_free(rpmsg_resmgr_conn_object * resmgr, UInt32 addr, struct rprm_request * request)
446     int status = EOK;
447     struct rprm_free_data * fdata = (struct rprm_free_data *)request->data;
448     rpmsg_resmgr_client * client = NULL;
450     /* Check if this client is connected */
451     client = find_client(resmgr->clients, addr);
453     /* If client found, free the resource */
454     if (client) {
455         /* Find this resource in the resource list */
456         rpmsg_resmgr_res * resource = find_resource(client, fdata->res_id);
457         if (resource) {
458             /* Remove resource from list and free memory */
459             List_remove(client->resources, &resource->element);
460             switch (resource->res_type) {
461                 case RPRM_IVAHD:
462 #if defined(SYSLINK_USE_IPU_PM)
463                     status = ipu_pm_ivahd_disable();
464 #endif
465                     break;
466                 case RPRM_IVASEQ0:
467 #if defined(SYSLINK_USE_IPU_PM)
468                     status = ipu_pm_ivaseq0_disable();
469 #endif
470                     break;
471                 case RPRM_IVASEQ1:
472 #if defined(SYSLINK_USE_IPU_PM)
473                     status = ipu_pm_ivaseq1_disable();
474 #endif
475                     break;
476                 case RPRM_L3BUS:
477                     /* TODO: handle RPRM_L3BUS free request */
478                     break;
479                 case RPRM_SL2IF:
480                     /* TODO: handle SL2IF free request */
481                     break;
482                 case RPRM_IPU:
483                     /* TODO: handle IPU free request */
484                     break;
485                 case RPRM_DSP:
486                     /* TODO: handle DSP free request */
487                     break;
488                 case RPRM_SDMA:
489                 {
490 #if defined(SYSLINK_USE_IPU_PM)
491                     struct rprm_sdma * sdma = (struct rprm_sdma *)resource->data;
492                     status = ipu_pm_free_sdma(sdma->num_chs, sdma->channels);
493                     if (status < 0) {
494                         status = -1;
495                         GT_setFailureReason (curTrace,
496                                             GT_4CLASS,
497                                             "rpmsg_resmgr_free",
498                                             status,
499                                             "Failed to free DMA!");
500                     }
501 #endif
502                 }
503                 break;
504                 case RPRM_CAMERA:
505                     /* Nothing to do.  Always passes. */
506                     break;
507                 case RPRM_LED:
508                     /* Nothing to do.  Always passes. */
509                     break;
510                 default:
511                     break;
512             }
513             /* Free the resource */
514             Memory_free(NULL, resource, sizeof(*resource));
515             fdata->res_id = 0;
516         }
517         else {
518             status = -ENOENT;
519         }
520     }
521     else {
522         status = -ENOTCONN;
523     }
525     if (status >= 0) {
526         resmgr->resRefCount--;
527     }
529     return status;
532 int rpmsg_resmgr_alloc(rpmsg_resmgr_conn_object * resmgr, UInt32 addr, struct rprm_request * request, uint32_t res_type)
534     int status = EOK;
535     IArg key = NULL;
536     rpmsg_resmgr_client * client = NULL;
537 #if defined(SYSLINK_USE_IPU_PM)
538     struct rprm_alloc_data * adata = (struct rprm_alloc_data *)request->data;
539 #endif
541     /* Grab the gate */
542     key = IGateProvider_enter (rpmsg_resmgr_state.gateHandle);
543     /* Check if this client is connected */
544     client = find_client(resmgr->clients, addr);
546     /* If client found, alloc the resource */
547     if (client) {
548         /* TODO: alloc the resource */
549         switch (res_type) {
550             case RPRM_IVAHD:
551 #if defined(SYSLINK_USE_IPU_PM)
552                 status = ipu_pm_ivahd_enable();
553                 if (status < 0) {
554                     status = -1;
555                     ipu_pm_ivahd_disable();
556                     GT_setFailureReason (curTrace,
557                                          GT_4CLASS,
558                                          "rpmsg_resmgr_alloc",
559                                          status,
560                                          "Failed to enable IVAHD!");
561                 }
562 #endif
563             break;
564             case RPRM_IVASEQ0:
565 #if defined(SYSLINK_USE_IPU_PM)
566                 status = ipu_pm_ivaseq0_enable();
567 #endif
568             break;
569             case RPRM_IVASEQ1:
570 #if defined(SYSLINK_USE_IPU_PM)
571                 status = ipu_pm_ivaseq1_enable();
572 #endif
573             break;
574             case RPRM_L3BUS:
575                 /* TODO: handle RPRM_L3BUS alloc request */
576             break;
577             case RPRM_SL2IF:
578                 /* TODO: handle SL2IF alloc request */
579             break;
580             case RPRM_IPU:
581                 /* TODO: handle IPU alloc request */
582             break;
583             case RPRM_DSP:
584                 /* TODO: handle DSP alloc request */
585             break;
586             case RPRM_SDMA:
587             {
588 #if defined(SYSLINK_USE_IPU_PM)
589                 struct rprm_sdma * sdma = (struct rprm_sdma *)adata->data;
590                 status = ipu_pm_alloc_sdma(sdma->num_chs, sdma->channels);
591                 if (status < 0) {
592                     status = -1;
593                     GT_setFailureReason (curTrace,
594                                          GT_4CLASS,
595                                          "rpmsg_resmgr_alloc",
596                                          status,
597                                          "Failed to alloc DMA!");
598                 }
599 #endif
600             }
601             break;
603             case RPRM_CAMERA:
604             {
605 #if defined(SYSLINK_USE_IPU_PM)
606                 struct rprm_camera * cam = (struct rprm_camera *)adata->data;
607                 status = ipu_pm_camera_enable(cam->mode, cam->on);
608                 if (status < 0) {
609                     status = -1;
610                     GT_setFailureReason (curTrace,
611                                          GT_4CLASS,
612                                          "rpmsg_resmgr_alloc",
613                                          status,
614                                          "Failed to enable camera!");
615                 }
616 #endif
617             }
618             break;
619             case RPRM_LED:
620             {
621 #if defined(SYSLINK_USE_IPU_PM)
622                 struct rprm_led * led = (struct rprm_led *)adata->data;
623                 led->intensity = ipu_pm_led_enable(led->mode, led->intensity);
624                 if (led->intensity == -1) {
625                     status = -1;
626                     GT_setFailureReason (curTrace,
627                                          GT_4CLASS,
628                                          "rpmsg_resmgr_alloc",
629                                          status,
630                                          "Failed to enable led!");
631                 }
632 #endif
633             }
634             break;
635             default:
636                 status = -ENOENT;
637             break;
638         }
639         if (status >= 0) {
640             rpmsg_resmgr_res * resource = NULL;
641             /* store the resource per-client for tracking */
642             resource = Memory_alloc(NULL, sizeof (rpmsg_resmgr_res), 0x0, NULL);
643             if (resource) {
644                 resource->res_type = res_type;
645                 List_put(client->resources, &resource->element);
646             }
647             else {
648                 status = -ENOMEM;
649             }
650             /* give the resource id back to the requester */
651             status = (int)resource;
652         }
653     }
654     else {
655         status = -ENOTCONN;
656     }
658     if (status >= 0) {
659         resmgr->resRefCount++;
660     }
661     /* Release the gate */
662     IGateProvider_leave (rpmsg_resmgr_state.gateHandle, key);
663     return status;
666 int rpmsg_resmgr_connect(rpmsg_resmgr_conn_object * resmgr, UInt32 addr)
668     int status = EOK;
669     IArg key = NULL;
670     rpmsg_resmgr_client * client = NULL;
671     List_Params listParams;
673     /* Grab the gate */
674     key = IGateProvider_enter (rpmsg_resmgr_state.gateHandle);
675     /* Check if this addr already connected */
676     client = find_client(resmgr->clients, addr);
678     /* Otherwise, add to the list */
679     if (!client) {
680         client = Memory_alloc (NULL, sizeof(*client), 0x0, NULL);
681         if (client) {
682             client->addr = addr;
683             /* create a list to store resources used by this client */
684             List_Params_init(&listParams);
685             client->resources = List_create(&listParams);
686             if (client->resources) {
687                 List_put (resmgr->clients, &(client->element));
688             }
689             else {
690                 Memory_free (NULL, client, sizeof(*client));
691                 client = NULL;
692                 status = -ENOMEM;
693             }
694         }
695         else {
696             status = -ENOMEM;
697         }
698     }
699     else {
700         status = -EISCONN;
701     }
702     /* Release the gate */
703     IGateProvider_leave (rpmsg_resmgr_state.gateHandle, key);
704     return status;
707 uint32_t rpmsg_resmgr_get_resp_len(uint32_t res_type)
709     uint32_t len = 0;
711     switch (res_type) {
712         case RPRM_GPTIMER:
713             len = sizeof(struct rprm_gpt);
714             break;
715         case RPRM_AUXCLK:
716             len = sizeof(struct rprm_auxclk);
717             break;
718         case RPRM_REGULATOR:
719             len = sizeof(struct rprm_regulator);
720             break;
721         case RPRM_GPIO:
722             len = sizeof(struct rprm_gpio);
723             break;
724         case RPRM_SDMA:
725             len = sizeof(struct rprm_sdma);
726             break;
727         case RPRM_IPU:
728         case RPRM_DSP:
729             len = sizeof(struct rprm_proc);
730             break;
731         case RPRM_I2C:
732             len = sizeof(struct rprm_i2c);
733             break;
734         case RPRM_CAMERA:
735             len = sizeof(struct rprm_camera);
736             break;
737         case RPRM_LED:
738             len = sizeof(struct rprm_led);
739             break;
740         default:
741             len = 0;
742             break;
743     }
745     return len;
748 uint32_t rpmsg_resmgr_get_req_data_len(uint32_t res_type)
750     uint32_t len = 0;
752     switch (res_type) {
753         case RPRM_REQTYPE_MAXFREQ:
754             len = sizeof(struct rprm_freq);
755             break;
756         default:
757             len = 0;
758             break;
759     }
761     return len;
764 uint32_t rpmsg_resmgr_get_req_len(uint32_t acquire)
766     uint32_t len = 0;
768     switch (acquire) {
769         case RPRM_REQ_ALLOC:
770             len = sizeof(struct rprm_alloc_data);
771             break;
772         case RPRM_REQ_FREE:
773             len = sizeof(struct rprm_free_data);
774             break;
775         case RPRM_REQ_CONSTRAINTS:
776             len = sizeof(struct rprm_constraint);
777             break;
778         case RPRM_REQ_DATA:
779             len = sizeof(struct rprm_reqdata);
780             break;
781         default:
782             break;
783     }
785     return len;
788 uint32_t rpmsg_resmgr_get_alloc_data_len(uint32_t res_type)
790     uint32_t len = 0;
792     switch (res_type) {
793         case RPRM_GPTIMER:
794             len = sizeof(struct rprm_gpt);
795             break;
796        case RPRM_AUXCLK:
797             len = sizeof(struct rprm_auxclk);
798             break;
799         case RPRM_REGULATOR:
800             len = sizeof(struct rprm_regulator);
801             break;
802         case RPRM_GPIO:
803             len = sizeof(struct rprm_gpio);
804             break;
805         case RPRM_SDMA:
806             len = sizeof(struct rprm_sdma);
807             break;
808         case RPRM_IPU:
809         case RPRM_DSP:
810             len = sizeof(struct rprm_proc);
811             break;
812         case RPRM_I2C:
813             len = sizeof(struct rprm_i2c);
814             break;
815         case RPRM_CAMERA:
816             len = sizeof(struct rprm_camera);
817             break;
818         case RPRM_LED:
819             len = sizeof(struct rprm_led);
820             break;
821         default:
822             break;
823     }
825     return len;
828 /*!
829  *  @brief      This function implements the callback registered with IPS. Here
830  *              to pass event no. back to user function (so that it can do
831  *              another level of demultiplexing of callbacks)
832  *
833  *  @param      procId    processor Id from which interrupt is received
834  *  @param      lineId    Interrupt line ID to be used
835  *  @param      eventId   eventId registered
836  *  @param      arg       argument to call back
837  *  @param      payload   payload received
838  *
839  *  @sa
840  */
841 Void
842 _rpmsg_resmgr_cb (MessageQCopy_Handle handle, void * data, int len, void * priv, UInt32 src, UInt16 srcProc)
844 #if !defined(SYSLINK_BUILD_OPTIMIZE)
845     Int32                   status = 0;
846 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
847     int err = EOK;
848     int i = 0;
849     rpmsg_resmgr_conn_object * resmgr_conn = NULL;
850     struct rprm_request * request = (struct rprm_request *)data;
851     char msg[MessageQCopy_BUFSIZE];
852     struct rprm_ack * response = (struct rprm_ack *)msg;
853     int resp_len = 0;
854     int req_len = 0;
855     IArg key = NULL;
856     Int res_type = -1;
857     struct rprm_alloc_data * adata = NULL;
858     struct rprm_ack_data *ack_data = (struct rprm_ack_data *)response->data;
859     struct rprm_reqdata * rdata = NULL;
861     GT_6trace (curTrace,
862                GT_ENTER,
863                "_rpmsg_resmgr_cb",
864                handle,
865                data,
866                len,
867                priv,
868                src,
869                srcProc);
871     if (len < sizeof(struct rprm_request)) {
872         /* Message is not large enough */
873         /* TODO: handle error */
874         return;
875     }
877     req_len = rpmsg_resmgr_get_req_len(request->acquire);
878     if (len < sizeof(struct rprm_request) + req_len) {
879         /* Message is not large enough */
880         /* TODO: handle error */
881         err = -EINVAL;
882         goto exit;
883     }
884     if (request->acquire == RPRM_REQ_ALLOC) {
885         adata = (struct rprm_alloc_data *)request->data;
886         res_type = rpmsg_resmgr_to_type(adata->res_name);
887         if (res_type != -1) {
888             if (res_type == -2) {
889                 struct rprm_proc * proc = (struct rprm_proc *)adata->data;
890                 if (len < sizeof(struct rprm_request) +
891                         sizeof(struct rprm_proc) + req_len) {
892                     /* Message is not large enough */
893                     err = -EINVAL;
894                     goto exit;
895                 }
896                 res_type = rpmsg_resmgr_to_type(proc->name);
897             }
898             req_len += rpmsg_resmgr_get_alloc_data_len(res_type);
899             if (len < sizeof(struct rprm_request) + req_len) {
900                 /* Message is not large enough */
901                 err = -EINVAL;
902                 goto exit;
903             }
904         }
905         else {
906             err = -EINVAL;
907             goto exit;
908         }
909     }
910     else if (request->acquire == RPRM_REQ_DATA) {
911         rdata = (struct rprm_reqdata *)request->data;
912         res_type = rdata->type;
913         req_len += rpmsg_resmgr_get_req_data_len(res_type);
914         if (len < sizeof(struct rprm_request) + req_len) {
915             /* Message is not large enough */
916             err = -EINVAL;
917             goto exit;
918         }
919     }
921     for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
922         if (rpmsg_resmgr_state.objects[i] != NULL) {
923             if (rpmsg_resmgr_state.objects[i]->procId == srcProc)
924                 break;
925         }
926     }
927     if (i == MultiProc_MAXPROCESSORS) {
928         err = -EINVAL;
929         goto exit;
930     }
931     resmgr_conn = (rpmsg_resmgr_conn_object *) rpmsg_resmgr_state.objects[i];
933     switch (request->acquire) {
934         case RPRM_REQ_ALLOC:
935             err = rpmsg_resmgr_alloc(resmgr_conn, src, request, res_type);
936             if (err > EOK) {
937                 resp_len = rpmsg_resmgr_get_resp_len(res_type);
938                 ack_data->res_id = err;
939                 Memory_copy(ack_data->data, adata->data, resp_len);
940                 resp_len += sizeof(*ack_data);
941                 err = EOK;
942             }
943             break;
944         case RPRM_REQ_FREE:
945             /* Grab the gate */
946             key = IGateProvider_enter (rpmsg_resmgr_state.gateHandle);
947             err = rpmsg_resmgr_free(resmgr_conn, src, request);
948             /* Release the gate */
949             IGateProvider_leave (rpmsg_resmgr_state.gateHandle, key);
950             /* don't send a response in this case */
951             return;
952         case RPRM_REQ_CONSTRAINTS:
953             resp_len = sizeof(struct rprm_constraint);
954             err = rpmsg_resmgr_constraints_req(resmgr_conn, src, request);
955             break;
956         case RPRM_REL_CONSTRAINTS:
957             err = rpmsg_resmgr_constraints_rel(resmgr_conn, src, request);
958             /* don't send a response in this case */
959             return;
960         case RPRM_REQ_DATA:
961             resp_len = rpmsg_resmgr_get_req_data_len(rdata->type);
962             err = rpmsg_resmgr_req_data(resmgr_conn, src, request);
963             break;
964         default:
965             err = -EINVAL;
966             break;
967     }
969 exit:
970     /* Populate the response */
971     response->acquire = request->acquire;
972     response->ret = err;
974     /* Send the response to the remote core */
975     status = MessageQCopy_send(srcProc, MultiProc_self(), src,
976                                rpmsg_resmgr_state.endpoint, response,
977                                sizeof(*response) + resp_len,
978                                TRUE);
979     if (status < 0) {
980         /* TODO: handle error */
981     }
983     GT_0trace (curTrace, GT_LEAVE, "_rpmsg_resmgr_cb");
986 #if defined(USE_MEMMGR)
987 /*
988  *  MemMgr request sent to MemMgr server
989  */
991 typedef struct {
992     UInt32 reqType;
993     char args[];
994 } MemMgr_Req;
996 /*
997  *  MemMgr response received from MemMgr server
998  */
1000 typedef struct {
1001     UInt32 result;
1002 } MemMgr_Resp;
1004 typedef enum {
1005     MemMgr_Function_ALLOC,
1006     MemMgr_Function_FREE
1007 } MemMgr_ReqType;
1009 /*!
1010  *  @brief      This function implements the callback registered with IPC. Here
1011  *              to pass event no. back to user function (so that it can do
1012  *              another level of demultiplexing of callbacks)
1013  *
1014  *  @param      procId    processor Id from which interrupt is received
1015  *  @param      lineId    Interrupt line ID to be used
1016  *  @param      eventId   eventId registered
1017  *  @param      arg       argument to call back
1018  *  @param      payload   payload received
1019  *
1020  *  @sa
1021  */
1022 Void
1023 _rpmsg_memmgr_cb (MessageQCopy_Handle handle, void * data, int len, void * priv, UInt32 src, UInt16 srcProc)
1025 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1026     Int32                   status = 0;
1027 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1028     int err = EOK;
1029     int i = 0;
1030     rpmsg_resmgr_conn_object * resmgr_conn = NULL;
1031     MemMgr_Req * request = (MemMgr_Req *)data;
1032     char msg[MessageQCopy_BUFSIZE];
1033     MemMgr_Resp * response = (MemMgr_Resp *)msg;
1034     List_Elem * elem = NULL;
1035     rpmsg_resmgr_tiler_res * res = NULL;
1037     GT_6trace (curTrace,
1038                GT_ENTER,
1039                "_rpmsg_memmgr_cb",
1040                handle,
1041                data,
1042                len,
1043                priv,
1044                src,
1045                srcProc);
1047     if (len < sizeof(MemMgr_Req)) {
1048         /* Message is not large enough */
1049         /* TODO: handle error */
1050         return;
1051     }
1053     for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
1054         if (rpmsg_resmgr_state.objects[i] != NULL) {
1055             if (rpmsg_resmgr_state.objects[i]->procId == srcProc)
1056                 break;
1057         }
1058     }
1059     if (i == MultiProc_MAXPROCESSORS) {
1060         /* TODO: handle error */
1061         return;
1062     }
1063     resmgr_conn = (rpmsg_resmgr_conn_object *) rpmsg_resmgr_state.objects[i];
1065     switch (request->reqType) {
1066         case MemMgr_Function_ALLOC:
1067             err = SysLinkMemUtils_alloc(len, (UInt32 *)request->args);
1068             if (err != 0) {
1069                 res = Memory_alloc(NULL, sizeof (rpmsg_resmgr_tiler_res), 0x0, NULL);
1070                 if (res) {
1071                     res->buf = err;
1072                     List_put(resmgr_conn->tilerBufs, &res->element);
1073                 }
1074                 else {
1075                     err = 0;
1076                     SysLinkMemUtils_free(len, (UInt32 *)&err);
1077                 }
1078             }
1079             break;
1080         case MemMgr_Function_FREE:
1081             err = SysLinkMemUtils_free(len, (UInt32 *)request->args);
1082             /* Search the client list for this addr */
1083             List_traverse(elem, resmgr_conn->tilerBufs) {
1084                 res = (rpmsg_resmgr_tiler_res *)elem;
1085                 if (res->buf == *(UInt32 *)(request->args)) {
1086                     break;
1087                 }
1088             }
1089             if (res) {
1090                 List_remove(resmgr_conn->tilerBufs, &res->element);
1091             }
1092             break;
1093         default:
1094             err = -EINVAL;
1095             break;
1096     }
1098     /* Populate the response */
1099     response->result = err;
1101     /* Send the response to the remote core */
1102     status = MessageQCopy_send(srcProc, MultiProc_self(), src, rpmsg_resmgr_state.memEndpoint, response, sizeof(*response), TRUE);
1103     if (status < 0) {
1104         /* TODO: handle error */
1105     }
1107     GT_0trace (curTrace, GT_LEAVE, "_rpmsg_memmgr_cb");
1109 #endif
1111 static
1112 Void
1113 _rpmsg_resmgr_create_conn (UInt16 procId, UInt32 endpoint)
1115     Int i = 0;
1116     Bool found = FALSE;
1117     rpmsg_resmgr_conn_object * obj = NULL;
1118     List_Params listParams;
1120     for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
1121         if (rpmsg_resmgr_state.objects[i] == NULL) {
1122             found = TRUE;
1123             break;
1124         }
1125     }
1127     if (found) {
1128         /* found a space to save this mq handle, allocate memory */
1129         obj = Memory_calloc (NULL, sizeof (rpmsg_resmgr_conn_object), 0x0, NULL);
1130         if (obj) {
1131             /* store the object in the module info */
1132             rpmsg_resmgr_state.objects[i] = obj;
1134             /* store the mq info in the object */
1135             obj->procId = procId;
1136             obj->addr = endpoint;
1138             /* create a list to store remote proc connections */
1139             List_Params_init(&listParams);
1140             obj->clients = List_create(&listParams);
1141             if (obj->clients == NULL) {
1142                 rpmsg_resmgr_state.objects[i] = NULL;
1143                 Memory_free (NULL, obj, sizeof (rpmsg_resmgr_conn_object));
1144             }
1145             else {
1146                 /* create a list to store remote proc connections */
1147                 List_Params_init(&listParams);
1148 #if defined(USE_MEMMGR)
1149                 obj->tilerBufs = List_create(&listParams);
1150                 if (obj->tilerBufs == NULL) {
1151                     List_delete(&obj->clients);
1152                     obj->clients = NULL;
1153                     rpmsg_resmgr_state.objects[i] = NULL;
1154                     Memory_free (NULL, obj, sizeof (rpmsg_resmgr_conn_object));
1155                 }
1156 #endif
1157             }
1158         }
1159     }
1163 static
1164  Void
1165  _rpmsg_resmgr_delete_conn (rpmsg_resmgr_conn_object * obj)
1167     Int i = 0;
1168     Bool found = FALSE;
1170     for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
1171         if (rpmsg_resmgr_state.objects[i] == obj) {
1172             found = TRUE;
1173             break;
1174         }
1175     }
1177     if (found) {
1178         if (obj) {
1179 #if defined(USE_MEMMGR)
1180             if (obj->tilerBufs) {
1181                 UInt32 buf = NULL;
1182                 List_Elem * elem = NULL, * temp = NULL;
1183                 /* Free up resources that weren't properly freed */
1184                 List_traverse_safe(elem, temp, obj->tilerBufs) {
1185                     buf = ((rpmsg_resmgr_tiler_res *)elem)->buf;
1186                     SysLinkMemUtils_free(sizeof(Ptr), &buf);
1187                 }
1188                 List_delete(&obj->tilerBufs);
1189             }
1190 #endif
1191             if (obj->clients) {
1192                 /* Check if there are still registered clients and
1193                    disconnect them, thereby freeing the resources. */
1194                 List_Elem * elem = NULL, * temp = NULL;
1195                 rpmsg_resmgr_client * client = NULL;
1197                 List_traverse_safe(elem, temp, obj->clients) {
1198                     client = (rpmsg_resmgr_client *)elem;
1199                     rpmsg_resmgr_disconnect(obj, client->addr);
1200                 }
1202                 List_delete(&obj->clients);
1203             }
1204             rpmsg_resmgr_state.objects[i] = NULL;
1205             Memory_free(NULL, obj, sizeof(rpmsg_resmgr_conn_object));
1206         }
1207     }
1210 /**
1211  * Callback passed to MessageQCopy_registerNotify.
1212  *
1213  * This callback is called when a remote processor creates a MessageQCopy
1214  * handle with the same name as the local MessageQCopy handle and then
1215  * calls NameMap_register to notify the HOST of the handle.
1216  *
1217  * \param handle    The remote handle.
1218  * \param procId    The remote proc ID of the remote handle.
1219  * \param endpoint  The endpoint address of the remote handle.
1220  * \param create    The endpoint is created or deleted
1221  *
1222  * \return None.
1223  */
1225 static
1226 Void
1227 _rpmsg_resmgr_notify_cb (MessageQCopy_Handle handle, UInt16 procId,
1228                          UInt32 endpoint, Char * desc, Bool create)
1230     int status = EOK;
1231     Int i = 0;
1232     Bool found = FALSE;
1233     rpmsg_resmgr_conn_object * resmgr_conn = NULL;
1234     Char msg[MessageQCopy_BUFSIZE];
1235     struct rprm_ack * response = (struct rprm_ack *)msg;
1237     for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
1238         if (rpmsg_resmgr_state.objects[i] != NULL) {
1239             if (rpmsg_resmgr_state.objects[i]->procId == procId) {
1240                 found = TRUE;
1241                 break;
1242             }
1243         }
1244     }
1246     if (found) {
1247         resmgr_conn = (rpmsg_resmgr_conn_object *) rpmsg_resmgr_state.objects[i];
1249         if (create)
1250             status = rpmsg_resmgr_connect(resmgr_conn, endpoint);
1251         else {
1252             status = rpmsg_resmgr_disconnect(resmgr_conn, endpoint);
1253             // don't send a response in this case
1254             return;
1255         }
1256     }
1257     else {
1258         status = -EINVAL;
1259     }
1261     /* Populate the response */
1262     response->ret = status;
1264     /* Send the response to the remote core */
1265     status = MessageQCopy_send(procId, MultiProc_self(), endpoint,
1266                                rpmsg_resmgr_state.endpoint, response,
1267                                sizeof(*response), TRUE);
1268     if (status < 0) {
1269         /* TODO: handle error */
1270     }
1273 Bool
1274 rpmsg_resmgr_allow_hib (UInt16 proc_id)
1276     Bool allow = FALSE;
1277     int i = 0;
1278     rpmsg_resmgr_conn_object * resmgr_conn = NULL;
1280     for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
1281         if (rpmsg_resmgr_state.objects[i] != NULL) {
1282             if (rpmsg_resmgr_state.objects[i]->procId == proc_id)
1283                 break;
1284         }
1285     }
1286     if (i < MultiProc_MAXPROCESSORS) {
1287         resmgr_conn = (rpmsg_resmgr_conn_object *) rpmsg_resmgr_state.objects[i];
1289         if (!resmgr_conn->resRefCount)
1290             allow = TRUE;
1291     }
1293     return allow;
1296 /*!
1297  *  @brief  Module setup function.
1298  *
1299  *  @sa     rpmsg_resmgr_destroy
1300  */
1301 Int
1302 rpmsg_resmgr_setup (Void)
1304     Int status = 0;
1305     UInt32 i = 0;
1306     Error_Block eb;
1308     GT_0trace (curTrace, GT_ENTER, "rpmsg_resmgr_setup");
1310     Error_init(&eb);
1312     rpmsg_resmgr_state.gateHandle = (IGateProvider_Handle)
1313                  GateSpinlock_create ((GateSpinlock_Handle) NULL, &eb);
1314 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1315     if (rpmsg_resmgr_state.gateHandle == NULL) {
1316         status = -ENOMEM;
1317         GT_setFailureReason (curTrace,
1318                              GT_4CLASS,
1319                              "_rpmsg_resmgr_setup",
1320                              status,
1321                              "Failed to create spinlock gate!");
1322     }
1323     else {
1324 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1325         rpmsg_resmgr_state.mqHandle = MessageQCopy_create (
1326                                                MessageQCopy_ADDRANY,
1327                                                "rpmsg-resmgr",
1328                                                _rpmsg_resmgr_cb,
1329                                                NULL,
1330                                                &rpmsg_resmgr_state.endpoint);
1331         if (rpmsg_resmgr_state.mqHandle == NULL) {
1332             /*! @retval ENOMEM Failed to register MQCopy handle! */
1333             status = -ENOMEM;
1334             GT_setFailureReason (curTrace,
1335                                  GT_4CLASS,
1336                                  "rpmsg_resmgr_setup",
1337                                  status,
1338                                  "Failed to create MessageQCopy handle!");
1339         }
1340         else {
1341             status = MessageQCopy_registerNotify(rpmsg_resmgr_state.mqHandle,
1342                                                  _rpmsg_resmgr_notify_cb);
1343             if (status >= 0) {
1344 #if defined(USE_MEMMGR)
1345                 rpmsg_resmgr_state.mqMemHandle = MessageQCopy_create (
1346                                                90,
1347                                                "rpmsg-memmgr",
1348                                                _rpmsg_memmgr_cb,
1349                                                NULL,
1350                                                &rpmsg_resmgr_state.memEndpoint);
1351                 if (rpmsg_resmgr_state.mqMemHandle == NULL) {
1352                     MessageQCopy_delete (&rpmsg_resmgr_state.mqHandle);
1353                     /*! @retval ENOMEM Failed to register MQCopy handle! */
1354                     status = -ENOMEM;
1355                     GT_setFailureReason (curTrace,
1356                                        GT_4CLASS,
1357                                        "rpmsg_resmgr_setup",
1358                                        status,
1359                                        "Failed to create MessageQCopy handle!");
1360                 }
1361                 else {
1362 #endif
1363                     for (i = 0; i < MultiProc_getNumProcessors(); i++) {
1364                         if (i != MultiProc_self())
1365                             _rpmsg_resmgr_create_conn(i,
1366                                                    rpmsg_resmgr_state.endpoint);
1367                     }
1368                     if (status < 0) {
1369 #if defined(USE_MEMMGR)
1370                         MessageQCopy_delete (&rpmsg_resmgr_state.mqMemHandle);
1371 #endif
1372                         MessageQCopy_delete (&rpmsg_resmgr_state.mqHandle);
1373                         /*! @retval ENOMEM Failed to register MQCopy handle! */
1374                         status = -ENOMEM;
1375                         GT_setFailureReason (curTrace,
1376                                            GT_4CLASS,
1377                                            "rpmsg_resmgr_setup",
1378                                            status,
1379                                            "Failed to register MQCopy handle!");
1380                     }
1381                     if (status >= 0) {
1382                          rpmsg_resmgr_state.isSetup = TRUE;
1383                     }
1384 #if defined (USE_MEMMGR)
1385                 }
1386 #endif
1387             }
1388             else {
1389                 GT_setFailureReason (curTrace,
1390                                      GT_4CLASS,
1391                                      "_rpmsg_resmgr_setup",
1392                                      status,
1393                                      "Failed to register callback!");
1394             }
1395         }
1396 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1397     }
1398 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1400     GT_0trace (curTrace, GT_LEAVE, "rpmsg_resmgr_setup");
1401     return status;
1405 /*!
1406  *  @brief  Module destroy function.
1407  *
1408  *  @sa     rpmsg_resmgr_setup
1409  */
1410 Void
1411 rpmsg_resmgr_destroy (Void)
1413     int i = 0;
1415     GT_0trace (curTrace, GT_ENTER, "_rpmsg_resmgr_destroy");
1417     for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
1418         if (rpmsg_resmgr_state.objects[i])
1419             _rpmsg_resmgr_delete_conn(rpmsg_resmgr_state.objects[i]);
1420     }
1421 #if defined(USE_MEMMGR)
1422     MessageQCopy_delete(&rpmsg_resmgr_state.mqMemHandle);
1423 #endif
1424     MessageQCopy_delete(&rpmsg_resmgr_state.mqHandle);
1426     if (rpmsg_resmgr_state.gateHandle != NULL) {
1427         GateSpinlock_delete ((GateSpinlock_Handle *)
1428                                        &(rpmsg_resmgr_state.gateHandle));
1429     }
1431 #if defined(SYSLINK_USE_IPU_PM)
1432     ipu_pm_ivahd_off();
1433 #endif
1435     rpmsg_resmgr_state.isSetup = FALSE ;
1437     GT_0trace (curTrace, GT_LEAVE, "_rpmsgDrv_destroy");
1441 /** ============================================================================
1442  *  Internal functions
1443  *  ============================================================================
1444  */