@@ -855,7 +855,8 @@ static void scp_remove_rpmsg_subdev(struct mtk_scp *scp)
855
855
}
856
856
857
857
static struct mtk_scp * scp_rproc_init (struct platform_device * pdev ,
858
- struct mtk_scp_of_cluster * scp_cluster )
858
+ struct mtk_scp_of_cluster * scp_cluster ,
859
+ const struct mtk_scp_of_data * of_data )
859
860
{
860
861
struct device * dev = & pdev -> dev ;
861
862
struct device_node * np = dev -> of_node ;
@@ -878,7 +879,7 @@ static struct mtk_scp *scp_rproc_init(struct platform_device *pdev,
878
879
scp = rproc -> priv ;
879
880
scp -> rproc = rproc ;
880
881
scp -> dev = dev ;
881
- scp -> data = of_device_get_match_data ( dev ) ;
882
+ scp -> data = of_data ;
882
883
scp -> cluster = scp_cluster ;
883
884
platform_set_drvdata (pdev , scp );
884
885
@@ -951,15 +952,15 @@ static void scp_free(struct mtk_scp *scp)
951
952
mutex_destroy (& scp -> send_lock );
952
953
}
953
954
954
- static int scp_cluster_init (struct platform_device * pdev ,
955
- struct mtk_scp_of_cluster * scp_cluster )
955
+ static int scp_add_single_core (struct platform_device * pdev ,
956
+ struct mtk_scp_of_cluster * scp_cluster )
956
957
{
957
958
struct device * dev = & pdev -> dev ;
958
959
struct list_head * scp_list = & scp_cluster -> mtk_scp_list ;
959
960
struct mtk_scp * scp ;
960
961
int ret ;
961
962
962
- scp = scp_rproc_init (pdev , scp_cluster );
963
+ scp = scp_rproc_init (pdev , scp_cluster , of_device_get_match_data ( dev ) );
963
964
if (IS_ERR (scp ))
964
965
return PTR_ERR (scp );
965
966
@@ -975,6 +976,108 @@ static int scp_cluster_init(struct platform_device *pdev,
975
976
return 0 ;
976
977
}
977
978
979
+ static int scp_add_multi_core (struct platform_device * pdev ,
980
+ struct mtk_scp_of_cluster * scp_cluster )
981
+ {
982
+ struct device * dev = & pdev -> dev ;
983
+ struct device_node * np = dev_of_node (dev );
984
+ struct platform_device * cpdev ;
985
+ struct device_node * child ;
986
+ struct list_head * scp_list = & scp_cluster -> mtk_scp_list ;
987
+ const struct mtk_scp_of_data * * cluster_of_data ;
988
+ struct mtk_scp * scp , * temp ;
989
+ int core_id = 0 ;
990
+ int ret ;
991
+
992
+ cluster_of_data = (const struct mtk_scp_of_data * * )of_device_get_match_data (dev );
993
+
994
+ for_each_available_child_of_node (np , child ) {
995
+ if (!cluster_of_data [core_id ]) {
996
+ ret = - EINVAL ;
997
+ dev_err (dev , "Not support core %d\n" , core_id );
998
+ of_node_put (child );
999
+ goto init_fail ;
1000
+ }
1001
+
1002
+ cpdev = of_find_device_by_node (child );
1003
+ if (!cpdev ) {
1004
+ ret = - ENODEV ;
1005
+ dev_err (dev , "Not found platform device for core %d\n" , core_id );
1006
+ of_node_put (child );
1007
+ goto init_fail ;
1008
+ }
1009
+
1010
+ scp = scp_rproc_init (cpdev , scp_cluster , cluster_of_data [core_id ]);
1011
+ put_device (& cpdev -> dev );
1012
+ if (IS_ERR (scp )) {
1013
+ ret = PTR_ERR (scp );
1014
+ dev_err (dev , "Failed to initialize core %d rproc\n" , core_id );
1015
+ of_node_put (child );
1016
+ goto init_fail ;
1017
+ }
1018
+
1019
+ ret = rproc_add (scp -> rproc );
1020
+ if (ret ) {
1021
+ dev_err (dev , "Failed to add rproc of core %d\n" , core_id );
1022
+ of_node_put (child );
1023
+ scp_free (scp );
1024
+ goto init_fail ;
1025
+ }
1026
+
1027
+ list_add_tail (& scp -> elem , scp_list );
1028
+ core_id ++ ;
1029
+ }
1030
+
1031
+ /*
1032
+ * Here we are setting the platform device for @pdev to the last @scp that was
1033
+ * created, which is needed because (1) scp_rproc_init() is calling
1034
+ * platform_set_drvdata() on the child platform devices and (2) we need a handle to
1035
+ * the cluster list in scp_remove().
1036
+ */
1037
+ platform_set_drvdata (pdev , scp );
1038
+
1039
+ return 0 ;
1040
+
1041
+ init_fail :
1042
+ list_for_each_entry_safe_reverse (scp , temp , scp_list , elem ) {
1043
+ list_del (& scp -> elem );
1044
+ rproc_del (scp -> rproc );
1045
+ scp_free (scp );
1046
+ }
1047
+
1048
+ return ret ;
1049
+ }
1050
+
1051
+ static int scp_is_single_core (struct platform_device * pdev )
1052
+ {
1053
+ struct device * dev = & pdev -> dev ;
1054
+ struct device_node * np = dev_of_node (dev );
1055
+ struct device_node * child ;
1056
+
1057
+ child = of_get_next_available_child (np , NULL );
1058
+ if (!child )
1059
+ return dev_err_probe (dev , - ENODEV , "No child node\n" );
1060
+
1061
+ of_node_put (child );
1062
+ return of_node_name_eq (child , "cros-ec-rpmsg" );
1063
+ }
1064
+
1065
+ static int scp_cluster_init (struct platform_device * pdev , struct mtk_scp_of_cluster * scp_cluster )
1066
+ {
1067
+ int ret ;
1068
+
1069
+ ret = scp_is_single_core (pdev );
1070
+ if (ret < 0 )
1071
+ return ret ;
1072
+
1073
+ if (ret )
1074
+ ret = scp_add_single_core (pdev , scp_cluster );
1075
+ else
1076
+ ret = scp_add_multi_core (pdev , scp_cluster );
1077
+
1078
+ return ret ;
1079
+ }
1080
+
978
1081
static int scp_probe (struct platform_device * pdev )
979
1082
{
980
1083
struct device * dev = & pdev -> dev ;
@@ -1007,6 +1110,10 @@ static int scp_probe(struct platform_device *pdev)
1007
1110
1008
1111
INIT_LIST_HEAD (& scp_cluster -> mtk_scp_list );
1009
1112
1113
+ ret = devm_of_platform_populate (dev );
1114
+ if (ret )
1115
+ return dev_err_probe (dev , ret , "Failed to populate platform devices\n" );
1116
+
1010
1117
ret = scp_cluster_init (pdev , scp_cluster );
1011
1118
if (ret )
1012
1119
return ret ;
@@ -1101,12 +1208,19 @@ static const struct mtk_scp_of_data mt8195_of_data_c1 = {
1101
1208
.host_to_scp_int_bit = MT8195_CORE1_HOST_IPC_INT_BIT ,
1102
1209
};
1103
1210
1211
+ static const struct mtk_scp_of_data * mt8195_of_data_cores [] = {
1212
+ & mt8195_of_data ,
1213
+ & mt8195_of_data_c1 ,
1214
+ NULL
1215
+ };
1216
+
1104
1217
static const struct of_device_id mtk_scp_of_match [] = {
1105
1218
{ .compatible = "mediatek,mt8183-scp" , .data = & mt8183_of_data },
1106
1219
{ .compatible = "mediatek,mt8186-scp" , .data = & mt8186_of_data },
1107
1220
{ .compatible = "mediatek,mt8188-scp" , .data = & mt8188_of_data },
1108
1221
{ .compatible = "mediatek,mt8192-scp" , .data = & mt8192_of_data },
1109
1222
{ .compatible = "mediatek,mt8195-scp" , .data = & mt8195_of_data },
1223
+ { .compatible = "mediatek,mt8195-scp-dual" , .data = & mt8195_of_data_cores },
1110
1224
{},
1111
1225
};
1112
1226
MODULE_DEVICE_TABLE (of , mtk_scp_of_match );
0 commit comments