450-04-mtd-ubi-attach-from-device-tree.patch 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. From 471a17d8d1b838092d1a76e48cdce8b5b67ff809 Mon Sep 17 00:00:00 2001
  2. From: Daniel Golle <[email protected]>
  3. Date: Mon, 27 Nov 2023 01:54:28 +0000
  4. Subject: [PATCH 04/15] mtd: ubi: attach from device tree
  5. Introduce device tree compatible 'linux,ubi' and attach compatible MTD
  6. devices using the MTD add notifier. This is needed for a UBI device to
  7. be available early at boot (and not only after late_initcall), so
  8. volumes on them can be used eg. as NVMEM providers for other drivers.
  9. Signed-off-by: Daniel Golle <[email protected]>
  10. ---
  11. drivers/mtd/ubi/build.c | 146 ++++++++++++++++++++++++++++------------
  12. drivers/mtd/ubi/cdev.c | 2 +-
  13. drivers/mtd/ubi/ubi.h | 2 +-
  14. 3 files changed, 106 insertions(+), 44 deletions(-)
  15. --- a/drivers/mtd/ubi/build.c
  16. +++ b/drivers/mtd/ubi/build.c
  17. @@ -27,6 +27,7 @@
  18. #include <linux/log2.h>
  19. #include <linux/kthread.h>
  20. #include <linux/kernel.h>
  21. +#include <linux/of.h>
  22. #include <linux/slab.h>
  23. #include <linux/major.h>
  24. #include "ubi.h"
  25. @@ -1072,6 +1073,7 @@ out_free:
  26. * ubi_detach_mtd_dev - detach an MTD device.
  27. * @ubi_num: UBI device number to detach from
  28. * @anyway: detach MTD even if device reference count is not zero
  29. + * @have_lock: called by MTD notifier holding mtd_table_mutex
  30. *
  31. * This function destroys an UBI device number @ubi_num and detaches the
  32. * underlying MTD device. Returns zero in case of success and %-EBUSY if the
  33. @@ -1081,7 +1083,7 @@ out_free:
  34. * Note, the invocations of this function has to be serialized by the
  35. * @ubi_devices_mutex.
  36. */
  37. -int ubi_detach_mtd_dev(int ubi_num, int anyway)
  38. +int ubi_detach_mtd_dev(int ubi_num, int anyway, bool have_lock)
  39. {
  40. struct ubi_device *ubi;
  41. @@ -1137,7 +1139,11 @@ int ubi_detach_mtd_dev(int ubi_num, int
  42. vfree(ubi->peb_buf);
  43. vfree(ubi->fm_buf);
  44. ubi_msg(ubi, "mtd%d is detached", ubi->mtd->index);
  45. - put_mtd_device(ubi->mtd);
  46. + if (have_lock)
  47. + __put_mtd_device(ubi->mtd);
  48. + else
  49. + put_mtd_device(ubi->mtd);
  50. +
  51. put_device(&ubi->dev);
  52. return 0;
  53. }
  54. @@ -1214,43 +1220,43 @@ static struct mtd_info * __init open_mtd
  55. return mtd;
  56. }
  57. -static int __init ubi_init(void)
  58. +static void ubi_notify_add(struct mtd_info *mtd)
  59. {
  60. - int err, i, k;
  61. + struct device_node *np = mtd_get_of_node(mtd);
  62. + int err;
  63. - /* Ensure that EC and VID headers have correct size */
  64. - BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64);
  65. - BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64);
  66. + if (!of_device_is_compatible(np, "linux,ubi"))
  67. + return;
  68. - if (mtd_devs > UBI_MAX_DEVICES) {
  69. - pr_err("UBI error: too many MTD devices, maximum is %d\n",
  70. - UBI_MAX_DEVICES);
  71. - return -EINVAL;
  72. - }
  73. + /*
  74. + * we are already holding &mtd_table_mutex, but still need
  75. + * to bump refcount
  76. + */
  77. + err = __get_mtd_device(mtd);
  78. + if (err)
  79. + return;
  80. - /* Create base sysfs directory and sysfs files */
  81. - err = class_register(&ubi_class);
  82. + /* called while holding mtd_table_mutex */
  83. + mutex_lock_nested(&ubi_devices_mutex, SINGLE_DEPTH_NESTING);
  84. + err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false);
  85. + mutex_unlock(&ubi_devices_mutex);
  86. if (err < 0)
  87. - return err;
  88. -
  89. - err = misc_register(&ubi_ctrl_cdev);
  90. - if (err) {
  91. - pr_err("UBI error: cannot register device\n");
  92. - goto out;
  93. - }
  94. + __put_mtd_device(mtd);
  95. +}
  96. - ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
  97. - sizeof(struct ubi_wl_entry),
  98. - 0, 0, NULL);
  99. - if (!ubi_wl_entry_slab) {
  100. - err = -ENOMEM;
  101. - goto out_dev_unreg;
  102. - }
  103. +static void ubi_notify_remove(struct mtd_info *mtd)
  104. +{
  105. + WARN(1, "mtd%d removed despite UBI still being attached", mtd->index);
  106. +}
  107. - err = ubi_debugfs_init();
  108. - if (err)
  109. - goto out_slab;
  110. +static struct mtd_notifier ubi_mtd_notifier = {
  111. + .add = ubi_notify_add,
  112. + .remove = ubi_notify_remove,
  113. +};
  114. +static int __init ubi_init_attach(void)
  115. +{
  116. + int err, i, k;
  117. /* Attach MTD devices */
  118. for (i = 0; i < mtd_devs; i++) {
  119. @@ -1298,25 +1304,79 @@ static int __init ubi_init(void)
  120. }
  121. }
  122. + return 0;
  123. +
  124. +out_detach:
  125. + for (k = 0; k < i; k++)
  126. + if (ubi_devices[k]) {
  127. + mutex_lock(&ubi_devices_mutex);
  128. + ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1, false);
  129. + mutex_unlock(&ubi_devices_mutex);
  130. + }
  131. + return err;
  132. +}
  133. +#ifndef CONFIG_MTD_UBI_MODULE
  134. +late_initcall(ubi_init_attach);
  135. +#endif
  136. +
  137. +static int __init ubi_init(void)
  138. +{
  139. + int err;
  140. +
  141. + /* Ensure that EC and VID headers have correct size */
  142. + BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64);
  143. + BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64);
  144. +
  145. + if (mtd_devs > UBI_MAX_DEVICES) {
  146. + pr_err("UBI error: too many MTD devices, maximum is %d\n",
  147. + UBI_MAX_DEVICES);
  148. + return -EINVAL;
  149. + }
  150. +
  151. + /* Create base sysfs directory and sysfs files */
  152. + err = class_register(&ubi_class);
  153. + if (err < 0)
  154. + return err;
  155. +
  156. + err = misc_register(&ubi_ctrl_cdev);
  157. + if (err) {
  158. + pr_err("UBI error: cannot register device\n");
  159. + goto out;
  160. + }
  161. +
  162. + ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
  163. + sizeof(struct ubi_wl_entry),
  164. + 0, 0, NULL);
  165. + if (!ubi_wl_entry_slab) {
  166. + err = -ENOMEM;
  167. + goto out_dev_unreg;
  168. + }
  169. +
  170. + err = ubi_debugfs_init();
  171. + if (err)
  172. + goto out_slab;
  173. +
  174. err = ubiblock_init();
  175. if (err) {
  176. pr_err("UBI error: block: cannot initialize, error %d\n", err);
  177. /* See comment above re-ubi_is_module(). */
  178. if (ubi_is_module())
  179. - goto out_detach;
  180. + goto out_slab;
  181. + }
  182. +
  183. + register_mtd_user(&ubi_mtd_notifier);
  184. +
  185. + if (ubi_is_module()) {
  186. + err = ubi_init_attach();
  187. + if (err)
  188. + goto out_mtd_notifier;
  189. }
  190. return 0;
  191. -out_detach:
  192. - for (k = 0; k < i; k++)
  193. - if (ubi_devices[k]) {
  194. - mutex_lock(&ubi_devices_mutex);
  195. - ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1);
  196. - mutex_unlock(&ubi_devices_mutex);
  197. - }
  198. - ubi_debugfs_exit();
  199. +out_mtd_notifier:
  200. + unregister_mtd_user(&ubi_mtd_notifier);
  201. out_slab:
  202. kmem_cache_destroy(ubi_wl_entry_slab);
  203. out_dev_unreg:
  204. @@ -1326,18 +1386,20 @@ out:
  205. pr_err("UBI error: cannot initialize UBI, error %d\n", err);
  206. return err;
  207. }
  208. -late_initcall(ubi_init);
  209. +device_initcall(ubi_init);
  210. +
  211. static void __exit ubi_exit(void)
  212. {
  213. int i;
  214. ubiblock_exit();
  215. + unregister_mtd_user(&ubi_mtd_notifier);
  216. for (i = 0; i < UBI_MAX_DEVICES; i++)
  217. if (ubi_devices[i]) {
  218. mutex_lock(&ubi_devices_mutex);
  219. - ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1);
  220. + ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1, false);
  221. mutex_unlock(&ubi_devices_mutex);
  222. }
  223. ubi_debugfs_exit();
  224. --- a/drivers/mtd/ubi/cdev.c
  225. +++ b/drivers/mtd/ubi/cdev.c
  226. @@ -1065,7 +1065,7 @@ static long ctrl_cdev_ioctl(struct file
  227. }
  228. mutex_lock(&ubi_devices_mutex);
  229. - err = ubi_detach_mtd_dev(ubi_num, 0);
  230. + err = ubi_detach_mtd_dev(ubi_num, 0, false);
  231. mutex_unlock(&ubi_devices_mutex);
  232. break;
  233. }
  234. --- a/drivers/mtd/ubi/ubi.h
  235. +++ b/drivers/mtd/ubi/ubi.h
  236. @@ -939,7 +939,7 @@ int ubi_io_write_vid_hdr(struct ubi_devi
  237. int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
  238. int vid_hdr_offset, int max_beb_per1024,
  239. bool disable_fm);
  240. -int ubi_detach_mtd_dev(int ubi_num, int anyway);
  241. +int ubi_detach_mtd_dev(int ubi_num, int anyway, bool have_lock);
  242. struct ubi_device *ubi_get_device(int ubi_num);
  243. void ubi_put_device(struct ubi_device *ubi);
  244. struct ubi_device *ubi_get_by_major(int major);