~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/dsp/syslink/procmgr/proc4430/proc4430.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * proc4430.c
3
 
 *
4
 
 * Syslink driver support functions for TI OMAP processors.
5
 
 *
6
 
 * Copyright (C) 2009-2010 Texas Instruments, Inc.
7
 
 *
8
 
 * This package is free software; you can redistribute it and/or modify
9
 
 * it under the terms of the GNU General Public License version 2 as
10
 
 * published by the Free Software Foundation.
11
 
 *
12
 
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
13
 
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
14
 
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15
 
 */
16
 
 
17
 
#include <linux/types.h>
18
 
#include <linux/mm.h>
19
 
#include <linux/sched.h>
20
 
#include <linux/module.h>
21
 
#include <linux/mutex.h>
22
 
#include <linux/vmalloc.h>
23
 
#include <linux/uaccess.h>
24
 
#include <linux/io.h>
25
 
#include <linux/delay.h>
26
 
#include <linux/slab.h>
27
 
 
28
 
/* Module level headers */
29
 
#include "../procdefs.h"
30
 
#include "../processor.h"
31
 
#include <procmgr.h>
32
 
#include "../procmgr_drvdefs.h"
33
 
#include "proc4430.h"
34
 
#include "../../ipu_pm/ipu_pm.h"
35
 
#include <syslink/multiproc.h>
36
 
#include <syslink/platform_mem.h>
37
 
#include <syslink/atomic_linux.h>
38
 
 
39
 
 
40
 
#define OMAP4430PROC_MODULEID          (u16) 0xbbec
41
 
 
42
 
/* Macro to make a correct module magic number with refCount */
43
 
#define OMAP4430PROC_MAKE_MAGICSTAMP(x) ((OMAP4430PROC_MODULEID << 12u) | (x))
44
 
 
45
 
#define PG_MASK(pg_size) (~((pg_size)-1))
46
 
#define PG_ALIGN_LOW(addr, pg_size) ((addr) & PG_MASK(pg_size))
47
 
 
48
 
/*OMAP4430 Module state object */
49
 
struct proc4430_module_object {
50
 
        u32 config_size;
51
 
        /* Size of configuration structure */
52
 
        struct proc4430_config cfg;
53
 
        /* OMAP4430 configuration structure */
54
 
        struct proc4430_config def_cfg;
55
 
        /* Default module configuration */
56
 
        struct proc4430_params def_inst_params;
57
 
        /* Default parameters for the OMAP4430 instances */
58
 
        void *proc_handles[MULTIPROC_MAXPROCESSORS];
59
 
        /* Processor handle array. */
60
 
        struct mutex *gate_handle;
61
 
        /* void * of gate to be used for local thread safety */
62
 
        atomic_t ref_count;
63
 
};
64
 
 
65
 
/*
66
 
  OMAP4430 instance object.
67
 
 */
68
 
struct proc4430_object {
69
 
        struct proc4430_params params;
70
 
        /* Instance parameters (configuration values) */
71
 
        atomic_t attach_count;
72
 
        /* attach reference count */
73
 
};
74
 
 
75
 
 
76
 
/* =================================
77
 
 *  Globals
78
 
 * =================================
79
 
 */
80
 
/*
81
 
  OMAP4430 state object variable
82
 
 */
83
 
 
84
 
static struct proc4430_module_object proc4430_state = {
85
 
        .config_size = sizeof(struct proc4430_config),
86
 
        .gate_handle = NULL,
87
 
        .def_inst_params.num_mem_entries = 0u,
88
 
        .def_inst_params.mem_entries = NULL,
89
 
        .def_inst_params.reset_vector_mem_entry = 0
90
 
};
91
 
 
92
 
 
93
 
/* =================================
94
 
 * APIs directly called by applications
95
 
 * =================================
96
 
 */
97
 
/*
98
 
 * Function to get the default configuration for the OMAP4430
99
 
 * module.
100
 
 *
101
 
 * This function can be called by the application to get their
102
 
 * configuration parameter to proc4430_setup filled in by the
103
 
 * OMAP4430 module with the default parameters. If the user
104
 
 * does not wish to make any change in the default parameters, this
105
 
 * API is not required to be called.
106
 
 */
