Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: handle partitioning on devices with 0 erasesize

erasesize is meaningful for flash devices but for SRAM there is no
concept of an erase block so erasesize is set to 0. When partitioning
these devices instead of ensuring partitions fall on erasesize
boundaries we ensure they fall on writesize boundaries.

Helped-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>

authored by

Chris Packham and committed by
Brian Norris
1eeef2d7 c46adf09

+17 -9
+17 -9
drivers/mtd/mtdpart.c
··· 393 393 const struct mtd_partition *part, int partno, 394 394 uint64_t cur_offset) 395 395 { 396 + int wr_alignment = (master->flags & MTD_NO_ERASE) ? master->writesize: 397 + master->erasesize; 396 398 struct mtd_part *slave; 399 + u32 remainder; 397 400 char *name; 401 + u64 tmp; 398 402 399 403 /* allocate the partition structure */ 400 404 slave = kzalloc(sizeof(*slave), GFP_KERNEL); ··· 503 499 if (slave->offset == MTDPART_OFS_APPEND) 504 500 slave->offset = cur_offset; 505 501 if (slave->offset == MTDPART_OFS_NXTBLK) { 502 + tmp = cur_offset; 506 503 slave->offset = cur_offset; 507 - if (mtd_mod_by_eb(cur_offset, master) != 0) { 508 - /* Round up to next erasesize */ 509 - slave->offset = (mtd_div_by_eb(cur_offset, master) + 1) * master->erasesize; 504 + remainder = do_div(tmp, wr_alignment); 505 + if (remainder) { 506 + slave->offset += wr_alignment - remainder; 510 507 printk(KERN_NOTICE "Moving partition %d: " 511 508 "0x%012llx -> 0x%012llx\n", partno, 512 509 (unsigned long long)cur_offset, (unsigned long long)slave->offset); ··· 572 567 slave->mtd.erasesize = master->erasesize; 573 568 } 574 569 575 - if ((slave->mtd.flags & MTD_WRITEABLE) && 576 - mtd_mod_by_eb(slave->offset, &slave->mtd)) { 570 + tmp = slave->offset; 571 + remainder = do_div(tmp, wr_alignment); 572 + if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { 577 573 /* Doesn't start on a boundary of major erase size */ 578 574 /* FIXME: Let it be writable if it is on a boundary of 579 575 * _minor_ erase size though */ 580 576 slave->mtd.flags &= ~MTD_WRITEABLE; 581 - printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", 577 + printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n", 582 578 part->name); 583 579 } 584 - if ((slave->mtd.flags & MTD_WRITEABLE) && 585 - mtd_mod_by_eb(slave->mtd.size, &slave->mtd)) { 580 + 581 + tmp = slave->mtd.size; 582 + remainder = do_div(tmp, wr_alignment); 583 + if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { 586 584 slave->mtd.flags &= ~MTD_WRITEABLE; 587 - printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", 585 + printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n", 588 586 part->name); 589 587 } 590 588