Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: ubi: attach from device tree

Introduce device tree compatible 'linux,ubi' and attach compatible MTD
devices using the MTD add notifier. This is needed for a UBI device to
be available early at boot (and not only after late_initcall), so
volumes on them can be used eg. as NVMEM providers for other drivers.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: Richard Weinberger <richard@nod.at>

authored by

Daniel Golle and committed by
Richard Weinberger
927c1452 762d73cd

+103 -46
+103 -46
drivers/mtd/ubi/build.c
··· 27 27 #include <linux/log2.h> 28 28 #include <linux/kthread.h> 29 29 #include <linux/kernel.h> 30 + #include <linux/of.h> 30 31 #include <linux/slab.h> 31 32 #include <linux/major.h> 32 33 #include "ubi.h" ··· 1220 1219 return mtd; 1221 1220 } 1222 1221 1223 - static int __init ubi_init(void) 1222 + static void ubi_notify_add(struct mtd_info *mtd) 1223 + { 1224 + struct device_node *np = mtd_get_of_node(mtd); 1225 + int err; 1226 + 1227 + if (!of_device_is_compatible(np, "linux,ubi")) 1228 + return; 1229 + 1230 + /* 1231 + * we are already holding &mtd_table_mutex, but still need 1232 + * to bump refcount 1233 + */ 1234 + err = __get_mtd_device(mtd); 1235 + if (err) 1236 + return; 1237 + 1238 + /* called while holding mtd_table_mutex */ 1239 + mutex_lock_nested(&ubi_devices_mutex, SINGLE_DEPTH_NESTING); 1240 + err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false, false); 1241 + mutex_unlock(&ubi_devices_mutex); 1242 + if (err < 0) 1243 + __put_mtd_device(mtd); 1244 + } 1245 + 1246 + static void ubi_notify_remove(struct mtd_info *mtd) 1247 + { 1248 + /* do nothing for now */ 1249 + } 1250 + 1251 + static struct mtd_notifier ubi_mtd_notifier = { 1252 + .add = ubi_notify_add, 1253 + .remove = ubi_notify_remove, 1254 + }; 1255 + 1256 + static int __init ubi_init_attach(void) 1224 1257 { 1225 1258 int err, i, k; 1226 - 1227 - /* Ensure that EC and VID headers have correct size */ 1228 - BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64); 1229 - BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64); 1230 - 1231 - if (mtd_devs > UBI_MAX_DEVICES) { 1232 - pr_err("UBI error: too many MTD devices, maximum is %d\n", 1233 - UBI_MAX_DEVICES); 1234 - return -EINVAL; 1235 - } 1236 - 1237 - /* Create base sysfs directory and sysfs files */ 1238 - err = class_register(&ubi_class); 1239 - if (err < 0) 1240 - return err; 1241 - 1242 - err = misc_register(&ubi_ctrl_cdev); 1243 - if (err) { 1244 - pr_err("UBI error: cannot register device\n"); 1245 - goto out; 1246 - } 1247 - 1248 - ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", 1249 - sizeof(struct ubi_wl_entry), 1250 - 0, 0, NULL); 1251 - if (!ubi_wl_entry_slab) { 1252 - err = -ENOMEM; 1253 - goto out_dev_unreg; 1254 - } 1255 - 1256 - err = ubi_debugfs_init(); 1257 - if (err) 1258 - goto out_slab; 1259 - 1260 1259 1261 1260 /* Attach MTD devices */ 1262 1261 for (i = 0; i < mtd_devs; i++) { ··· 1305 1304 } 1306 1305 } 1307 1306 1308 - err = ubiblock_init(); 1309 - if (err) { 1310 - pr_err("UBI error: block: cannot initialize, error %d\n", err); 1311 - 1312 - /* See comment above re-ubi_is_module(). */ 1313 - if (ubi_is_module()) 1314 - goto out_detach; 1315 - } 1316 - 1317 1307 return 0; 1318 1308 1319 1309 out_detach: ··· 1314 1322 ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1); 1315 1323 mutex_unlock(&ubi_devices_mutex); 1316 1324 } 1317 - ubi_debugfs_exit(); 1325 + return err; 1326 + } 1327 + #ifndef CONFIG_MTD_UBI_MODULE 1328 + late_initcall(ubi_init_attach); 1329 + #endif 1330 + 1331 + static int __init ubi_init(void) 1332 + { 1333 + int err; 1334 + 1335 + /* Ensure that EC and VID headers have correct size */ 1336 + BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64); 1337 + BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64); 1338 + 1339 + if (mtd_devs > UBI_MAX_DEVICES) { 1340 + pr_err("UBI error: too many MTD devices, maximum is %d\n", 1341 + UBI_MAX_DEVICES); 1342 + return -EINVAL; 1343 + } 1344 + 1345 + /* Create base sysfs directory and sysfs files */ 1346 + err = class_register(&ubi_class); 1347 + if (err < 0) 1348 + return err; 1349 + 1350 + err = misc_register(&ubi_ctrl_cdev); 1351 + if (err) { 1352 + pr_err("UBI error: cannot register device\n"); 1353 + goto out; 1354 + } 1355 + 1356 + ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", 1357 + sizeof(struct ubi_wl_entry), 1358 + 0, 0, NULL); 1359 + if (!ubi_wl_entry_slab) { 1360 + err = -ENOMEM; 1361 + goto out_dev_unreg; 1362 + } 1363 + 1364 + err = ubi_debugfs_init(); 1365 + if (err) 1366 + goto out_slab; 1367 + 1368 + err = ubiblock_init(); 1369 + if (err) { 1370 + pr_err("UBI error: block: cannot initialize, error %d\n", err); 1371 + 1372 + /* See comment above re-ubi_is_module(). */ 1373 + if (ubi_is_module()) 1374 + goto out_slab; 1375 + } 1376 + 1377 + register_mtd_user(&ubi_mtd_notifier); 1378 + 1379 + if (ubi_is_module()) { 1380 + err = ubi_init_attach(); 1381 + if (err) 1382 + goto out_mtd_notifier; 1383 + } 1384 + 1385 + return 0; 1386 + 1387 + out_mtd_notifier: 1388 + unregister_mtd_user(&ubi_mtd_notifier); 1318 1389 out_slab: 1319 1390 kmem_cache_destroy(ubi_wl_entry_slab); 1320 1391 out_dev_unreg: ··· 1387 1332 pr_err("UBI error: cannot initialize UBI, error %d\n", err); 1388 1333 return err; 1389 1334 } 1390 - late_initcall(ubi_init); 1335 + device_initcall(ubi_init); 1336 + 1391 1337 1392 1338 static void __exit ubi_exit(void) 1393 1339 { 1394 1340 int i; 1395 1341 1396 1342 ubiblock_exit(); 1343 + unregister_mtd_user(&ubi_mtd_notifier); 1397 1344 1398 1345 for (i = 0; i < UBI_MAX_DEVICES; i++) 1399 1346 if (ubi_devices[i]) {