107
 
void proc4430_get_config(struct proc4430_config *cfg)
108
 
{
109
 
        BUG_ON(cfg == NULL);
110
 
        memcpy(cfg, &(proc4430_state.def_cfg),
111
 
                        sizeof(struct proc4430_config));
112
 
}
113
 
EXPORT_SYMBOL(proc4430_get_config);
114
 
 
115
 
/*
116
 
 * Function to setup the OMAP4430 module.
117
 
 *
118
 
 * This function sets up the OMAP4430 module. This function
119
 
 * must be called before any other instance-level APIs can be
120
 
 * invoked.
121
 
 * Module-level configuration needs to be provided to this
122
 
 * function. If the user wishes to change some specific config
123
 
 * parameters, then proc4430_get_config can be called to get the
124
 
 * configuration filled with the default values. After this, only
125
 
 * the required configuration values can be changed. If the user
126
 
 * does not wish to make any change in the default parameters, the
127
 
 * application can simply call proc4430_setup with NULL
128
 
 * parameters. The default parameters would get automatically used.
129
 
 */
130
 
int proc4430_setup(struct proc4430_config *cfg)
131
 
{
132
 
        int retval = 0;
133
 
        struct proc4430_config tmp_cfg;
134
 
        atomic_cmpmask_and_set(&proc4430_state.ref_count,
135
 
                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
136
 
                                 OMAP4430PROC_MAKE_MAGICSTAMP(0));
137
 
 
138
 
        if (atomic_inc_return(&proc4430_state.ref_count) !=
139
 
                                OMAP4430PROC_MAKE_MAGICSTAMP(1)) {
140
 
                return 1;
141
 
        }
142
 
 
143
 
        if (cfg == NULL) {
144
 
                proc4430_get_config(&tmp_cfg);
145
 
                cfg = &tmp_cfg;
146
 
        }
147
 
 
148
 
        /* Create a default gate handle for local module protection. */
149
 
        proc4430_state.gate_handle =
150
 
                kmalloc(sizeof(struct mutex), GFP_KERNEL);
151
 
        if (proc4430_state.gate_handle == NULL) {
152
 
                retval = -ENOMEM;
153
 
                goto error;
154
 
        }
155
 
 
156
 
        mutex_init(proc4430_state.gate_handle);
157
 
 
158
 
        /* Initialize the name to handles mapping array. */
159
 
        memset(&proc4430_state.proc_handles, 0,
160
 
                (sizeof(void *) * MULTIPROC_MAXPROCESSORS));
161
 
 
162
 
        /* Copy the user provided values into the state object. */
163
 
        memcpy(&proc4430_state.cfg, cfg,
164
 
                                sizeof(struct proc4430_config));
165
 
 
166
 
        return 0;
167
 
 
168
 
error:
169
 
        atomic_dec_return(&proc4430_state.ref_count);
170
 
 
171
 
        return retval;
172
 
}
173
 
EXPORT_SYMBOL(proc4430_setup);
174
 
 
175
 
/*
176
 
 * Function to destroy the OMAP4430 module.
177
 
 *
178
 
 * Once this function is called, other OMAP4430 module APIs,
179
 
 * except for the proc4430_get_config API cannot be called
180
 
 * anymore.
181
 
 */
182
 
int proc4430_destroy(void)
183
 
{
184
 
        int retval = 0;
185
 
        u16 i;
186
 
 
187
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
188
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
189
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
190
 
                                        == true) {
191
 
                retval = -ENODEV;
192
 
                goto exit;
193
 
        }
194
 
        if (!(atomic_dec_return(&proc4430_state.ref_count)
195
 
                        == OMAP4430PROC_MAKE_MAGICSTAMP(0))) {
196
 
 
197
 
                retval = 1;
198
 
                goto exit;
199
 
        }
200
 
 
201
 
        /* Check if any OMAP4430 instances have not been
202
 
         * deleted so far. If not,delete them.
203
 
         */
204
 
 
205
 
        for (i = 0; i < MULTIPROC_MAXPROCESSORS; i++) {
206
 
                if (proc4430_state.proc_handles[i] == NULL)
207
 
                        continue;
208
 
                proc4430_delete(&(proc4430_state.proc_handles[i]));
209
 
        }
