ofpart.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * Flash partitions described by the OF (or flattened) device tree
  3. *
  4. * Copyright © 2006 MontaVista Software Inc.
  5. * Author: Vitaly Wool <vwool@ru.mvista.com>
  6. *
  7. * Revised to handle newer style flash binding by:
  8. * Copyright © 2007 David Gibson, IBM Corporation.
  9. *
  10. * This program is free software; you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by the
  12. * Free Software Foundation; either version 2 of the License, or (at your
  13. * option) any later version.
  14. */
  15. #include <linux/module.h>
  16. #include <linux/init.h>
  17. #include <linux/of.h>
  18. #include <linux/mtd/mtd.h>
  19. #include <linux/slab.h>
  20. #include <linux/mtd/partitions.h>
  21. static int parse_ofpart_partitions(struct mtd_info *master,
  22. struct mtd_partition **pparts,
  23. struct mtd_part_parser_data *data)
  24. {
  25. if (!data || !data->of_node)
  26. return 0;
  27. return of_mtd_parse_partitions(NULL, data->of_node, pparts);
  28. }
  29. int of_mtd_parse_partitions(struct device *dev,
  30. struct device_node *node,
  31. struct mtd_partition **pparts)
  32. {
  33. const char *partname;
  34. struct device_node *pp;
  35. int nr_parts, i;
  36. /* First count the subnodes */
  37. pp = NULL;
  38. nr_parts = 0;
  39. while ((pp = of_get_next_child(node, pp)))
  40. nr_parts++;
  41. if (nr_parts == 0)
  42. return 0;
  43. *pparts = kzalloc(nr_parts * sizeof(**pparts), GFP_KERNEL);
  44. if (!*pparts)
  45. return -ENOMEM;
  46. pp = NULL;
  47. i = 0;
  48. while ((pp = of_get_next_child(node, pp))) {
  49. const __be32 *reg;
  50. int len;
  51. reg = of_get_property(pp, "reg", &len);
  52. if (!reg) {
  53. nr_parts--;
  54. continue;
  55. }
  56. (*pparts)[i].offset = be32_to_cpu(reg[0]);
  57. (*pparts)[i].size = be32_to_cpu(reg[1]);
  58. partname = of_get_property(pp, "label", &len);
  59. if (!partname)
  60. partname = of_get_property(pp, "name", &len);
  61. (*pparts)[i].name = (char *)partname;
  62. if (of_get_property(pp, "read-only", &len))
  63. (*pparts)[i].mask_flags = MTD_WRITEABLE;
  64. i++;
  65. }
  66. if (!i) {
  67. of_node_put(pp);
  68. pr_err("No valid partition found on %s\n", node->full_name);
  69. kfree(*pparts);
  70. *pparts = NULL;
  71. return -EINVAL;
  72. }
  73. return nr_parts;
  74. }
  75. EXPORT_SYMBOL(of_mtd_parse_partitions);
  76. static struct mtd_part_parser ofpart_parser = {
  77. .owner = THIS_MODULE,
  78. .parse_fn = parse_ofpart_partitions,
  79. .name = "ofpart",
  80. };
  81. static int __init ofpart_parser_init(void)
  82. {
  83. return register_mtd_parser(&ofpart_parser);
  84. }
  85. module_init(ofpart_parser_init);
  86. MODULE_LICENSE("GPL");