18
18
#include <linux/of.h>
19
19
#include <linux/irq.h>
20
20
#include <linux/irqdomain.h>
21
+ #include <linux/mailbox_client.h>
21
22
#include <linux/mfd/syscon.h>
22
23
#include <linux/module.h>
23
24
#include <linux/platform_device.h>
@@ -126,6 +127,8 @@ struct smp2p_entry {
126
127
* @ipc_regmap: regmap for the outbound ipc
127
128
* @ipc_offset: offset within the regmap
128
129
* @ipc_bit: bit in regmap@offset to kick to signal remote processor
130
+ * @mbox_client: mailbox client handle
131
+ * @mbox_chan: apcs ipc mailbox channel handle
129
132
* @inbound: list of inbound entries
130
133
* @outbound: list of outbound entries
131
134
*/
@@ -146,6 +149,9 @@ struct qcom_smp2p {
146
149
int ipc_offset ;
147
150
int ipc_bit ;
148
151
152
+ struct mbox_client mbox_client ;
153
+ struct mbox_chan * mbox_chan ;
154
+
149
155
struct list_head inbound ;
150
156
struct list_head outbound ;
151
157
};
@@ -154,7 +160,13 @@ static void qcom_smp2p_kick(struct qcom_smp2p *smp2p)
154
160
{
155
161
/* Make sure any updated data is written before the kick */
156
162
wmb ();
157
- regmap_write (smp2p -> ipc_regmap , smp2p -> ipc_offset , BIT (smp2p -> ipc_bit ));
163
+
164
+ if (smp2p -> mbox_chan ) {
165
+ mbox_send_message (smp2p -> mbox_chan , NULL );
166
+ mbox_client_txdone (smp2p -> mbox_chan , 0 );
167
+ } else {
168
+ regmap_write (smp2p -> ipc_regmap , smp2p -> ipc_offset , BIT (smp2p -> ipc_bit ));
169
+ }
158
170
}
159
171
160
172
/**
@@ -453,10 +465,6 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
453
465
454
466
platform_set_drvdata (pdev , smp2p );
455
467
456
- ret = smp2p_parse_ipc (smp2p );
457
- if (ret )
458
- return ret ;
459
-
460
468
key = "qcom,smem" ;
461
469
ret = of_property_read_u32_array (pdev -> dev .of_node , key ,
462
470
smp2p -> smem_items , 2 );
@@ -483,9 +491,23 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
483
491
return irq ;
484
492
}
485
493
494
+ smp2p -> mbox_client .dev = & pdev -> dev ;
495
+ smp2p -> mbox_client .knows_txdone = true;
496
+ smp2p -> mbox_chan = mbox_request_channel (& smp2p -> mbox_client , 0 );
497
+ if (IS_ERR (smp2p -> mbox_chan )) {
498
+ if (PTR_ERR (smp2p -> mbox_chan ) != - ENODEV )
499
+ return PTR_ERR (smp2p -> mbox_chan );
500
+
501
+ smp2p -> mbox_chan = NULL ;
502
+
503
+ ret = smp2p_parse_ipc (smp2p );
504
+ if (ret )
505
+ return ret ;
506
+ }
507
+
486
508
ret = qcom_smp2p_alloc_outbound_item (smp2p );
487
509
if (ret < 0 )
488
- return ret ;
510
+ goto release_mbox ;
489
511
490
512
for_each_available_child_of_node (pdev -> dev .of_node , node ) {
491
513
entry = devm_kzalloc (& pdev -> dev , sizeof (* entry ), GFP_KERNEL );
@@ -540,6 +562,9 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
540
562
541
563
smp2p -> out -> valid_entries = 0 ;
542
564
565
+ release_mbox :
566
+ mbox_free_channel (smp2p -> mbox_chan );
567
+
543
568
return ret ;
544
569
}
545
570
@@ -554,6 +579,8 @@ static int qcom_smp2p_remove(struct platform_device *pdev)
554
579
list_for_each_entry (entry , & smp2p -> outbound , node )
555
580
qcom_smem_state_unregister (entry -> state );
556
581
582
+ mbox_free_channel (smp2p -> mbox_chan );
583
+
557
584
smp2p -> out -> valid_entries = 0 ;
558
585
559
586
return 0 ;
0 commit comments