210
 
 
211
 
        /* Check if the gate_handle was created internally. */
212
 
        if (proc4430_state.gate_handle != NULL) {
213
 
                mutex_destroy(proc4430_state.gate_handle);
214
 
                kfree(proc4430_state.gate_handle);
215
 
        }
216
 
 
217
 
exit:
218
 
        return retval;
219
 
}
220
 
EXPORT_SYMBOL(proc4430_destroy);
221
 
 
222
 
/*=================================================
223
 
 * Function to initialize the parameters for this Processor
224
 
 * instance.
225
 
 */
226
 
void proc4430_params_init(void *handle, struct proc4430_params *params)
227
 
{
228
 
        struct proc4430_object *proc_object = (struct proc4430_object *)handle;
229
 
 
230
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
231
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
232
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
233
 
                                        == true) {
234
 
                pr_err("proc4430_params_init failed - Module not initialized");
235
 
                return;
236
 
        }
237
 
 
238
 
        if (WARN_ON(params == NULL)) {
239
 
                pr_err("proc4430_params_init failed "
240
 
                        "Argument of type proc4430_params * "
241
 
                        "is NULL");
242
 
                return;
243
 
        }
244
 
 
245
 
        if (handle == NULL)
246
 
                memcpy(params, &(proc4430_state.def_inst_params),
247
 
                                sizeof(struct proc4430_params));
248
 
        else
249
 
                memcpy(params, &(proc_object->params),
250
 
                                sizeof(struct proc4430_params));
251
 
}
252
 
EXPORT_SYMBOL(proc4430_params_init);
253
 
 
254
 
/*===================================================
255
 
 *Function to create an instance of this Processor.
256
 
 *
257
 
 */
258
 
void *proc4430_create(u16 proc_id, const struct proc4430_params *params)
259
 
{
260
 
        struct processor_object *handle = NULL;
261
 
        struct proc4430_object *object = NULL;
262
 
 
263
 
        BUG_ON(!IS_VALID_PROCID(proc_id));
264
 
        BUG_ON(params == NULL);
265
 
 
266
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
267
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
268
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
269
 
                                        == true) {
270
 
                pr_err("proc4430_create failed - Module not initialized");
271
 
                goto error;
272
 
        }
273
 
 
274
 
        /* Enter critical section protection. */
275
 
        WARN_ON(mutex_lock_interruptible(proc4430_state.gate_handle));
276
 
        if (proc4430_state.proc_handles[proc_id] != NULL) {
277
 
                handle = proc4430_state.proc_handles[proc_id];
278
 
                goto func_end;
279
 
        } else {
280
 
                handle = (struct processor_object *)
281
 
                        vmalloc(sizeof(struct processor_object));
282
 
                if (WARN_ON(handle == NULL))
283
 
                        goto func_end;
284
 
 
285
 
                handle->proc_fxn_table.attach = &proc4430_attach;
286
 
                handle->proc_fxn_table.detach = &proc4430_detach;
287
 
                handle->proc_fxn_table.read = &proc4430_read;
288
 
                handle->proc_fxn_table.write = &proc4430_write;
289
 
                handle->proc_fxn_table.control = &proc4430_control;
290
 
                handle->proc_fxn_table.translateAddr =
291
 
                                         &proc4430_translate_addr;
292
 
                handle->proc_fxn_table.procinfo = &proc4430_proc_info;
293
 
                handle->proc_fxn_table.virt_to_phys = &proc4430_virt_to_phys;
294
 
                handle->state = PROC_MGR_STATE_UNKNOWN;
295
 
                handle->object = vmalloc(sizeof(struct proc4430_object));
296
 
                handle->proc_id = proc_id;
297
 
                object = (struct proc4430_object *)handle->object;
298
 
                if (params != NULL) {
299
 
                        /* Copy params into instance object. */
300
 
                        memcpy(&(object->params), (void *)params,
301
 
                                        sizeof(struct proc4430_params));
302
 
                }
303
 
                if ((params != NULL) && (params->mem_entries != NULL)
304
 
                                        && (params->num_mem_entries > 0)) {
305
 
                        /* Allocate memory for, and copy mem_entries table*/
306
 
                        object->params.mem_entries = vmalloc(sizeof(struct
307
 
                                                proc4430_mem_entry) *
308
 
                                                params->num_mem_entries);
309
 
                        memcpy(object->params.mem_entries,
310
 
                                params->mem_entries,
311
 
                                (sizeof(struct proc4430_mem_entry) *
312
 
                                 params->num_mem_entries));
313
 
                }
314
 
                handle->boot_mode = PROC_MGR_BOOTMODE_NOLOAD;
315
 
                /* Set the handle in the state object. */
316
 
                proc4430_state.proc_handles[proc_id] = handle;
317
 
        }
