Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / drivers / staging / tidspbridge / rmgr / proc.c
1 /*
2  * proc.c
3  *
4  * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5  *
6  * Processor interface at the driver level.
7  *
8  * Copyright (C) 2005-2006 Texas Instruments, Inc.
9  *
10  * This package is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  */
18
19 #include <linux/types.h>
20 /* ------------------------------------ Host OS */
21 #include <linux/dma-mapping.h>
22 #include <linux/scatterlist.h>
23 #include <dspbridge/host_os.h>
24
25 /*  ----------------------------------- DSP/BIOS Bridge */
26 #include <dspbridge/dbdefs.h>
27
28 /*  ----------------------------------- Trace & Debug */
29 #include <dspbridge/dbc.h>
30
31 /*  ----------------------------------- OS Adaptation Layer */
32 #include <dspbridge/cfg.h>
33 #include <dspbridge/list.h>
34 #include <dspbridge/ntfy.h>
35 #include <dspbridge/sync.h>
36 /*  ----------------------------------- Bridge Driver */
37 #include <dspbridge/dspdefs.h>
38 #include <dspbridge/dspdeh.h>
39 /*  ----------------------------------- Platform Manager */
40 #include <dspbridge/cod.h>
41 #include <dspbridge/dev.h>
42 #include <dspbridge/procpriv.h>
43 #include <dspbridge/dmm.h>
44
45 /*  ----------------------------------- Resource Manager */
46 #include <dspbridge/mgr.h>
47 #include <dspbridge/node.h>
48 #include <dspbridge/nldr.h>
49 #include <dspbridge/rmm.h>
50
51 /*  ----------------------------------- Others */
52 #include <dspbridge/dbdcd.h>
53 #include <dspbridge/msg.h>
54 #include <dspbridge/dspioctl.h>
55 #include <dspbridge/drv.h>
56
57 /*  ----------------------------------- This */
58 #include <dspbridge/proc.h>
59 #include <dspbridge/pwr.h>
60
61 #include <dspbridge/resourcecleanup.h>
62 /*  ----------------------------------- Defines, Data Structures, Typedefs */
63 #define MAXCMDLINELEN       255
64 #define PROC_ENVPROCID      "PROC_ID=%d"
65 #define MAXPROCIDLEN    (8 + 5)
66 #define PROC_DFLT_TIMEOUT   10000       /* Time out in milliseconds */
67 #define PWR_TIMEOUT      500    /* Sleep/wake timout in msec */
68 #define EXTEND        "_EXT_END"        /* Extmem end addr in DSP binary */
69
70 #define DSP_CACHE_LINE 128
71
72 #define BUFMODE_MASK    (3 << 14)
73
74 /* Buffer modes from DSP perspective */
75 #define RBUF            0x4000          /* Input buffer */
76 #define WBUF            0x8000          /* Output Buffer */
77
78 extern struct device *bridge;
79
80 /*  ----------------------------------- Globals */
81
82 /* The proc_object structure. */
83 struct proc_object {
84         struct list_head link;  /* Link to next proc_object */
85         struct dev_object *hdev_obj;    /* Device this PROC represents */
86         u32 process;            /* Process owning this Processor */
87         struct mgr_object *hmgr_obj;    /* Manager Object Handle */
88         u32 attach_count;       /* Processor attach count */
89         u32 processor_id;       /* Processor number */
90         u32 utimeout;           /* Time out count */
91         enum dsp_procstate proc_state;  /* Processor state */
92         u32 ul_unit;            /* DDSP unit number */
93         bool is_already_attached;       /*
94                                          * True if the Device below has
95                                          * GPP Client attached
96                                          */
97         struct ntfy_object *ntfy_obj;   /* Manages  notifications */
98         /* Bridge Context Handle */
99         struct bridge_dev_context *hbridge_context;
100         /* Function interface to Bridge driver */
101         struct bridge_drv_interface *intf_fxns;
102         char *psz_last_coff;
103         struct list_head proc_list;
104 };
105
106 static u32 refs;
107
108 DEFINE_MUTEX(proc_lock);        /* For critical sections */
109
110 /*  ----------------------------------- Function Prototypes */
111 static int proc_monitor(struct proc_object *proc_obj);
112 static s32 get_envp_count(char **envp);
113 static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems,
114                            s32 cnew_envp, char *sz_var);
115
116 /* remember mapping information */
117 static struct dmm_map_object *add_mapping_info(struct process_context *pr_ctxt,
118                                 u32 mpu_addr, u32 dsp_addr, u32 size)
119 {
120         struct dmm_map_object *map_obj;
121
122         u32 num_usr_pgs = size / PG_SIZE4K;
123
124         pr_debug("%s: adding map info: mpu_addr 0x%x virt 0x%x size 0x%x\n",
125                                                 __func__, mpu_addr,
126                                                 dsp_addr, size);
127
128         map_obj = kzalloc(sizeof(struct dmm_map_object), GFP_KERNEL);
129         if (!map_obj) {
130                 pr_err("%s: kzalloc failed\n", __func__);
131                 return NULL;
132         }
133         INIT_LIST_HEAD(&map_obj->link);
134
135         map_obj->pages = kcalloc(num_usr_pgs, sizeof(struct page *),
136                                                         GFP_KERNEL);
137         if (!map_obj->pages) {
138                 pr_err("%s: kzalloc failed\n", __func__);
139                 kfree(map_obj);
140                 return NULL;
141         }
142
143         map_obj->mpu_addr = mpu_addr;
144         map_obj->dsp_addr = dsp_addr;
145         map_obj->size = size;
146         map_obj->num_usr_pgs = num_usr_pgs;
147
148         spin_lock(&pr_ctxt->dmm_map_lock);
149         list_add(&map_obj->link, &pr_ctxt->dmm_map_list);
150         spin_unlock(&pr_ctxt->dmm_map_lock);
151
152         return map_obj;
153 }
154
155 static int match_exact_map_obj(struct dmm_map_object *map_obj,
156                                         u32 dsp_addr, u32 size)
157 {
158         if (map_obj->dsp_addr == dsp_addr && map_obj->size != size)
159                 pr_err("%s: addr match (0x%x), size don't (0x%x != 0x%x)\n",
160                                 __func__, dsp_addr, map_obj->size, size);
161
162         return map_obj->dsp_addr == dsp_addr &&
163                 map_obj->size == size;
164 }
165
166 static void remove_mapping_information(struct process_context *pr_ctxt,
167                                                 u32 dsp_addr, u32 size)
168 {
169         struct dmm_map_object *map_obj;
170
171         pr_debug("%s: looking for virt 0x%x size 0x%x\n", __func__,
172                                                         dsp_addr, size);
173
174         spin_lock(&pr_ctxt->dmm_map_lock);
175         list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) {
176                 pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n",
177                                                         __func__,
178                                                         map_obj->mpu_addr,
179                                                         map_obj->dsp_addr,
180                                                         map_obj->size);
181
182                 if (match_exact_map_obj(map_obj, dsp_addr, size)) {
183                         pr_debug("%s: match, deleting map info\n", __func__);
184                         list_del(&map_obj->link);
185                         kfree(map_obj->dma_info.sg);
186                         kfree(map_obj->pages);
187                         kfree(map_obj);
188                         goto out;
189                 }
190                 pr_debug("%s: candidate didn't match\n", __func__);
191         }
192
193         pr_err("%s: failed to find given map info\n", __func__);
194 out:
195         spin_unlock(&pr_ctxt->dmm_map_lock);
196 }
197
198 static int match_containing_map_obj(struct dmm_map_object *map_obj,
199                                         u32 mpu_addr, u32 size)
200 {
201         u32 map_obj_end = map_obj->mpu_addr + map_obj->size;
202
203         return mpu_addr >= map_obj->mpu_addr &&
204                 mpu_addr + size <= map_obj_end;
205 }
206
207 static struct dmm_map_object *find_containing_mapping(
208                                 struct process_context *pr_ctxt,
209                                 u32 mpu_addr, u32 size)
210 {
211         struct dmm_map_object *map_obj;
212         pr_debug("%s: looking for mpu_addr 0x%x size 0x%x\n", __func__,
213                                                 mpu_addr, size);
214
215         spin_lock(&pr_ctxt->dmm_map_lock);
216         list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) {
217                 pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n",
218                                                 __func__,
219                                                 map_obj->mpu_addr,
220                                                 map_obj->dsp_addr,
221                                                 map_obj->size);
222                 if (match_containing_map_obj(map_obj, mpu_addr, size)) {
223                         pr_debug("%s: match!\n", __func__);
224                         goto out;
225                 }
226
227                 pr_debug("%s: no match!\n", __func__);
228         }
229
230         map_obj = NULL;
231 out:
232         spin_unlock(&pr_ctxt->dmm_map_lock);
233         return map_obj;
234 }
235
236 static int find_first_page_in_cache(struct dmm_map_object *map_obj,
237                                         unsigned long mpu_addr)
238 {
239         u32 mapped_base_page = map_obj->mpu_addr >> PAGE_SHIFT;
240         u32 requested_base_page = mpu_addr >> PAGE_SHIFT;
241         int pg_index = requested_base_page - mapped_base_page;
242
243         if (pg_index < 0 || pg_index >= map_obj->num_usr_pgs) {
244                 pr_err("%s: failed (got %d)\n", __func__, pg_index);
245                 return -1;
246         }
247
248         pr_debug("%s: first page is %d\n", __func__, pg_index);
249         return pg_index;
250 }
251
252 static inline struct page *get_mapping_page(struct dmm_map_object *map_obj,
253                                                                 int pg_i)
254 {
255         pr_debug("%s: looking for pg_i %d, num_usr_pgs: %d\n", __func__,
256                                         pg_i, map_obj->num_usr_pgs);
257
258         if (pg_i < 0 || pg_i >= map_obj->num_usr_pgs) {
259                 pr_err("%s: requested pg_i %d is out of mapped range\n",
260                                 __func__, pg_i);
261                 return NULL;
262         }
263
264         return map_obj->pages[pg_i];
265 }
266
267 /*
268  *  ======== proc_attach ========
269  *  Purpose:
270  *      Prepare for communication with a particular DSP processor, and return
271  *      a handle to the processor object.
272  */
273 int
274 proc_attach(u32 processor_id,
275             const struct dsp_processorattrin *attr_in,
276             void **ph_processor, struct process_context *pr_ctxt)
277 {
278         int status = 0;
279         struct dev_object *hdev_obj;
280         struct proc_object *p_proc_object = NULL;
281         struct mgr_object *hmgr_obj = NULL;
282         struct drv_object *hdrv_obj = NULL;
283         u8 dev_type;
284
285         DBC_REQUIRE(refs > 0);
286         DBC_REQUIRE(ph_processor != NULL);
287
288         if (pr_ctxt->hprocessor) {
289                 *ph_processor = pr_ctxt->hprocessor;
290                 return status;
291         }
292
293         /* Get the Driver and Manager Object Handles */
294         status = cfg_get_object((u32 *) &hdrv_obj, REG_DRV_OBJECT);
295         if (!status)
296                 status = cfg_get_object((u32 *) &hmgr_obj, REG_MGR_OBJECT);
297
298         if (!status) {
299                 /* Get the Device Object */
300                 status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
301         }
302         if (!status)
303                 status = dev_get_dev_type(hdev_obj, &dev_type);
304
305         if (status)
306                 goto func_end;
307
308         /* If we made it this far, create the Proceesor object: */
309         p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL);
310         /* Fill out the Processor Object: */
311         if (p_proc_object == NULL) {
312                 status = -ENOMEM;
313                 goto func_end;
314         }
315         p_proc_object->hdev_obj = hdev_obj;
316         p_proc_object->hmgr_obj = hmgr_obj;
317         p_proc_object->processor_id = dev_type;
318         /* Store TGID instead of process handle */
319         p_proc_object->process = current->tgid;
320
321         INIT_LIST_HEAD(&p_proc_object->proc_list);
322
323         if (attr_in)
324                 p_proc_object->utimeout = attr_in->utimeout;
325         else
326                 p_proc_object->utimeout = PROC_DFLT_TIMEOUT;
327
328         status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns);
329         if (!status) {
330                 status = dev_get_bridge_context(hdev_obj,
331                                              &p_proc_object->hbridge_context);
332                 if (status)
333                         kfree(p_proc_object);
334         } else
335                 kfree(p_proc_object);
336
337         if (status)
338                 goto func_end;
339
340         /* Create the Notification Object */
341         /* This is created with no event mask, no notify mask
342          * and no valid handle to the notification. They all get
343          * filled up when proc_register_notify is called */
344         p_proc_object->ntfy_obj = kmalloc(sizeof(struct ntfy_object),
345                                                         GFP_KERNEL);
346         if (p_proc_object->ntfy_obj)
347                 ntfy_init(p_proc_object->ntfy_obj);
348         else
349                 status = -ENOMEM;
350
351         if (!status) {
352                 /* Insert the Processor Object into the DEV List.
353                  * Return handle to this Processor Object:
354                  * Find out if the Device is already attached to a
355                  * Processor. If so, return AlreadyAttached status */
356                 lst_init_elem(&p_proc_object->link);
357                 status = dev_insert_proc_object(p_proc_object->hdev_obj,
358                                                 (u32) p_proc_object,
359                                                 &p_proc_object->
360                                                 is_already_attached);
361                 if (!status) {
362                         if (p_proc_object->is_already_attached)
363                                 status = 0;
364                 } else {
365                         if (p_proc_object->ntfy_obj) {
366                                 ntfy_delete(p_proc_object->ntfy_obj);
367                                 kfree(p_proc_object->ntfy_obj);
368                         }
369
370                         kfree(p_proc_object);
371                 }
372                 if (!status) {
373                         *ph_processor = (void *)p_proc_object;
374                         pr_ctxt->hprocessor = *ph_processor;
375                         (void)proc_notify_clients(p_proc_object,
376                                                   DSP_PROCESSORATTACH);
377                 }
378         } else {
379                 /* Don't leak memory if status is failed */
380                 kfree(p_proc_object);
381         }
382 func_end:
383         DBC_ENSURE((status == -EPERM && *ph_processor == NULL) ||
384                    (!status && p_proc_object) ||
385                    (status == 0 && p_proc_object));
386
387         return status;
388 }
389
390 static int get_exec_file(struct cfg_devnode *dev_node_obj,
391                                 struct dev_object *hdev_obj,
392                                 u32 size, char *exec_file)
393 {
394         u8 dev_type;
395         s32 len;
396
397         dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
398         if (dev_type == DSP_UNIT) {
399                 return cfg_get_exec_file(dev_node_obj, size, exec_file);
400         } else if (dev_type == IVA_UNIT) {
401                 if (iva_img) {
402                         len = strlen(iva_img);
403                         strncpy(exec_file, iva_img, len + 1);
404                         return 0;
405                 }
406         }
407         return -ENOENT;
408 }
409
410 /*
411  *  ======== proc_auto_start ======== =
412  *  Purpose:
413  *      A Particular device gets loaded with the default image
414  *      if the AutoStart flag is set.
415  *  Parameters:
416  *      hdev_obj:     Handle to the Device
417  *  Returns:
418  *      0:   On Successful Loading
419  *      -EPERM  General Failure
420  *  Requires:
421  *      hdev_obj != NULL
422  *  Ensures:
423  */
424 int proc_auto_start(struct cfg_devnode *dev_node_obj,
425                            struct dev_object *hdev_obj)
426 {
427         int status = -EPERM;
428         struct proc_object *p_proc_object;
429         char sz_exec_file[MAXCMDLINELEN];
430         char *argv[2];
431         struct mgr_object *hmgr_obj = NULL;
432         u8 dev_type;
433
434         DBC_REQUIRE(refs > 0);
435         DBC_REQUIRE(dev_node_obj != NULL);
436         DBC_REQUIRE(hdev_obj != NULL);
437
438         /* Create a Dummy PROC Object */
439         status = cfg_get_object((u32 *) &hmgr_obj, REG_MGR_OBJECT);
440         if (status)
441                 goto func_end;
442
443         p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL);
444         if (p_proc_object == NULL) {
445                 status = -ENOMEM;
446                 goto func_end;
447         }
448         p_proc_object->hdev_obj = hdev_obj;
449         p_proc_object->hmgr_obj = hmgr_obj;
450         status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns);
451         if (!status)
452                 status = dev_get_bridge_context(hdev_obj,
453                                              &p_proc_object->hbridge_context);
454         if (status)
455                 goto func_cont;
456
457         /* Stop the Device, put it into standby mode */
458         status = proc_stop(p_proc_object);
459
460         if (status)
461                 goto func_cont;
462
463         /* Get the default executable for this board... */
464         dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
465         p_proc_object->processor_id = dev_type;
466         status = get_exec_file(dev_node_obj, hdev_obj, sizeof(sz_exec_file),
467                                sz_exec_file);
468         if (!status) {
469                 argv[0] = sz_exec_file;
470                 argv[1] = NULL;
471                 /* ...and try to load it: */
472                 status = proc_load(p_proc_object, 1, (const char **)argv, NULL);
473                 if (!status)
474                         status = proc_start(p_proc_object);
475         }
476         kfree(p_proc_object->psz_last_coff);
477         p_proc_object->psz_last_coff = NULL;
478 func_cont:
479         kfree(p_proc_object);
480 func_end:
481         return status;
482 }
483
484 /*
485  *  ======== proc_ctrl ========
486  *  Purpose:
487  *      Pass control information to the GPP device driver managing the
488  *      DSP processor.
489  *
490  *      This will be an OEM-only function, and not part of the DSP/BIOS Bridge
491  *      application developer's API.
492  *      Call the bridge_dev_ctrl fxn with the Argument. This is a Synchronous
493  *      Operation. arg can be null.
494  */
495 int proc_ctrl(void *hprocessor, u32 dw_cmd, struct dsp_cbdata * arg)
496 {
497         int status = 0;
498         struct proc_object *p_proc_object = hprocessor;
499         u32 timeout = 0;
500
501         DBC_REQUIRE(refs > 0);
502
503         if (p_proc_object) {
504                 /* intercept PWR deep sleep command */
505                 if (dw_cmd == BRDIOCTL_DEEPSLEEP) {
506                         timeout = arg->cb_data;
507                         status = pwr_sleep_dsp(PWR_DEEPSLEEP, timeout);
508                 }
509                 /* intercept PWR emergency sleep command */
510                 else if (dw_cmd == BRDIOCTL_EMERGENCYSLEEP) {
511                         timeout = arg->cb_data;
512                         status = pwr_sleep_dsp(PWR_EMERGENCYDEEPSLEEP, timeout);
513                 } else if (dw_cmd == PWR_DEEPSLEEP) {
514                         /* timeout = arg->cb_data; */
515                         status = pwr_sleep_dsp(PWR_DEEPSLEEP, timeout);
516                 }
517                 /* intercept PWR wake commands */
518                 else if (dw_cmd == BRDIOCTL_WAKEUP) {
519                         timeout = arg->cb_data;
520                         status = pwr_wake_dsp(timeout);
521                 } else if (dw_cmd == PWR_WAKEUP) {
522                         /* timeout = arg->cb_data; */
523                         status = pwr_wake_dsp(timeout);
524                 } else
525                     if (!((*p_proc_object->intf_fxns->pfn_dev_cntrl)
526                                       (p_proc_object->hbridge_context, dw_cmd,
527                                        arg))) {
528                         status = 0;
529                 } else {
530                         status = -EPERM;
531                 }
532         } else {
533                 status = -EFAULT;
534         }
535
536         return status;
537 }
538
539 /*
540  *  ======== proc_detach ========
541  *  Purpose:
542  *      Destroys the  Processor Object. Removes the notification from the Dev
543  *      List.
544  */
545 int proc_detach(struct process_context *pr_ctxt)
546 {
547         int status = 0;
548         struct proc_object *p_proc_object = NULL;
549
550         DBC_REQUIRE(refs > 0);
551
552         p_proc_object = (struct proc_object *)pr_ctxt->hprocessor;
553
554         if (p_proc_object) {
555                 /* Notify the Client */
556                 ntfy_notify(p_proc_object->ntfy_obj, DSP_PROCESSORDETACH);
557                 /* Remove the notification memory */
558                 if (p_proc_object->ntfy_obj) {
559                         ntfy_delete(p_proc_object->ntfy_obj);
560                         kfree(p_proc_object->ntfy_obj);
561                 }
562
563                 kfree(p_proc_object->psz_last_coff);
564                 p_proc_object->psz_last_coff = NULL;
565                 /* Remove the Proc from the DEV List */
566                 (void)dev_remove_proc_object(p_proc_object->hdev_obj,
567                                              (u32) p_proc_object);
568                 /* Free the Processor Object */
569                 kfree(p_proc_object);
570                 pr_ctxt->hprocessor = NULL;
571         } else {
572                 status = -EFAULT;
573         }
574
575         return status;
576 }
577
578 /*
579  *  ======== proc_enum_nodes ========
580  *  Purpose:
581  *      Enumerate and get configuration information about nodes allocated
582  *      on a DSP processor.
583  */
584 int proc_enum_nodes(void *hprocessor, void **node_tab,
585                            u32 node_tab_size, u32 *pu_num_nodes,
586                            u32 *pu_allocated)
587 {
588         int status = -EPERM;
589         struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
590         struct node_mgr *hnode_mgr = NULL;
591
592         DBC_REQUIRE(refs > 0);
593         DBC_REQUIRE(node_tab != NULL || node_tab_size == 0);
594         DBC_REQUIRE(pu_num_nodes != NULL);
595         DBC_REQUIRE(pu_allocated != NULL);
596
597         if (p_proc_object) {
598                 if (!(dev_get_node_manager(p_proc_object->hdev_obj,
599                                                        &hnode_mgr))) {
600                         if (hnode_mgr) {
601                                 status = node_enum_nodes(hnode_mgr, node_tab,
602                                                          node_tab_size,
603                                                          pu_num_nodes,
604                                                          pu_allocated);
605                         }
606                 }
607         } else {
608                 status = -EFAULT;
609         }
610
611         return status;
612 }
613
614 /* Cache operation against kernel address instead of users */
615 static int build_dma_sg(struct dmm_map_object *map_obj, unsigned long start,
616                                                 ssize_t len, int pg_i)
617 {
618         struct page *page;
619         unsigned long offset;
620         ssize_t rest;
621         int ret = 0, i = 0;
622         struct scatterlist *sg = map_obj->dma_info.sg;
623
624         while (len) {
625                 page = get_mapping_page(map_obj, pg_i);
626                 if (!page) {
627                         pr_err("%s: no page for %08lx\n", __func__, start);
628                         ret = -EINVAL;
629                         goto out;
630                 } else if (IS_ERR(page)) {
631                         pr_err("%s: err page for %08lx(%lu)\n", __func__, start,
632                                PTR_ERR(page));
633                         ret = PTR_ERR(page);
634                         goto out;
635                 }
636
637                 offset = start & ~PAGE_MASK;
638                 rest = min_t(ssize_t, PAGE_SIZE - offset, len);
639
640                 sg_set_page(&sg[i], page, rest, offset);
641
642                 len -= rest;
643                 start += rest;
644                 pg_i++, i++;
645         }
646
647         if (i != map_obj->dma_info.num_pages) {
648                 pr_err("%s: bad number of sg iterations\n", __func__);
649                 ret = -EFAULT;
650                 goto out;
651         }
652
653 out:
654         return ret;
655 }
656
657 static int memory_regain_ownership(struct dmm_map_object *map_obj,
658                 unsigned long start, ssize_t len, enum dma_data_direction dir)
659 {
660         int ret = 0;
661         unsigned long first_data_page = start >> PAGE_SHIFT;
662         unsigned long last_data_page = ((u32)(start + len - 1) >> PAGE_SHIFT);
663         /* calculating the number of pages this area spans */
664         unsigned long num_pages = last_data_page - first_data_page + 1;
665         struct bridge_dma_map_info *dma_info = &map_obj->dma_info;
666
667         if (!dma_info->sg)
668                 goto out;
669
670         if (dma_info->dir != dir || dma_info->num_pages != num_pages) {
671                 pr_err("%s: dma info doesn't match given params\n", __func__);
672                 return -EINVAL;
673         }
674
675         dma_unmap_sg(bridge, dma_info->sg, num_pages, dma_info->dir);
676
677         pr_debug("%s: dma_map_sg unmapped\n", __func__);
678
679         kfree(dma_info->sg);
680
681         map_obj->dma_info.sg = NULL;
682
683 out:
684         return ret;
685 }
686
687 /* Cache operation against kernel address instead of users */
688 static int memory_give_ownership(struct dmm_map_object *map_obj,
689                 unsigned long start, ssize_t len, enum dma_data_direction dir)
690 {
691         int pg_i, ret, sg_num;
692         struct scatterlist *sg;
693         unsigned long first_data_page = start >> PAGE_SHIFT;
694         unsigned long last_data_page = ((u32)(start + len - 1) >> PAGE_SHIFT);
695         /* calculating the number of pages this area spans */
696         unsigned long num_pages = last_data_page - first_data_page + 1;
697
698         pg_i = find_first_page_in_cache(map_obj, start);
699         if (pg_i < 0) {
700                 pr_err("%s: failed to find first page in cache\n", __func__);
701                 ret = -EINVAL;
702                 goto out;
703         }
704
705         sg = kcalloc(num_pages, sizeof(*sg), GFP_KERNEL);
706         if (!sg) {
707                 pr_err("%s: kcalloc failed\n", __func__);
708                 ret = -ENOMEM;
709                 goto out;
710         }
711
712         sg_init_table(sg, num_pages);
713
714         /* cleanup a previous sg allocation */
715         /* this may happen if application doesn't signal for e/o DMA */
716         kfree(map_obj->dma_info.sg);
717
718         map_obj->dma_info.sg = sg;
719         map_obj->dma_info.dir = dir;
720         map_obj->dma_info.num_pages = num_pages;
721
722         ret = build_dma_sg(map_obj, start, len, pg_i);
723         if (ret)
724                 goto kfree_sg;
725
726         sg_num = dma_map_sg(bridge, sg, num_pages, dir);
727         if (sg_num < 1) {
728                 pr_err("%s: dma_map_sg failed: %d\n", __func__, sg_num);
729                 ret = -EFAULT;
730                 goto kfree_sg;
731         }
732
733         pr_debug("%s: dma_map_sg mapped %d elements\n", __func__, sg_num);
734         map_obj->dma_info.sg_num = sg_num;
735
736         return 0;
737
738 kfree_sg:
739         kfree(sg);
740         map_obj->dma_info.sg = NULL;
741 out:
742         return ret;
743 }
744
745 int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
746                                 enum dma_data_direction dir)
747 {
748         /* Keep STATUS here for future additions to this function */
749         int status = 0;
750         struct process_context *pr_ctxt = (struct process_context *) hprocessor;
751         struct dmm_map_object *map_obj;
752
753         DBC_REQUIRE(refs > 0);
754
755         if (!pr_ctxt) {
756                 status = -EFAULT;
757                 goto err_out;
758         }
759
760         pr_debug("%s: addr 0x%x, size 0x%x, type %d\n", __func__,
761                                                         (u32)pmpu_addr,
762                                                         ul_size, dir);
763
764         /* find requested memory are in cached mapping information */
765         map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size);
766         if (!map_obj) {
767                 pr_err("%s: find_containing_mapping failed\n", __func__);
768                 status = -EFAULT;
769                 goto err_out;
770         }
771
772         if (memory_give_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) {
773                 pr_err("%s: InValid address parameters %p %x\n",
774                                __func__, pmpu_addr, ul_size);
775                 status = -EFAULT;
776         }
777
778 err_out:
779
780         return status;
781 }
782
783 int proc_end_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
784                         enum dma_data_direction dir)
785 {
786         /* Keep STATUS here for future additions to this function */
787         int status = 0;
788         struct process_context *pr_ctxt = (struct process_context *) hprocessor;
789         struct dmm_map_object *map_obj;
790
791         DBC_REQUIRE(refs > 0);
792
793         if (!pr_ctxt) {
794                 status = -EFAULT;
795                 goto err_out;
796         }
797
798         pr_debug("%s: addr 0x%x, size 0x%x, type %d\n", __func__,
799                                                         (u32)pmpu_addr,
800                                                         ul_size, dir);
801
802         /* find requested memory are in cached mapping information */
803         map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size);
804         if (!map_obj) {
805                 pr_err("%s: find_containing_mapping failed\n", __func__);
806                 status = -EFAULT;
807                 goto err_out;
808         }
809
810         if (memory_regain_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) {
811                 pr_err("%s: InValid address parameters %p %x\n",
812                        __func__, pmpu_addr, ul_size);
813                 status = -EFAULT;
814                 goto err_out;
815         }
816
817 err_out:
818         return status;
819 }
820
821 /*
822  *  ======== proc_flush_memory ========
823  *  Purpose:
824  *     Flush cache
825  */
826 int proc_flush_memory(void *hprocessor, void *pmpu_addr,
827                              u32 ul_size, u32 ul_flags)
828 {
829         enum dma_data_direction dir = DMA_BIDIRECTIONAL;
830
831         return proc_begin_dma(hprocessor, pmpu_addr, ul_size, dir);
832 }
833
834 /*
835  *  ======== proc_invalidate_memory ========
836  *  Purpose:
837  *     Invalidates the memory specified
838  */
839 int proc_invalidate_memory(void *hprocessor, void *pmpu_addr, u32 size)
840 {
841         enum dma_data_direction dir = DMA_FROM_DEVICE;
842
843         return proc_begin_dma(hprocessor, pmpu_addr, size, dir);
844 }
845
846 /*
847  *  ======== proc_get_resource_info ========
848  *  Purpose:
849  *      Enumerate the resources currently available on a processor.
850  */
851 int proc_get_resource_info(void *hprocessor, u32 resource_type,
852                                   struct dsp_resourceinfo *resource_info,
853                                   u32 resource_info_size)
854 {
855         int status = -EPERM;
856         struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
857         struct node_mgr *hnode_mgr = NULL;
858         struct nldr_object *nldr_obj = NULL;
859         struct rmm_target_obj *rmm = NULL;
860         struct io_mgr *hio_mgr = NULL;  /* IO manager handle */
861
862         DBC_REQUIRE(refs > 0);
863         DBC_REQUIRE(resource_info != NULL);
864         DBC_REQUIRE(resource_info_size >= sizeof(struct dsp_resourceinfo));
865
866         if (!p_proc_object) {
867                 status = -EFAULT;
868                 goto func_end;
869         }
870         switch (resource_type) {
871         case DSP_RESOURCE_DYNDARAM:
872         case DSP_RESOURCE_DYNSARAM:
873         case DSP_RESOURCE_DYNEXTERNAL:
874         case DSP_RESOURCE_DYNSRAM:
875                 status = dev_get_node_manager(p_proc_object->hdev_obj,
876                                               &hnode_mgr);
877                 if (!hnode_mgr) {
878                         status = -EFAULT;
879                         goto func_end;
880                 }
881
882                 status = node_get_nldr_obj(hnode_mgr, &nldr_obj);
883                 if (!status) {
884                         status = nldr_get_rmm_manager(nldr_obj, &rmm);
885                         if (rmm) {
886                                 if (!rmm_stat(rmm,
887                                               (enum dsp_memtype)resource_type,
888                                               (struct dsp_memstat *)
889                                               &(resource_info->result.
890                                                 mem_stat)))
891                                         status = -EINVAL;
892                         } else {
893                                 status = -EFAULT;
894                         }
895                 }
896                 break;
897         case DSP_RESOURCE_PROCLOAD:
898                 status = dev_get_io_mgr(p_proc_object->hdev_obj, &hio_mgr);
899                 if (hio_mgr)
900                         status =
901                             p_proc_object->intf_fxns->
902                             pfn_io_get_proc_load(hio_mgr,
903                                                  (struct dsp_procloadstat *)
904                                                  &(resource_info->result.
905                                                    proc_load_stat));
906                 else
907                         status = -EFAULT;
908                 break;
909         default:
910                 status = -EPERM;
911                 break;
912         }
913 func_end:
914         return status;
915 }
916
917 /*
918  *  ======== proc_exit ========
919  *  Purpose:
920  *      Decrement reference count, and free resources when reference count is
921  *      0.
922  */
923 void proc_exit(void)
924 {
925         DBC_REQUIRE(refs > 0);
926
927         refs--;
928
929         DBC_ENSURE(refs >= 0);
930 }
931
932 /*
933  *  ======== proc_get_dev_object ========
934  *  Purpose:
935  *      Return the Dev Object handle for a given Processor.
936  *
937  */
938 int proc_get_dev_object(void *hprocessor,
939                                struct dev_object **device_obj)
940 {
941         int status = -EPERM;
942         struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
943
944         DBC_REQUIRE(refs > 0);
945         DBC_REQUIRE(device_obj != NULL);
946
947         if (p_proc_object) {
948                 *device_obj = p_proc_object->hdev_obj;
949                 status = 0;
950         } else {
951                 *device_obj = NULL;
952                 status = -EFAULT;
953         }
954
955         DBC_ENSURE((!status && *device_obj != NULL) ||
956                    (status && *device_obj == NULL));
957
958         return status;
959 }
960
961 /*
962  *  ======== proc_get_state ========
963  *  Purpose:
964  *      Report the state of the specified DSP processor.
965  */
966 int proc_get_state(void *hprocessor,
967                           struct dsp_processorstate *proc_state_obj,
968                           u32 state_info_size)
969 {
970         int status = 0;
971         struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
972         int brd_status;
973
974         DBC_REQUIRE(refs > 0);
975         DBC_REQUIRE(proc_state_obj != NULL);
976         DBC_REQUIRE(state_info_size >= sizeof(struct dsp_processorstate));
977
978         if (p_proc_object) {
979                 /* First, retrieve BRD state information */
980                 status = (*p_proc_object->intf_fxns->pfn_brd_status)
981                     (p_proc_object->hbridge_context, &brd_status);
982                 if (!status) {
983                         switch (brd_status) {
984                         case BRD_STOPPED:
985                                 proc_state_obj->proc_state = PROC_STOPPED;
986                                 break;
987                         case BRD_SLEEP_TRANSITION:
988                         case BRD_DSP_HIBERNATION:
989                                 /* Fall through */
990                         case BRD_RUNNING:
991                                 proc_state_obj->proc_state = PROC_RUNNING;
992                                 break;
993                         case BRD_LOADED:
994                                 proc_state_obj->proc_state = PROC_LOADED;
995                                 break;
996                         case BRD_ERROR:
997                                 proc_state_obj->proc_state = PROC_ERROR;
998                                 break;
999                         default:
1000                                 proc_state_obj->proc_state = 0xFF;
1001                                 status = -EPERM;
1002                                 break;
1003                         }
1004                 }
1005         } else {
1006                 status = -EFAULT;
1007         }
1008         dev_dbg(bridge, "%s, results: status: 0x%x proc_state_obj: 0x%x\n",
1009                 __func__, status, proc_state_obj->proc_state);
1010         return status;
1011 }
1012
1013 /*
1014  *  ======== proc_get_trace ========
1015  *  Purpose:
1016  *      Retrieve the current contents of the trace buffer, located on the
1017  *      Processor.  Predefined symbols for the trace buffer must have been
1018  *      configured into the DSP executable.
1019  *  Details:
1020  *      We support using the symbols SYS_PUTCBEG and SYS_PUTCEND to define a
1021  *      trace buffer, only.  Treat it as an undocumented feature.
1022  *      This call is destructive, meaning the processor is placed in the monitor
1023  *      state as a result of this function.
1024  */
1025 int proc_get_trace(void *hprocessor, u8 * pbuf, u32 max_size)
1026 {
1027         int status;
1028         status = -ENOSYS;
1029         return status;
1030 }
1031
1032 /*
1033  *  ======== proc_init ========
1034  *  Purpose:
1035  *      Initialize PROC's private state, keeping a reference count on each call
1036  */
1037 bool proc_init(void)
1038 {
1039         bool ret = true;
1040
1041         DBC_REQUIRE(refs >= 0);
1042
1043         if (ret)
1044                 refs++;
1045
1046         DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
1047
1048         return ret;
1049 }
1050
1051 /*
1052  *  ======== proc_load ========
1053  *  Purpose:
1054  *      Reset a processor and load a new base program image.
1055  *      This will be an OEM-only function, and not part of the DSP/BIOS Bridge
1056  *      application developer's API.
1057  */
1058 int proc_load(void *hprocessor, const s32 argc_index,
1059                      const char **user_args, const char **user_envp)
1060 {
1061         int status = 0;
1062         struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1063         struct io_mgr *hio_mgr; /* IO manager handle */
1064         struct msg_mgr *hmsg_mgr;
1065         struct cod_manager *cod_mgr;    /* Code manager handle */
1066         char *pargv0;           /* temp argv[0] ptr */
1067         char **new_envp;        /* Updated envp[] array. */
1068         char sz_proc_id[MAXPROCIDLEN];  /* Size of "PROC_ID=<n>" */
1069         s32 envp_elems;         /* Num elements in envp[]. */
1070         s32 cnew_envp;          /* "  " in new_envp[] */
1071         s32 nproc_id = 0;       /* Anticipate MP version. */
1072         struct dcd_manager *hdcd_handle;
1073         struct dmm_object *dmm_mgr;
1074         u32 dw_ext_end;
1075         u32 proc_id;
1076         int brd_state;
1077         struct drv_data *drv_datap = dev_get_drvdata(bridge);
1078
1079 #ifdef OPT_LOAD_TIME_INSTRUMENTATION
1080         struct timeval tv1;
1081         struct timeval tv2;
1082 #endif
1083
1084 #if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
1085         struct dspbridge_platform_data *pdata =
1086             omap_dspbridge_dev->dev.platform_data;
1087 #endif
1088
1089         DBC_REQUIRE(refs > 0);
1090         DBC_REQUIRE(argc_index > 0);
1091         DBC_REQUIRE(user_args != NULL);
1092
1093 #ifdef OPT_LOAD_TIME_INSTRUMENTATION
1094         do_gettimeofday(&tv1);
1095 #endif
1096         if (!p_proc_object) {
1097                 status = -EFAULT;
1098                 goto func_end;
1099         }
1100         dev_get_cod_mgr(p_proc_object->hdev_obj, &cod_mgr);
1101         if (!cod_mgr) {
1102                 status = -EPERM;
1103                 goto func_end;
1104         }
1105         status = proc_stop(hprocessor);
1106         if (status)
1107                 goto func_end;
1108
1109         /* Place the board in the monitor state. */
1110         status = proc_monitor(hprocessor);
1111         if (status)
1112                 goto func_end;
1113
1114         /* Save ptr to  original argv[0]. */
1115         pargv0 = (char *)user_args[0];
1116         /*Prepend "PROC_ID=<nproc_id>"to envp array for target. */
1117         envp_elems = get_envp_count((char **)user_envp);
1118         cnew_envp = (envp_elems ? (envp_elems + 1) : (envp_elems + 2));
1119         new_envp = kzalloc(cnew_envp * sizeof(char **), GFP_KERNEL);
1120         if (new_envp) {
1121                 status = snprintf(sz_proc_id, MAXPROCIDLEN, PROC_ENVPROCID,
1122                                   nproc_id);
1123                 if (status == -1) {
1124                         dev_dbg(bridge, "%s: Proc ID string overflow\n",
1125                                 __func__);
1126                         status = -EPERM;
1127                 } else {
1128                         new_envp =
1129                             prepend_envp(new_envp, (char **)user_envp,
1130                                          envp_elems, cnew_envp, sz_proc_id);
1131                         /* Get the DCD Handle */
1132                         status = mgr_get_dcd_handle(p_proc_object->hmgr_obj,
1133                                                     (u32 *) &hdcd_handle);
1134                         if (!status) {
1135                                 /*  Before proceeding with new load,
1136                                  *  check if a previously registered COFF
1137                                  *  exists.
1138                                  *  If yes, unregister nodes in previously
1139                                  *  registered COFF.  If any error occurred,
1140                                  *  set previously registered COFF to NULL. */
1141                                 if (p_proc_object->psz_last_coff != NULL) {
1142                                         status =
1143                                             dcd_auto_unregister(hdcd_handle,
1144                                                                 p_proc_object->
1145                                                                 psz_last_coff);
1146                                         /* Regardless of auto unregister status,
1147                                          *  free previously allocated
1148                                          *  memory. */
1149                                         kfree(p_proc_object->psz_last_coff);
1150                                         p_proc_object->psz_last_coff = NULL;
1151                                 }
1152                         }
1153                         /* On success, do cod_open_base() */
1154                         status = cod_open_base(cod_mgr, (char *)user_args[0],
1155                                                COD_SYMB);
1156                 }
1157         } else {
1158                 status = -ENOMEM;
1159         }
1160         if (!status) {
1161                 /* Auto-register data base */
1162                 /* Get the DCD Handle */
1163                 status = mgr_get_dcd_handle(p_proc_object->hmgr_obj,
1164                                             (u32 *) &hdcd_handle);
1165                 if (!status) {
1166                         /*  Auto register nodes in specified COFF
1167                          *  file.  If registration did not fail,
1168                          *  (status = 0 or -EACCES)
1169                          *  save the name of the COFF file for
1170                          *  de-registration in the future. */
1171                         status =
1172                             dcd_auto_register(hdcd_handle,
1173                                               (char *)user_args[0]);
1174                         if (status == -EACCES)
1175                                 status = 0;
1176
1177                         if (status) {
1178                                 status = -EPERM;
1179                         } else {
1180                                 DBC_ASSERT(p_proc_object->psz_last_coff ==
1181                                            NULL);
1182                                 /* Allocate memory for pszLastCoff */
1183                                 p_proc_object->psz_last_coff =
1184                                                 kzalloc((strlen(user_args[0]) +
1185                                                 1), GFP_KERNEL);
1186                                 /* If memory allocated, save COFF file name */
1187                                 if (p_proc_object->psz_last_coff) {
1188                                         strncpy(p_proc_object->psz_last_coff,
1189                                                 (char *)user_args[0],
1190                                                 (strlen((char *)user_args[0]) +
1191                                                  1));
1192                                 }
1193                         }
1194                 }
1195         }
1196         /* Update shared memory address and size */
1197         if (!status) {
1198                 /*  Create the message manager. This must be done
1199                  *  before calling the IOOnLoaded function. */
1200                 dev_get_msg_mgr(p_proc_object->hdev_obj, &hmsg_mgr);
1201                 if (!hmsg_mgr) {
1202                         status = msg_create(&hmsg_mgr, p_proc_object->hdev_obj,
1203                                             (msg_onexit) node_on_exit);
1204                         DBC_ASSERT(!status);
1205                         dev_set_msg_mgr(p_proc_object->hdev_obj, hmsg_mgr);
1206                 }
1207         }
1208         if (!status) {
1209                 /* Set the Device object's message manager */
1210                 status = dev_get_io_mgr(p_proc_object->hdev_obj, &hio_mgr);
1211                 if (hio_mgr)
1212                         status = (*p_proc_object->intf_fxns->pfn_io_on_loaded)
1213                                                                 (hio_mgr);
1214                 else
1215                         status = -EFAULT;
1216         }
1217         if (!status) {
1218                 /* Now, attempt to load an exec: */
1219
1220                 /* Boost the OPP level to Maximum level supported by baseport */
1221 #if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
1222                 if (pdata->cpu_set_freq)
1223                         (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP5]);
1224 #endif
1225                 status = cod_load_base(cod_mgr, argc_index, (char **)user_args,
1226                                        dev_brd_write_fxn,
1227                                        p_proc_object->hdev_obj, NULL);
1228                 if (status) {
1229                         if (status == -EBADF) {
1230                                 dev_dbg(bridge, "%s: Failure to Load the EXE\n",
1231                                         __func__);
1232                         }
1233                         if (status == -ESPIPE) {
1234                                 pr_err("%s: Couldn't parse the file\n",
1235                                        __func__);
1236                         }
1237                 }
1238                 /* Requesting the lowest opp supported */
1239 #if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
1240                 if (pdata->cpu_set_freq)
1241                         (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP1]);
1242 #endif
1243
1244         }
1245         if (!status) {
1246                 /* Update the Processor status to loaded */
1247                 status = (*p_proc_object->intf_fxns->pfn_brd_set_state)
1248                     (p_proc_object->hbridge_context, BRD_LOADED);
1249                 if (!status) {
1250                         p_proc_object->proc_state = PROC_LOADED;
1251                         if (p_proc_object->ntfy_obj)
1252                                 proc_notify_clients(p_proc_object,
1253                                                     DSP_PROCESSORSTATECHANGE);
1254                 }
1255         }
1256         if (!status) {
1257                 status = proc_get_processor_id(hprocessor, &proc_id);
1258                 if (proc_id == DSP_UNIT) {
1259                         /* Use all available DSP address space after EXTMEM
1260                          * for DMM */
1261                         if (!status)
1262                                 status = cod_get_sym_value(cod_mgr, EXTEND,
1263                                                            &dw_ext_end);
1264
1265                         /* Reset DMM structs and add an initial free chunk */
1266                         if (!status) {
1267                                 status =
1268                                     dev_get_dmm_mgr(p_proc_object->hdev_obj,
1269                                                     &dmm_mgr);
1270                                 if (dmm_mgr) {
1271                                         /* Set dw_ext_end to DMM START u8
1272                                          * address */
1273                                         dw_ext_end =
1274                                             (dw_ext_end + 1) * DSPWORDSIZE;
1275                                         /* DMM memory is from EXT_END */
1276                                         status = dmm_create_tables(dmm_mgr,
1277                                                                    dw_ext_end,
1278                                                                    DMMPOOLSIZE);
1279                                 } else {
1280                                         status = -EFAULT;
1281                                 }
1282                         }
1283                 }
1284         }
1285         /* Restore the original argv[0] */
1286         kfree(new_envp);
1287         user_args[0] = pargv0;
1288         if (!status) {
1289                 if (!((*p_proc_object->intf_fxns->pfn_brd_status)
1290                                 (p_proc_object->hbridge_context, &brd_state))) {
1291                         pr_info("%s: Processor Loaded %s\n", __func__, pargv0);
1292                         kfree(drv_datap->base_img);
1293                         drv_datap->base_img = kmalloc(strlen(pargv0) + 1,
1294                                                                 GFP_KERNEL);
1295                         if (drv_datap->base_img)
1296                                 strncpy(drv_datap->base_img, pargv0,
1297                                                         strlen(pargv0) + 1);
1298                         else
1299                                 status = -ENOMEM;
1300                         DBC_ASSERT(brd_state == BRD_LOADED);
1301                 }
1302         }
1303
1304 func_end:
1305         if (status) {
1306                 pr_err("%s: Processor failed to load\n", __func__);
1307                 proc_stop(p_proc_object);
1308         }
1309         DBC_ENSURE((!status
1310                     && p_proc_object->proc_state == PROC_LOADED)
1311                    || status);
1312 #ifdef OPT_LOAD_TIME_INSTRUMENTATION
1313         do_gettimeofday(&tv2);
1314         if (tv2.tv_usec < tv1.tv_usec) {
1315                 tv2.tv_usec += 1000000;
1316                 tv2.tv_sec--;
1317         }
1318         dev_dbg(bridge, "%s: time to load %d sec and %d usec\n", __func__,
1319                 tv2.tv_sec - tv1.tv_sec, tv2.tv_usec - tv1.tv_usec);
1320 #endif
1321         return status;
1322 }
1323
1324 /*
1325  *  ======== proc_map ========
1326  *  Purpose:
1327  *      Maps a MPU buffer to DSP address space.
1328  */
1329 int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
1330                     void *req_addr, void **pp_map_addr, u32 ul_map_attr,
1331                     struct process_context *pr_ctxt)
1332 {
1333         u32 va_align;
1334         u32 pa_align;
1335         struct dmm_object *dmm_mgr;
1336         u32 size_align;
1337         int status = 0;
1338         struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1339         struct dmm_map_object *map_obj;
1340         u32 tmp_addr = 0;
1341
1342 #ifdef CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK
1343         if ((ul_map_attr & BUFMODE_MASK) != RBUF) {
1344                 if (!IS_ALIGNED((u32)pmpu_addr, DSP_CACHE_LINE) ||
1345                     !IS_ALIGNED(ul_size, DSP_CACHE_LINE)) {
1346                         pr_err("%s: not aligned: 0x%x (%d)\n", __func__,
1347                                                 (u32)pmpu_addr, ul_size);
1348                         return -EFAULT;
1349                 }
1350         }
1351 #endif
1352
1353         /* Calculate the page-aligned PA, VA and size */
1354         va_align = PG_ALIGN_LOW((u32) req_addr, PG_SIZE4K);
1355         pa_align = PG_ALIGN_LOW((u32) pmpu_addr, PG_SIZE4K);
1356         size_align = PG_ALIGN_HIGH(ul_size + (u32) pmpu_addr - pa_align,
1357                                    PG_SIZE4K);
1358
1359         if (!p_proc_object) {
1360                 status = -EFAULT;
1361                 goto func_end;
1362         }
1363         /* Critical section */
1364         mutex_lock(&proc_lock);
1365         dmm_get_handle(p_proc_object, &dmm_mgr);
1366         if (dmm_mgr)
1367                 status = dmm_map_memory(dmm_mgr, va_align, size_align);
1368         else
1369                 status = -EFAULT;
1370
1371         /* Add mapping to the page tables. */
1372         if (!status) {
1373
1374                 /* Mapped address = MSB of VA | LSB of PA */
1375                 tmp_addr = (va_align | ((u32) pmpu_addr & (PG_SIZE4K - 1)));
1376                 /* mapped memory resource tracking */
1377                 map_obj = add_mapping_info(pr_ctxt, pa_align, tmp_addr,
1378                                                 size_align);
1379                 if (!map_obj)
1380                         status = -ENOMEM;
1381                 else
1382                         status = (*p_proc_object->intf_fxns->pfn_brd_mem_map)
1383                             (p_proc_object->hbridge_context, pa_align, va_align,
1384                              size_align, ul_map_attr, map_obj->pages);
1385         }
1386         if (!status) {
1387                 /* Mapped address = MSB of VA | LSB of PA */
1388                 *pp_map_addr = (void *) tmp_addr;
1389         } else {
1390                 remove_mapping_information(pr_ctxt, tmp_addr, size_align);
1391                 dmm_un_map_memory(dmm_mgr, va_align, &size_align);
1392         }
1393         mutex_unlock(&proc_lock);
1394
1395         if (status)
1396                 goto func_end;
1397
1398 func_end:
1399         dev_dbg(bridge, "%s: hprocessor %p, pmpu_addr %p, ul_size %x, "
1400                 "req_addr %p, ul_map_attr %x, pp_map_addr %p, va_align %x, "
1401                 "pa_align %x, size_align %x status 0x%x\n", __func__,
1402                 hprocessor, pmpu_addr, ul_size, req_addr, ul_map_attr,
1403                 pp_map_addr, va_align, pa_align, size_align, status);
1404
1405         return status;
1406 }
1407
1408 /*
1409  *  ======== proc_register_notify ========
1410  *  Purpose:
1411  *      Register to be notified of specific processor events.
1412  */
1413 int proc_register_notify(void *hprocessor, u32 event_mask,
1414                                 u32 notify_type, struct dsp_notification
1415                                 * hnotification)
1416 {
1417         int status = 0;
1418         struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1419         struct deh_mgr *hdeh_mgr;
1420
1421         DBC_REQUIRE(hnotification != NULL);
1422         DBC_REQUIRE(refs > 0);
1423
1424         /* Check processor handle */
1425         if (!p_proc_object) {
1426                 status = -EFAULT;
1427                 goto func_end;
1428         }
1429         /* Check if event mask is a valid processor related event */
1430         if (event_mask & ~(DSP_PROCESSORSTATECHANGE | DSP_PROCESSORATTACH |
1431                         DSP_PROCESSORDETACH | DSP_PROCESSORRESTART |
1432                         DSP_MMUFAULT | DSP_SYSERROR | DSP_PWRERROR |
1433                         DSP_WDTOVERFLOW))
1434                 status = -EINVAL;
1435
1436         /* Check if notify type is valid */
1437         if (notify_type != DSP_SIGNALEVENT)
1438                 status = -EINVAL;
1439
1440         if (!status) {
1441                 /* If event mask is not DSP_SYSERROR, DSP_MMUFAULT,
1442                  * or DSP_PWRERROR then register event immediately. */
1443                 if (event_mask &
1444                     ~(DSP_SYSERROR | DSP_MMUFAULT | DSP_PWRERROR |
1445                                 DSP_WDTOVERFLOW)) {
1446                         status = ntfy_register(p_proc_object->ntfy_obj,
1447                                                hnotification, event_mask,
1448                                                notify_type);
1449                         /* Special case alert, special case alert!
1450                          * If we're trying to *deregister* (i.e. event_mask
1451                          * is 0), a DSP_SYSERROR or DSP_MMUFAULT notification,
1452                          * we have to deregister with the DEH manager.
1453                          * There's no way to know, based on event_mask which
1454                          * manager the notification event was registered with,
1455                          * so if we're trying to deregister and ntfy_register
1456                          * failed, we'll give the deh manager a shot.
1457                          */
1458                         if ((event_mask == 0) && status) {
1459                                 status =
1460                                     dev_get_deh_mgr(p_proc_object->hdev_obj,
1461                                                     &hdeh_mgr);
1462                                 status =
1463                                         bridge_deh_register_notify(hdeh_mgr,
1464                                                         event_mask,
1465                                                         notify_type,
1466                                                         hnotification);
1467                         }
1468                 } else {
1469                         status = dev_get_deh_mgr(p_proc_object->hdev_obj,
1470                                                  &hdeh_mgr);
1471                         status =
1472                             bridge_deh_register_notify(hdeh_mgr,
1473                                             event_mask,
1474                                             notify_type,
1475                                             hnotification);
1476
1477                 }
1478         }
1479 func_end:
1480         return status;
1481 }
1482
1483 /*
1484  *  ======== proc_reserve_memory ========
1485  *  Purpose:
1486  *      Reserve a virtually contiguous region of DSP address space.
1487  */
1488 int proc_reserve_memory(void *hprocessor, u32 ul_size,
1489                                void **pp_rsv_addr,
1490                                struct process_context *pr_ctxt)
1491 {
1492         struct dmm_object *dmm_mgr;
1493         int status = 0;
1494         struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1495         struct dmm_rsv_object *rsv_obj;
1496
1497         if (!p_proc_object) {
1498                 status = -EFAULT;
1499                 goto func_end;
1500         }
1501
1502         status = dmm_get_handle(p_proc_object, &dmm_mgr);
1503         if (!dmm_mgr) {
1504                 status = -EFAULT;
1505                 goto func_end;
1506         }
1507
1508         status = dmm_reserve_memory(dmm_mgr, ul_size, (u32 *) pp_rsv_addr);
1509         if (status != 0)
1510                 goto func_end;
1511
1512         /*
1513          * A successful reserve should be followed by insertion of rsv_obj
1514          * into dmm_rsv_list, so that reserved memory resource tracking
1515          * remains uptodate
1516          */
1517         rsv_obj = kmalloc(sizeof(struct dmm_rsv_object), GFP_KERNEL);
1518         if (rsv_obj) {
1519                 rsv_obj->dsp_reserved_addr = (u32) *pp_rsv_addr;
1520                 spin_lock(&pr_ctxt->dmm_rsv_lock);
1521                 list_add(&rsv_obj->link, &pr_ctxt->dmm_rsv_list);
1522                 spin_unlock(&pr_ctxt->dmm_rsv_lock);
1523         }
1524
1525 func_end:
1526         dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p "
1527                 "status 0x%x\n", __func__, hprocessor,
1528                 ul_size, pp_rsv_addr, status);
1529         return status;
1530 }
1531
1532 /*
1533  *  ======== proc_start ========
1534  *  Purpose:
1535  *      Start a processor running.
1536  */
1537 int proc_start(void *hprocessor)
1538 {
1539         int status = 0;
1540         struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1541         struct cod_manager *cod_mgr;    /* Code manager handle */
1542         u32 dw_dsp_addr;        /* Loaded code's entry point. */
1543         int brd_state;
1544
1545         DBC_REQUIRE(refs > 0);
1546         if (!p_proc_object) {
1547                 status = -EFAULT;
1548                 goto func_end;
1549         }
1550         /* Call the bridge_brd_start */
1551         if (p_proc_object->proc_state != PROC_LOADED) {
1552                 status = -EBADR;
1553                 goto func_end;
1554         }
1555         status = dev_get_cod_mgr(p_proc_object->hdev_obj, &cod_mgr);
1556         if (!cod_mgr) {
1557                 status = -EFAULT;
1558                 goto func_cont;
1559         }
1560
1561         status = cod_get_entry(cod_mgr, &dw_dsp_addr);
1562         if (status)
1563                 goto func_cont;
1564
1565         status = (*p_proc_object->intf_fxns->pfn_brd_start)
1566             (p_proc_object->hbridge_context, dw_dsp_addr);
1567         if (status)
1568                 goto func_cont;
1569
1570         /* Call dev_create2 */
1571         status = dev_create2(p_proc_object->hdev_obj);
1572         if (!status) {
1573                 p_proc_object->proc_state = PROC_RUNNING;
1574                 /* Deep sleep switces off the peripheral clocks.
1575                  * we just put the DSP CPU in idle in the idle loop.
1576                  * so there is no need to send a command to DSP */
1577
1578                 if (p_proc_object->ntfy_obj) {
1579                         proc_notify_clients(p_proc_object,
1580                                             DSP_PROCESSORSTATECHANGE);
1581                 }
1582         } else {
1583                 /* Failed to Create Node Manager and DISP Object
1584                  * Stop the Processor from running. Put it in STOPPED State */
1585                 (void)(*p_proc_object->intf_fxns->
1586                        pfn_brd_stop) (p_proc_object->hbridge_context);
1587                 p_proc_object->proc_state = PROC_STOPPED;
1588         }
1589 func_cont:
1590         if (!status) {
1591                 if (!((*p_proc_object->intf_fxns->pfn_brd_status)
1592                                 (p_proc_object->hbridge_context, &brd_state))) {
1593                         pr_info("%s: dsp in running state\n", __func__);
1594                         DBC_ASSERT(brd_state != BRD_HIBERNATION);
1595                 }
1596         } else {
1597                 pr_err("%s: Failed to start the dsp\n", __func__);
1598                 proc_stop(p_proc_object);
1599         }
1600
1601 func_end:
1602         DBC_ENSURE((!status && p_proc_object->proc_state ==
1603                     PROC_RUNNING) || status);
1604         return status;
1605 }
1606
1607 /*
1608  *  ======== proc_stop ========
1609  *  Purpose:
1610  *      Stop a processor running.
1611  */
1612 int proc_stop(void *hprocessor)
1613 {
1614         int status = 0;
1615         struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1616         struct msg_mgr *hmsg_mgr;
1617         struct node_mgr *hnode_mgr;
1618         void *hnode;
1619         u32 node_tab_size = 1;
1620         u32 num_nodes = 0;
1621         u32 nodes_allocated = 0;
1622         int brd_state;
1623
1624         DBC_REQUIRE(refs > 0);
1625         if (!p_proc_object) {
1626                 status = -EFAULT;
1627                 goto func_end;
1628         }
1629         /* check if there are any running nodes */
1630         status = dev_get_node_manager(p_proc_object->hdev_obj, &hnode_mgr);
1631         if (!status && hnode_mgr) {
1632                 status = node_enum_nodes(hnode_mgr, &hnode, node_tab_size,
1633                                          &num_nodes, &nodes_allocated);
1634                 if ((status == -EINVAL) || (nodes_allocated > 0)) {
1635                         pr_err("%s: Can't stop device, active nodes = %d \n",
1636                                __func__, nodes_allocated);
1637                         return -EBADR;
1638                 }
1639         }
1640         /* Call the bridge_brd_stop */
1641         /* It is OK to stop a device that does n't have nodes OR not started */
1642         status =
1643             (*p_proc_object->intf_fxns->
1644              pfn_brd_stop) (p_proc_object->hbridge_context);
1645         if (!status) {
1646                 dev_dbg(bridge, "%s: processor in standby mode\n", __func__);
1647                 p_proc_object->proc_state = PROC_STOPPED;
1648                 /* Destory the Node Manager, msg_ctrl Manager */
1649                 if (!(dev_destroy2(p_proc_object->hdev_obj))) {
1650                         /* Destroy the msg_ctrl by calling msg_delete */
1651                         dev_get_msg_mgr(p_proc_object->hdev_obj, &hmsg_mgr);
1652                         if (hmsg_mgr) {
1653                                 msg_delete(hmsg_mgr);
1654                                 dev_set_msg_mgr(p_proc_object->hdev_obj, NULL);
1655                         }
1656                         if (!((*p_proc_object->
1657                               intf_fxns->pfn_brd_status) (p_proc_object->
1658                                                           hbridge_context,
1659                                                           &brd_state)))
1660                                 DBC_ASSERT(brd_state == BRD_STOPPED);
1661                 }
1662         } else {
1663                 pr_err("%s: Failed to stop the processor\n", __func__);
1664         }
1665 func_end:
1666
1667         return status;
1668 }
1669
1670 /*
1671  *  ======== proc_un_map ========
1672  *  Purpose:
1673  *      Removes a MPU buffer mapping from the DSP address space.
1674  */
1675 int proc_un_map(void *hprocessor, void *map_addr,
1676                        struct process_context *pr_ctxt)
1677 {
1678         int status = 0;
1679         struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1680         struct dmm_object *dmm_mgr;
1681         u32 va_align;
1682         u32 size_align;
1683
1684         va_align = PG_ALIGN_LOW((u32) map_addr, PG_SIZE4K);
1685         if (!p_proc_object) {
1686                 status = -EFAULT;
1687                 goto func_end;
1688         }
1689
1690         status = dmm_get_handle(hprocessor, &dmm_mgr);
1691         if (!dmm_mgr) {
1692                 status = -EFAULT;
1693                 goto func_end;
1694         }
1695
1696         /* Critical section */
1697         mutex_lock(&proc_lock);
1698         /*
1699          * Update DMM structures. Get the size to unmap.
1700          * This function returns error if the VA is not mapped
1701          */
1702         status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align);
1703         /* Remove mapping from the page tables. */
1704         if (!status) {
1705                 status = (*p_proc_object->intf_fxns->pfn_brd_mem_un_map)
1706                     (p_proc_object->hbridge_context, va_align, size_align);
1707         }
1708
1709         mutex_unlock(&proc_lock);
1710         if (status)
1711                 goto func_end;
1712
1713         /*
1714          * A successful unmap should be followed by removal of map_obj
1715          * from dmm_map_list, so that mapped memory resource tracking
1716          * remains uptodate
1717          */
1718         remove_mapping_information(pr_ctxt, (u32) map_addr, size_align);
1719
1720 func_end:
1721         dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n",
1722                 __func__, hprocessor, map_addr, status);
1723         return status;
1724 }
1725
1726 /*
1727  *  ======== proc_un_reserve_memory ========
1728  *  Purpose:
1729  *      Frees a previously reserved region of DSP address space.
1730  */
1731 int proc_un_reserve_memory(void *hprocessor, void *prsv_addr,
1732                                   struct process_context *pr_ctxt)
1733 {
1734         struct dmm_object *dmm_mgr;
1735         int status = 0;
1736         struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1737         struct dmm_rsv_object *rsv_obj;
1738
1739         if (!p_proc_object) {
1740                 status = -EFAULT;
1741                 goto func_end;
1742         }
1743
1744         status = dmm_get_handle(p_proc_object, &dmm_mgr);
1745         if (!dmm_mgr) {
1746                 status = -EFAULT;
1747                 goto func_end;
1748         }
1749
1750         status = dmm_un_reserve_memory(dmm_mgr, (u32) prsv_addr);
1751         if (status != 0)
1752                 goto func_end;
1753
1754         /*
1755          * A successful unreserve should be followed by removal of rsv_obj
1756          * from dmm_rsv_list, so that reserved memory resource tracking
1757          * remains uptodate
1758          */
1759         spin_lock(&pr_ctxt->dmm_rsv_lock);
1760         list_for_each_entry(rsv_obj, &pr_ctxt->dmm_rsv_list, link) {
1761                 if (rsv_obj->dsp_reserved_addr == (u32) prsv_addr) {
1762                         list_del(&rsv_obj->link);
1763                         kfree(rsv_obj);
1764                         break;
1765                 }
1766         }
1767         spin_unlock(&pr_ctxt->dmm_rsv_lock);
1768
1769 func_end:
1770         dev_dbg(bridge, "%s: hprocessor: 0x%p prsv_addr: 0x%p status: 0x%x\n",
1771                 __func__, hprocessor, prsv_addr, status);
1772         return status;
1773 }
1774
1775 /*
1776  *  ======== = proc_monitor ======== ==
1777  *  Purpose:
1778  *      Place the Processor in Monitor State. This is an internal
1779  *      function and a requirement before Processor is loaded.
1780  *      This does a bridge_brd_stop, dev_destroy2 and bridge_brd_monitor.
1781  *      In dev_destroy2 we delete the node manager.
1782  *  Parameters:
1783  *      p_proc_object:    Pointer to Processor Object
1784  *  Returns:
1785  *      0:      Processor placed in monitor mode.
1786  *      !0:       Failed to place processor in monitor mode.
1787  *  Requires:
1788  *      Valid Processor Handle
1789  *  Ensures:
1790  *      Success:        ProcObject state is PROC_IDLE
1791  */
1792 static int proc_monitor(struct proc_object *proc_obj)
1793 {
1794         int status = -EPERM;
1795         struct msg_mgr *hmsg_mgr;
1796         int brd_state;
1797
1798         DBC_REQUIRE(refs > 0);
1799         DBC_REQUIRE(proc_obj);
1800
1801         /* This is needed only when Device is loaded when it is
1802          * already 'ACTIVE' */
1803         /* Destory the Node Manager, msg_ctrl Manager */
1804         if (!dev_destroy2(proc_obj->hdev_obj)) {
1805                 /* Destroy the msg_ctrl by calling msg_delete */
1806                 dev_get_msg_mgr(proc_obj->hdev_obj, &hmsg_mgr);
1807                 if (hmsg_mgr) {
1808                         msg_delete(hmsg_mgr);
1809                         dev_set_msg_mgr(proc_obj->hdev_obj, NULL);
1810                 }
1811         }
1812         /* Place the Board in the Monitor State */
1813         if (!((*proc_obj->intf_fxns->pfn_brd_monitor)
1814                           (proc_obj->hbridge_context))) {
1815                 status = 0;
1816                 if (!((*proc_obj->intf_fxns->pfn_brd_status)
1817                                   (proc_obj->hbridge_context, &brd_state)))
1818                         DBC_ASSERT(brd_state == BRD_IDLE);
1819         }
1820
1821         DBC_ENSURE((!status && brd_state == BRD_IDLE) ||
1822                    status);
1823         return status;
1824 }
1825
1826 /*
1827  *  ======== get_envp_count ========
1828  *  Purpose:
1829  *      Return the number of elements in the envp array, including the
1830  *      terminating NULL element.
1831  */
1832 static s32 get_envp_count(char **envp)
1833 {
1834         s32 ret = 0;
1835         if (envp) {
1836                 while (*envp++)
1837                         ret++;
1838
1839                 ret += 1;       /* Include the terminating NULL in the count. */
1840         }
1841
1842         return ret;
1843 }
1844
1845 /*
1846  *  ======== prepend_envp ========
1847  *  Purpose:
1848  *      Prepend an environment variable=value pair to the new envp array, and
1849  *      copy in the existing var=value pairs in the old envp array.
1850  */
1851 static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems,
1852                            s32 cnew_envp, char *sz_var)
1853 {
1854         char **pp_envp = new_envp;
1855
1856         DBC_REQUIRE(new_envp);
1857
1858         /* Prepend new environ var=value string */
1859         *new_envp++ = sz_var;
1860
1861         /* Copy user's environment into our own. */
1862         while (envp_elems--)
1863                 *new_envp++ = *envp++;
1864
1865         /* Ensure NULL terminates the new environment strings array. */
1866         if (envp_elems == 0)
1867                 *new_envp = NULL;
1868
1869         return pp_envp;
1870 }
1871
1872 /*
1873  *  ======== proc_notify_clients ========
1874  *  Purpose:
1875  *      Notify the processor the events.
1876  */
1877 int proc_notify_clients(void *proc, u32 events)
1878 {
1879         int status = 0;
1880         struct proc_object *p_proc_object = (struct proc_object *)proc;
1881
1882         DBC_REQUIRE(p_proc_object);
1883         DBC_REQUIRE(is_valid_proc_event(events));
1884         DBC_REQUIRE(refs > 0);
1885         if (!p_proc_object) {
1886                 status = -EFAULT;
1887                 goto func_end;
1888         }
1889
1890         ntfy_notify(p_proc_object->ntfy_obj, events);
1891 func_end:
1892         return status;
1893 }
1894
1895 /*
1896  *  ======== proc_notify_all_clients ========
1897  *  Purpose:
1898  *      Notify the processor the events. This includes notifying all clients
1899  *      attached to a particulat DSP.
1900  */
1901 int proc_notify_all_clients(void *proc, u32 events)
1902 {
1903         int status = 0;
1904         struct proc_object *p_proc_object = (struct proc_object *)proc;
1905
1906         DBC_REQUIRE(is_valid_proc_event(events));
1907         DBC_REQUIRE(refs > 0);
1908
1909         if (!p_proc_object) {
1910                 status = -EFAULT;
1911                 goto func_end;
1912         }
1913
1914         dev_notify_clients(p_proc_object->hdev_obj, events);
1915
1916 func_end:
1917         return status;
1918 }
1919
1920 /*
1921  *  ======== proc_get_processor_id ========
1922  *  Purpose:
1923  *      Retrieves the processor ID.
1924  */
1925 int proc_get_processor_id(void *proc, u32 * proc_id)
1926 {
1927         int status = 0;
1928         struct proc_object *p_proc_object = (struct proc_object *)proc;
1929
1930         if (p_proc_object)
1931                 *proc_id = p_proc_object->processor_id;
1932         else
1933                 status = -EFAULT;
1934
1935         return status;
1936 }