blob: 8612112c133b1c256522ef52f95515fa3a36d13a [file] [log] [blame]
tharun kumarae860532017-06-28 16:56:10 +05301/*
2 * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/cdev.h>
16#include <linux/device.h>
17#include <linux/fs.h>
18#include <linux/slab.h>
19#include <linux/module.h>
20#include <linux/of_gpio.h>
21#include <soc/qcom/smem.h>
22#include <linux/uaccess.h>
23#include <linux/interrupt.h>
24
tharun kumar414f6bc2017-07-08 16:04:49 +053025#define SMP2P_NUM_PROCS 16
tharun kumarae860532017-06-28 16:56:10 +053026#define MAX_RETRIES 20
27
28#define SM_VERSION 1
29#define SM_BLOCKSIZE 128
30
31#define SMQ_MAGIC_INIT 0xFF00FF00
32#define SMQ_MAGIC_PRODUCER (SMQ_MAGIC_INIT | 0x1)
33#define SMQ_MAGIC_CONSUMER (SMQ_MAGIC_INIT | 0x2)
34
35enum SMQ_STATUS {
36 SMQ_SUCCESS = 0,
37 SMQ_ENOMEMORY = -1,
38 SMQ_EBADPARM = -2,
39 SMQ_UNDERFLOW = -3,
40 SMQ_OVERFLOW = -4
41};
42
43enum smq_type {
44 PRODUCER = 1,
45 CONSUMER = 2,
46 INVALID = 3
47};
48
49struct smq_block_map {
50 uint32_t index_read;
51 uint32_t num_blocks;
52 uint8_t *map;
53};
54
55struct smq_node {
56 uint16_t index_block;
57 uint16_t num_blocks;
58} __attribute__ ((__packed__));
59
60struct smq_hdr {
61 uint8_t producer_version;
62 uint8_t consumer_version;
63} __attribute__ ((__packed__));
64
65struct smq_out_state {
66 uint32_t init;
67 uint32_t index_check_queue_for_reset;
68 uint32_t index_sent_write;
69 uint32_t index_free_read;
70} __attribute__ ((__packed__));
71
72struct smq_out {
73 struct smq_out_state s;
74 struct smq_node sent[1];
75};
76
77struct smq_in_state {
78 uint32_t init;
79 uint32_t index_check_queue_for_reset_ack;
80 uint32_t index_sent_read;
81 uint32_t index_free_write;
82} __attribute__ ((__packed__));
83
84struct smq_in {
85 struct smq_in_state s;
86 struct smq_node free[1];
87};
88
89struct smq {
90 struct smq_hdr *hdr;
91 struct smq_out *out;
92 struct smq_in *in;
93 uint8_t *blocks;
94 uint32_t num_blocks;
95 struct mutex *lock;
96 uint32_t initialized;
97 struct smq_block_map block_map;
98 enum smq_type type;
99};
100
101struct gpio_info {
102 int gpio_base_id;
103 int irq_base_id;
104};
105
106struct rdbg_data {
107 struct device *device;
108 struct completion work;
109 struct gpio_info in;
110 struct gpio_info out;
111 bool device_initialized;
112 int gpio_out_offset;
113 bool device_opened;
114 void *smem_addr;
115 size_t smem_size;
116 struct smq producer_smrb;
117 struct smq consumer_smrb;
118 struct mutex write_mutex;
119};
120
121struct rdbg_device {
122 struct cdev cdev;
123 struct class *class;
124 dev_t dev_no;
125 int num_devices;
126 struct rdbg_data *rdbg_data;
127};
128
129static struct rdbg_device g_rdbg_instance = {
130 { {0} },
131 NULL,
132 0,
133 SMP2P_NUM_PROCS,
134 NULL
135};
136
137struct processor_specific_info {
138 char *name;
139 unsigned int smem_buffer_addr;
140 size_t smem_buffer_size;
141};
142
143static struct processor_specific_info proc_info[SMP2P_NUM_PROCS] = {
144 {0}, /*APPS*/
145 {"rdbg_modem", 0, 0}, /*MODEM*/
146 {"rdbg_adsp", SMEM_LC_DEBUGGER, 16*1024}, /*ADSP*/
147 {0}, /*SMP2P_RESERVED_PROC_1*/
148 {"rdbg_wcnss", 0, 0}, /*WCNSS*/
tharun kumar414f6bc2017-07-08 16:04:49 +0530149 {"rdbg_cdsp", SMEM_LC_DEBUGGER, 16*1024}, /*CDSP*/
150 {NULL}, /*SMP2P_POWER_PROC*/
151 {NULL}, /*SMP2P_TZ_PROC*/
152 {NULL}, /*EMPTY*/
153 {NULL}, /*EMPTY*/
154 {NULL}, /*EMPTY*/
155 {NULL}, /*EMPTY*/
156 {NULL}, /*EMPTY*/
157 {NULL}, /*EMPTY*/
158 {NULL}, /*EMPTY*/
159 {NULL} /*SMP2P_REMOTE_MOCK_PROC*/
tharun kumarae860532017-06-28 16:56:10 +0530160};
161
162static int smq_blockmap_get(struct smq_block_map *block_map,
163 uint32_t *block_index, uint32_t n)
164{
165 uint32_t start;
166 uint32_t mark = 0;
167 uint32_t found = 0;
168 uint32_t i = 0;
169
170 start = block_map->index_read;
171
172 if (n == 1) {
173 do {
174 if (!block_map->map[block_map->index_read]) {
175 *block_index = block_map->index_read;
176 block_map->map[block_map->index_read] = 1;
177 block_map->index_read++;
178 block_map->index_read %= block_map->num_blocks;
179 return SMQ_SUCCESS;
180 }
181 block_map->index_read++;
182 } while (start != (block_map->index_read %=
183 block_map->num_blocks));
184 } else {
185 mark = block_map->num_blocks;
186
187 do {
188 if (!block_map->map[block_map->index_read]) {
189 if (mark > block_map->index_read) {
190 mark = block_map->index_read;
191 start = block_map->index_read;
192 found = 0;
193 }
194
195 found++;
196 if (found == n) {
197 *block_index = mark;
198 for (i = 0; i < n; i++)
199 block_map->map[mark + i] =
200 (uint8_t)(n - i);
201 block_map->index_read += block_map->map
202 [block_map->index_read] - 1;
203 return SMQ_SUCCESS;
204 }
205 } else {
206 found = 0;
207 block_map->index_read += block_map->map
208 [block_map->index_read] - 1;
209 mark = block_map->num_blocks;
210 }
211 block_map->index_read++;
212 } while (start != (block_map->index_read %=
213 block_map->num_blocks));
214 }
215
216 return SMQ_ENOMEMORY;
217}
218
219static void smq_blockmap_put(struct smq_block_map *block_map, uint32_t i)
220{
221 uint32_t num_blocks = block_map->map[i];
222
223 while (num_blocks--) {
224 block_map->map[i] = 0;
225 i++;
226 }
227}
228
229static int smq_blockmap_reset(struct smq_block_map *block_map)
230{
231 if (!block_map->map)
232 return SMQ_ENOMEMORY;
233 memset(block_map->map, 0, block_map->num_blocks + 1);
234 block_map->index_read = 0;
235
236 return SMQ_SUCCESS;
237}
238
239static int smq_blockmap_ctor(struct smq_block_map *block_map,
240 uint32_t num_blocks)
241{
242 if (num_blocks <= 1)
243 return SMQ_ENOMEMORY;
244
245 block_map->map = kcalloc(num_blocks, sizeof(uint8_t), GFP_KERNEL);
246 if (!block_map->map)
247 return SMQ_ENOMEMORY;
248
249 block_map->num_blocks = num_blocks - 1;
250 smq_blockmap_reset(block_map);
251
252 return SMQ_SUCCESS;
253}
254
255static void smq_blockmap_dtor(struct smq_block_map *block_map)
256{
257 kfree(block_map->map);
258 block_map->map = NULL;
259}
260
261static int smq_free(struct smq *smq, void *data)
262{
263 struct smq_node node;
264 uint32_t index_block;
265 int err = SMQ_SUCCESS;
266
267 if (smq->lock)
268 mutex_lock(smq->lock);
269
270 if ((smq->hdr->producer_version != SM_VERSION) &&
271 (smq->out->s.init != SMQ_MAGIC_PRODUCER)) {
272 err = SMQ_UNDERFLOW;
273 goto bail;
274 }
275
276 index_block = ((uint8_t *)data - smq->blocks) / SM_BLOCKSIZE;
277 if (index_block >= smq->num_blocks) {
278 err = SMQ_EBADPARM;
279 goto bail;
280 }
281
282 node.index_block = (uint16_t)index_block;
283 node.num_blocks = 0;
284 *((struct smq_node *)(smq->in->free + smq->in->
285 s.index_free_write)) = node;
286
287 smq->in->s.index_free_write = (smq->in->s.index_free_write + 1)
288 % smq->num_blocks;
289
290bail:
291 if (smq->lock)
292 mutex_unlock(smq->lock);
293 return err;
294}
295
296static int smq_receive(struct smq *smq, void **pp, int *pnsize, int *pbmore)
297{
298 struct smq_node *node;
299 int err = SMQ_SUCCESS;
300 int more = 0;
301
302 if ((smq->hdr->producer_version != SM_VERSION) &&
303 (smq->out->s.init != SMQ_MAGIC_PRODUCER))
304 return SMQ_UNDERFLOW;
305
306 if (smq->in->s.index_sent_read == smq->out->s.index_sent_write) {
307 err = SMQ_UNDERFLOW;
308 goto bail;
309 }
310
311 node = (struct smq_node *)(smq->out->sent + smq->in->s.index_sent_read);
312 if (node->index_block >= smq->num_blocks) {
313 err = SMQ_EBADPARM;
314 goto bail;
315 }
316
317 smq->in->s.index_sent_read = (smq->in->s.index_sent_read + 1)
318 % smq->num_blocks;
319
320 *pp = smq->blocks + (node->index_block * SM_BLOCKSIZE);
321 *pnsize = SM_BLOCKSIZE * node->num_blocks;
322
323 /*
324 * Ensure that the reads and writes are updated in the memory
325 * when they are done and not cached. Also, ensure that the reads
326 * and writes are not reordered as they are shared between two cores.
327 */
328 rmb();
329 if (smq->in->s.index_sent_read != smq->out->s.index_sent_write)
330 more = 1;
331
332bail:
333 *pbmore = more;
334 return err;
335}
336
337static int smq_alloc_send(struct smq *smq, const uint8_t *pcb, int nsize)
338{
339 void *pv = 0;
340 int num_blocks;
341 uint32_t index_block = 0;
342 int err = SMQ_SUCCESS;
343 struct smq_node *node = NULL;
344
345 mutex_lock(smq->lock);
346
347 if ((smq->in->s.init == SMQ_MAGIC_CONSUMER) &&
348 (smq->hdr->consumer_version == SM_VERSION)) {
349 if (smq->out->s.index_check_queue_for_reset ==
350 smq->in->s.index_check_queue_for_reset_ack) {
351 while (smq->out->s.index_free_read !=
352 smq->in->s.index_free_write) {
353 node = (struct smq_node *)(
354 smq->in->free +
355 smq->out->s.index_free_read);
356 if (node->index_block >= smq->num_blocks) {
357 err = SMQ_EBADPARM;
358 goto bail;
359 }
360
361 smq->out->s.index_free_read =
362 (smq->out->s.index_free_read + 1)
363 % smq->num_blocks;
364
365 smq_blockmap_put(&smq->block_map,
366 node->index_block);
367 /*
368 * Ensure that the reads and writes are
369 * updated in the memory when they are done
370 * and not cached. Also, ensure that the reads
371 * and writes are not reordered as they are
372 * shared between two cores.
373 */
374 rmb();
375 }
376 }
377 }
378
379 num_blocks = ALIGN(nsize, SM_BLOCKSIZE)/SM_BLOCKSIZE;
380 err = smq_blockmap_get(&smq->block_map, &index_block, num_blocks);
381 if (err != SMQ_SUCCESS)
382 goto bail;
383
384 pv = smq->blocks + (SM_BLOCKSIZE * index_block);
385
386 err = copy_from_user((void *)pv, (void *)pcb, nsize);
387 if (err != 0)
388 goto bail;
389
390 ((struct smq_node *)(smq->out->sent +
391 smq->out->s.index_sent_write))->index_block
392 = (uint16_t)index_block;
393 ((struct smq_node *)(smq->out->sent +
394 smq->out->s.index_sent_write))->num_blocks
395 = (uint16_t)num_blocks;
396
397 smq->out->s.index_sent_write = (smq->out->s.index_sent_write + 1)
398 % smq->num_blocks;
399
400bail:
401 if (err != SMQ_SUCCESS) {
402 if (pv)
403 smq_blockmap_put(&smq->block_map, index_block);
404 }
405 mutex_unlock(smq->lock);
406 return err;
407}
408
409static int smq_reset_producer_queue_internal(struct smq *smq,
410 uint32_t reset_num)
411{
412 int retval = 0;
413 uint32_t i;
414
415 if (smq->type != PRODUCER)
416 goto bail;
417
418 mutex_lock(smq->lock);
419 if (smq->out->s.index_check_queue_for_reset != reset_num) {
420 smq->out->s.index_check_queue_for_reset = reset_num;
421 for (i = 0; i < smq->num_blocks; i++)
422 (smq->out->sent + i)->index_block = 0xFFFF;
423
424 smq_blockmap_reset(&smq->block_map);
425 smq->out->s.index_sent_write = 0;
426 smq->out->s.index_free_read = 0;
427 retval = 1;
428 }
429 mutex_unlock(smq->lock);
430
431bail:
432 return retval;
433}
434
435static int smq_check_queue_reset(struct smq *p_cons, struct smq *p_prod)
436{
437 int retval = 0;
438 uint32_t reset_num, i;
439
440 if ((p_cons->type != CONSUMER) ||
441 (p_cons->out->s.init != SMQ_MAGIC_PRODUCER) ||
442 (p_cons->hdr->producer_version != SM_VERSION))
443 goto bail;
444
445 reset_num = p_cons->out->s.index_check_queue_for_reset;
446 if (p_cons->in->s.index_check_queue_for_reset_ack != reset_num) {
447 p_cons->in->s.index_check_queue_for_reset_ack = reset_num;
448 for (i = 0; i < p_cons->num_blocks; i++)
449 (p_cons->in->free + i)->index_block = 0xFFFF;
450
451 p_cons->in->s.index_sent_read = 0;
452 p_cons->in->s.index_free_write = 0;
453
454 retval = smq_reset_producer_queue_internal(p_prod, reset_num);
455 }
456
457bail:
458 return retval;
459}
460
461static int check_subsystem_debug_enabled(void *base_addr, int size)
462{
463 int num_blocks;
464 uint8_t *pb_orig;
465 uint8_t *pb;
466 struct smq smq;
467 int err = 0;
468
469 pb = pb_orig = (uint8_t *)base_addr;
470 pb += sizeof(struct smq_hdr);
471 pb = PTR_ALIGN(pb, 8);
472 size -= pb - (uint8_t *)pb_orig;
473 num_blocks = (int)((size - sizeof(struct smq_out_state) -
474 sizeof(struct smq_in_state))/(SM_BLOCKSIZE +
475 sizeof(struct smq_node) * 2));
476 if (num_blocks <= 0) {
477 err = SMQ_EBADPARM;
478 goto bail;
479 }
480
481 pb += num_blocks * SM_BLOCKSIZE;
482 smq.out = (struct smq_out *)pb;
483 pb += sizeof(struct smq_out_state) + (num_blocks *
484 sizeof(struct smq_node));
485 smq.in = (struct smq_in *)pb;
486
487 if (smq.in->s.init != SMQ_MAGIC_CONSUMER) {
488 pr_err("%s, smq in consumer not initialized", __func__);
489 err = -ECOMM;
490 }
491
492bail:
493 return err;
494}
495
496static void smq_dtor(struct smq *smq)
497{
498 if (smq->initialized == SMQ_MAGIC_INIT) {
499 switch (smq->type) {
500 case PRODUCER:
501 smq->out->s.init = 0;
502 smq_blockmap_dtor(&smq->block_map);
503 break;
504 case CONSUMER:
505 smq->in->s.init = 0;
506 break;
507 default:
508 case INVALID:
509 break;
510 }
511
512 smq->initialized = 0;
513 }
514}
515
516/*
517 * The shared memory is used as a circular ring buffer in each direction.
518 * Thus we have a bi-directional shared memory channel between the AP
519 * and a subsystem. We call this SMQ. Each memory channel contains a header,
520 * data and a control mechanism that is used to synchronize read and write
521 * of data between the AP and the remote subsystem.
522 *
523 * Overall SMQ memory view:
524 *
525 * +------------------------------------------------+
526 * | SMEM buffer |
527 * |-----------------------+------------------------|
528 * |Producer: LA | Producer: Remote |
529 * |Consumer: Remote | subsystem |
530 * | subsystem | Consumer: LA |
531 * | | |
532 * | Producer| Consumer|
533 * +-----------------------+------------------------+
534 * | |
535 * | |
536 * | +--------------------------------------+
537 * | |
538 * | |
539 * v v
540 * +--------------------------------------------------------------+
541 * | Header | Data | Control |
542 * +-----------+---+---+---+-----+----+--+--+-----+---+--+--+-----+
543 * | | b | b | b | | S |n |n | | S |n |n | |
544 * | Producer | l | l | l | | M |o |o | | M |o |o | |
545 * | Ver | o | o | o | | Q |d |d | | Q |d |d | |
546 * |-----------| c | c | c | ... | |e |e | ... | |e |e | ... |
547 * | | k | k | k | | O | | | | I | | | |
548 * | Consumer | | | | | u |0 |1 | | n |0 |1 | |
549 * | Ver | 0 | 1 | 2 | | t | | | | | | | |
550 * +-----------+---+---+---+-----+----+--+--+-----+---+--+--+-----+
551 * | |
552 * + |
553 * |
554 * +------------------------+
555 * |
556 * v
557 * +----+----+----+----+
558 * | SMQ Nodes |
559 * |----|----|----|----|
560 * Node # | 0 | 1 | 2 | ...|
561 * |----|----|----|----|
562 * Starting Block Index # | 0 | 3 | 8 | ...|
563 * |----|----|----|----|
564 * # of blocks | 3 | 5 | 1 | ...|
565 * +----+----+----+----+
566 *
567 * Header: Contains version numbers for software compatibility to ensure
568 * that both producers and consumers on the AP and subsystems know how to
569 * read from and write to the queue.
570 * Both the producer and consumer versions are 1.
571 * +---------+-------------------+
572 * | Size | Field |
573 * +---------+-------------------+
574 * | 1 byte | Producer Version |
575 * +---------+-------------------+
576 * | 1 byte | Consumer Version |
577 * +---------+-------------------+
578 *
579 * Data: The data portion contains multiple blocks [0..N] of a fixed size.
580 * The block size SM_BLOCKSIZE is fixed to 128 bytes for header version #1.
581 * Payload sent from the debug agent app is split (if necessary) and placed
582 * in these blocks. The first data block is placed at the next 8 byte aligned
583 * address after the header.
584 *
585 * The number of blocks for a given SMEM allocation is derived as follows:
586 * Number of Blocks = ((Total Size - Alignment - Size of Header
587 * - Size of SMQIn - Size of SMQOut)/(SM_BLOCKSIZE))
588 *
589 * The producer maintains a private block map of each of these blocks to
590 * determine which of these blocks in the queue is available and which are free.
591 *
592 * Control:
593 * The control portion contains a list of nodes [0..N] where N is number
594 * of available data blocks. Each node identifies the data
595 * block indexes that contain a particular debug message to be transferred,
596 * and the number of blocks it took to hold the contents of the message.
597 *
598 * Each node has the following structure:
599 * +---------+-------------------+
600 * | Size | Field |
601 * +---------+-------------------+
602 * | 2 bytes |Staring Block Index|
603 * +---------+-------------------+
604 * | 2 bytes |Number of Blocks |
605 * +---------+-------------------+
606 *
607 * The producer and the consumer update different parts of the control channel
608 * (SMQOut / SMQIn) respectively. Each of these control data structures contains
609 * information about the last node that was written / read, and the actual nodes
610 * that were written/read.
611 *
612 * SMQOut Structure (R/W by producer, R by consumer):
613 * +---------+-------------------+
614 * | Size | Field |
615 * +---------+-------------------+
616 * | 4 bytes | Magic Init Number |
617 * +---------+-------------------+
618 * | 4 bytes | Reset |
619 * +---------+-------------------+
620 * | 4 bytes | Last Sent Index |
621 * +---------+-------------------+
622 * | 4 bytes | Index Free Read |
623 * +---------+-------------------+
624 *
625 * SMQIn Structure (R/W by consumer, R by producer):
626 * +---------+-------------------+
627 * | Size | Field |
628 * +---------+-------------------+
629 * | 4 bytes | Magic Init Number |
630 * +---------+-------------------+
631 * | 4 bytes | Reset ACK |
632 * +---------+-------------------+
633 * | 4 bytes | Last Read Index |
634 * +---------+-------------------+
635 * | 4 bytes | Index Free Write |
636 * +---------+-------------------+
637 *
638 * Magic Init Number:
639 * Both SMQ Out and SMQ In initialize this field with a predefined magic
640 * number so as to make sure that both the consumer and producer blocks
641 * have fully initialized and have valid data in the shared memory control area.
642 * Producer Magic #: 0xFF00FF01
643 * Consumer Magic #: 0xFF00FF02
644 */
645static int smq_ctor(struct smq *smq, void *base_addr, int size,
646 enum smq_type type, struct mutex *lock_ptr)
647{
648 int num_blocks;
649 uint8_t *pb_orig;
650 uint8_t *pb;
651 uint32_t i;
652 int err;
653
654 if (smq->initialized == SMQ_MAGIC_INIT) {
655 err = SMQ_EBADPARM;
656 goto bail;
657 }
658
659 if (!base_addr || !size) {
660 err = SMQ_EBADPARM;
661 goto bail;
662 }
663
664 if (type == PRODUCER)
665 smq->lock = lock_ptr;
666
667 pb_orig = (uint8_t *)base_addr;
668 smq->hdr = (struct smq_hdr *)pb_orig;
669 pb = pb_orig;
670 pb += sizeof(struct smq_hdr);
671 pb = PTR_ALIGN(pb, 8);
672 size -= pb - (uint8_t *)pb_orig;
673 num_blocks = (int)((size - sizeof(struct smq_out_state) -
674 sizeof(struct smq_in_state))/(SM_BLOCKSIZE +
675 sizeof(struct smq_node) * 2));
676 if (num_blocks <= 0) {
677 err = SMQ_ENOMEMORY;
678 goto bail;
679 }
680
681 smq->blocks = pb;
682 smq->num_blocks = num_blocks;
683 pb += num_blocks * SM_BLOCKSIZE;
684 smq->out = (struct smq_out *)pb;
685 pb += sizeof(struct smq_out_state) + (num_blocks *
686 sizeof(struct smq_node));
687 smq->in = (struct smq_in *)pb;
688 smq->type = type;
689 if (type == PRODUCER) {
690 smq->hdr->producer_version = SM_VERSION;
691 for (i = 0; i < smq->num_blocks; i++)
692 (smq->out->sent + i)->index_block = 0xFFFF;
693
694 err = smq_blockmap_ctor(&smq->block_map, smq->num_blocks);
695 if (err != SMQ_SUCCESS)
696 goto bail;
697
698 smq->out->s.index_sent_write = 0;
699 smq->out->s.index_free_read = 0;
700 if (smq->out->s.init == SMQ_MAGIC_PRODUCER) {
701 smq->out->s.index_check_queue_for_reset += 1;
702 } else {
703 smq->out->s.index_check_queue_for_reset = 1;
704 smq->out->s.init = SMQ_MAGIC_PRODUCER;
705 }
706 } else {
707 smq->hdr->consumer_version = SM_VERSION;
708 for (i = 0; i < smq->num_blocks; i++)
709 (smq->in->free + i)->index_block = 0xFFFF;
710
711 smq->in->s.index_sent_read = 0;
712 smq->in->s.index_free_write = 0;
713 if (smq->out->s.init == SMQ_MAGIC_PRODUCER) {
714 smq->in->s.index_check_queue_for_reset_ack =
715 smq->out->s.index_check_queue_for_reset;
716 } else {
717 smq->in->s.index_check_queue_for_reset_ack = 0;
718 }
719
720 smq->in->s.init = SMQ_MAGIC_CONSUMER;
721 }
722 smq->initialized = SMQ_MAGIC_INIT;
723 err = SMQ_SUCCESS;
724
725bail:
726 return err;
727}
728
729static void send_interrupt_to_subsystem(struct rdbg_data *rdbgdata)
730{
731 int offset = rdbgdata->gpio_out_offset;
732 int val = 1 ^ gpio_get_value(rdbgdata->out.gpio_base_id + offset);
733
734 gpio_set_value(rdbgdata->out.gpio_base_id + offset, val);
735 rdbgdata->gpio_out_offset = (offset + 1) % 32;
736
737 dev_dbg(rdbgdata->device, "%s: sent interrupt %d to subsystem",
738 __func__, val);
739}
740
741static irqreturn_t on_interrupt_from(int irq, void *ptr)
742{
743 struct rdbg_data *rdbgdata = (struct rdbg_data *) ptr;
744
745 dev_dbg(rdbgdata->device, "%s: Received interrupt %d from subsystem",
746 __func__, irq);
747
748 complete(&(rdbgdata->work));
749 return IRQ_HANDLED;
750}
751
752static int initialize_smq(struct rdbg_data *rdbgdata)
753{
754 int err = 0;
755 unsigned char *smem_consumer_buffer = rdbgdata->smem_addr;
756
757 smem_consumer_buffer += (rdbgdata->smem_size/2);
758
759 if (smq_ctor(&(rdbgdata->producer_smrb), (void *)(rdbgdata->smem_addr),
760 ((rdbgdata->smem_size)/2), PRODUCER, &rdbgdata->write_mutex)) {
761 dev_err(rdbgdata->device, "%s: smq producer allocation failed",
762 __func__);
763 err = -ENOMEM;
764 goto bail;
765 }
766
767 if (smq_ctor(&(rdbgdata->consumer_smrb), (void *)smem_consumer_buffer,
768 ((rdbgdata->smem_size)/2), CONSUMER, NULL)) {
769 dev_err(rdbgdata->device, "%s: smq conmsumer allocation failed",
770 __func__);
771 err = -ENOMEM;
772 }
773
774bail:
775 return err;
776
777}
778
779static int rdbg_open(struct inode *inode, struct file *filp)
780{
781 int device_id = -1;
782 struct rdbg_device *device = &g_rdbg_instance;
783 struct rdbg_data *rdbgdata = NULL;
784 int err = 0;
785
786 if (!inode || !device->rdbg_data) {
787 pr_err("Memory not allocated yet");
788 err = -ENODEV;
789 goto bail;
790 }
791
792 device_id = MINOR(inode->i_rdev);
793 rdbgdata = &device->rdbg_data[device_id];
794
795 if (rdbgdata->device_opened) {
796 dev_err(rdbgdata->device, "%s: Device already opened",
797 __func__);
798 err = -EEXIST;
799 goto bail;
800 }
801
802 rdbgdata->smem_size = proc_info[device_id].smem_buffer_size;
803 if (!rdbgdata->smem_size) {
804 dev_err(rdbgdata->device, "%s: smem not initialized", __func__);
805 err = -ENOMEM;
806 goto bail;
807 }
808
809 rdbgdata->smem_addr = smem_find(proc_info[device_id].smem_buffer_addr,
810 rdbgdata->smem_size, 0, SMEM_ANY_HOST_FLAG);
811 if (!rdbgdata->smem_addr) {
812 dev_err(rdbgdata->device, "%s: Could not allocate smem memory",
813 __func__);
814 err = -ENOMEM;
815 goto bail;
816 }
817 dev_dbg(rdbgdata->device, "%s: SMEM address=0x%lx smem_size=%d",
818 __func__, (unsigned long)rdbgdata->smem_addr,
819 (unsigned int)rdbgdata->smem_size);
820
821 if (check_subsystem_debug_enabled(rdbgdata->smem_addr,
822 rdbgdata->smem_size/2)) {
823 dev_err(rdbgdata->device, "%s: Subsystem %s is not debug enabled",
824 __func__, proc_info[device_id].name);
825 err = -ECOMM;
826 goto bail;
827 }
828
829 init_completion(&rdbgdata->work);
830
831 err = request_irq(rdbgdata->in.irq_base_id, on_interrupt_from,
832 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
833 proc_info[device_id].name,
834 (void *)&device->rdbg_data[device_id]);
835 if (err) {
836 dev_err(rdbgdata->device,
837 "%s: Failed to register interrupt.Err=%d,irqid=%d.",
838 __func__, err, rdbgdata->in.irq_base_id);
839 goto irq_bail;
840 }
841
842 err = enable_irq_wake(rdbgdata->in.irq_base_id);
843 if (err < 0) {
844 dev_dbg(rdbgdata->device, "enable_irq_wake() failed with err=%d",
845 err);
846 err = 0;
847 }
848
849 mutex_init(&rdbgdata->write_mutex);
850
851 err = initialize_smq(rdbgdata);
852 if (err) {
853 dev_err(rdbgdata->device, "Error initializing smq. Err=%d",
854 err);
855 goto smq_bail;
856 }
857
858 rdbgdata->device_opened = 1;
859
860 filp->private_data = (void *)rdbgdata;
861
862 return 0;
863
864smq_bail:
865 smq_dtor(&(rdbgdata->producer_smrb));
866 smq_dtor(&(rdbgdata->consumer_smrb));
867 mutex_destroy(&rdbgdata->write_mutex);
868irq_bail:
869 free_irq(rdbgdata->in.irq_base_id, (void *)
870 &device->rdbg_data[device_id]);
871bail:
872 return err;
873}
874
875static int rdbg_release(struct inode *inode, struct file *filp)
876{
877 int device_id = -1;
878 struct rdbg_device *rdbgdevice = &g_rdbg_instance;
879 struct rdbg_data *rdbgdata = NULL;
880 int err = 0;
881
882 if (!inode || !rdbgdevice->rdbg_data) {
883 pr_err("Memory not allocated yet");
884 err = -ENODEV;
885 goto bail;
886 }
887
888 device_id = MINOR(inode->i_rdev);
889 rdbgdata = &rdbgdevice->rdbg_data[device_id];
890
891 if (rdbgdata->device_opened == 1) {
892 dev_dbg(rdbgdata->device, "%s: Destroying %s.", __func__,
893 proc_info[device_id].name);
894 rdbgdata->device_opened = 0;
895 complete(&(rdbgdata->work));
896 free_irq(rdbgdata->in.irq_base_id, (void *)
897 &rdbgdevice->rdbg_data[device_id]);
898 if (rdbgdevice->rdbg_data[device_id].producer_smrb.initialized)
899 smq_dtor(&(rdbgdevice->rdbg_data[device_id].
900 producer_smrb));
901 if (rdbgdevice->rdbg_data[device_id].consumer_smrb.initialized)
902 smq_dtor(&(rdbgdevice->rdbg_data[device_id].
903 consumer_smrb));
904 mutex_destroy(&rdbgdata->write_mutex);
905 }
906
907 filp->private_data = NULL;
908
909bail:
910 return err;
911}
912
913static ssize_t rdbg_read(struct file *filp, char __user *buf, size_t size,
914 loff_t *offset)
915{
916 int err = 0;
917 struct rdbg_data *rdbgdata = filp->private_data;
918 void *p_sent_buffer = NULL;
919 int nsize = 0;
920 int more = 0;
921
922 if (!rdbgdata) {
923 pr_err("Invalid argument");
924 err = -EINVAL;
925 goto bail;
926 }
927
928 dev_dbg(rdbgdata->device, "%s: In receive", __func__);
929 err = wait_for_completion_interruptible(&(rdbgdata->work));
930 if (err) {
931 dev_err(rdbgdata->device, "%s: Error in wait", __func__);
932 goto bail;
933 }
934
935 smq_check_queue_reset(&(rdbgdata->consumer_smrb),
936 &(rdbgdata->producer_smrb));
937 if (smq_receive(&(rdbgdata->consumer_smrb), &p_sent_buffer,
938 &nsize, &more) != SMQ_SUCCESS) {
939 dev_err(rdbgdata->device, "%s: Error in smq_recv(). Err code = %d",
940 __func__, err);
941 err = -ENODATA;
942 goto bail;
943 }
944
945 size = ((size < nsize) ? size : nsize);
946 err = copy_to_user(buf, p_sent_buffer, size);
947 if (err != 0) {
948 dev_err(rdbgdata->device, "%s: Error in copy_to_user(). Err code = %d",
949 __func__, err);
950 err = -ENODATA;
951 goto bail;
952 }
953
954 smq_free(&(rdbgdata->consumer_smrb), p_sent_buffer);
955 err = size;
956 dev_dbg(rdbgdata->device, "%s: Read data to buffer with address 0x%lx",
957 __func__, (unsigned long) buf);
958
959bail:
960 return err;
961}
962
963static ssize_t rdbg_write(struct file *filp, const char __user *buf,
964 size_t size, loff_t *offset)
965{
966 int err = 0;
967 int num_retries = 0;
968 struct rdbg_data *rdbgdata = filp->private_data;
969
970 if (!rdbgdata) {
971 pr_err("Invalid argument");
972 err = -EINVAL;
973 goto bail;
974 }
975
976 do {
977 err = smq_alloc_send(&(rdbgdata->producer_smrb), buf, size);
978 dev_dbg(rdbgdata->device, "%s, smq_alloc_send returned %d.",
979 __func__, err);
980 } while (err != 0 && num_retries++ < MAX_RETRIES);
981
982 if (err != 0) {
983 err = -ECOMM;
984 goto bail;
985 }
986
987 send_interrupt_to_subsystem(rdbgdata);
988
989 err = size;
990
991bail:
992 return err;
993}
994
995
996static const struct file_operations rdbg_fops = {
997 .open = rdbg_open,
998 .read = rdbg_read,
999 .write = rdbg_write,
1000 .release = rdbg_release,
1001};
1002
1003static int register_smp2p(char *node_name, struct gpio_info *gpio_info_ptr)
1004{
1005 struct device_node *node = NULL;
1006 int cnt = 0;
1007 int id = 0;
1008
1009 node = of_find_compatible_node(NULL, NULL, node_name);
1010 if (node) {
1011 cnt = of_gpio_count(node);
1012 if (cnt && gpio_info_ptr) {
1013 id = of_get_gpio(node, 0);
1014 gpio_info_ptr->gpio_base_id = id;
1015 gpio_info_ptr->irq_base_id = gpio_to_irq(id);
1016 return 0;
1017 }
1018 }
1019 return -EINVAL;
1020}
1021
1022static int __init rdbg_init(void)
1023{
1024 int err = 0;
1025 struct rdbg_device *rdbgdevice = &g_rdbg_instance;
1026 int minor = 0;
1027 int major = 0;
1028 int minor_nodes_created = 0;
1029
1030 char *rdbg_compatible_string = "qcom,smp2pgpio_client_rdbg_";
1031 int max_len = strlen(rdbg_compatible_string) + strlen("xx_out");
1032
1033 char *node_name = kcalloc(max_len, sizeof(char), GFP_KERNEL);
1034
1035 if (!node_name) {
1036 err = -ENOMEM;
1037 goto bail;
1038 }
1039
1040 if (rdbgdevice->num_devices < 1 ||
1041 rdbgdevice->num_devices > SMP2P_NUM_PROCS) {
1042 pr_err("rgdb: invalid num_devices");
1043 err = -EDOM;
1044 goto name_bail;
1045 }
1046
1047 rdbgdevice->rdbg_data = kcalloc(rdbgdevice->num_devices,
1048 sizeof(struct rdbg_data), GFP_KERNEL);
1049 if (!rdbgdevice->rdbg_data) {
1050 err = -ENOMEM;
1051 goto name_bail;
1052 }
1053
1054 err = alloc_chrdev_region(&rdbgdevice->dev_no, 0,
1055 rdbgdevice->num_devices, "rdbgctl");
1056 if (err) {
1057 pr_err("Error in alloc_chrdev_region.");
1058 goto data_bail;
1059 }
1060 major = MAJOR(rdbgdevice->dev_no);
1061
1062 cdev_init(&rdbgdevice->cdev, &rdbg_fops);
1063 rdbgdevice->cdev.owner = THIS_MODULE;
1064 err = cdev_add(&rdbgdevice->cdev, MKDEV(major, 0),
1065 rdbgdevice->num_devices);
1066 if (err) {
1067 pr_err("Error in cdev_add");
1068 goto chrdev_bail;
1069 }
1070
1071 rdbgdevice->class = class_create(THIS_MODULE, "rdbg");
1072 if (IS_ERR(rdbgdevice->class)) {
1073 err = PTR_ERR(rdbgdevice->class);
1074 pr_err("Error in class_create");
1075 goto cdev_bail;
1076 }
1077
1078 for (minor = 0; minor < rdbgdevice->num_devices; minor++) {
1079 if (!proc_info[minor].name)
1080 continue;
1081
1082 if (snprintf(node_name, max_len, "%s%d_in",
1083 rdbg_compatible_string, minor) <= 0) {
1084 pr_err("Error in snprintf");
1085 err = -ENOMEM;
1086 goto device_bail;
1087 }
1088
1089 if (register_smp2p(node_name,
1090 &rdbgdevice->rdbg_data[minor].in)) {
1091 pr_debug("No incoming device tree entry found for %s",
1092 proc_info[minor].name);
1093 continue;
1094 }
1095
1096 if (snprintf(node_name, max_len, "%s%d_out",
1097 rdbg_compatible_string, minor) <= 0) {
1098 pr_err("Error in snprintf");
1099 err = -ENOMEM;
1100 goto device_bail;
1101 }
1102
1103 if (register_smp2p(node_name,
1104 &rdbgdevice->rdbg_data[minor].out)) {
1105 pr_err("No outgoing device tree entry found for %s",
1106 proc_info[minor].name);
1107 err = -EINVAL;
1108 goto device_bail;
1109 }
1110
1111 rdbgdevice->rdbg_data[minor].device = device_create(
1112 rdbgdevice->class, NULL, MKDEV(major, minor),
1113 NULL, "%s", proc_info[minor].name);
1114 if (IS_ERR(rdbgdevice->rdbg_data[minor].device)) {
1115 err = PTR_ERR(rdbgdevice->rdbg_data[minor].device);
1116 pr_err("Error in device_create");
1117 goto device_bail;
1118 }
1119 rdbgdevice->rdbg_data[minor].device_initialized = 1;
1120 minor_nodes_created++;
1121 dev_dbg(rdbgdevice->rdbg_data[minor].device,
1122 "%s: created /dev/%s c %d %d'", __func__,
1123 proc_info[minor].name, major, minor);
1124 }
1125
1126 if (!minor_nodes_created) {
1127 pr_err("No device tree entries found");
1128 err = -EINVAL;
1129 goto class_bail;
1130 }
1131
1132 goto name_bail;
1133
1134device_bail:
1135 for (--minor; minor >= 0; minor--) {
1136 if (rdbgdevice->rdbg_data[minor].device_initialized)
1137 device_destroy(rdbgdevice->class,
1138 MKDEV(MAJOR(rdbgdevice->dev_no), minor));
1139 }
1140class_bail:
1141 class_destroy(rdbgdevice->class);
1142cdev_bail:
1143 cdev_del(&rdbgdevice->cdev);
1144chrdev_bail:
1145 unregister_chrdev_region(rdbgdevice->dev_no, rdbgdevice->num_devices);
1146data_bail:
1147 kfree(rdbgdevice->rdbg_data);
1148name_bail:
1149 kfree(node_name);
1150bail:
1151 return err;
1152}
1153
1154static void __exit rdbg_exit(void)
1155{
1156 struct rdbg_device *rdbgdevice = &g_rdbg_instance;
1157 int minor;
1158
1159 for (minor = 0; minor < rdbgdevice->num_devices; minor++) {
1160 if (rdbgdevice->rdbg_data[minor].device_initialized) {
1161 device_destroy(rdbgdevice->class,
1162 MKDEV(MAJOR(rdbgdevice->dev_no), minor));
1163 }
1164 }
1165 class_destroy(rdbgdevice->class);
1166 cdev_del(&rdbgdevice->cdev);
1167 unregister_chrdev_region(rdbgdevice->dev_no, 1);
1168 kfree(rdbgdevice->rdbg_data);
1169}
1170
1171module_init(rdbg_init);
1172module_exit(rdbg_exit);
1173
1174MODULE_DESCRIPTION("rdbg module");
1175MODULE_LICENSE("GPL v2");