Blame view
drivers/mtd/ofpart.c
3.99 KB
9a310d211 [MTD] Factor out ... |
1 2 3 |
/* * Flash partitions described by the OF (or flattened) device tree * |
a1452a377 mtd: Update copyr... |
4 |
* Copyright © 2006 MontaVista Software Inc. |
9a310d211 [MTD] Factor out ... |
5 6 7 |
* Author: Vitaly Wool <vwool@ru.mvista.com> * * Revised to handle newer style flash binding by: |
a1452a377 mtd: Update copyr... |
8 |
* Copyright © 2007 David Gibson, IBM Corporation. |
9a310d211 [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 include cleanup: ... |
20 |
#include <linux/slab.h> |
9a310d211 [MTD] Factor out ... |
21 |
#include <linux/mtd/partitions.h> |
d26c87d64 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 mtd: drop of_mtd_... |
26 |
struct device_node *node; |
9a310d211 [MTD] Factor out ... |
27 28 29 |
const char *partname; struct device_node *pp; int nr_parts, i; |
628376fb5 mtd: drop of_mtd_... |
30 31 32 33 34 35 36 |
if (!data) return 0; node = data->of_node; if (!node) return 0; |
9a310d211 [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 mtd: Fix endianne... |
53 |
const __be32 *reg; |
9a310d211 [MTD] Factor out ... |
54 |
int len; |
ebd5a74db mtd: ofpart: Chec... |
55 56 |
reg = of_get_property(pp, "reg", &len); if (!reg) { |
4b08e149c [MTD] ofpart: Che... |
57 58 59 |
nr_parts--; continue; } |
766f271a6 mtd: Fix endianne... |
60 61 |
(*pparts)[i].offset = be32_to_cpu(reg[0]); (*pparts)[i].size = be32_to_cpu(reg[1]); |
9a310d211 [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 mtd: ofpart: Chec... |
73 74 |
if (!i) { of_node_put(pp); |
d26c87d64 mtd: prepare to c... |
75 76 |
pr_err("No valid partition found on %s ", node->full_name); |
ebd5a74db mtd: ofpart: Chec... |
77 78 79 80 |
kfree(*pparts); *pparts = NULL; return -EINVAL; } |
9a310d211 [MTD] Factor out ... |
81 82 |
return nr_parts; } |
950bcb258 [MTD] mtd/ofpart.... |
83 |
|
d26c87d64 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 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 mtd: prepare to c... |
151 152 |
static int __init ofpart_parser_init(void) { |
fbcf62a32 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 mtd: prepare to c... |
165 166 167 |
} module_init(ofpart_parser_init); |
950bcb258 [MTD] mtd/ofpart.... |
168 |
MODULE_LICENSE("GPL"); |
d6137bade mtd: make ofpart ... |
169 170 |
MODULE_DESCRIPTION("Parser for MTD partitioning information in device tree"); MODULE_AUTHOR("Vitaly Wool, David Gibson"); |
9786f6e68 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"); |