1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/interrupt.h>
16#include <linux/io.h>
17#include <linux/mfd/syscon.h>
18#include <linux/module.h>
19#include <linux/of_irq.h>
20#include <linux/of_platform.h>
21#include <linux/platform_device.h>
22#include <linux/regmap.h>
23#include <linux/sched.h>
24#include <linux/slab.h>
25#include <linux/soc/qcom/smem.h>
26#include <linux/wait.h>
27#include <linux/rpmsg.h>
28#include <linux/rpmsg/qcom_smd.h>
29
30#include "rpmsg_internal.h"
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70struct smd_channel_info;
71struct smd_channel_info_pair;
72struct smd_channel_info_word;
73struct smd_channel_info_word_pair;
74
75static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops;
76
77#define SMD_ALLOC_TBL_COUNT 2
78#define SMD_ALLOC_TBL_SIZE 64
79
80
81
82
83
84static const struct {
85 unsigned alloc_tbl_id;
86 unsigned info_base_id;
87 unsigned fifo_base_id;
88} smem_items[SMD_ALLOC_TBL_COUNT] = {
89 {
90 .alloc_tbl_id = 13,
91 .info_base_id = 14,
92 .fifo_base_id = 338
93 },
94 {
95 .alloc_tbl_id = 266,
96 .info_base_id = 138,
97 .fifo_base_id = 202,
98 },
99};
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117struct qcom_smd_edge {
118 struct device dev;
119
120 const char *name;
121
122 struct device_node *of_node;
123 unsigned edge_id;
124 unsigned remote_pid;
125
126 int irq;
127
128 struct regmap *ipc_regmap;
129 int ipc_offset;
130 int ipc_bit;
131
132 struct list_head channels;
133 spinlock_t channels_lock;
134
135 DECLARE_BITMAP(allocated[SMD_ALLOC_TBL_COUNT], SMD_ALLOC_TBL_SIZE);
136
137 unsigned smem_available;
138
139 wait_queue_head_t new_channel_event;
140
141 struct work_struct scan_work;
142 struct work_struct state_work;
143};
144
145
146
147
148enum smd_channel_state {
149 SMD_CHANNEL_CLOSED,
150 SMD_CHANNEL_OPENING,
151 SMD_CHANNEL_OPENED,
152 SMD_CHANNEL_FLUSHING,
153 SMD_CHANNEL_CLOSING,
154 SMD_CHANNEL_RESET,
155 SMD_CHANNEL_RESET_OPENING
156};
157
158struct qcom_smd_device {
159 struct rpmsg_device rpdev;
160
161 struct qcom_smd_edge *edge;
162};
163
164struct qcom_smd_endpoint {
165 struct rpmsg_endpoint ept;
166
167 struct qcom_smd_channel *qsch;
168};
169
170#define to_smd_device(r) container_of(r, struct qcom_smd_device, rpdev)
171#define to_smd_edge(d) container_of(d, struct qcom_smd_edge, dev)
172#define to_smd_endpoint(e) container_of(e, struct qcom_smd_endpoint, ept)
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194struct qcom_smd_channel {
195 struct qcom_smd_edge *edge;
196
197 struct qcom_smd_endpoint *qsept;
198 bool registered;
199
200 char *name;
201 enum smd_channel_state state;
202 enum smd_channel_state remote_state;
203 wait_queue_head_t state_change_event;
204
205 struct smd_channel_info_pair *info;
206 struct smd_channel_info_word_pair *info_word;
207
208 spinlock_t tx_lock;
209 wait_queue_head_t fblockread_event;
210
211 void *tx_fifo;
212 void *rx_fifo;
213 int fifo_size;
214
215 void *bounce_buffer;
216
217 spinlock_t recv_lock;
218
219 int pkt_size;
220
221 void *drvdata;
222
223 struct list_head list;
224};
225
226
227
228
229struct smd_channel_info {
230 __le32 state;
231 u8 fDSR;
232 u8 fCTS;
233 u8 fCD;
234 u8 fRI;
235 u8 fHEAD;
236 u8 fTAIL;
237 u8 fSTATE;
238 u8 fBLOCKREADINTR;
239 __le32 tail;
240 __le32 head;
241};
242
243struct smd_channel_info_pair {
244 struct smd_channel_info tx;
245 struct smd_channel_info rx;
246};
247
248
249
250
251struct smd_channel_info_word {
252 __le32 state;
253 __le32 fDSR;
254 __le32 fCTS;
255 __le32 fCD;
256 __le32 fRI;
257 __le32 fHEAD;
258 __le32 fTAIL;
259 __le32 fSTATE;
260 __le32 fBLOCKREADINTR;
261 __le32 tail;
262 __le32 head;
263};
264
265struct smd_channel_info_word_pair {
266 struct smd_channel_info_word tx;
267 struct smd_channel_info_word rx;
268};
269
270#define GET_RX_CHANNEL_FLAG(channel, param) \
271 ({ \
272 BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u8)); \
273 channel->info_word ? \
274 le32_to_cpu(channel->info_word->rx.param) : \
275 channel->info->rx.param; \
276 })
277
278#define GET_RX_CHANNEL_INFO(channel, param) \
279 ({ \
280 BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u32)); \
281 le32_to_cpu(channel->info_word ? \
282 channel->info_word->rx.param : \
283 channel->info->rx.param); \
284 })
285
286#define SET_RX_CHANNEL_FLAG(channel, param, value) \
287 ({ \
288 BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u8)); \
289 if (channel->info_word) \
290 channel->info_word->rx.param = cpu_to_le32(value); \
291 else \
292 channel->info->rx.param = value; \
293 })
294
295#define SET_RX_CHANNEL_INFO(channel, param, value) \
296 ({ \
297 BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u32)); \
298 if (channel->info_word) \
299 channel->info_word->rx.param = cpu_to_le32(value); \
300 else \
301 channel->info->rx.param = cpu_to_le32(value); \
302 })
303
304#define GET_TX_CHANNEL_FLAG(channel, param) \
305 ({ \
306 BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u8)); \
307 channel->info_word ? \
308 le32_to_cpu(channel->info_word->tx.param) : \
309 channel->info->tx.param; \
310 })
311
312#define GET_TX_CHANNEL_INFO(channel, param) \
313 ({ \
314 BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u32)); \
315 le32_to_cpu(channel->info_word ? \
316 channel->info_word->tx.param : \
317 channel->info->tx.param); \
318 })
319
320#define SET_TX_CHANNEL_FLAG(channel, param, value) \
321 ({ \
322 BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u8)); \
323 if (channel->info_word) \
324 channel->info_word->tx.param = cpu_to_le32(value); \
325 else \
326 channel->info->tx.param = value; \
327 })
328
329#define SET_TX_CHANNEL_INFO(channel, param, value) \
330 ({ \
331 BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u32)); \
332 if (channel->info_word) \
333 channel->info_word->tx.param = cpu_to_le32(value); \
334 else \
335 channel->info->tx.param = cpu_to_le32(value); \
336 })
337
338
339
340
341
342
343
344
345struct qcom_smd_alloc_entry {
346 u8 name[20];
347 __le32 cid;
348 __le32 flags;
349 __le32 ref_count;
350} __packed;
351
352#define SMD_CHANNEL_FLAGS_EDGE_MASK 0xff
353#define SMD_CHANNEL_FLAGS_STREAM BIT(8)
354#define SMD_CHANNEL_FLAGS_PACKET BIT(9)
355
356
357
358
359
360#define SMD_PACKET_HEADER_LEN 20
361
362
363
364
365static void qcom_smd_signal_channel(struct qcom_smd_channel *channel)
366{
367 struct qcom_smd_edge *edge = channel->edge;
368
369 regmap_write(edge->ipc_regmap, edge->ipc_offset, BIT(edge->ipc_bit));
370}
371
372
373
374
375static void qcom_smd_channel_reset(struct qcom_smd_channel *channel)
376{
377 SET_TX_CHANNEL_INFO(channel, state, SMD_CHANNEL_CLOSED);
378 SET_TX_CHANNEL_FLAG(channel, fDSR, 0);
379 SET_TX_CHANNEL_FLAG(channel, fCTS, 0);
380 SET_TX_CHANNEL_FLAG(channel, fCD, 0);
381 SET_TX_CHANNEL_FLAG(channel, fRI, 0);
382 SET_TX_CHANNEL_FLAG(channel, fHEAD, 0);
383 SET_TX_CHANNEL_FLAG(channel, fTAIL, 0);
384 SET_TX_CHANNEL_FLAG(channel, fSTATE, 1);
385 SET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR, 1);
386 SET_TX_CHANNEL_INFO(channel, head, 0);
387 SET_RX_CHANNEL_INFO(channel, tail, 0);
388
389 qcom_smd_signal_channel(channel);
390
391 channel->state = SMD_CHANNEL_CLOSED;
392 channel->pkt_size = 0;
393}
394
395
396
397
398static void qcom_smd_channel_set_callback(struct qcom_smd_channel *channel,
399 rpmsg_rx_cb_t cb)
400{
401 struct rpmsg_endpoint *ept = &channel->qsept->ept;
402 unsigned long flags;
403
404 spin_lock_irqsave(&channel->recv_lock, flags);
405 ept->cb = cb;
406 spin_unlock_irqrestore(&channel->recv_lock, flags);
407};
408
409
410
411
412static size_t qcom_smd_channel_get_rx_avail(struct qcom_smd_channel *channel)
413{
414 unsigned head;
415 unsigned tail;
416
417 head = GET_RX_CHANNEL_INFO(channel, head);
418 tail = GET_RX_CHANNEL_INFO(channel, tail);
419
420 return (head - tail) & (channel->fifo_size - 1);
421}
422
423
424
425
426static void qcom_smd_channel_set_state(struct qcom_smd_channel *channel,
427 int state)
428{
429 struct qcom_smd_edge *edge = channel->edge;
430 bool is_open = state == SMD_CHANNEL_OPENED;
431
432 if (channel->state == state)
433 return;
434
435 dev_dbg(&edge->dev, "set_state(%s, %d)\n", channel->name, state);
436
437 SET_TX_CHANNEL_FLAG(channel, fDSR, is_open);
438 SET_TX_CHANNEL_FLAG(channel, fCTS, is_open);
439 SET_TX_CHANNEL_FLAG(channel, fCD, is_open);
440
441 SET_TX_CHANNEL_INFO(channel, state, state);
442 SET_TX_CHANNEL_FLAG(channel, fSTATE, 1);
443
444 channel->state = state;
445 qcom_smd_signal_channel(channel);
446}
447
448
449
450
451static void smd_copy_to_fifo(void __iomem *dst,
452 const void *src,
453 size_t count,
454 bool word_aligned)
455{
456 if (word_aligned) {
457 __iowrite32_copy(dst, src, count / sizeof(u32));
458 } else {
459 memcpy_toio(dst, src, count);
460 }
461}
462
463
464
465
466static void smd_copy_from_fifo(void *dst,
467 const void __iomem *src,
468 size_t count,
469 bool word_aligned)
470{
471 if (word_aligned) {
472 __ioread32_copy(dst, src, count / sizeof(u32));
473 } else {
474 memcpy_fromio(dst, src, count);
475 }
476}
477
478
479
480
481
482static size_t qcom_smd_channel_peek(struct qcom_smd_channel *channel,
483 void *buf, size_t count)
484{
485 bool word_aligned;
486 unsigned tail;
487 size_t len;
488
489 word_aligned = channel->info_word;
490 tail = GET_RX_CHANNEL_INFO(channel, tail);
491
492 len = min_t(size_t, count, channel->fifo_size - tail);
493 if (len) {
494 smd_copy_from_fifo(buf,
495 channel->rx_fifo + tail,
496 len,
497 word_aligned);
498 }
499
500 if (len != count) {
501 smd_copy_from_fifo(buf + len,
502 channel->rx_fifo,
503 count - len,
504 word_aligned);
505 }
506
507 return count;
508}
509
510
511
512
513static void qcom_smd_channel_advance(struct qcom_smd_channel *channel,
514 size_t count)
515{
516 unsigned tail;
517
518 tail = GET_RX_CHANNEL_INFO(channel, tail);
519 tail += count;
520 tail &= (channel->fifo_size - 1);
521 SET_RX_CHANNEL_INFO(channel, tail, tail);
522}
523
524
525
526
527static int qcom_smd_channel_recv_single(struct qcom_smd_channel *channel)
528{
529 struct rpmsg_endpoint *ept = &channel->qsept->ept;
530 unsigned tail;
531 size_t len;
532 void *ptr;
533 int ret;
534
535 tail = GET_RX_CHANNEL_INFO(channel, tail);
536
537
538 if (tail + channel->pkt_size >= channel->fifo_size) {
539 ptr = channel->bounce_buffer;
540 len = qcom_smd_channel_peek(channel, ptr, channel->pkt_size);
541 } else {
542 ptr = channel->rx_fifo + tail;
543 len = channel->pkt_size;
544 }
545
546 ret = ept->cb(ept->rpdev, ptr, len, ept->priv, RPMSG_ADDR_ANY);
547 if (ret < 0)
548 return ret;
549
550
551 qcom_smd_channel_advance(channel, len);
552
553 channel->pkt_size = 0;
554
555 return 0;
556}
557
558
559
560
561static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
562{
563 bool need_state_scan = false;
564 int remote_state;
565 __le32 pktlen;
566 int avail;
567 int ret;
568
569
570 remote_state = GET_RX_CHANNEL_INFO(channel, state);
571 if (remote_state != channel->remote_state) {
572 channel->remote_state = remote_state;
573 need_state_scan = true;
574
575 wake_up_interruptible_all(&channel->state_change_event);
576 }
577
578 SET_RX_CHANNEL_FLAG(channel, fSTATE, 0);
579
580
581 if (!GET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR))
582 wake_up_interruptible_all(&channel->fblockread_event);
583
584
585 if (channel->state != SMD_CHANNEL_OPENED)
586 goto out;
587
588
589 SET_RX_CHANNEL_FLAG(channel, fHEAD, 0);
590
591
592 for (;;) {
593 avail = qcom_smd_channel_get_rx_avail(channel);
594
595 if (!channel->pkt_size && avail >= SMD_PACKET_HEADER_LEN) {
596 qcom_smd_channel_peek(channel, &pktlen, sizeof(pktlen));
597 qcom_smd_channel_advance(channel, SMD_PACKET_HEADER_LEN);
598 channel->pkt_size = le32_to_cpu(pktlen);
599 } else if (channel->pkt_size && avail >= channel->pkt_size) {
600 ret = qcom_smd_channel_recv_single(channel);
601 if (ret)
602 break;
603 } else {
604 break;
605 }
606 }
607
608
609 SET_RX_CHANNEL_FLAG(channel, fTAIL, 1);
610
611
612 if (!GET_RX_CHANNEL_FLAG(channel, fBLOCKREADINTR)) {
613
614 wmb();
615
616 qcom_smd_signal_channel(channel);
617 }
618
619out:
620 return need_state_scan;
621}
622
623
624
625
626
627static irqreturn_t qcom_smd_edge_intr(int irq, void *data)
628{
629 struct qcom_smd_edge *edge = data;
630 struct qcom_smd_channel *channel;
631 unsigned available;
632 bool kick_scanner = false;
633 bool kick_state = false;
634
635
636
637
638 spin_lock(&edge->channels_lock);
639 list_for_each_entry(channel, &edge->channels, list) {
640 spin_lock(&channel->recv_lock);
641 kick_state |= qcom_smd_channel_intr(channel);
642 spin_unlock(&channel->recv_lock);
643 }
644 spin_unlock(&edge->channels_lock);
645
646
647
648
649
650
651 available = qcom_smem_get_free_space(edge->remote_pid);
652 if (available != edge->smem_available) {
653 edge->smem_available = available;
654 kick_scanner = true;
655 }
656
657 if (kick_scanner)
658 schedule_work(&edge->scan_work);
659 if (kick_state)
660 schedule_work(&edge->state_work);
661
662 return IRQ_HANDLED;
663}
664
665
666
667
668static size_t qcom_smd_get_tx_avail(struct qcom_smd_channel *channel)
669{
670 unsigned head;
671 unsigned tail;
672 unsigned mask = channel->fifo_size - 1;
673
674 head = GET_TX_CHANNEL_INFO(channel, head);
675 tail = GET_TX_CHANNEL_INFO(channel, tail);
676
677 return mask - ((head - tail) & mask);
678}
679
680
681
682
683static int qcom_smd_write_fifo(struct qcom_smd_channel *channel,
684 const void *data,
685 size_t count)
686{
687 bool word_aligned;
688 unsigned head;
689 size_t len;
690
691 word_aligned = channel->info_word;
692 head = GET_TX_CHANNEL_INFO(channel, head);
693
694 len = min_t(size_t, count, channel->fifo_size - head);
695 if (len) {
696 smd_copy_to_fifo(channel->tx_fifo + head,
697 data,
698 len,
699 word_aligned);
700 }
701
702 if (len != count) {
703 smd_copy_to_fifo(channel->tx_fifo,
704 data + len,
705 count - len,
706 word_aligned);
707 }
708
709 head += count;
710 head &= (channel->fifo_size - 1);
711 SET_TX_CHANNEL_INFO(channel, head, head);
712
713 return count;
714}
715
716
717
718
719
720
721
722
723
724
725
726
727static int __qcom_smd_send(struct qcom_smd_channel *channel, const void *data,
728 int len, bool wait)
729{
730 __le32 hdr[5] = { cpu_to_le32(len), };
731 int tlen = sizeof(hdr) + len;
732 unsigned long flags;
733 int ret;
734
735
736 if (channel->info_word && len % 4)
737 return -EINVAL;
738
739
740 if (tlen >= channel->fifo_size)
741 return -EINVAL;
742
743
744 if (wait)
745 might_sleep();
746
747 spin_lock_irqsave(&channel->tx_lock, flags);
748
749 while (qcom_smd_get_tx_avail(channel) < tlen &&
750 channel->state == SMD_CHANNEL_OPENED) {
751 if (!wait) {
752 ret = -EAGAIN;
753 goto out_unlock;
754 }
755
756 SET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR, 0);
757
758
759 spin_unlock_irqrestore(&channel->tx_lock, flags);
760
761 ret = wait_event_interruptible(channel->fblockread_event,
762 qcom_smd_get_tx_avail(channel) >= tlen ||
763 channel->state != SMD_CHANNEL_OPENED);
764 if (ret)
765 return ret;
766
767 spin_lock_irqsave(&channel->tx_lock, flags);
768
769 SET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR, 1);
770 }
771
772
773 if (channel->state != SMD_CHANNEL_OPENED) {
774 ret = -EPIPE;
775 goto out_unlock;
776 }
777
778 SET_TX_CHANNEL_FLAG(channel, fTAIL, 0);
779
780 qcom_smd_write_fifo(channel, hdr, sizeof(hdr));
781 qcom_smd_write_fifo(channel, data, len);
782
783 SET_TX_CHANNEL_FLAG(channel, fHEAD, 1);
784
785
786 wmb();
787
788 qcom_smd_signal_channel(channel);
789
790out_unlock:
791 spin_unlock_irqrestore(&channel->tx_lock, flags);
792
793 return ret;
794}
795
796
797
798
799static int qcom_smd_channel_open(struct qcom_smd_channel *channel,
800 rpmsg_rx_cb_t cb)
801{
802 struct qcom_smd_edge *edge = channel->edge;
803 size_t bb_size;
804 int ret;
805
806
807
808
809 bb_size = min(channel->fifo_size, SZ_4K);
810 channel->bounce_buffer = kmalloc(bb_size, GFP_KERNEL);
811 if (!channel->bounce_buffer)
812 return -ENOMEM;
813
814 qcom_smd_channel_set_callback(channel, cb);
815 qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENING);
816
817
818 ret = wait_event_interruptible_timeout(channel->state_change_event,
819 channel->remote_state == SMD_CHANNEL_OPENING ||
820 channel->remote_state == SMD_CHANNEL_OPENED,
821 HZ);
822 if (!ret) {
823 dev_err(&edge->dev, "remote side did not enter opening state\n");
824 goto out_close_timeout;
825 }
826
827 qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENED);
828
829
830 ret = wait_event_interruptible_timeout(channel->state_change_event,
831 channel->remote_state == SMD_CHANNEL_OPENED,
832 HZ);
833 if (!ret) {
834 dev_err(&edge->dev, "remote side did not enter open state\n");
835 goto out_close_timeout;
836 }
837
838 return 0;
839
840out_close_timeout:
841 qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSED);
842 return -ETIMEDOUT;
843}
844
845
846
847
848static void qcom_smd_channel_close(struct qcom_smd_channel *channel)
849{
850 qcom_smd_channel_set_callback(channel, NULL);
851
852 kfree(channel->bounce_buffer);
853 channel->bounce_buffer = NULL;
854
855 qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSED);
856 qcom_smd_channel_reset(channel);
857}
858
859static struct qcom_smd_channel *
860qcom_smd_find_channel(struct qcom_smd_edge *edge, const char *name)
861{
862 struct qcom_smd_channel *channel;
863 struct qcom_smd_channel *ret = NULL;
864 unsigned long flags;
865
866 spin_lock_irqsave(&edge->channels_lock, flags);
867 list_for_each_entry(channel, &edge->channels, list) {
868 if (!strcmp(channel->name, name)) {
869 ret = channel;
870 break;
871 }
872 }
873 spin_unlock_irqrestore(&edge->channels_lock, flags);
874
875 return ret;
876}
877
878static void __ept_release(struct kref *kref)
879{
880 struct rpmsg_endpoint *ept = container_of(kref, struct rpmsg_endpoint,
881 refcount);
882 kfree(to_smd_endpoint(ept));
883}
884
885static struct rpmsg_endpoint *qcom_smd_create_ept(struct rpmsg_device *rpdev,
886 rpmsg_rx_cb_t cb, void *priv,
887 struct rpmsg_channel_info chinfo)
888{
889 struct qcom_smd_endpoint *qsept;
890 struct qcom_smd_channel *channel;
891 struct qcom_smd_device *qsdev = to_smd_device(rpdev);
892 struct qcom_smd_edge *edge = qsdev->edge;
893 struct rpmsg_endpoint *ept;
894 const char *name = chinfo.name;
895 int ret;
896
897
898 ret = wait_event_interruptible_timeout(edge->new_channel_event,
899 (channel = qcom_smd_find_channel(edge, name)) != NULL,
900 HZ);
901 if (!ret)
902 return NULL;
903
904 if (channel->state != SMD_CHANNEL_CLOSED) {
905 dev_err(&rpdev->dev, "channel %s is busy\n", channel->name);
906 return NULL;
907 }
908
909 qsept = kzalloc(sizeof(*qsept), GFP_KERNEL);
910 if (!qsept)
911 return NULL;
912
913 ept = &qsept->ept;
914
915 kref_init(&ept->refcount);
916
917 ept->rpdev = rpdev;
918 ept->cb = cb;
919 ept->priv = priv;
920 ept->ops = &qcom_smd_endpoint_ops;
921
922 channel->qsept = qsept;
923 qsept->qsch = channel;
924
925 ret = qcom_smd_channel_open(channel, cb);
926 if (ret)
927 goto free_ept;
928
929 return ept;
930
931free_ept:
932 channel->qsept = NULL;
933 kref_put(&ept->refcount, __ept_release);
934 return NULL;
935}
936
937static void qcom_smd_destroy_ept(struct rpmsg_endpoint *ept)
938{
939 struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept);
940 struct qcom_smd_channel *ch = qsept->qsch;
941
942 qcom_smd_channel_close(ch);
943 ch->qsept = NULL;
944 kref_put(&ept->refcount, __ept_release);
945}
946
947static int qcom_smd_send(struct rpmsg_endpoint *ept, void *data, int len)
948{
949 struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept);
950
951 return __qcom_smd_send(qsept->qsch, data, len, true);
952}
953
954static int qcom_smd_trysend(struct rpmsg_endpoint *ept, void *data, int len)
955{
956 struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept);
957
958 return __qcom_smd_send(qsept->qsch, data, len, false);
959}
960
961static __poll_t qcom_smd_poll(struct rpmsg_endpoint *ept,
962 struct file *filp, poll_table *wait)
963{
964 struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept);
965 struct qcom_smd_channel *channel = qsept->qsch;
966 __poll_t mask = 0;
967
968 poll_wait(filp, &channel->fblockread_event, wait);
969
970 if (qcom_smd_get_tx_avail(channel) > 20)
971 mask |= EPOLLOUT | EPOLLWRNORM;
972
973 return mask;
974}
975
976
977
978
979static struct device_node *qcom_smd_match_channel(struct device_node *edge_node,
980 const char *channel)
981{
982 struct device_node *child;
983 const char *name;
984 const char *key;
985 int ret;
986
987 for_each_available_child_of_node(edge_node, child) {
988 key = "qcom,smd-channels";
989 ret = of_property_read_string(child, key, &name);
990 if (ret)
991 continue;
992
993 if (strcmp(name, channel) == 0)
994 return child;
995 }
996
997 return NULL;
998}
999
1000static int qcom_smd_announce_create(struct rpmsg_device *rpdev)
1001{
1002 struct qcom_smd_endpoint *qept = to_smd_endpoint(rpdev->ept);
1003 struct qcom_smd_channel *channel = qept->qsch;
1004 unsigned long flags;
1005 bool kick_state;
1006
1007 spin_lock_irqsave(&channel->recv_lock, flags);
1008 kick_state = qcom_smd_channel_intr(channel);
1009 spin_unlock_irqrestore(&channel->recv_lock, flags);
1010
1011 if (kick_state)
1012 schedule_work(&channel->edge->state_work);
1013
1014 return 0;
1015}
1016
1017static const struct rpmsg_device_ops qcom_smd_device_ops = {
1018 .create_ept = qcom_smd_create_ept,
1019 .announce_create = qcom_smd_announce_create,
1020};
1021
1022static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops = {
1023 .destroy_ept = qcom_smd_destroy_ept,
1024 .send = qcom_smd_send,
1025 .trysend = qcom_smd_trysend,
1026 .poll = qcom_smd_poll,
1027};
1028
1029static void qcom_smd_release_device(struct device *dev)
1030{
1031 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
1032 struct qcom_smd_device *qsdev = to_smd_device(rpdev);
1033
1034 kfree(qsdev);
1035}
1036
1037
1038
1039
1040static int qcom_smd_create_device(struct qcom_smd_channel *channel)
1041{
1042 struct qcom_smd_device *qsdev;
1043 struct rpmsg_device *rpdev;
1044 struct qcom_smd_edge *edge = channel->edge;
1045
1046 dev_dbg(&edge->dev, "registering '%s'\n", channel->name);
1047
1048 qsdev = kzalloc(sizeof(*qsdev), GFP_KERNEL);
1049 if (!qsdev)
1050 return -ENOMEM;
1051
1052
1053 qsdev->edge = edge;
1054
1055
1056 qsdev->rpdev.ops = &qcom_smd_device_ops;
1057
1058
1059 rpdev = &qsdev->rpdev;
1060 strncpy(rpdev->id.name, channel->name, RPMSG_NAME_SIZE);
1061 rpdev->src = RPMSG_ADDR_ANY;
1062 rpdev->dst = RPMSG_ADDR_ANY;
1063
1064 rpdev->dev.of_node = qcom_smd_match_channel(edge->of_node, channel->name);
1065 rpdev->dev.parent = &edge->dev;
1066 rpdev->dev.release = qcom_smd_release_device;
1067
1068 return rpmsg_register_device(rpdev);
1069}
1070
1071static int qcom_smd_create_chrdev(struct qcom_smd_edge *edge)
1072{
1073 struct qcom_smd_device *qsdev;
1074
1075 qsdev = kzalloc(sizeof(*qsdev), GFP_KERNEL);
1076 if (!qsdev)
1077 return -ENOMEM;
1078
1079 qsdev->edge = edge;
1080 qsdev->rpdev.ops = &qcom_smd_device_ops;
1081 qsdev->rpdev.dev.parent = &edge->dev;
1082 qsdev->rpdev.dev.release = qcom_smd_release_device;
1083
1084 return rpmsg_chrdev_register_device(&qsdev->rpdev);
1085}
1086
1087
1088
1089
1090
1091static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *edge,
1092 unsigned smem_info_item,
1093 unsigned smem_fifo_item,
1094 char *name)
1095{
1096 struct qcom_smd_channel *channel;
1097 size_t fifo_size;
1098 size_t info_size;
1099 void *fifo_base;
1100 void *info;
1101 int ret;
1102
1103 channel = devm_kzalloc(&edge->dev, sizeof(*channel), GFP_KERNEL);
1104 if (!channel)
1105 return ERR_PTR(-ENOMEM);
1106
1107 channel->edge = edge;
1108 channel->name = devm_kstrdup(&edge->dev, name, GFP_KERNEL);
1109 if (!channel->name)
1110 return ERR_PTR(-ENOMEM);
1111
1112 spin_lock_init(&channel->tx_lock);
1113 spin_lock_init(&channel->recv_lock);
1114 init_waitqueue_head(&channel->fblockread_event);
1115 init_waitqueue_head(&channel->state_change_event);
1116
1117 info = qcom_smem_get(edge->remote_pid, smem_info_item, &info_size);
1118 if (IS_ERR(info)) {
1119 ret = PTR_ERR(info);
1120 goto free_name_and_channel;
1121 }
1122
1123
1124
1125
1126
1127 if (info_size == 2 * sizeof(struct smd_channel_info_word)) {
1128 channel->info_word = info;
1129 } else if (info_size == 2 * sizeof(struct smd_channel_info)) {
1130 channel->info = info;
1131 } else {
1132 dev_err(&edge->dev,
1133 "channel info of size %zu not supported\n", info_size);
1134 ret = -EINVAL;
1135 goto free_name_and_channel;
1136 }
1137
1138 fifo_base = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_size);
1139 if (IS_ERR(fifo_base)) {
1140 ret = PTR_ERR(fifo_base);
1141 goto free_name_and_channel;
1142 }
1143
1144
1145 fifo_size /= 2;
1146
1147 dev_dbg(&edge->dev, "new channel '%s' info-size: %zu fifo-size: %zu\n",
1148 name, info_size, fifo_size);
1149
1150 channel->tx_fifo = fifo_base;
1151 channel->rx_fifo = fifo_base + fifo_size;
1152 channel->fifo_size = fifo_size;
1153
1154 qcom_smd_channel_reset(channel);
1155
1156 return channel;
1157
1158free_name_and_channel:
1159 devm_kfree(&edge->dev, channel->name);
1160 devm_kfree(&edge->dev, channel);
1161
1162 return ERR_PTR(ret);
1163}
1164
1165
1166
1167
1168
1169
1170static void qcom_channel_scan_worker(struct work_struct *work)
1171{
1172 struct qcom_smd_edge *edge = container_of(work, struct qcom_smd_edge, scan_work);
1173 struct qcom_smd_alloc_entry *alloc_tbl;
1174 struct qcom_smd_alloc_entry *entry;
1175 struct qcom_smd_channel *channel;
1176 unsigned long flags;
1177 unsigned fifo_id;
1178 unsigned info_id;
1179 int tbl;
1180 int i;
1181 u32 eflags, cid;
1182
1183 for (tbl = 0; tbl < SMD_ALLOC_TBL_COUNT; tbl++) {
1184 alloc_tbl = qcom_smem_get(edge->remote_pid,
1185 smem_items[tbl].alloc_tbl_id, NULL);
1186 if (IS_ERR(alloc_tbl))
1187 continue;
1188
1189 for (i = 0; i < SMD_ALLOC_TBL_SIZE; i++) {
1190 entry = &alloc_tbl[i];
1191 eflags = le32_to_cpu(entry->flags);
1192 if (test_bit(i, edge->allocated[tbl]))
1193 continue;
1194
1195 if (entry->ref_count == 0)
1196 continue;
1197
1198 if (!entry->name[0])
1199 continue;
1200
1201 if (!(eflags & SMD_CHANNEL_FLAGS_PACKET))
1202 continue;
1203
1204 if ((eflags & SMD_CHANNEL_FLAGS_EDGE_MASK) != edge->edge_id)
1205 continue;
1206
1207 cid = le32_to_cpu(entry->cid);
1208 info_id = smem_items[tbl].info_base_id + cid;
1209 fifo_id = smem_items[tbl].fifo_base_id + cid;
1210
1211 channel = qcom_smd_create_channel(edge, info_id, fifo_id, entry->name);
1212 if (IS_ERR(channel))
1213 continue;
1214
1215 spin_lock_irqsave(&edge->channels_lock, flags);
1216 list_add(&channel->list, &edge->channels);
1217 spin_unlock_irqrestore(&edge->channels_lock, flags);
1218
1219 dev_dbg(&edge->dev, "new channel found: '%s'\n", channel->name);
1220 set_bit(i, edge->allocated[tbl]);
1221
1222 wake_up_interruptible_all(&edge->new_channel_event);
1223 }
1224 }
1225
1226 schedule_work(&edge->state_work);
1227}
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237static void qcom_channel_state_worker(struct work_struct *work)
1238{
1239 struct qcom_smd_channel *channel;
1240 struct qcom_smd_edge *edge = container_of(work,
1241 struct qcom_smd_edge,
1242 state_work);
1243 struct rpmsg_channel_info chinfo;
1244 unsigned remote_state;
1245 unsigned long flags;
1246
1247
1248
1249
1250
1251 spin_lock_irqsave(&edge->channels_lock, flags);
1252 list_for_each_entry(channel, &edge->channels, list) {
1253 if (channel->state != SMD_CHANNEL_CLOSED)
1254 continue;
1255
1256 remote_state = GET_RX_CHANNEL_INFO(channel, state);
1257 if (remote_state != SMD_CHANNEL_OPENING &&
1258 remote_state != SMD_CHANNEL_OPENED)
1259 continue;
1260
1261 if (channel->registered)
1262 continue;
1263
1264 spin_unlock_irqrestore(&edge->channels_lock, flags);
1265 qcom_smd_create_device(channel);
1266 channel->registered = true;
1267 spin_lock_irqsave(&edge->channels_lock, flags);
1268
1269 channel->registered = true;
1270 }
1271
1272
1273
1274
1275
1276 list_for_each_entry(channel, &edge->channels, list) {
1277 if (channel->state != SMD_CHANNEL_OPENING &&
1278 channel->state != SMD_CHANNEL_OPENED)
1279 continue;
1280
1281 remote_state = GET_RX_CHANNEL_INFO(channel, state);
1282 if (remote_state == SMD_CHANNEL_OPENING ||
1283 remote_state == SMD_CHANNEL_OPENED)
1284 continue;
1285
1286 spin_unlock_irqrestore(&edge->channels_lock, flags);
1287
1288 strncpy(chinfo.name, channel->name, sizeof(chinfo.name));
1289 chinfo.src = RPMSG_ADDR_ANY;
1290 chinfo.dst = RPMSG_ADDR_ANY;
1291 rpmsg_unregister_device(&edge->dev, &chinfo);
1292 channel->registered = false;
1293 spin_lock_irqsave(&edge->channels_lock, flags);
1294 }
1295 spin_unlock_irqrestore(&edge->channels_lock, flags);
1296}
1297
1298
1299
1300
1301static int qcom_smd_parse_edge(struct device *dev,
1302 struct device_node *node,
1303 struct qcom_smd_edge *edge)
1304{
1305 struct device_node *syscon_np;
1306 const char *key;
1307 int irq;
1308 int ret;
1309
1310 INIT_LIST_HEAD(&edge->channels);
1311 spin_lock_init(&edge->channels_lock);
1312
1313 INIT_WORK(&edge->scan_work, qcom_channel_scan_worker);
1314 INIT_WORK(&edge->state_work, qcom_channel_state_worker);
1315
1316 edge->of_node = of_node_get(node);
1317
1318 key = "qcom,smd-edge";
1319 ret = of_property_read_u32(node, key, &edge->edge_id);
1320 if (ret) {
1321 dev_err(dev, "edge missing %s property\n", key);
1322 return -EINVAL;
1323 }
1324
1325 edge->remote_pid = QCOM_SMEM_HOST_ANY;
1326 key = "qcom,remote-pid";
1327 of_property_read_u32(node, key, &edge->remote_pid);
1328
1329 syscon_np = of_parse_phandle(node, "qcom,ipc", 0);
1330 if (!syscon_np) {
1331 dev_err(dev, "no qcom,ipc node\n");
1332 return -ENODEV;
1333 }
1334
1335 edge->ipc_regmap = syscon_node_to_regmap(syscon_np);
1336 if (IS_ERR(edge->ipc_regmap))
1337 return PTR_ERR(edge->ipc_regmap);
1338
1339 key = "qcom,ipc";
1340 ret = of_property_read_u32_index(node, key, 1, &edge->ipc_offset);
1341 if (ret < 0) {
1342 dev_err(dev, "no offset in %s\n", key);
1343 return -EINVAL;
1344 }
1345
1346 ret = of_property_read_u32_index(node, key, 2, &edge->ipc_bit);
1347 if (ret < 0) {
1348 dev_err(dev, "no bit in %s\n", key);
1349 return -EINVAL;
1350 }
1351
1352 ret = of_property_read_string(node, "label", &edge->name);
1353 if (ret < 0)
1354 edge->name = node->name;
1355
1356 irq = irq_of_parse_and_map(node, 0);
1357 if (irq < 0) {
1358 dev_err(dev, "required smd interrupt missing\n");
1359 return -EINVAL;
1360 }
1361
1362 ret = devm_request_irq(dev, irq,
1363 qcom_smd_edge_intr, IRQF_TRIGGER_RISING,
1364 node->name, edge);
1365 if (ret) {
1366 dev_err(dev, "failed to request smd irq\n");
1367 return ret;
1368 }
1369
1370 edge->irq = irq;
1371
1372 return 0;
1373}
1374
1375
1376
1377
1378
1379static void qcom_smd_edge_release(struct device *dev)
1380{
1381 struct qcom_smd_channel *channel;
1382 struct qcom_smd_edge *edge = to_smd_edge(dev);
1383
1384 list_for_each_entry(channel, &edge->channels, list) {
1385 SET_RX_CHANNEL_INFO(channel, state, SMD_CHANNEL_CLOSED);
1386 SET_RX_CHANNEL_INFO(channel, head, 0);
1387 SET_RX_CHANNEL_INFO(channel, tail, 0);
1388 }
1389
1390 kfree(edge);
1391}
1392
1393static ssize_t rpmsg_name_show(struct device *dev,
1394 struct device_attribute *attr, char *buf)
1395{
1396 struct qcom_smd_edge *edge = to_smd_edge(dev);
1397
1398 return sprintf(buf, "%s\n", edge->name);
1399}
1400static DEVICE_ATTR_RO(rpmsg_name);
1401
1402static struct attribute *qcom_smd_edge_attrs[] = {
1403 &dev_attr_rpmsg_name.attr,
1404 NULL
1405};
1406ATTRIBUTE_GROUPS(qcom_smd_edge);
1407
1408
1409
1410
1411
1412
1413
1414
1415struct qcom_smd_edge *qcom_smd_register_edge(struct device *parent,
1416 struct device_node *node)
1417{
1418 struct qcom_smd_edge *edge;
1419 int ret;
1420
1421 edge = kzalloc(sizeof(*edge), GFP_KERNEL);
1422 if (!edge)
1423 return ERR_PTR(-ENOMEM);
1424
1425 init_waitqueue_head(&edge->new_channel_event);
1426
1427 edge->dev.parent = parent;
1428 edge->dev.release = qcom_smd_edge_release;
1429 edge->dev.of_node = node;
1430 edge->dev.groups = qcom_smd_edge_groups;
1431 dev_set_name(&edge->dev, "%s:%s", dev_name(parent), node->name);
1432 ret = device_register(&edge->dev);
1433 if (ret) {
1434 pr_err("failed to register smd edge\n");
1435 put_device(&edge->dev);
1436 return ERR_PTR(ret);
1437 }
1438
1439 ret = qcom_smd_parse_edge(&edge->dev, node, edge);
1440 if (ret) {
1441 dev_err(&edge->dev, "failed to parse smd edge\n");
1442 goto unregister_dev;
1443 }
1444
1445 ret = qcom_smd_create_chrdev(edge);
1446 if (ret) {
1447 dev_err(&edge->dev, "failed to register chrdev for edge\n");
1448 goto unregister_dev;
1449 }
1450
1451 schedule_work(&edge->scan_work);
1452
1453 return edge;
1454
1455unregister_dev:
1456 device_unregister(&edge->dev);
1457 return ERR_PTR(ret);
1458}
1459EXPORT_SYMBOL(qcom_smd_register_edge);
1460
1461static int qcom_smd_remove_device(struct device *dev, void *data)
1462{
1463 device_unregister(dev);
1464
1465 return 0;
1466}
1467
1468
1469
1470
1471
1472int qcom_smd_unregister_edge(struct qcom_smd_edge *edge)
1473{
1474 int ret;
1475
1476 disable_irq(edge->irq);
1477 cancel_work_sync(&edge->scan_work);
1478 cancel_work_sync(&edge->state_work);
1479
1480 ret = device_for_each_child(&edge->dev, NULL, qcom_smd_remove_device);
1481 if (ret)
1482 dev_warn(&edge->dev, "can't remove smd device: %d\n", ret);
1483
1484 device_unregister(&edge->dev);
1485
1486 return 0;
1487}
1488EXPORT_SYMBOL(qcom_smd_unregister_edge);
1489
1490static int qcom_smd_probe(struct platform_device *pdev)
1491{
1492 struct device_node *node;
1493 void *p;
1494
1495
1496 p = qcom_smem_get(QCOM_SMEM_HOST_ANY, smem_items[0].alloc_tbl_id, NULL);
1497 if (PTR_ERR(p) == -EPROBE_DEFER)
1498 return PTR_ERR(p);
1499
1500 for_each_available_child_of_node(pdev->dev.of_node, node)
1501 qcom_smd_register_edge(&pdev->dev, node);
1502
1503 return 0;
1504}
1505
1506static int qcom_smd_remove_edge(struct device *dev, void *data)
1507{
1508 struct qcom_smd_edge *edge = to_smd_edge(dev);
1509
1510 return qcom_smd_unregister_edge(edge);
1511}
1512
1513
1514
1515
1516
1517static int qcom_smd_remove(struct platform_device *pdev)
1518{
1519 int ret;
1520
1521 ret = device_for_each_child(&pdev->dev, NULL, qcom_smd_remove_edge);
1522 if (ret)
1523 dev_warn(&pdev->dev, "can't remove smd device: %d\n", ret);
1524
1525 return ret;
1526}
1527
1528static const struct of_device_id qcom_smd_of_match[] = {
1529 { .compatible = "qcom,smd" },
1530 {}
1531};
1532MODULE_DEVICE_TABLE(of, qcom_smd_of_match);
1533
1534static struct platform_driver qcom_smd_driver = {
1535 .probe = qcom_smd_probe,
1536 .remove = qcom_smd_remove,
1537 .driver = {
1538 .name = "qcom-smd",
1539 .of_match_table = qcom_smd_of_match,
1540 },
1541};
1542
1543static int __init qcom_smd_init(void)
1544{
1545 return platform_driver_register(&qcom_smd_driver);
1546}
1547subsys_initcall(qcom_smd_init);
1548
1549static void __exit qcom_smd_exit(void)
1550{
1551 platform_driver_unregister(&qcom_smd_driver);
1552}
1553module_exit(qcom_smd_exit);
1554
1555MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
1556MODULE_DESCRIPTION("Qualcomm Shared Memory Driver");
1557MODULE_LICENSE("GPL v2");
1558