318
 
 
319
 
func_end:
320
 
        mutex_unlock(proc4430_state.gate_handle);
321
 
error:
322
 
        return (void *)handle;
323
 
}
324
 
EXPORT_SYMBOL(proc4430_create);
325
 
 
326
 
/*=================================================
327
 
 * Function to delete an instance of this Processor.
328
 
 *
329
 
 * The user provided pointer to the handle is reset after
330
 
 * successful completion of this function.
331
 
 *
332
 
 */
333
 
int proc4430_delete(void **handle_ptr)
334
 
{
335
 
        int retval = 0;
336
 
        struct proc4430_object *object = NULL;
337
 
        struct processor_object *handle;
338
 
 
339
 
        BUG_ON(handle_ptr == NULL);
340
 
        BUG_ON(*handle_ptr == NULL);
341
 
 
342
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
343
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
344
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
345
 
                                        == true) {
346
 
                pr_err("proc4430_delete failed Module not initialized");
347
 
                return -ENODEV;
348
 
        }
349
 
 
350
 
        handle = (struct processor_object *)(*handle_ptr);
351
 
        BUG_ON(!IS_VALID_PROCID(handle->proc_id));
352
 
        /* Enter critical section protection. */
353
 
        WARN_ON(mutex_lock_interruptible(proc4430_state.gate_handle));
354
 
        /* Reset handle in PwrMgr handle array. */
355
 
        proc4430_state.proc_handles[handle->proc_id] = NULL;
356
 
        /* Free memory used for the OMAP4430 object. */
357
 
        if (handle->object != NULL) {
358
 
                object = (struct proc4430_object *)handle->object;
359
 
                if (object->params.mem_entries != NULL) {
360
 
                        vfree(object->params.mem_entries);
361
 
                        object->params.mem_entries = NULL;
362
 
                }
363
 
                vfree(handle->object);
364
 
                handle->object = NULL;
365
 
        }
366
 
        /* Free memory used for the Processor object. */
367
 
        vfree(handle);
368
 
        *handle_ptr = NULL;
369
 
        /* Leave critical section protection. */
370
 
        mutex_unlock(proc4430_state.gate_handle);
371
 
        return retval;
372
 
}
373
 
EXPORT_SYMBOL(proc4430_delete);
374
 
 
375
 
/*===================================================
376
 
 * Function to open a handle to an instance of this Processor. This
377
 
 * function is called when access to the Processor is required from
378
 
 * a different process.
379
 
 */
380
 
int proc4430_open(void **handle_ptr, u16 proc_id)
381
 
{
382
 
        int retval = 0;
383
 
 
384
 
        BUG_ON(handle_ptr == NULL);
385
 
        BUG_ON(!IS_VALID_PROCID(proc_id));
386
 
 
387
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
388
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
389
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
390
 
                                        == true) {
391
 
                pr_err("proc4430_open failed Module not initialized");
392
 
                return -ENODEV;
393
 
        }
394
 
 
395
 
        /* Initialize return parameter handle. */
396
 
        *handle_ptr = NULL;
397
 
 
398
 
        /* Check if the PwrMgr exists and return the handle if found. */
399
 
        if (proc4430_state.proc_handles[proc_id] == NULL) {
400
 
                retval = -ENODEV;
401
 
                goto func_exit;
402
 
        } else
403
 
                *handle_ptr = proc4430_state.proc_handles[proc_id];
404
 
func_exit:
405
 
        return retval;
