diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-22 15:00:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-22 15:00:44 -0400 |
commit | a62d016cece2fce1d5e4eedf36b17f03a7a5c78e (patch) | |
tree | ac37b4835be5f4fe0e04611fdb40c85abb98ec78 /include | |
parent | 7c034dfd58bbc056280262887acf5b7a98944d0a (diff) | |
parent | 3e550d2396d9deef77328237ed992e19dcfefca5 (diff) |
Merge tag 'for-linus-20150422' of git://git.infradead.org/linux-mtd
Pull MTD updates from Brian Norris:
"Common MTD:
- Add Kconfig option for keeping both the 'master' and 'partition'
MTDs registered as devices. This would really make a better
default if we could do it over, as it allows a lot more flexibility
in (1) determining the flash topology of the system from user-space
and (2) adding temporary partitions at runtime (ioctl(BLKPG)).
Unfortunately, this would possibly cause user-space breakage, as it
will cause renumbering of the /dev/mtdX devices. We'll see if we
can change this in the future, as there have already been a few
people looking for this feature, and I know others have just been
working around our current limitations instead of fixing them this
way.
- Along with the previous change, add some additional information to
sysfs, so user-space can read the offset of each partition within
its master device
SPI NOR:
- add new device tree compatible binding to represent the
mostly-compatible class of SPI NOR flash which can be detected by
their extended JEDEC ID bytes, cutting down the duplication of our
ID tables
- misc. new IDs
Various other miscellaneous fixes and changes"
* tag 'for-linus-20150422' of git://git.infradead.org/linux-mtd: (53 commits)
mtd: spi-nor: Add support for Macronix mx25u6435f serial flash
mtd: spi-nor: Add support for Winbond w25q64dw serial flash
mtd: spi-nor: add support for the Winbond W25X05 flash
mtd: spi-nor: support en25s64 device
mtd: m25p80: bind to "nor-jedec" ID, for auto-detection
Documentation: devicetree: m25p80: add "nor-jedec" binding
mtd: Make MTD tests cancelable
mtd: mtd_oobtest: Fix bitflip_limit usage in test case 3
mtd: docg3: remove invalid __exit annotations
mtd: fsl_ifc_nand: use msecs_to_jiffies for time conversion
mtd: atmel_nand: don't map the ROM table if no pmecc table offset in DT
mtd: atmel_nand: add a definition for the oob reserved bytes
mtd: part: Remove partition overlap checks
mtd: part: Add sysfs variable for offset of partition
mtd: part: Create the master device node when partitioned
mtd: ts5500_flash: Fix typo in MODULE_DESCRIPTION in ts5500_flash.c
mtd: denali: Disable sub-page writes in Denali NAND driver
mtd: pxa3xx_nand: cleanup wait_for_completion handling
mtd: nand: gpmi: Check for scan_bbt() error
mtd: nand: gpmi: fixup return type of wait_for_completion_timeout
...
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/mtd/map.h | 54 | ||||
-rw-r--r-- | include/linux/mtd/spi-nor.h | 5 |
2 files changed, 40 insertions, 19 deletions
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index 5f487d776411..29975c73a953 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h | |||
@@ -77,7 +77,7 @@ | |||
77 | /* ensure we never evaluate anything shorted than an unsigned long | 77 | /* ensure we never evaluate anything shorted than an unsigned long |
78 | * to zero, and ensure we'll never miss the end of an comparison (bjd) */ | 78 | * to zero, and ensure we'll never miss the end of an comparison (bjd) */ |
79 | 79 | ||
80 | #define map_calc_words(map) ((map_bankwidth(map) + (sizeof(unsigned long)-1))/ sizeof(unsigned long)) | 80 | #define map_calc_words(map) ((map_bankwidth(map) + (sizeof(unsigned long)-1)) / sizeof(unsigned long)) |
81 | 81 | ||
82 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_8 | 82 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_8 |
83 | # ifdef map_bankwidth | 83 | # ifdef map_bankwidth |
@@ -181,7 +181,7 @@ static inline int map_bankwidth_supported(int w) | |||
181 | } | 181 | } |
182 | } | 182 | } |
183 | 183 | ||
184 | #define MAX_MAP_LONGS ( ((MAX_MAP_BANKWIDTH*8) + BITS_PER_LONG - 1) / BITS_PER_LONG ) | 184 | #define MAX_MAP_LONGS (((MAX_MAP_BANKWIDTH * 8) + BITS_PER_LONG - 1) / BITS_PER_LONG) |
185 | 185 | ||
186 | typedef union { | 186 | typedef union { |
187 | unsigned long x[MAX_MAP_LONGS]; | 187 | unsigned long x[MAX_MAP_LONGS]; |
@@ -264,20 +264,22 @@ void unregister_mtd_chip_driver(struct mtd_chip_driver *); | |||
264 | struct mtd_info *do_map_probe(const char *name, struct map_info *map); | 264 | struct mtd_info *do_map_probe(const char *name, struct map_info *map); |
265 | void map_destroy(struct mtd_info *mtd); | 265 | void map_destroy(struct mtd_info *mtd); |
266 | 266 | ||
267 | #define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0) | 267 | #define ENABLE_VPP(map) do { if (map->set_vpp) map->set_vpp(map, 1); } while (0) |
268 | #define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0) | 268 | #define DISABLE_VPP(map) do { if (map->set_vpp) map->set_vpp(map, 0); } while (0) |
269 | 269 | ||
270 | #define INVALIDATE_CACHED_RANGE(map, from, size) \ | 270 | #define INVALIDATE_CACHED_RANGE(map, from, size) \ |
271 | do { if(map->inval_cache) map->inval_cache(map, from, size); } while(0) | 271 | do { if (map->inval_cache) map->inval_cache(map, from, size); } while (0) |
272 | 272 | ||
273 | 273 | ||
274 | static inline int map_word_equal(struct map_info *map, map_word val1, map_word val2) | 274 | static inline int map_word_equal(struct map_info *map, map_word val1, map_word val2) |
275 | { | 275 | { |
276 | int i; | 276 | int i; |
277 | for (i=0; i<map_words(map); i++) { | 277 | |
278 | for (i = 0; i < map_words(map); i++) { | ||
278 | if (val1.x[i] != val2.x[i]) | 279 | if (val1.x[i] != val2.x[i]) |
279 | return 0; | 280 | return 0; |
280 | } | 281 | } |
282 | |||
281 | return 1; | 283 | return 1; |
282 | } | 284 | } |
283 | 285 | ||
@@ -286,9 +288,9 @@ static inline map_word map_word_and(struct map_info *map, map_word val1, map_wor | |||
286 | map_word r; | 288 | map_word r; |
287 | int i; | 289 | int i; |
288 | 290 | ||
289 | for (i=0; i<map_words(map); i++) { | 291 | for (i = 0; i < map_words(map); i++) |
290 | r.x[i] = val1.x[i] & val2.x[i]; | 292 | r.x[i] = val1.x[i] & val2.x[i]; |
291 | } | 293 | |
292 | return r; | 294 | return r; |
293 | } | 295 | } |
294 | 296 | ||
@@ -297,9 +299,9 @@ static inline map_word map_word_clr(struct map_info *map, map_word val1, map_wor | |||
297 | map_word r; | 299 | map_word r; |
298 | int i; | 300 | int i; |
299 | 301 | ||
300 | for (i=0; i<map_words(map); i++) { | 302 | for (i = 0; i < map_words(map); i++) |
301 | r.x[i] = val1.x[i] & ~val2.x[i]; | 303 | r.x[i] = val1.x[i] & ~val2.x[i]; |
302 | } | 304 | |
303 | return r; | 305 | return r; |
304 | } | 306 | } |
305 | 307 | ||
@@ -308,22 +310,33 @@ static inline map_word map_word_or(struct map_info *map, map_word val1, map_word | |||
308 | map_word r; | 310 | map_word r; |
309 | int i; | 311 | int i; |
310 | 312 | ||
311 | for (i=0; i<map_words(map); i++) { | 313 | for (i = 0; i < map_words(map); i++) |
312 | r.x[i] = val1.x[i] | val2.x[i]; | 314 | r.x[i] = val1.x[i] | val2.x[i]; |
313 | } | 315 | |
314 | return r; | 316 | return r; |
315 | } | 317 | } |
316 | 318 | ||
317 | #define map_word_andequal(m, a, b, z) map_word_equal(m, z, map_word_and(m, a, b)) | 319 | static inline int map_word_andequal(struct map_info *map, map_word val1, map_word val2, map_word val3) |
320 | { | ||
321 | int i; | ||
322 | |||
323 | for (i = 0; i < map_words(map); i++) { | ||
324 | if ((val1.x[i] & val2.x[i]) != val3.x[i]) | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | return 1; | ||
329 | } | ||
318 | 330 | ||
319 | static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2) | 331 | static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2) |
320 | { | 332 | { |
321 | int i; | 333 | int i; |
322 | 334 | ||
323 | for (i=0; i<map_words(map); i++) { | 335 | for (i = 0; i < map_words(map); i++) { |
324 | if (val1.x[i] & val2.x[i]) | 336 | if (val1.x[i] & val2.x[i]) |
325 | return 1; | 337 | return 1; |
326 | } | 338 | } |
339 | |||
327 | return 0; | 340 | return 0; |
328 | } | 341 | } |
329 | 342 | ||
@@ -355,14 +368,16 @@ static inline map_word map_word_load_partial(struct map_info *map, map_word orig | |||
355 | 368 | ||
356 | if (map_bankwidth_is_large(map)) { | 369 | if (map_bankwidth_is_large(map)) { |
357 | char *dest = (char *)&orig; | 370 | char *dest = (char *)&orig; |
371 | |||
358 | memcpy(dest+start, buf, len); | 372 | memcpy(dest+start, buf, len); |
359 | } else { | 373 | } else { |
360 | for (i=start; i < start+len; i++) { | 374 | for (i = start; i < start+len; i++) { |
361 | int bitpos; | 375 | int bitpos; |
376 | |||
362 | #ifdef __LITTLE_ENDIAN | 377 | #ifdef __LITTLE_ENDIAN |
363 | bitpos = i*8; | 378 | bitpos = i * 8; |
364 | #else /* __BIG_ENDIAN */ | 379 | #else /* __BIG_ENDIAN */ |
365 | bitpos = (map_bankwidth(map)-1-i)*8; | 380 | bitpos = (map_bankwidth(map) - 1 - i) * 8; |
366 | #endif | 381 | #endif |
367 | orig.x[0] &= ~(0xff << bitpos); | 382 | orig.x[0] &= ~(0xff << bitpos); |
368 | orig.x[0] |= (unsigned long)buf[i-start] << bitpos; | 383 | orig.x[0] |= (unsigned long)buf[i-start] << bitpos; |
@@ -384,9 +399,10 @@ static inline map_word map_word_ff(struct map_info *map) | |||
384 | 399 | ||
385 | if (map_bankwidth(map) < MAP_FF_LIMIT) { | 400 | if (map_bankwidth(map) < MAP_FF_LIMIT) { |
386 | int bw = 8 * map_bankwidth(map); | 401 | int bw = 8 * map_bankwidth(map); |
402 | |||
387 | r.x[0] = (1UL << bw) - 1; | 403 | r.x[0] = (1UL << bw) - 1; |
388 | } else { | 404 | } else { |
389 | for (i=0; i<map_words(map); i++) | 405 | for (i = 0; i < map_words(map); i++) |
390 | r.x[i] = ~0UL; | 406 | r.x[i] = ~0UL; |
391 | } | 407 | } |
392 | return r; | 408 | return r; |
@@ -407,7 +423,7 @@ static inline map_word inline_map_read(struct map_info *map, unsigned long ofs) | |||
407 | r.x[0] = __raw_readq(map->virt + ofs); | 423 | r.x[0] = __raw_readq(map->virt + ofs); |
408 | #endif | 424 | #endif |
409 | else if (map_bankwidth_is_large(map)) | 425 | else if (map_bankwidth_is_large(map)) |
410 | memcpy_fromio(r.x, map->virt+ofs, map->bankwidth); | 426 | memcpy_fromio(r.x, map->virt + ofs, map->bankwidth); |
411 | else | 427 | else |
412 | BUG(); | 428 | BUG(); |
413 | 429 | ||
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 4720b86ee73d..e5409524bb0a 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h | |||
@@ -155,6 +155,8 @@ enum spi_nor_option_flags { | |||
155 | * @write: [DRIVER-SPECIFIC] write data to the SPI NOR | 155 | * @write: [DRIVER-SPECIFIC] write data to the SPI NOR |
156 | * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR | 156 | * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR |
157 | * at the offset @offs | 157 | * at the offset @offs |
158 | * @lock: [FLASH-SPECIFIC] lock a region of the SPI NOR | ||
159 | * @unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR | ||
158 | * @priv: the private data | 160 | * @priv: the private data |
159 | */ | 161 | */ |
160 | struct spi_nor { | 162 | struct spi_nor { |
@@ -189,6 +191,9 @@ struct spi_nor { | |||
189 | size_t len, size_t *retlen, const u_char *write_buf); | 191 | size_t len, size_t *retlen, const u_char *write_buf); |
190 | int (*erase)(struct spi_nor *nor, loff_t offs); | 192 | int (*erase)(struct spi_nor *nor, loff_t offs); |
191 | 193 | ||
194 | int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len); | ||
195 | int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len); | ||
196 | |||
192 | void *priv; | 197 | void *priv; |
193 | }; | 198 | }; |
194 | 199 | ||