Blame view

drivers/mtd/ofpart.c 3.99 KB
9a310d211   Scott Wood   [MTD] Factor out ...
1
2
3
  /*
   * Flash partitions described by the OF (or flattened) device tree
   *
a1452a377   David Woodhouse   mtd: Update copyr...
4
   * Copyright © 2006 MontaVista Software Inc.
9a310d211   Scott Wood   [MTD] Factor out ...
5
6
7
   * Author: Vitaly Wool <vwool@ru.mvista.com>
   *
   * Revised to handle newer style flash binding by:
a1452a377   David Woodhouse   mtd: Update copyr...
8
   *   Copyright © 2007 David Gibson, IBM Corporation.
9a310d211   Scott Wood   [MTD] Factor out ...
9
10
11
12
13
14
15
16
17
18
19
   *
   * This program is free software; you can redistribute  it and/or modify it
   * under  the terms of  the GNU General  Public License as published by the
   * Free Software Foundation;  either version 2 of the  License, or (at your
   * option) any later version.
   */
  
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/of.h>
  #include <linux/mtd/mtd.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
20
  #include <linux/slab.h>
9a310d211   Scott Wood   [MTD] Factor out ...
21
  #include <linux/mtd/partitions.h>
d26c87d64   Dmitry Eremin-Solenikov   mtd: prepare to c...
22
23
24
25
  static int parse_ofpart_partitions(struct mtd_info *master,
  				   struct mtd_partition **pparts,
  				   struct mtd_part_parser_data *data)
  {
628376fb5   Dmitry Eremin-Solenikov   mtd: drop of_mtd_...
26
  	struct device_node *node;
9a310d211   Scott Wood   [MTD] Factor out ...
27
28
29
  	const char *partname;
  	struct device_node *pp;
  	int nr_parts, i;
628376fb5   Dmitry Eremin-Solenikov   mtd: drop of_mtd_...
30
31
32
33
34
35
36
  
  	if (!data)
  		return 0;
  
  	node = data->of_node;
  	if (!node)
  		return 0;
9a310d211   Scott Wood   [MTD] Factor out ...
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  	/* First count the subnodes */
  	pp = NULL;
  	nr_parts = 0;
  	while ((pp = of_get_next_child(node, pp)))
  		nr_parts++;
  
  	if (nr_parts == 0)
  		return 0;
  
  	*pparts = kzalloc(nr_parts * sizeof(**pparts), GFP_KERNEL);
  	if (!*pparts)
  		return -ENOMEM;
  
  	pp = NULL;
  	i = 0;
  	while ((pp = of_get_next_child(node, pp))) {
766f271a6   Ian Munsie   mtd: Fix endianne...
53
  		const __be32 *reg;
9a310d211   Scott Wood   [MTD] Factor out ...
54
  		int len;
ebd5a74db   Benjamin Krill   mtd: ofpart: Chec...
55
56
  		reg = of_get_property(pp, "reg", &len);
  		if (!reg) {
4b08e149c   Benjamin Krill   [MTD] ofpart: Che...
57
58
59
  			nr_parts--;
  			continue;
  		}
766f271a6   Ian Munsie   mtd: Fix endianne...
60
61
  		(*pparts)[i].offset = be32_to_cpu(reg[0]);
  		(*pparts)[i].size = be32_to_cpu(reg[1]);
9a310d211   Scott Wood   [MTD] Factor out ...
62
63
64
65
66
67
68
69
70
71
72
  
  		partname = of_get_property(pp, "label", &len);
  		if (!partname)
  			partname = of_get_property(pp, "name", &len);
  		(*pparts)[i].name = (char *)partname;
  
  		if (of_get_property(pp, "read-only", &len))
  			(*pparts)[i].mask_flags = MTD_WRITEABLE;
  
  		i++;
  	}
ebd5a74db   Benjamin Krill   mtd: ofpart: Chec...
73
74
  	if (!i) {
  		of_node_put(pp);
d26c87d64   Dmitry Eremin-Solenikov   mtd: prepare to c...
75
76
  		pr_err("No valid partition found on %s
  ", node->full_name);
ebd5a74db   Benjamin Krill   mtd: ofpart: Chec...
77
78
79
80
  		kfree(*pparts);
  		*pparts = NULL;
  		return -EINVAL;
  	}
9a310d211   Scott Wood   [MTD] Factor out ...
81
82
  	return nr_parts;
  }
950bcb258   Adrian Bunk   [MTD] mtd/ofpart....
83

d26c87d64   Dmitry Eremin-Solenikov   mtd: prepare to c...
84
85
86
87
88
  static struct mtd_part_parser ofpart_parser = {
  	.owner = THIS_MODULE,
  	.parse_fn = parse_ofpart_partitions,
  	.name = "ofpart",
  };
fbcf62a32   Dmitry Eremin-Solenikov   mtd: physmap_of: ...
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
  static int parse_ofoldpart_partitions(struct mtd_info *master,
  				      struct mtd_partition **pparts,
  				      struct mtd_part_parser_data *data)
  {
  	struct device_node *dp;
  	int i, plen, nr_parts;
  	const struct {
  		__be32 offset, len;
  	} *part;
  	const char *names;
  
  	if (!data)
  		return 0;
  
  	dp = data->of_node;
  	if (!dp)
  		return 0;
  
  	part = of_get_property(dp, "partitions", &plen);
  	if (!part)
  		return 0; /* No partitions found */
  
  	pr_warning("Device tree uses obsolete partition map binding: %s
  ",
  			dp->full_name);
  
  	nr_parts = plen / sizeof(part[0]);
  
  	*pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL);
  	if (!pparts)
  		return -ENOMEM;
  
  	names = of_get_property(dp, "partition-names", &plen);
  
  	for (i = 0; i < nr_parts; i++) {
  		(*pparts)[i].offset = be32_to_cpu(part->offset);
  		(*pparts)[i].size   = be32_to_cpu(part->len) & ~1;
  		/* bit 0 set signifies read only partition */
  		if (be32_to_cpu(part->len) & 1)
  			(*pparts)[i].mask_flags = MTD_WRITEABLE;
  
  		if (names && (plen > 0)) {
  			int len = strlen(names) + 1;
  
  			(*pparts)[i].name = (char *)names;
  			plen -= len;
  			names += len;
  		} else {
  			(*pparts)[i].name = "unnamed";
  		}
  
  		part++;
  	}
  
  	return nr_parts;
  }
  
  static struct mtd_part_parser ofoldpart_parser = {
  	.owner = THIS_MODULE,
  	.parse_fn = parse_ofoldpart_partitions,
  	.name = "ofoldpart",
  };