406
 
}
407
 
EXPORT_SYMBOL(proc4430_open);
408
 
 
409
 
/*===============================================
410
 
 * Function to close a handle to an instance of this Processor.
411
 
 *
412
 
 */
413
 
int proc4430_close(void *handle)
414
 
{
415
 
        int retval = 0;
416
 
 
417
 
        BUG_ON(handle == NULL);
418
 
 
419
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
420
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
421
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
422
 
                                        == true) {
423
 
                pr_err("proc4430_close failed Module not initialized");
424
 
                return -ENODEV;
425
 
        }
426
 
 
427
 
        /* nothing to be done for now */
428
 
        return retval;
429
 
}
430
 
EXPORT_SYMBOL(proc4430_close);
431
 
 
432
 
/* =================================
433
 
 * APIs called by Processor module (part of function table interface)
434
 
 * =================================
435
 
 */
436
 
/*================================
437
 
 * Function to initialize the slave processor
438
 
 *
439
 
 */
440
 
int proc4430_attach(void *handle, struct processor_attach_params *params)
441
 
{
442
 
        int retval = 0;
443
 
 
444
 
        struct processor_object *proc_handle = NULL;
445
 
        struct proc4430_object *object = NULL;
446
 
        u32 map_count = 0;
447
 
        u32 i;
448
 
        memory_map_info map_info;
449
 
 
450
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
451
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
452
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
453
 
                                        == true) {
454
 
                pr_err("proc4430_attach failed Module not initialized");
455
 
                return -ENODEV;
456
 
        }
457
 
 
458
 
        if (WARN_ON(handle == NULL)) {
459
 
                pr_err("proc4430_attach failed Driver handle is NULL");
460
 
                return -EINVAL;
461
 
        }
462
 
 
463
 
        if (WARN_ON(params == NULL)) {
464
 
                pr_err("proc4430_attach failed"
465
 
                        "Argument processor_attach_params * is NULL");
466
 
                return -EINVAL;
467
 
        }
468
 
 
469
 
        proc_handle = (struct processor_object *)handle;
470
 
 
471
 
        object = (struct proc4430_object *)proc_handle->object;
472
 
 
473
 
        atomic_cmpmask_and_set(&object->attach_count,
474
 
                                OMAP4430PROC_MAKE_MAGICSTAMP(0),
475
 
                                OMAP4430PROC_MAKE_MAGICSTAMP(0));
476
 
        atomic_inc_return(&object->attach_count);
477
 
 
478
 
        pr_err("proc4430_attach num_mem_entries = %d",
479
 
                                object->params.num_mem_entries);
480
 
        /* Return memory information in params. */
481
 
        for (i = 0; (i < object->params.num_mem_entries); i++) {
482
 
                /* If the configured master virtual address is invalid, get the
483
 
                * actual address by mapping the physical address into master
484
 
                * kernel memory space.
485
 
                */
486
 
                if ((object->params.mem_entries[i].master_virt_addr == (u32)-1)
487
 
                && (object->params.mem_entries[i].shared == true)) {
488
 
                        map_info.src = object->params.mem_entries[i].phys_addr;
489
 
                        map_info.size = object->params.mem_entries[i].size;
490
 
                        map_info.is_cached = false;
491
 
                        retval = platform_mem_map(&map_info);
492
 
                        if (retval != 0) {
493
 
                                pr_err("proc4430_attach failed\n");
494
 
                                return -EFAULT;
495
 
                        }
496
 
                        map_count++;
497
 
                        object->params.mem_entries[i].master_virt_addr =
498
 
                                                                map_info.dst;
499
 
                        params->mem_entries[i].addr
500
 
                                [PROC_MGR_ADDRTYPE_MASTERKNLVIRT] =
501
 
                                                                map_info.dst;
502
 
                        params->mem_entries[i].addr
503
 
                                [PROC_MGR_ADDRTYPE_SLAVEVIRT] =
504
 
                        (object->params.mem_entries[i].slave_virt_addr);
505
 
                        /* User virtual will be filled by user side. For now,
506
 
                        fill in the physical address so that it can be used
507
 
                        by mmap to remap this region into user-space */
508
 
                        params->mem_entries[i].addr
509
 
                                [PROC_MGR_ADDRTYPE_MASTERUSRVIRT] = \
510
 
                                object->params.mem_entries[i].phys_addr;
511
 
                        params->mem_entries[i].size =
512
 
                                object->params.mem_entries[i].size;
513
 
                }
514
 
        }
