aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/base.c1
-rw-r--r--drivers/of/fdt.c2
-rw-r--r--drivers/of/overlay.c11
-rw-r--r--drivers/of/platform.c9
-rw-r--r--drivers/of/unittest-data/tests-overlay.dtsi149
-rw-r--r--drivers/of/unittest.c539
6 files changed, 655 insertions, 56 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 36536b6a8834..0a8aeb8523fe 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1303,6 +1303,7 @@ int of_property_read_u64_array(const struct device_node *np,
1303 } 1303 }
1304 return 0; 1304 return 0;
1305} 1305}
1306EXPORT_SYMBOL_GPL(of_property_read_u64_array);
1306 1307
1307/** 1308/**
1308 * of_property_read_string - Find and read a string from a property 1309 * of_property_read_string - Find and read a string from a property
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 510074226d57..3a896c9aeb74 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -762,7 +762,7 @@ static inline void early_init_dt_check_for_initrd(unsigned long node)
762#ifdef CONFIG_SERIAL_EARLYCON 762#ifdef CONFIG_SERIAL_EARLYCON
763extern struct of_device_id __earlycon_of_table[]; 763extern struct of_device_id __earlycon_of_table[];
764 764
765int __init early_init_dt_scan_chosen_serial(void) 765static int __init early_init_dt_scan_chosen_serial(void)
766{ 766{
767 int offset; 767 int offset;
768 const char *p; 768 const char *p;
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index ea63fbd228ed..352b4f28f82c 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -114,17 +114,6 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov,
114 ret = of_overlay_apply_one(ov, tchild, child); 114 ret = of_overlay_apply_one(ov, tchild, child);
115 if (ret) 115 if (ret)
116 return ret; 116 return ret;
117
118 /* The properties are already copied, now do the child nodes */
119 for_each_child_of_node(child, grandchild) {
120 ret = of_overlay_apply_single_device_node(ov, tchild, grandchild);
121 if (ret) {
122 pr_err("%s: Failed to apply single node @%s/%s\n",
123 __func__, tchild->full_name,
124 grandchild->name);
125 return ret;
126 }
127 }
128 } 117 }
129 118
130 return ret; 119 return ret;
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index a54ec1087fd2..b0d50d70a8a1 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -566,6 +566,10 @@ static int of_platform_notify(struct notifier_block *nb,
566 if (!of_node_check_flag(rd->dn->parent, OF_POPULATED_BUS)) 566 if (!of_node_check_flag(rd->dn->parent, OF_POPULATED_BUS))
567 return NOTIFY_OK; /* not for us */ 567 return NOTIFY_OK; /* not for us */
568 568
569 /* already populated? (driver using of_populate manually) */
570 if (of_node_check_flag(rd->dn, OF_POPULATED))
571 return NOTIFY_OK;
572
569 /* pdev_parent may be NULL when no bus platform device */ 573 /* pdev_parent may be NULL when no bus platform device */
570 pdev_parent = of_find_device_by_node(rd->dn->parent); 574 pdev_parent = of_find_device_by_node(rd->dn->parent);
571 pdev = of_platform_device_create(rd->dn, NULL, 575 pdev = of_platform_device_create(rd->dn, NULL,
@@ -581,6 +585,11 @@ static int of_platform_notify(struct notifier_block *nb,
581 break; 585 break;
582 586
583 case OF_RECONFIG_CHANGE_REMOVE: 587 case OF_RECONFIG_CHANGE_REMOVE:
588
589 /* already depopulated? */
590 if (!of_node_check_flag(rd->dn, OF_POPULATED))
591 return NOTIFY_OK;
592
584 /* find our device by node */ 593 /* find our device by node */
585 pdev = of_find_device_by_node(rd->dn); 594 pdev = of_find_device_by_node(rd->dn);
586 if (pdev == NULL) 595 if (pdev == NULL)
diff --git a/drivers/of/unittest-data/tests-overlay.dtsi b/drivers/of/unittest-data/tests-overlay.dtsi
index 75976da22b2e..244226cbb5a3 100644
--- a/drivers/of/unittest-data/tests-overlay.dtsi
+++ b/drivers/of/unittest-data/tests-overlay.dtsi
@@ -68,6 +68,48 @@
68 status = "disabled"; 68 status = "disabled";
69 reg = <8>; 69 reg = <8>;
70 }; 70 };
71
72 i2c-test-bus {
73 compatible = "selftest-i2c-bus";
74 status = "okay";
75 reg = <50>;
76
77 #address-cells = <1>;
78 #size-cells = <0>;
79
80 test-selftest12 {
81 reg = <8>;
82 compatible = "selftest-i2c-dev";
83 status = "disabled";
84 };
85
86 test-selftest13 {
87 reg = <9>;
88 compatible = "selftest-i2c-dev";
89 status = "okay";
90 };
91
92 test-selftest14 {
93 reg = <10>;
94 compatible = "selftest-i2c-mux";
95 status = "okay";
96
97 #address-cells = <1>;
98 #size-cells = <0>;
99
100 i2c@0 {
101 #address-cells = <1>;
102 #size-cells = <0>;
103 reg = <0>;
104
105 test-mux-dev {
106 reg = <32>;
107 compatible = "selftest-i2c-dev";
108 status = "okay";
109 };
110 };
111 };
112 };
71 }; 113 };
72 }; 114 };
73 115
@@ -176,5 +218,112 @@
176 }; 218 };
177 }; 219 };
178 220
221 overlay10 {
222 fragment@0 {
223 target-path = "/testcase-data/overlay-node/test-bus";
224 __overlay__ {
225
226 /* suppress DTC warning */
227 #address-cells = <1>;
228 #size-cells = <0>;
229
230 test-selftest10 {
231 compatible = "selftest";
232 status = "okay";
233 reg = <10>;
234
235 #address-cells = <1>;
236 #size-cells = <0>;
237
238 test-selftest101 {
239 compatible = "selftest";
240 status = "okay";
241 reg = <1>;
242 };
243
244 };
245 };
246 };
247 };
248
249 overlay11 {
250 fragment@0 {
251 target-path = "/testcase-data/overlay-node/test-bus";
252 __overlay__ {
253
254 /* suppress DTC warning */
255 #address-cells = <1>;
256 #size-cells = <0>;
257
258 test-selftest11 {
259 compatible = "selftest";
260 status = "okay";
261 reg = <11>;
262
263 #address-cells = <1>;
264 #size-cells = <0>;
265
266 test-selftest111 {
267 compatible = "selftest";
268 status = "okay";
269 reg = <1>;
270 };
271
272 };
273 };
274 };
275 };
276
277 /* test enable using absolute target path (i2c) */
278 overlay12 {
279 fragment@0 {
280 target-path = "/testcase-data/overlay-node/test-bus/i2c-test-bus/test-selftest12";
281 __overlay__ {
282 status = "okay";
283 };
284 };
285 };
286
287 /* test disable using absolute target path (i2c) */
288 overlay13 {
289 fragment@0 {
290 target-path = "/testcase-data/overlay-node/test-bus/i2c-test-bus/test-selftest13";
291 __overlay__ {
292 status = "disabled";
293 };
294 };
295 };
296
297 /* test mux overlay */
298 overlay15 {
299 fragment@0 {
300 target-path = "/testcase-data/overlay-node/test-bus/i2c-test-bus";
301 __overlay__ {
302 #address-cells = <1>;
303 #size-cells = <0>;
304 test-selftest15 {
305 reg = <11>;
306 compatible = "selftest-i2c-mux";
307 status = "okay";
308
309 #address-cells = <1>;
310 #size-cells = <0>;
311
312 i2c@0 {
313 #address-cells = <1>;
314 #size-cells = <0>;
315 reg = <0>;
316
317 test-mux-dev {
318 reg = <32>;
319 compatible = "selftest-i2c-dev";
320 status = "okay";
321 };
322 };
323 };
324 };
325 };
326 };
327
179 }; 328 };
180}; 329};
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index 7aa1d6dae5ba..0cf9a236d438 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -20,6 +20,9 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/of_platform.h> 21#include <linux/of_platform.h>
22 22
23#include <linux/i2c.h>
24#include <linux/i2c-mux.h>
25
23#include "of_private.h" 26#include "of_private.h"
24 27
25static struct selftest_results { 28static struct selftest_results {
@@ -920,6 +923,9 @@ static int selftest_probe(struct platform_device *pdev)
920 } 923 }
921 924
922 dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); 925 dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name);
926
927 of_platform_populate(np, NULL, NULL, &pdev->dev);
928
923 return 0; 929 return 0;
924} 930}
925 931
@@ -973,17 +979,94 @@ static int of_path_platform_device_exists(const char *path)
973 return pdev != NULL; 979 return pdev != NULL;
974} 980}
975 981
976static const char *selftest_path(int nr) 982#if IS_ENABLED(CONFIG_I2C)
983
984/* get the i2c client device instantiated at the path */
985static struct i2c_client *of_path_to_i2c_client(const char *path)
986{
987 struct device_node *np;
988 struct i2c_client *client;
989
990 np = of_find_node_by_path(path);
991 if (np == NULL)
992 return NULL;
993
994 client = of_find_i2c_device_by_node(np);
995 of_node_put(np);
996
997 return client;
998}
999
1000/* find out if a i2c client device exists at that path */
1001static int of_path_i2c_client_exists(const char *path)
1002{
1003 struct i2c_client *client;
1004
1005 client = of_path_to_i2c_client(path);
1006 if (client)
1007 put_device(&client->dev);
1008 return client != NULL;
1009}
1010#else
1011static int of_path_i2c_client_exists(const char *path)
1012{
1013 return 0;
1014}
1015#endif
1016
1017enum overlay_type {
1018 PDEV_OVERLAY,
1019 I2C_OVERLAY
1020};
1021
1022static int of_path_device_type_exists(const char *path,
1023 enum overlay_type ovtype)
1024{
1025 switch (ovtype) {
1026 case PDEV_OVERLAY:
1027 return of_path_platform_device_exists(path);
1028 case I2C_OVERLAY:
1029 return of_path_i2c_client_exists(path);
1030 }
1031 return 0;
1032}
1033
1034static const char *selftest_path(int nr, enum overlay_type ovtype)
977{ 1035{
1036 const char *base;
978 static char buf[256]; 1037 static char buf[256];
979 1038
980 snprintf(buf, sizeof(buf) - 1, 1039 switch (ovtype) {
981 "/testcase-data/overlay-node/test-bus/test-selftest%d", nr); 1040 case PDEV_OVERLAY:
1041 base = "/testcase-data/overlay-node/test-bus";
1042 break;
1043 case I2C_OVERLAY:
1044 base = "/testcase-data/overlay-node/test-bus/i2c-test-bus";
1045 break;
1046 default:
1047 buf[0] = '\0';
1048 return buf;
1049 }
1050 snprintf(buf, sizeof(buf) - 1, "%s/test-selftest%d", base, nr);
982 buf[sizeof(buf) - 1] = '\0'; 1051 buf[sizeof(buf) - 1] = '\0';
983
984 return buf; 1052 return buf;
985} 1053}
986 1054
1055static int of_selftest_device_exists(int selftest_nr, enum overlay_type ovtype)
1056{
1057 const char *path;
1058
1059 path = selftest_path(selftest_nr, ovtype);
1060
1061 switch (ovtype) {
1062 case PDEV_OVERLAY:
1063 return of_path_platform_device_exists(path);
1064 case I2C_OVERLAY:
1065 return of_path_i2c_client_exists(path);
1066 }
1067 return 0;
1068}
1069
987static const char *overlay_path(int nr) 1070static const char *overlay_path(int nr)
988{ 1071{
989 static char buf[256]; 1072 static char buf[256];
@@ -1032,16 +1115,15 @@ out:
1032 1115
1033/* apply an overlay while checking before and after states */ 1116/* apply an overlay while checking before and after states */
1034static int of_selftest_apply_overlay_check(int overlay_nr, int selftest_nr, 1117static int of_selftest_apply_overlay_check(int overlay_nr, int selftest_nr,
1035 int before, int after) 1118 int before, int after, enum overlay_type ovtype)
1036{ 1119{
1037 int ret; 1120 int ret;
1038 1121
1039 /* selftest device must not be in before state */ 1122 /* selftest device must not be in before state */
1040 if (of_path_platform_device_exists(selftest_path(selftest_nr)) 1123 if (of_selftest_device_exists(selftest_nr, ovtype) != before) {
1041 != before) {
1042 selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n", 1124 selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
1043 overlay_path(overlay_nr), 1125 overlay_path(overlay_nr),
1044 selftest_path(selftest_nr), 1126 selftest_path(selftest_nr, ovtype),
1045 !before ? "enabled" : "disabled"); 1127 !before ? "enabled" : "disabled");
1046 return -EINVAL; 1128 return -EINVAL;
1047 } 1129 }
@@ -1053,11 +1135,10 @@ static int of_selftest_apply_overlay_check(int overlay_nr, int selftest_nr,
1053 } 1135 }
1054 1136
1055 /* selftest device must be to set to after state */ 1137 /* selftest device must be to set to after state */
1056 if (of_path_platform_device_exists(selftest_path(selftest_nr)) 1138 if (of_selftest_device_exists(selftest_nr, ovtype) != after) {
1057 != after) {
1058 selftest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n", 1139 selftest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n",
1059 overlay_path(overlay_nr), 1140 overlay_path(overlay_nr),
1060 selftest_path(selftest_nr), 1141 selftest_path(selftest_nr, ovtype),
1061 !after ? "enabled" : "disabled"); 1142 !after ? "enabled" : "disabled");
1062 return -EINVAL; 1143 return -EINVAL;
1063 } 1144 }
@@ -1067,16 +1148,16 @@ static int of_selftest_apply_overlay_check(int overlay_nr, int selftest_nr,
1067 1148
1068/* apply an overlay and then revert it while checking before, after states */ 1149/* apply an overlay and then revert it while checking before, after states */
1069static int of_selftest_apply_revert_overlay_check(int overlay_nr, 1150static int of_selftest_apply_revert_overlay_check(int overlay_nr,
1070 int selftest_nr, int before, int after) 1151 int selftest_nr, int before, int after,
1152 enum overlay_type ovtype)
1071{ 1153{
1072 int ret, ov_id; 1154 int ret, ov_id;
1073 1155
1074 /* selftest device must be in before state */ 1156 /* selftest device must be in before state */
1075 if (of_path_platform_device_exists(selftest_path(selftest_nr)) 1157 if (of_selftest_device_exists(selftest_nr, ovtype) != before) {
1076 != before) {
1077 selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n", 1158 selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
1078 overlay_path(overlay_nr), 1159 overlay_path(overlay_nr),
1079 selftest_path(selftest_nr), 1160 selftest_path(selftest_nr, ovtype),
1080 !before ? "enabled" : "disabled"); 1161 !before ? "enabled" : "disabled");
1081 return -EINVAL; 1162 return -EINVAL;
1082 } 1163 }
@@ -1089,11 +1170,10 @@ static int of_selftest_apply_revert_overlay_check(int overlay_nr,
1089 } 1170 }
1090 1171
1091 /* selftest device must be in after state */ 1172 /* selftest device must be in after state */
1092 if (of_path_platform_device_exists(selftest_path(selftest_nr)) 1173 if (of_selftest_device_exists(selftest_nr, ovtype) != after) {
1093 != after) {
1094 selftest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n", 1174 selftest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n",
1095 overlay_path(overlay_nr), 1175 overlay_path(overlay_nr),
1096 selftest_path(selftest_nr), 1176 selftest_path(selftest_nr, ovtype),
1097 !after ? "enabled" : "disabled"); 1177 !after ? "enabled" : "disabled");
1098 return -EINVAL; 1178 return -EINVAL;
1099 } 1179 }
@@ -1102,16 +1182,15 @@ static int of_selftest_apply_revert_overlay_check(int overlay_nr,
1102 if (ret != 0) { 1182 if (ret != 0) {
1103 selftest(0, "overlay @\"%s\" failed to be destroyed @\"%s\"\n", 1183 selftest(0, "overlay @\"%s\" failed to be destroyed @\"%s\"\n",
1104 overlay_path(overlay_nr), 1184 overlay_path(overlay_nr),
1105 selftest_path(selftest_nr)); 1185 selftest_path(selftest_nr, ovtype));
1106 return ret; 1186 return ret;
1107 } 1187 }
1108 1188
1109 /* selftest device must be again in before state */ 1189 /* selftest device must be again in before state */
1110 if (of_path_platform_device_exists(selftest_path(selftest_nr)) 1190 if (of_selftest_device_exists(selftest_nr, PDEV_OVERLAY) != before) {
1111 != before) {
1112 selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n", 1191 selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
1113 overlay_path(overlay_nr), 1192 overlay_path(overlay_nr),
1114 selftest_path(selftest_nr), 1193 selftest_path(selftest_nr, ovtype),
1115 !before ? "enabled" : "disabled"); 1194 !before ? "enabled" : "disabled");
1116 return -EINVAL; 1195 return -EINVAL;
1117 } 1196 }
@@ -1125,7 +1204,7 @@ static void of_selftest_overlay_0(void)
1125 int ret; 1204 int ret;
1126 1205
1127 /* device should enable */ 1206 /* device should enable */
1128 ret = of_selftest_apply_overlay_check(0, 0, 0, 1); 1207 ret = of_selftest_apply_overlay_check(0, 0, 0, 1, PDEV_OVERLAY);
1129 if (ret != 0) 1208 if (ret != 0)
1130 return; 1209 return;
1131 1210
@@ -1138,7 +1217,7 @@ static void of_selftest_overlay_1(void)
1138 int ret; 1217 int ret;
1139 1218
1140 /* device should disable */ 1219 /* device should disable */
1141 ret = of_selftest_apply_overlay_check(1, 1, 1, 0); 1220 ret = of_selftest_apply_overlay_check(1, 1, 1, 0, PDEV_OVERLAY);
1142 if (ret != 0) 1221 if (ret != 0)
1143 return; 1222 return;
1144 1223
@@ -1151,7 +1230,7 @@ static void of_selftest_overlay_2(void)
1151 int ret; 1230 int ret;
1152 1231
1153 /* device should enable */ 1232 /* device should enable */
1154 ret = of_selftest_apply_overlay_check(2, 2, 0, 1); 1233 ret = of_selftest_apply_overlay_check(2, 2, 0, 1, PDEV_OVERLAY);
1155 if (ret != 0) 1234 if (ret != 0)
1156 return; 1235 return;
1157 1236
@@ -1164,7 +1243,7 @@ static void of_selftest_overlay_3(void)
1164 int ret; 1243 int ret;
1165 1244
1166 /* device should disable */ 1245 /* device should disable */
1167 ret = of_selftest_apply_overlay_check(3, 3, 1, 0); 1246 ret = of_selftest_apply_overlay_check(3, 3, 1, 0, PDEV_OVERLAY);
1168 if (ret != 0) 1247 if (ret != 0)
1169 return; 1248 return;
1170 1249
@@ -1177,7 +1256,7 @@ static void of_selftest_overlay_4(void)
1177 int ret; 1256 int ret;
1178 1257
1179 /* device should disable */ 1258 /* device should disable */
1180 ret = of_selftest_apply_overlay_check(4, 4, 0, 1); 1259 ret = of_selftest_apply_overlay_check(4, 4, 0, 1, PDEV_OVERLAY);
1181 if (ret != 0) 1260 if (ret != 0)
1182 return; 1261 return;
1183 1262
@@ -1190,7 +1269,7 @@ static void of_selftest_overlay_5(void)
1190 int ret; 1269 int ret;
1191 1270
1192 /* device should disable */ 1271 /* device should disable */
1193 ret = of_selftest_apply_revert_overlay_check(5, 5, 0, 1); 1272 ret = of_selftest_apply_revert_overlay_check(5, 5, 0, 1, PDEV_OVERLAY);
1194 if (ret != 0) 1273 if (ret != 0)
1195 return; 1274 return;
1196 1275
@@ -1207,12 +1286,12 @@ static void of_selftest_overlay_6(void)
1207 1286
1208 /* selftest device must be in before state */ 1287 /* selftest device must be in before state */
1209 for (i = 0; i < 2; i++) { 1288 for (i = 0; i < 2; i++) {
1210 if (of_path_platform_device_exists( 1289 if (of_selftest_device_exists(selftest_nr + i, PDEV_OVERLAY)
1211 selftest_path(selftest_nr + i))
1212 != before) { 1290 != before) {
1213 selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n", 1291 selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
1214 overlay_path(overlay_nr + i), 1292 overlay_path(overlay_nr + i),
1215 selftest_path(selftest_nr + i), 1293 selftest_path(selftest_nr + i,
1294 PDEV_OVERLAY),
1216 !before ? "enabled" : "disabled"); 1295 !before ? "enabled" : "disabled");
1217 return; 1296 return;
1218 } 1297 }
@@ -1239,12 +1318,12 @@ static void of_selftest_overlay_6(void)
1239 1318
1240 for (i = 0; i < 2; i++) { 1319 for (i = 0; i < 2; i++) {
1241 /* selftest device must be in after state */ 1320 /* selftest device must be in after state */
1242 if (of_path_platform_device_exists( 1321 if (of_selftest_device_exists(selftest_nr + i, PDEV_OVERLAY)
1243 selftest_path(selftest_nr + i))
1244 != after) { 1322 != after) {
1245 selftest(0, "overlay @\"%s\" failed @\"%s\" %s\n", 1323 selftest(0, "overlay @\"%s\" failed @\"%s\" %s\n",
1246 overlay_path(overlay_nr + i), 1324 overlay_path(overlay_nr + i),
1247 selftest_path(selftest_nr + i), 1325 selftest_path(selftest_nr + i,
1326 PDEV_OVERLAY),
1248 !after ? "enabled" : "disabled"); 1327 !after ? "enabled" : "disabled");
1249 return; 1328 return;
1250 } 1329 }
@@ -1255,19 +1334,20 @@ static void of_selftest_overlay_6(void)
1255 if (ret != 0) { 1334 if (ret != 0) {
1256 selftest(0, "overlay @\"%s\" failed destroy @\"%s\"\n", 1335 selftest(0, "overlay @\"%s\" failed destroy @\"%s\"\n",
1257 overlay_path(overlay_nr + i), 1336 overlay_path(overlay_nr + i),
1258 selftest_path(selftest_nr + i)); 1337 selftest_path(selftest_nr + i,
1338 PDEV_OVERLAY));
1259 return; 1339 return;
1260 } 1340 }
1261 } 1341 }
1262 1342
1263 for (i = 0; i < 2; i++) { 1343 for (i = 0; i < 2; i++) {
1264 /* selftest device must be again in before state */ 1344 /* selftest device must be again in before state */
1265 if (of_path_platform_device_exists( 1345 if (of_selftest_device_exists(selftest_nr + i, PDEV_OVERLAY)
1266 selftest_path(selftest_nr + i))
1267 != before) { 1346 != before) {
1268 selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n", 1347 selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
1269 overlay_path(overlay_nr + i), 1348 overlay_path(overlay_nr + i),
1270 selftest_path(selftest_nr + i), 1349 selftest_path(selftest_nr + i,
1350 PDEV_OVERLAY),
1271 !before ? "enabled" : "disabled"); 1351 !before ? "enabled" : "disabled");
1272 return; 1352 return;
1273 } 1353 }
@@ -1309,7 +1389,8 @@ static void of_selftest_overlay_8(void)
1309 if (ret == 0) { 1389 if (ret == 0) {
1310 selftest(0, "overlay @\"%s\" was destroyed @\"%s\"\n", 1390 selftest(0, "overlay @\"%s\" was destroyed @\"%s\"\n",
1311 overlay_path(overlay_nr + 0), 1391 overlay_path(overlay_nr + 0),
1312 selftest_path(selftest_nr)); 1392 selftest_path(selftest_nr,
1393 PDEV_OVERLAY));
1313 return; 1394 return;
1314 } 1395 }
1315 1396
@@ -1319,7 +1400,8 @@ static void of_selftest_overlay_8(void)
1319 if (ret != 0) { 1400 if (ret != 0) {
1320 selftest(0, "overlay @\"%s\" not destroyed @\"%s\"\n", 1401 selftest(0, "overlay @\"%s\" not destroyed @\"%s\"\n",
1321 overlay_path(overlay_nr + i), 1402 overlay_path(overlay_nr + i),
1322 selftest_path(selftest_nr)); 1403 selftest_path(selftest_nr,
1404 PDEV_OVERLAY));
1323 return; 1405 return;
1324 } 1406 }
1325 } 1407 }
@@ -1327,6 +1409,360 @@ static void of_selftest_overlay_8(void)
1327 selftest(1, "overlay test %d passed\n", 8); 1409 selftest(1, "overlay test %d passed\n", 8);
1328} 1410}
1329 1411
1412/* test insertion of a bus with parent devices */
1413static void of_selftest_overlay_10(void)
1414{
1415 int ret;
1416 char *child_path;
1417
1418 /* device should disable */
1419 ret = of_selftest_apply_overlay_check(10, 10, 0, 1, PDEV_OVERLAY);
1420 if (selftest(ret == 0,
1421 "overlay test %d failed; overlay application\n", 10))
1422 return;
1423
1424 child_path = kasprintf(GFP_KERNEL, "%s/test-selftest101",
1425 selftest_path(10, PDEV_OVERLAY));
1426 if (selftest(child_path, "overlay test %d failed; kasprintf\n", 10))
1427 return;
1428
1429 ret = of_path_device_type_exists(child_path, PDEV_OVERLAY);
1430 kfree(child_path);
1431 if (selftest(ret, "overlay test %d failed; no child device\n", 10))
1432 return;
1433}
1434
1435/* test insertion of a bus with parent devices (and revert) */
1436static void of_selftest_overlay_11(void)
1437{
1438 int ret;
1439
1440 /* device should disable */
1441 ret = of_selftest_apply_revert_overlay_check(11, 11, 0, 1,
1442 PDEV_OVERLAY);
1443 if (selftest(ret == 0,
1444 "overlay test %d failed; overlay application\n", 11))
1445 return;
1446}
1447
1448#if IS_ENABLED(CONFIG_I2C) && IS_ENABLED(CONFIG_OF_OVERLAY)
1449
1450struct selftest_i2c_bus_data {
1451 struct platform_device *pdev;
1452 struct i2c_adapter adap;
1453};
1454
1455static int selftest_i2c_master_xfer(struct i2c_adapter *adap,
1456 struct i2c_msg *msgs, int num)
1457{
1458 struct selftest_i2c_bus_data *std = i2c_get_adapdata(adap);
1459
1460 (void)std;
1461
1462 return num;
1463}
1464
1465static u32 selftest_i2c_functionality(struct i2c_adapter *adap)
1466{
1467 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
1468}
1469
1470static const struct i2c_algorithm selftest_i2c_algo = {
1471 .master_xfer = selftest_i2c_master_xfer,
1472 .functionality = selftest_i2c_functionality,
1473};
1474
1475static int selftest_i2c_bus_probe(struct platform_device *pdev)
1476{
1477 struct device *dev = &pdev->dev;
1478 struct device_node *np = dev->of_node;
1479 struct selftest_i2c_bus_data *std;
1480 struct i2c_adapter *adap;
1481 int ret;
1482
1483 if (np == NULL) {
1484 dev_err(dev, "No OF data for device\n");
1485 return -EINVAL;
1486
1487 }
1488
1489 dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name);
1490
1491 std = devm_kzalloc(dev, sizeof(*std), GFP_KERNEL);
1492 if (!std) {
1493 dev_err(dev, "Failed to allocate selftest i2c data\n");
1494 return -ENOMEM;
1495 }
1496
1497 /* link them together */
1498 std->pdev = pdev;
1499 platform_set_drvdata(pdev, std);
1500
1501 adap = &std->adap;
1502 i2c_set_adapdata(adap, std);
1503 adap->nr = -1;
1504 strlcpy(adap->name, pdev->name, sizeof(adap->name));
1505 adap->class = I2C_CLASS_DEPRECATED;
1506 adap->algo = &selftest_i2c_algo;
1507 adap->dev.parent = dev;
1508 adap->dev.of_node = dev->of_node;
1509 adap->timeout = 5 * HZ;
1510 adap->retries = 3;
1511
1512 ret = i2c_add_numbered_adapter(adap);
1513 if (ret != 0) {
1514 dev_err(dev, "Failed to add I2C adapter\n");
1515 return ret;
1516 }
1517
1518 return 0;
1519}
1520
1521static int selftest_i2c_bus_remove(struct platform_device *pdev)
1522{
1523 struct device *dev = &pdev->dev;
1524 struct device_node *np = dev->of_node;
1525 struct selftest_i2c_bus_data *std = platform_get_drvdata(pdev);
1526
1527 dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name);
1528 i2c_del_adapter(&std->adap);
1529
1530 return 0;
1531}
1532
1533static struct of_device_id selftest_i2c_bus_match[] = {
1534 { .compatible = "selftest-i2c-bus", },
1535 {},
1536};
1537
1538static struct platform_driver selftest_i2c_bus_driver = {
1539 .probe = selftest_i2c_bus_probe,
1540 .remove = selftest_i2c_bus_remove,
1541 .driver = {
1542 .name = "selftest-i2c-bus",
1543 .of_match_table = of_match_ptr(selftest_i2c_bus_match),
1544 },
1545};
1546
1547static int selftest_i2c_dev_probe(struct i2c_client *client,
1548 const struct i2c_device_id *id)
1549{
1550 struct device *dev = &client->dev;
1551 struct device_node *np = client->dev.of_node;
1552
1553 if (!np) {
1554 dev_err(dev, "No OF node\n");
1555 return -EINVAL;
1556 }
1557
1558 dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name);
1559
1560 return 0;
1561};
1562
1563static int selftest_i2c_dev_remove(struct i2c_client *client)
1564{
1565 struct device *dev = &client->dev;
1566 struct device_node *np = client->dev.of_node;
1567
1568 dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name);
1569 return 0;
1570}
1571
1572static const struct i2c_device_id selftest_i2c_dev_id[] = {
1573 { .name = "selftest-i2c-dev" },
1574 { }
1575};
1576
1577static struct i2c_driver selftest_i2c_dev_driver = {
1578 .driver = {
1579 .name = "selftest-i2c-dev",
1580 .owner = THIS_MODULE,
1581 },
1582 .probe = selftest_i2c_dev_probe,
1583 .remove = selftest_i2c_dev_remove,
1584 .id_table = selftest_i2c_dev_id,
1585};
1586
1587#if IS_ENABLED(CONFIG_I2C_MUX)
1588
1589struct selftest_i2c_mux_data {
1590 int nchans;
1591 struct i2c_adapter *adap[];
1592};
1593
1594static int selftest_i2c_mux_select_chan(struct i2c_adapter *adap,
1595 void *client, u32 chan)
1596{
1597 return 0;
1598}
1599
1600static int selftest_i2c_mux_probe(struct i2c_client *client,
1601 const struct i2c_device_id *id)
1602{
1603 int ret, i, nchans, size;
1604 struct device *dev = &client->dev;
1605 struct i2c_adapter *adap = to_i2c_adapter(dev->parent);
1606 struct device_node *np = client->dev.of_node, *child;
1607 struct selftest_i2c_mux_data *stm;
1608 u32 reg, max_reg;
1609
1610 dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name);
1611
1612 if (!np) {
1613 dev_err(dev, "No OF node\n");
1614 return -EINVAL;
1615 }
1616
1617 max_reg = (u32)-1;
1618 for_each_child_of_node(np, child) {
1619 ret = of_property_read_u32(child, "reg", &reg);
1620 if (ret)
1621 continue;
1622 if (max_reg == (u32)-1 || reg > max_reg)
1623 max_reg = reg;
1624 }
1625 nchans = max_reg == (u32)-1 ? 0 : max_reg + 1;
1626 if (nchans == 0) {
1627 dev_err(dev, "No channels\n");
1628 return -EINVAL;
1629 }
1630
1631 size = offsetof(struct selftest_i2c_mux_data, adap[nchans]);
1632 stm = devm_kzalloc(dev, size, GFP_KERNEL);
1633 if (!stm) {
1634 dev_err(dev, "Out of memory\n");
1635 return -ENOMEM;
1636 }
1637 stm->nchans = nchans;
1638 for (i = 0; i < nchans; i++) {
1639 stm->adap[i] = i2c_add_mux_adapter(adap, dev, client,
1640 0, i, 0, selftest_i2c_mux_select_chan, NULL);
1641 if (!stm->adap[i]) {
1642 dev_err(dev, "Failed to register mux #%d\n", i);
1643 for (i--; i >= 0; i--)
1644 i2c_del_mux_adapter(stm->adap[i]);
1645 return -ENODEV;
1646 }
1647 }
1648
1649 i2c_set_clientdata(client, stm);
1650
1651 return 0;
1652};
1653
1654static int selftest_i2c_mux_remove(struct i2c_client *client)
1655{
1656 struct device *dev = &client->dev;
1657 struct device_node *np = client->dev.of_node;
1658 struct selftest_i2c_mux_data *stm = i2c_get_clientdata(client);
1659 int i;
1660
1661 dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name);
1662 for (i = stm->nchans - 1; i >= 0; i--)
1663 i2c_del_mux_adapter(stm->adap[i]);
1664 return 0;
1665}
1666
1667static const struct i2c_device_id selftest_i2c_mux_id[] = {
1668 { .name = "selftest-i2c-mux" },
1669 { }
1670};
1671
1672static struct i2c_driver selftest_i2c_mux_driver = {
1673 .driver = {
1674 .name = "selftest-i2c-mux",
1675 .owner = THIS_MODULE,
1676 },
1677 .probe = selftest_i2c_mux_probe,
1678 .remove = selftest_i2c_mux_remove,
1679 .id_table = selftest_i2c_mux_id,
1680};
1681
1682#endif
1683
1684static int of_selftest_overlay_i2c_init(void)
1685{
1686 int ret;
1687
1688 ret = i2c_add_driver(&selftest_i2c_dev_driver);
1689 if (selftest(ret == 0,
1690 "could not register selftest i2c device driver\n"))
1691 return ret;
1692
1693 ret = platform_driver_register(&selftest_i2c_bus_driver);
1694 if (selftest(ret == 0,
1695 "could not register selftest i2c bus driver\n"))
1696 return ret;
1697
1698#if IS_ENABLED(CONFIG_I2C_MUX)
1699 ret = i2c_add_driver(&selftest_i2c_mux_driver);
1700 if (selftest(ret == 0,
1701 "could not register selftest i2c mux driver\n"))
1702 return ret;
1703#endif
1704
1705 return 0;
1706}
1707
1708static void of_selftest_overlay_i2c_cleanup(void)
1709{
1710#if IS_ENABLED(CONFIG_I2C_MUX)
1711 i2c_del_driver(&selftest_i2c_mux_driver);
1712#endif
1713 platform_driver_unregister(&selftest_i2c_bus_driver);
1714 i2c_del_driver(&selftest_i2c_dev_driver);
1715}
1716
1717static void of_selftest_overlay_i2c_12(void)
1718{
1719 int ret;
1720
1721 /* device should enable */
1722 ret = of_selftest_apply_overlay_check(12, 12, 0, 1, I2C_OVERLAY);
1723 if (ret != 0)
1724 return;
1725
1726 selftest(1, "overlay test %d passed\n", 12);
1727}
1728
1729/* test deactivation of device */
1730static void of_selftest_overlay_i2c_13(void)
1731{
1732 int ret;
1733
1734 /* device should disable */
1735 ret = of_selftest_apply_overlay_check(13, 13, 1, 0, I2C_OVERLAY);
1736 if (ret != 0)
1737 return;
1738
1739 selftest(1, "overlay test %d passed\n", 13);
1740}
1741
1742/* just check for i2c mux existence */
1743static void of_selftest_overlay_i2c_14(void)
1744{
1745}
1746
1747static void of_selftest_overlay_i2c_15(void)
1748{
1749 int ret;
1750
1751 /* device should enable */
1752 ret = of_selftest_apply_overlay_check(16, 15, 0, 1, I2C_OVERLAY);
1753 if (ret != 0)
1754 return;
1755
1756 selftest(1, "overlay test %d passed\n", 15);
1757}
1758
1759#else
1760
1761static inline void of_selftest_overlay_i2c_14(void) { }
1762static inline void of_selftest_overlay_i2c_15(void) { }
1763
1764#endif
1765
1330static void __init of_selftest_overlay(void) 1766static void __init of_selftest_overlay(void)
1331{ 1767{
1332 struct device_node *bus_np = NULL; 1768 struct device_node *bus_np = NULL;
@@ -1351,15 +1787,15 @@ static void __init of_selftest_overlay(void)
1351 goto out; 1787 goto out;
1352 } 1788 }
1353 1789
1354 if (!of_path_platform_device_exists(selftest_path(100))) { 1790 if (!of_selftest_device_exists(100, PDEV_OVERLAY)) {
1355 selftest(0, "could not find selftest0 @ \"%s\"\n", 1791 selftest(0, "could not find selftest0 @ \"%s\"\n",
1356 selftest_path(100)); 1792 selftest_path(100, PDEV_OVERLAY));
1357 goto out; 1793 goto out;
1358 } 1794 }
1359 1795
1360 if (of_path_platform_device_exists(selftest_path(101))) { 1796 if (of_selftest_device_exists(101, PDEV_OVERLAY)) {
1361 selftest(0, "selftest1 @ \"%s\" should not exist\n", 1797 selftest(0, "selftest1 @ \"%s\" should not exist\n",
1362 selftest_path(101)); 1798 selftest_path(101, PDEV_OVERLAY));
1363 goto out; 1799 goto out;
1364 } 1800 }
1365 1801
@@ -1375,6 +1811,21 @@ static void __init of_selftest_overlay(void)
1375 of_selftest_overlay_6(); 1811 of_selftest_overlay_6();
1376 of_selftest_overlay_8(); 1812 of_selftest_overlay_8();
1377 1813
1814 of_selftest_overlay_10();
1815 of_selftest_overlay_11();
1816
1817#if IS_ENABLED(CONFIG_I2C)
1818 if (selftest(of_selftest_overlay_i2c_init() == 0, "i2c init failed\n"))
1819 goto out;
1820
1821 of_selftest_overlay_i2c_12();
1822 of_selftest_overlay_i2c_13();
1823 of_selftest_overlay_i2c_14();
1824 of_selftest_overlay_i2c_15();
1825
1826 of_selftest_overlay_i2c_cleanup();
1827#endif
1828
1378out: 1829out:
1379 of_node_put(bus_np); 1830 of_node_put(bus_np);
1380} 1831}