d26c87d64   Dmitry Eremin-Solenikov   mtd: prepare to c...
151
152
  static int __init ofpart_parser_init(void)
  {
fbcf62a32   Dmitry Eremin-Solenikov   mtd: physmap_of: ...
153
154
155
156
157
158
159
160
161
162
163
164
  	int rc;
  	rc = register_mtd_parser(&ofpart_parser);
  	if (rc)
  		goto out;
  
  	rc = register_mtd_parser(&ofoldpart_parser);
  	if (!rc)
  		return 0;
  
  	deregister_mtd_parser(&ofoldpart_parser);
  out:
  	return rc;
d26c87d64   Dmitry Eremin-Solenikov   mtd: prepare to c...
165
166
167
  }
  
  module_init(ofpart_parser_init);
950bcb258   Adrian Bunk   [MTD] mtd/ofpart....
168
  MODULE_LICENSE("GPL");
d6137bade   Dmitry Eremin-Solenikov   mtd: make ofpart ...
169
170
  MODULE_DESCRIPTION("Parser for MTD partitioning information in device tree");
  MODULE_AUTHOR("Vitaly Wool, David Gibson");
9786f6e68   Dmitry Eremin-Solenikov   mtd: ofpart: add ...
171
172
173
174
175
176
  /*
   * When MTD core cannot find the requested parser, it tries to load the module
   * with the same name. Since we provide the ofoldpart parser, we should have
   * the corresponding alias.
   */
  MODULE_ALIAS("ofoldpart");