diff options
Diffstat (limited to 'drivers/mtd/devices')
-rw-r--r-- | drivers/mtd/devices/mtd_dataflash.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 6dd9aff8bb2d..68068975940b 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/mutex.h> | 17 | #include <linux/mutex.h> |
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/math64.h> | ||
19 | 20 | ||
20 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
21 | #include <linux/spi/flash.h> | 22 | #include <linux/spi/flash.h> |
@@ -152,15 +153,20 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
152 | struct spi_message msg; | 153 | struct spi_message msg; |
153 | unsigned blocksize = priv->page_size << 3; | 154 | unsigned blocksize = priv->page_size << 3; |
154 | uint8_t *command; | 155 | uint8_t *command; |
156 | uint32_t rem; | ||
155 | 157 | ||
156 | DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%x len 0x%x\n", | 158 | DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%llx len 0x%llx\n", |
157 | spi->dev.bus_id, | 159 | spi->dev.bus_id, (long long)instr->addr, |
158 | instr->addr, instr->len); | 160 | (long long)instr->len); |
159 | 161 | ||
160 | /* Sanity checks */ | 162 | /* Sanity checks */ |
161 | if ((instr->addr + instr->len) > mtd->size | 163 | if (instr->addr + instr->len > mtd->size) |
162 | || (instr->len % priv->page_size) != 0 | 164 | return -EINVAL; |
163 | || (instr->addr % priv->page_size) != 0) | 165 | div_u64_rem(instr->len, priv->page_size, &rem); |
166 | if (rem) | ||
167 | return -EINVAL; | ||
168 | div_u64_rem(instr->addr, priv->page_size, &rem); | ||
169 | if (rem) | ||
164 | return -EINVAL; | 170 | return -EINVAL; |
165 | 171 | ||
166 | spi_message_init(&msg); | 172 | spi_message_init(&msg); |
@@ -178,7 +184,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
178 | /* Calculate flash page address; use block erase (for speed) if | 184 | /* Calculate flash page address; use block erase (for speed) if |
179 | * we're at a block boundary and need to erase the whole block. | 185 | * we're at a block boundary and need to erase the whole block. |
180 | */ | 186 | */ |
181 | pageaddr = instr->addr / priv->page_size; | 187 | pageaddr = div_u64(instr->len, priv->page_size); |
182 | do_block = (pageaddr & 0x7) == 0 && instr->len >= blocksize; | 188 | do_block = (pageaddr & 0x7) == 0 && instr->len >= blocksize; |
183 | pageaddr = pageaddr << priv->page_offset; | 189 | pageaddr = pageaddr << priv->page_offset; |
184 | 190 | ||
@@ -667,8 +673,8 @@ add_dataflash_otp(struct spi_device *spi, char *name, | |||
667 | if (revision >= 'c') | 673 | if (revision >= 'c') |
668 | otp_tag = otp_setup(device, revision); | 674 | otp_tag = otp_setup(device, revision); |
669 | 675 | ||
670 | dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes%s\n", | 676 | dev_info(&spi->dev, "%s (%lld KBytes) pagesize %d bytes%s\n", |
671 | name, DIV_ROUND_UP(device->size, 1024), | 677 | name, (long long)((device->size + 1023) >> 10), |
672 | pagesize, otp_tag); | 678 | pagesize, otp_tag); |
673 | dev_set_drvdata(&spi->dev, priv); | 679 | dev_set_drvdata(&spi->dev, priv); |
674 | 680 | ||