@@ -113,6 +113,7 @@ struct scmi_chan_info {
113
113
* implementation version and (sub-)vendor identification.
114
114
* @minfo: Message info
115
115
* @tx_idr: IDR object to map protocol id to Tx channel info pointer
116
+ * @rx_idr: IDR object to map protocol id to Rx channel info pointer
116
117
* @protocols_imp: List of protocols implemented, currently maximum of
117
118
* MAX_PROTOCOLS_IMP elements allocated by the base protocol
118
119
* @node: List head
@@ -125,6 +126,7 @@ struct scmi_info {
125
126
struct scmi_handle handle ;
126
127
struct scmi_xfers_info minfo ;
127
128
struct idr tx_idr ;
129
+ struct idr rx_idr ;
128
130
u8 * protocols_imp ;
129
131
struct list_head node ;
130
132
int users ;
@@ -655,13 +657,17 @@ static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev,
655
657
struct device_node * shmem , * np = dev -> of_node ;
656
658
struct scmi_chan_info * cinfo ;
657
659
struct mbox_client * cl ;
660
+ struct idr * idr ;
658
661
const char * desc = tx ? "Tx" : "Rx" ;
659
662
660
663
/* Transmit channel is first entry i.e. index 0 */
661
664
idx = tx ? 0 : 1 ;
665
+ idr = tx ? & info -> tx_idr : & info -> rx_idr ;
662
666
663
667
if (scmi_mailbox_check (np , idx )) {
664
- cinfo = idr_find (& info -> tx_idr , SCMI_PROTOCOL_BASE );
668
+ cinfo = idr_find (idr , SCMI_PROTOCOL_BASE );
669
+ if (unlikely (!cinfo )) /* Possible only if platform has no Rx */
670
+ return - EINVAL ;
665
671
goto idr_alloc ;
666
672
}
667
673
@@ -703,7 +709,7 @@ static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev,
703
709
}
704
710
705
711
idr_alloc :
706
- ret = idr_alloc (& info -> tx_idr , cinfo , prot_id , prot_id + 1 , GFP_KERNEL );
712
+ ret = idr_alloc (idr , cinfo , prot_id , prot_id + 1 , GFP_KERNEL );
707
713
if (ret != prot_id ) {
708
714
dev_err (dev , "unable to allocate SCMI idr slot err %d\n" , ret );
709
715
return ret ;
@@ -713,6 +719,17 @@ static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev,
713
719
return 0 ;
714
720
}
715
721
722
+ static inline int
723
+ scmi_mbox_txrx_setup (struct scmi_info * info , struct device * dev , int prot_id )
724
+ {
725
+ int ret = scmi_mbox_chan_setup (info , dev , prot_id , true);
726
+
727
+ if (!ret ) /* Rx is optional, hence no error check */
728
+ scmi_mbox_chan_setup (info , dev , prot_id , false);
729
+
730
+ return ret ;
731
+ }
732
+
716
733
static inline void
717
734
scmi_create_protocol_device (struct device_node * np , struct scmi_info * info ,
718
735
int prot_id )
@@ -726,7 +743,7 @@ scmi_create_protocol_device(struct device_node *np, struct scmi_info *info,
726
743
return ;
727
744
}
728
745
729
- if (scmi_mbox_chan_setup (info , & sdev -> dev , prot_id , true )) {
746
+ if (scmi_mbox_txrx_setup (info , & sdev -> dev , prot_id )) {
730
747
dev_err (& sdev -> dev , "failed to setup transport\n" );
731
748
scmi_device_destroy (sdev );
732
749
return ;
@@ -769,12 +786,13 @@ static int scmi_probe(struct platform_device *pdev)
769
786
770
787
platform_set_drvdata (pdev , info );
771
788
idr_init (& info -> tx_idr );
789
+ idr_init (& info -> rx_idr );
772
790
773
791
handle = & info -> handle ;
774
792
handle -> dev = info -> dev ;
775
793
handle -> version = & info -> version ;
776
794
777
- ret = scmi_mbox_chan_setup (info , dev , SCMI_PROTOCOL_BASE , true );
795
+ ret = scmi_mbox_txrx_setup (info , dev , SCMI_PROTOCOL_BASE );
778
796
if (ret )
779
797
return ret ;
780
798
@@ -844,6 +862,10 @@ static int scmi_remove(struct platform_device *pdev)
844
862
ret = idr_for_each (idr , scmi_mbox_free_channel , idr );
845
863
idr_destroy (& info -> tx_idr );
846
864
865
+ idr = & info -> rx_idr ;
866
+ ret = idr_for_each (idr , scmi_mbox_free_channel , idr );
867
+ idr_destroy (& info -> rx_idr );
868
+
847
869
return ret ;
848
870
}
849
871
0 commit comments