515
 
        params->num_mem_entries = map_count;
516
 
        return retval;
517
 
}
518
 
 
519
 
 
520
 
/*==========================================
521
 
 * Function to detach from the Processor.
522
 
 *
523
 
 */
524
 
int proc4430_detach(void *handle)
525
 
{
526
 
        struct processor_object *proc_handle = NULL;
527
 
        struct proc4430_object *object = NULL;
528
 
        u32 i;
529
 
        memory_unmap_info unmap_info;
530
 
 
531
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
532
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
533
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
534
 
                                        == true) {
535
 
 
536
 
                pr_err("proc4430_detach failed Module not initialized");
537
 
                return -ENODEV;
538
 
        }
539
 
        if (WARN_ON(handle == NULL)) {
540
 
                pr_err("proc4430_detach failed "
541
 
                        "Argument Driverhandle is NULL");
542
 
                return -EINVAL;
543
 
        }
544
 
 
545
 
        proc_handle = (struct processor_object *)handle;
546
 
        object = (struct proc4430_object *)proc_handle->object;
547
 
 
548
 
        if (!(atomic_dec_return(&object->attach_count) == \
549
 
                OMAP4430PROC_MAKE_MAGICSTAMP(0)))
550
 
                return 1;
551
 
 
552
 
        for (i = 0; (i < object->params.num_mem_entries); i++) {
553
 
                if ((object->params.mem_entries[i].master_virt_addr > 0)
554
 
                    && (object->params.mem_entries[i].shared == true)) {
555
 
                        unmap_info.addr =
556
 
                                object->params.mem_entries[i].master_virt_addr;
557
 
                        unmap_info.size = object->params.mem_entries[i].size;
558
 
                        platform_mem_unmap(&unmap_info);
559
 
                        object->params.mem_entries[i].master_virt_addr =
560
 
                                (u32)-1;
561
 
                }
562
 
        }
563
 
        return 0;
564
 
}
565
 
 
566
 
 
567
 
/*==============================================
568
 
 *       Function to read from the slave processor's memory.
569
 
 *
570
 
 * Read from the slave processor's memory and copy into the
571
 
 * provided buffer.
572
 
 */
573
 
int proc4430_read(void *handle, u32 proc_addr, u32 *num_bytes,
574
 
                                                void *buffer)
575
 
{
576
 
        int retval = 0;
577
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
578
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
579
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
580
 
                                        == true) {
581
 
                pr_err("proc4430_read failed Module not initialized");
582
 
                return -ENODEV;
583
 
        }
584
 
 
585
 
        buffer = memcpy(buffer, (void *)proc_addr, *num_bytes);
586
 
 
587
 
        return retval;
588
 
}
589
 
 
590
 
 
591
 
/*==============================================
592
 
 * Function to write into the slave processor's memory.
593
 
 *
594
 
 * Read from the provided buffer and copy into the slave
595
 
 * processor's memory.
596
 
 *
597
 
 */
598
 
int proc4430_write(void *handle, u32 proc_addr, u32 *num_bytes,
599
 
                                                void *buffer)
600
 
{
601
 
        int retval = 0;
602
 
 
603
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
604
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
605
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
606
 
                                        == true) {
607
 
                pr_err("proc4430_write failed Module not initialized");
608
 
                return -ENODEV;
609
 
        }
610
 
 
611
 
        proc_addr = (u32)memcpy((void *)proc_addr, buffer, *num_bytes);
612
 
 
613
 
        return retval;
614
 
}
615
 
 
616
 
 
617
 
/*=========================================================
618
 
 * Function to perform device-dependent operations.
619
 
 *
620
 
 * Performs device-dependent control operations as exposed by this
621
 
 * implementation of the Processor module.
622
 
 */
623
 
int proc4430_control(void *handle, int cmd, void *arg)
624
 
{
625
 
        int retval = 0;
626
 
 
627
 
        /*FIXME: Remove handle,etc if not used */
628
 
 
629
 
#ifdef CONFIG_SYSLINK_DUCATI_PM
630
 
        /* Just for testing purpose */
631
 
        switch (cmd) {
632
 
        case PM_SUSPEND:
633
 
                retval = ipu_pm_notifications(APP_M3, cmd, NULL);
634
 
                retval = ipu_pm_notifications(SYS_M3, cmd, NULL);
635
 
                ipu_pm_save_ctx(SYS_M3);
636
 
                break;
637
 
        case PM_RESUME:
638
 
                retval = ipu_pm_notifications(APP_M3, cmd, NULL);
639
 
                retval = ipu_pm_notifications(SYS_M3, cmd, NULL);
640
 
                break;
641
 
        default:
642
 
                pr_err("Invalid notification\n");
643
 
        }
644
 
        if (retval != PM_SUCCESS)
645
 
                pr_err("Error in notifications\n");
646
 
#endif
647
 
 
648
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
649
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
650
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
651
 
                                        == true) {
652
 
                pr_err("proc4430_control failed Module not initialized");
653
 
                return -ENODEV;
654
 
        }
655
 
 
656
 
        return retval;
657
 
}
658
 
 
659
 
 
660
 
/*=====================================================
661
 
 * Function to translate between two types of address spaces.
662
 
 *
663
 
 * Translate between the specified address spaces.
664
 
 */
665
 
int proc4430_translate_addr(void *handle,
666
 
                void **dst_addr, enum proc_mgr_addr_type dst_addr_type,
667
 
                void *src_addr, enum proc_mgr_addr_type src_addr_type)
668
 
{
669
 
        int retval = 0;
670
 
        struct processor_object *proc_handle = NULL;
671
 
        struct proc4430_object *object = NULL;
672
 
        struct proc4430_mem_entry *entry = NULL;
673
 
        bool found = false;
674
 
        u32 fm_addr_base = (u32)NULL;
675
 
        u32 to_addr_base = (u32)NULL;
676
 
        u32 i;
677
 
 
678
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
679
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
680
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
681
 
                                        == true) {
682
 
                pr_err("proc4430_translate_addr failed Module not initialized");
683
 
                retval = -ENODEV;
684
 
                goto error_exit;
685
 
        }
686
 
 
687
 
        if (WARN_ON(handle == NULL)) {
688
 
                retval = -EINVAL;
689
 
                goto error_exit;
690
 
        }
691
 
        if (WARN_ON(dst_addr == NULL)) {
692
 
                retval = -EINVAL;
693
 
                goto error_exit;
694
 
        }
695
 
        if (WARN_ON(dst_addr_type > PROC_MGR_ADDRTYPE_ENDVALUE)) {
696
 
                retval = -EINVAL;
697
 
                goto error_exit;
698
 
        }
699
 
        if (WARN_ON(src_addr == NULL)) {
700
 
                retval = -EINVAL;
701
 
                goto error_exit;
702
 
        }
703
 
        if (WARN_ON(src_addr_type > PROC_MGR_ADDRTYPE_ENDVALUE)) {
704
 
                retval = -EINVAL;
705
 
                goto error_exit;
706
 
        }
707
 
 
708
 
        proc_handle = (struct processor_object *)handle;
709
 
        object = (struct proc4430_object *)proc_handle->object;
710
 
        *dst_addr = NULL;
711
 
        for (i = 0 ; i < object->params.num_mem_entries ; i++) {
712
 
                entry = &(object->params.mem_entries[i]);
713
 
                fm_addr_base =
714
 
                        (src_addr_type == PROC_MGR_ADDRTYPE_MASTERKNLVIRT) ?
715
 
                        entry->master_virt_addr : entry->slave_virt_addr;
716
 
                to_addr_base =
717
 
                        (dst_addr_type == PROC_MGR_ADDRTYPE_MASTERKNLVIRT) ?
718
 
                        entry->master_virt_addr : entry->slave_virt_addr;
719
 
                /* Determine whether which way to convert */
720
 
                if (((u32)src_addr < (fm_addr_base + entry->size)) &&
721
 
                        ((u32)src_addr >= fm_addr_base)) {
722
 
                        found = true;
723
 
                        *dst_addr = (void *)(((u32)src_addr - fm_addr_base)
724
 
                                + to_addr_base);
725
 
                        break;
726
 
                }
727
 
        }
728
 
 
729
 
        /* This check must not be removed even with build optimize. */
730
 
        if (WARN_ON(found == false)) {
731
 
                /*Failed to translate address. */
732
 
                retval = -ENXIO;
733
 
                goto error_exit;
734
 
        }
735
 
        return 0;
736
 
 
737
 
error_exit:
738
 
        return retval;
739
 
}
740
 
 
741
 
 
742
 
/*=================================================
743
 
 * Function to return list of translated mem entries
744
 
 *
745
 
 * This function takes the remote processor address as
746
 
 * an input and returns the mapped Page entries in the
747
 
 * buffer passed
748
 
 */
749
 
int proc4430_virt_to_phys(void *handle, u32 da, u32 *mapped_entries,
750
 
                                                u32 num_of_entries)
751
 
{
752
 
        int da_align;
753
 
        int i;
754
 
        int ret_val = 0;
755
 
 
756
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
757
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
758
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
759
 
                                        == true) {
760
 
                pr_err("proc4430_virt_to_phys failed Module not initialized");
761
 
                ret_val = -EFAULT;
762
 
                goto error_exit;
763
 
        }
764
 
 
765
 
        if (handle == NULL || mapped_entries == NULL || num_of_entries == 0) {
766
 
                ret_val = -EFAULT;
767
 
                goto error_exit;
768
 
        }
769
 
        da_align = PG_ALIGN_LOW((u32)da, PAGE_SIZE);
770
 
        for (i = 0; i < num_of_entries; i++) {
771
 
                mapped_entries[i] = da_align;
772
 
                da_align += PAGE_SIZE;
773
 
        }
774
 
        return 0;
775
 
 
776
 
error_exit:
777
 
        pr_warn("proc4430_virtToPhys failed !!!!\n");
778
 
        return ret_val;
779
 
}
780
 
 
781
 
 
782
 
/*=================================================
783
 
 * Function to return PROC4430 mem_entries info
784
 
 *
785
 
 */
786
 
int proc4430_proc_info(void *handle, struct proc_mgr_proc_info *procinfo)
787
 
{
788
 
        struct processor_object *proc_handle = NULL;
789
 
        struct proc4430_object *object = NULL;
790
 
        struct proc4430_mem_entry *entry = NULL;
791
 
        int i;
792
 
 
793
 
        if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
794
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(0),
795
 
                                        OMAP4430PROC_MAKE_MAGICSTAMP(1))
796
 
                                        == true) {
797
 
                pr_err("proc4430_proc_info failed Module not initialized");
798
 
                goto error_exit;
799
 
        }
800
 
 
801
 
        if (WARN_ON(handle == NULL))
802
 
                goto error_exit;
803
 
        if (WARN_ON(procinfo == NULL))
804
 
                goto error_exit;
805
 
 
806
 
        proc_handle = (struct processor_object *)handle;
807
 
 
808
 
        object = (struct proc4430_object *)proc_handle->object;
809
 
 
810
 
        for (i = 0 ; i < object->params.num_mem_entries ; i++) {
811
 
                entry = &(object->params.mem_entries[i]);
812
 
                procinfo->mem_entries[i].addr[PROC_MGR_ADDRTYPE_MASTERKNLVIRT]
813
 
                                                = entry->master_virt_addr;
814
 
                procinfo->mem_entries[i].addr[PROC_MGR_ADDRTYPE_SLAVEVIRT]
815
 
                                                = entry->slave_virt_addr;
816
 
                procinfo->mem_entries[i].size = entry->size;
817
 
        }
818
 
        procinfo->num_mem_entries = object->params.num_mem_entries;
819
 
        procinfo->boot_mode = proc_handle->boot_mode;
820
 
        return 0;
821
 
 
822
 
error_exit:
823
 
        pr_warn("proc4430_proc_info failed !!!!\n");
824
 
        return -EFAULT;
825
 
}