diff --git a/arch/arm/configs/edb93xx_defconfig b/arch/arm/configs/edb93xx_defconfig index 363e51172..86b104026 100644 --- a/arch/arm/configs/edb93xx_defconfig +++ b/arch/arm/configs/edb93xx_defconfig @@ -30,4 +30,5 @@ CONFIG_CMD_TFTP=y CONFIG_FS_TFTP=y CONFIG_DRIVER_NET_EP93XX=y # CONFIG_SPI is not set +CONFIG_MTD=y CONFIG_DRIVER_CFI=y diff --git a/arch/arm/configs/eukrea_cpuimx27_defconfig b/arch/arm/configs/eukrea_cpuimx27_defconfig index c751d1cef..bbcd454e3 100644 --- a/arch/arm/configs/eukrea_cpuimx27_defconfig +++ b/arch/arm/configs/eukrea_cpuimx27_defconfig @@ -46,6 +46,7 @@ CONFIG_DRIVER_NET_FEC_IMX=y CONFIG_I2C=y CONFIG_I2C_IMX=y CONFIG_MFD_LP3972=y +CONFIG_MTD=y CONFIG_DRIVER_CFI=y # CONFIG_DRIVER_CFI_AMD is not set # CONFIG_DRIVER_CFI_BANK_WIDTH_1 is not set diff --git a/arch/arm/configs/freescale_mx51_babbage_defconfig b/arch/arm/configs/freescale_mx51_babbage_defconfig index 0817cfa95..97963c1dc 100644 --- a/arch/arm/configs/freescale_mx51_babbage_defconfig +++ b/arch/arm/configs/freescale_mx51_babbage_defconfig @@ -55,6 +55,7 @@ CONFIG_NET_PING=y CONFIG_NET_RESOLV=y CONFIG_DRIVER_NET_FEC_IMX=y CONFIG_DRIVER_SPI_IMX=y +CONFIG_MTD=y CONFIG_DRIVER_CFI=y CONFIG_CFI_BUFFER_WRITE=y CONFIG_MCI=y diff --git a/arch/arm/configs/mmccpu_defconfig b/arch/arm/configs/mmccpu_defconfig index 334c5e85d..0e6914fd6 100644 --- a/arch/arm/configs/mmccpu_defconfig +++ b/arch/arm/configs/mmccpu_defconfig @@ -34,5 +34,6 @@ CONFIG_FS_TFTP=y CONFIG_DRIVER_NET_MACB=y # CONFIG_SPI is not set CONFIG_I2C=y +CONFIG_MTD=y CONFIG_DRIVER_CFI=y CONFIG_CFI_BUFFER_WRITE=y diff --git a/arch/arm/configs/mx21ads_defconfig b/arch/arm/configs/mx21ads_defconfig index 28ad01325..dbc296279 100644 --- a/arch/arm/configs/mx21ads_defconfig +++ b/arch/arm/configs/mx21ads_defconfig @@ -35,6 +35,7 @@ CONFIG_CMD_TFTP=y CONFIG_FS_TFTP=y CONFIG_DRIVER_NET_CS8900=y # CONFIG_SPI is not set +CONFIG_MTD=y CONFIG_DRIVER_CFI=y # CONFIG_DRIVER_CFI_INTEL is not set CONFIG_CFI_BUFFER_WRITE=y diff --git a/arch/arm/configs/mx27ads_defconfig b/arch/arm/configs/mx27ads_defconfig index 077e799dd..b3fdf84fa 100644 --- a/arch/arm/configs/mx27ads_defconfig +++ b/arch/arm/configs/mx27ads_defconfig @@ -33,6 +33,7 @@ CONFIG_NET_PING=y CONFIG_CMD_TFTP=y CONFIG_FS_TFTP=y CONFIG_DRIVER_SPI_IMX=y +CONFIG_MTD=y CONFIG_DRIVER_CFI=y # CONFIG_DRIVER_CFI_INTEL is not set CONFIG_CFI_BUFFER_WRITE=y diff --git a/arch/arm/configs/netx_nxdb500_defconfig b/arch/arm/configs/netx_nxdb500_defconfig index 6d32c5637..8e7a0b3cc 100644 --- a/arch/arm/configs/netx_nxdb500_defconfig +++ b/arch/arm/configs/netx_nxdb500_defconfig @@ -26,5 +26,6 @@ CONFIG_NET_PING=y CONFIG_CMD_TFTP=y CONFIG_FS_TFTP=y CONFIG_DRIVER_NET_NETX=y +CONFIG_MTD=y CONFIG_DRIVER_CFI=y CONFIG_CFI_BUFFER_WRITE=y diff --git a/arch/arm/configs/pcm027_defconfig b/arch/arm/configs/pcm027_defconfig index ac9269d3c..f91195127 100644 --- a/arch/arm/configs/pcm027_defconfig +++ b/arch/arm/configs/pcm027_defconfig @@ -54,6 +54,7 @@ CONFIG_FS_TFTP=y CONFIG_DRIVER_SERIAL_PXA=y CONFIG_DRIVER_NET_SMC91111=y # CONFIG_SPI is not set +CONFIG_MTD=y CONFIG_DRIVER_CFI=y CONFIG_VIDEO=y CONFIG_DRIVER_VIDEO_PXA=y diff --git a/arch/arm/configs/pm9263_defconfig b/arch/arm/configs/pm9263_defconfig index e223e773f..c9a7141f9 100644 --- a/arch/arm/configs/pm9263_defconfig +++ b/arch/arm/configs/pm9263_defconfig @@ -33,6 +33,7 @@ CONFIG_CMD_TFTP=y CONFIG_FS_TFTP=y CONFIG_DRIVER_NET_MACB=y # CONFIG_SPI is not set +CONFIG_MTD=y CONFIG_DRIVER_CFI=y CONFIG_CFI_BUFFER_WRITE=y CONFIG_W1=y diff --git a/arch/arm/configs/scb9328_defconfig b/arch/arm/configs/scb9328_defconfig index 818bbd0d7..21a2571d4 100644 --- a/arch/arm/configs/scb9328_defconfig +++ b/arch/arm/configs/scb9328_defconfig @@ -52,6 +52,7 @@ CONFIG_FS_TFTP=y CONFIG_NET_NETCONSOLE=y CONFIG_NET_RESOLV=y CONFIG_DRIVER_NET_DM9K=y +CONFIG_MTD=y CONFIG_DRIVER_CFI=y # CONFIG_DRIVER_CFI_BANK_WIDTH_4 is not set CONFIG_CFI_BUFFER_WRITE=y diff --git a/arch/blackfin/configs/ipe337_defconfig b/arch/blackfin/configs/ipe337_defconfig index d01c7e756..086a9716d 100644 --- a/arch/blackfin/configs/ipe337_defconfig +++ b/arch/blackfin/configs/ipe337_defconfig @@ -25,5 +25,6 @@ CONFIG_NET_PING=y CONFIG_CMD_TFTP=y CONFIG_FS_TFTP=y CONFIG_DRIVER_NET_SMC911X=y +CONFIG_MTD=y CONFIG_DRIVER_CFI=y CONFIG_CFI_BUFFER_WRITE=y diff --git a/arch/nios2/configs/generic_defconfig b/arch/nios2/configs/generic_defconfig index 5e27cc8d6..41899904b 100644 --- a/arch/nios2/configs/generic_defconfig +++ b/arch/nios2/configs/generic_defconfig @@ -27,6 +27,7 @@ CONFIG_CMD_PARTITION=y CONFIG_NET=y CONFIG_NET_PING=y CONFIG_DRIVER_NET_TSE=y +CONFIG_MTD=y CONFIG_DRIVER_CFI=y CONFIG_FS_TFTP=y CONFIG_ZLIB=y diff --git a/arch/ppc/configs/pcm030_defconfig b/arch/ppc/configs/pcm030_defconfig index d2ff16c71..97438416c 100644 --- a/arch/ppc/configs/pcm030_defconfig +++ b/arch/ppc/configs/pcm030_defconfig @@ -36,6 +36,7 @@ CONFIG_FS_TFTP=y CONFIG_ARCH_MPC5XXX=y CONFIG_MACH_PHYCORE_MPC5200B_TINY=y CONFIG_DRIVER_NET_MPC5200=y +CONFIG_MTD=y CONFIG_DRIVER_CFI=y CONFIG_CFI_BUFFER_WRITE=y CONFIG_ZLIB=y diff --git a/commands/ubiformat.c b/commands/ubiformat.c index efe1fde9f..47941bedb 100644 --- a/commands/ubiformat.c +++ b/commands/ubiformat.c @@ -338,7 +338,7 @@ static int flash_image(const struct mtd_dev_info *mtd, normsg_cont("eraseblock %d: erase", eb); } - err = mtd_erase(mtd, args.node_fd, eb); + err = libmtd_erase(mtd, args.node_fd, eb); if (err) { if (!args.quiet) printf("\n"); @@ -384,7 +384,7 @@ static int flash_image(const struct mtd_dev_info *mtd, new_len = drop_ffs(mtd, buf, mtd->eb_size); - err = mtd_write(mtd, args.node_fd, eb, 0, buf, new_len); + err = libmtd_write(mtd, args.node_fd, eb, 0, buf, new_len); if (err) { sys_errmsg("cannot write eraseblock %d", eb); @@ -453,7 +453,7 @@ static int format(const struct mtd_dev_info *mtd, normsg_cont("eraseblock %d: erase", eb); } - err = mtd_erase(mtd, args.node_fd, eb); + err = libmtd_erase(mtd, args.node_fd, eb); if (err) { if (!args.quiet) printf("\n"); @@ -484,7 +484,7 @@ static int format(const struct mtd_dev_info *mtd, printf(", write EC %lld\n", ec); } - err = mtd_write(mtd, args.node_fd, eb, 0, hdr, write_size); + err = libmtd_write(mtd, args.node_fd, eb, 0, hdr, write_size); if (err) { if (!args.quiet && !args.verbose) printf("\n"); diff --git a/drivers/Kconfig b/drivers/Kconfig index dac22de98..16ca5b99b 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -5,7 +5,6 @@ source "drivers/serial/Kconfig" source "drivers/net/Kconfig" source "drivers/spi/Kconfig" source "drivers/i2c/Kconfig" -source "drivers/nor/Kconfig" source "drivers/mtd/Kconfig" source "drivers/ata/Kconfig" source "drivers/usb/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 1fddee0dd..f81bf99ac 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -3,7 +3,6 @@ obj-$(CONFIG_ARM_AMBA) += amba/ obj-y += net/ obj-y += serial/ obj-y += mtd/ -obj-y += nor/ obj-y += usb/ obj-$(CONFIG_DISK) += ata/ obj-$(CONFIG_SPI) += spi/ diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 9450f5de8..e94e6b1f6 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -21,6 +21,7 @@ config MTD_RAW_DEVICE prompt "mtdraw device to read/write both data+oob" source "drivers/mtd/devices/Kconfig" +source "drivers/mtd/nor/Kconfig" source "drivers/mtd/nand/Kconfig" source "drivers/mtd/ubi/Kconfig" diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 4f97d9a6f..82b2cc9e6 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_NAND) += nand/ +obj-$(CONFIG_DRIVER_CFI) += nor/ obj-$(CONFIG_UBI) += ubi/ obj-y += devices/ obj-$(CONFIG_PARTITION_NEED_MTD) += partition.o diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c index ef985564b..b6c1d0143 100644 --- a/drivers/mtd/core.c +++ b/drivers/mtd/core.c @@ -62,16 +62,7 @@ int mtd_all_ff(const void *buf, unsigned int len) return 1; } -int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) -{ - if (!mtd->block_isbad) - return 0; - if (ofs < 0 || ofs > mtd->size) - return -EINVAL; - return mtd->block_isbad(mtd, ofs); -} - -static ssize_t mtd_read(struct cdev *cdev, void* buf, size_t count, +static ssize_t mtd_op_read(struct cdev *cdev, void* buf, size_t count, loff_t _offset, ulong flags) { struct mtd_info *mtd = cdev->priv; @@ -79,9 +70,10 @@ static ssize_t mtd_read(struct cdev *cdev, void* buf, size_t count, int ret; unsigned long offset = _offset; - debug("mtd_read: 0x%08lx 0x%08x\n", offset, count); + dev_dbg(cdev->dev, "read ofs: 0x%08lx count: 0x%08x\n", + offset, count); - ret = mtd->read(mtd, offset, count, &retlen, buf); + ret = mtd_read(mtd, offset, count, &retlen, buf); if(ret) { printf("err %d\n", ret); @@ -94,19 +86,19 @@ static ssize_t mtd_read(struct cdev *cdev, void* buf, size_t count, #define MTDPGALG(x) ((x) & ~(mtd->writesize - 1)) #ifdef CONFIG_MTD_WRITE -static ssize_t mtd_write(struct cdev* cdev, const void *buf, size_t _count, +static ssize_t mtd_op_write(struct cdev* cdev, const void *buf, size_t _count, loff_t _offset, ulong flags) { struct mtd_info *mtd = cdev->priv; size_t retlen; int ret; - ret = mtd->write(mtd, _offset, _count, &retlen, buf); + ret = mtd_write(mtd, _offset, _count, &retlen, buf); return ret ? ret : _count; } -static int mtd_erase(struct cdev *cdev, size_t count, loff_t offset) +static int mtd_op_erase(struct cdev *cdev, size_t count, loff_t offset) { struct mtd_info *mtd = cdev->priv; struct erase_info erase; @@ -124,7 +116,7 @@ static int mtd_erase(struct cdev *cdev, size_t count, loff_t offset) if (ret > 0) { printf("Skipping bad block at 0x%08x\n", erase.addr); } else { - ret = mtd->erase(mtd, &erase); + ret = mtd_erase(mtd, &erase); if (ret) return ret; } @@ -135,6 +127,20 @@ static int mtd_erase(struct cdev *cdev, size_t count, loff_t offset) return 0; } + +static ssize_t mtd_op_protect(struct cdev *cdev, size_t count, loff_t offset, int prot) +{ + struct mtd_info *mtd = cdev->priv; + + if (!mtd->unlock || !mtd->lock) + return -ENOSYS; + + if (prot) + return mtd_lock(mtd, offset, count); + else + return mtd_unlock(mtd, offset, count); +} + #endif /* CONFIG_MTD_WRITE */ int mtd_ioctl(struct cdev *cdev, int request, void *buf) @@ -159,10 +165,10 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf) #ifdef CONFIG_MTD_WRITE case MEMSETBADBLOCK: dev_dbg(cdev->dev, "MEMSETBADBLOCK: 0x%08llx\n", *offset); - ret = mtd->block_markbad(mtd, *offset); + ret = mtd_block_markbad(mtd, *offset); break; case MEMERASE: - ret = mtd_erase(cdev, ei->length, ei->start + cdev->offset); + ret = mtd_op_erase(cdev, ei->length, ei->start + cdev->offset); break; #endif case MEMGETINFO: @@ -201,11 +207,74 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf) return ret; } +int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) +{ + if (!mtd->lock) + return -EOPNOTSUPP; + if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) + return -EINVAL; + if (!len) + return 0; + return mtd->lock(mtd, ofs, len); +} + +int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) +{ + if (!mtd->unlock) + return -EOPNOTSUPP; + if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) + return -EINVAL; + if (!len) + return 0; + return mtd->unlock(mtd, ofs, len); +} + +int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) +{ + if (!mtd->block_isbad) + return 0; + + if (ofs < 0 || ofs > mtd->size) + return -EINVAL; + + return mtd->block_isbad(mtd, ofs); +} + +int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs) +{ + int ret; + + if (mtd->block_markbad) + ret = mtd->block_markbad(mtd, ofs); + else + ret = -ENOSYS; + + return ret; +} + +int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, + u_char *buf) +{ + return mtd->read(mtd, from, len, retlen, buf); +} + +int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, + const u_char *buf) +{ + return mtd->write(mtd, to, len, retlen, buf); +} + +int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) +{ + return mtd->erase(mtd, instr); +} + static struct file_operations mtd_ops = { - .read = mtd_read, + .read = mtd_op_read, #ifdef CONFIG_MTD_WRITE - .write = mtd_write, - .erase = mtd_erase, + .write = mtd_op_write, + .erase = mtd_op_erase, + .protect = mtd_op_protect, #endif .ioctl = mtd_ioctl, .lseek = dev_lseek_default, diff --git a/drivers/mtd/mtdraw.c b/drivers/mtd/mtdraw.c index ec7769249..5aaa0172d 100644 --- a/drivers/mtd/mtdraw.c +++ b/drivers/mtd/mtdraw.c @@ -245,7 +245,7 @@ static int mtdraw_erase(struct cdev *cdev, size_t count, loff_t _offset) if (ret > 0) { printf("Skipping bad block at 0x%08x\n", erase.addr); } else { - ret = mtd->erase(mtd, &erase); + ret = mtd_erase(mtd, &erase); if (ret) return ret; } diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index f7ae7cd71..56396bfd8 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -160,7 +160,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, while (totlen) { len = min(totlen, (size_t) (1 << this->bbt_erase_shift)); - res = mtd->read(mtd, from, len, &retlen, buf); + res = mtd_read(mtd, from, len, &retlen, buf); if (res < 0) { if (retlen != len) { pr_info("nand_bbt: Error reading bad block table\n"); @@ -669,7 +669,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, /* Make it block aligned */ to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1)); len = 1 << this->bbt_erase_shift; - res = mtd->read(mtd, to, len, &retlen, buf); + res = mtd_read(mtd, to, len, &retlen, buf); if (res < 0) { if (retlen != len) { pr_info("nand_bbt: Error " diff --git a/drivers/nor/Kconfig b/drivers/mtd/nor/Kconfig similarity index 81% rename from drivers/nor/Kconfig rename to drivers/mtd/nor/Kconfig index c8ce24ff0..44a418405 100644 --- a/drivers/nor/Kconfig +++ b/drivers/mtd/nor/Kconfig @@ -1,7 +1,5 @@ -menu "flash drivers" - menuconfig DRIVER_CFI - bool "CFI" + bool "CFI NOR flash support" help If you have NOR Flash devices connected to your system and wish to use them say yes here. @@ -10,17 +8,14 @@ if DRIVER_CFI config DRIVER_CFI_INTEL default y - depends on DRIVER_CFI bool "Support Intel flash chips" config DRIVER_CFI_AMD default y - depends on DRIVER_CFI bool "support AMD flash chips" config DRIVER_CFI_BANK_WIDTH_1 bool "Support 8-bit buswidth" - depends on DRIVER_CFI default y help If you wish to support CFI devices on a physical bus which is @@ -28,7 +23,6 @@ config DRIVER_CFI_BANK_WIDTH_1 config DRIVER_CFI_BANK_WIDTH_2 bool "Support 16-bit buswidth" - depends on DRIVER_CFI default y help If you wish to support CFI devices on a physical bus which is @@ -36,7 +30,6 @@ config DRIVER_CFI_BANK_WIDTH_2 config DRIVER_CFI_BANK_WIDTH_4 bool "Support 32-bit buswidth" - depends on DRIVER_CFI default y help If you wish to support CFI devices on a physical bus which is @@ -44,16 +37,11 @@ config DRIVER_CFI_BANK_WIDTH_4 config DRIVER_CFI_BANK_WIDTH_8 bool "Support 64-bit buswidth" - depends on DRIVER_CFI - default n help If you wish to support CFI devices on a physical bus which is 64 bits wide, say 'Y'. config CFI_BUFFER_WRITE bool "use cfi driver with buffer write" - depends on DRIVER_CFI || DRIVER_CFI endif - -endmenu diff --git a/drivers/nor/Makefile b/drivers/mtd/nor/Makefile similarity index 100% rename from drivers/nor/Makefile rename to drivers/mtd/nor/Makefile diff --git a/drivers/nor/cfi_flash.c b/drivers/mtd/nor/cfi_flash.c similarity index 93% rename from drivers/nor/cfi_flash.c rename to drivers/mtd/nor/cfi_flash.c index acdc38654..0cfac2d03 100644 --- a/drivers/nor/cfi_flash.c +++ b/drivers/mtd/nor/cfi_flash.c @@ -454,10 +454,8 @@ flash_sect_t find_sector (struct flash_info *info, ulong addr) return sector; } -static int __cfi_erase(struct cdev *cdev, size_t count, loff_t offset, - int verbose) +static int cfi_erase(struct flash_info *finfo, size_t count, loff_t offset) { - struct flash_info *finfo = (struct flash_info *)cdev->priv; unsigned long start, end; int i, ret = 0; @@ -467,9 +465,6 @@ static int __cfi_erase(struct cdev *cdev, size_t count, loff_t offset, end = find_sector(finfo, (unsigned long)finfo->base + offset + count - 1); - if (verbose) - init_progression_bar(end - start); - for (i = start; i <= end; i++) { ret = finfo->cfi_cmd_set->flash_erase_one(finfo, i); if (ret) @@ -479,21 +474,11 @@ static int __cfi_erase(struct cdev *cdev, size_t count, loff_t offset, ret = -EINTR; goto out; } - - if (verbose) - show_progress(i - start); } out: - if (verbose) - putchar('\n'); return ret; } -static int cfi_erase(struct cdev *cdev, size_t count, loff_t offset) -{ - return __cfi_erase(cdev, count, offset, 1); -} - /* * Copy memory to flash, returns: * 0 - OK @@ -626,18 +611,13 @@ static int flash_real_protect (struct flash_info *info, long sector, int prot) return retcode; } -static int cfi_protect(struct cdev *cdev, size_t count, loff_t offset, int prot) +static int cfi_mtd_protect(struct flash_info *finfo, loff_t offset, size_t len, int prot) { - struct flash_info *finfo = (struct flash_info *)cdev->priv; unsigned long start, end; int i, ret = 0; - const char *action = (prot? "protect" : "unprotect"); - - printf("%s: %s 0x%p (size %zu)\n", __func__, - action, finfo->base + offset, count); start = find_sector(finfo, (unsigned long)finfo->base + offset); - end = find_sector(finfo, (unsigned long)finfo->base + offset + count - 1); + end = find_sector(finfo, (unsigned long)finfo->base + offset + len - 1); for (i = start; i <= end; i++) { ret = flash_real_protect (finfo, i, prot); @@ -645,20 +625,21 @@ static int cfi_protect(struct cdev *cdev, size_t count, loff_t offset, int prot) goto out; } out: - putchar('\n'); return ret; } -static ssize_t cfi_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags) +static int cfi_mtd_lock(struct mtd_info *mtd, loff_t offset, size_t len) { - struct flash_info *finfo = (struct flash_info *)cdev->priv; - int ret; + struct flash_info *finfo = container_of(mtd, struct flash_info, mtd); - debug("cfi_write: buf=0x%p addr=0x%p count=0x%08zx\n", - buf, finfo->base + offset, count); + return cfi_mtd_protect(finfo, offset, len, 1); +} - ret = write_buff(finfo, buf, (unsigned long)finfo->base + offset, count); - return ret == 0 ? count : -1; +static int cfi_mtd_unlock(struct mtd_info *mtd, loff_t offset, size_t len) +{ + struct flash_info *finfo = container_of(mtd, struct flash_info, mtd); + + return cfi_mtd_protect(finfo, offset, len, 0); } static void cfi_info (struct device_d* dev) @@ -908,15 +889,6 @@ int flash_isset(struct flash_info *info, flash_sect_t sect, return retval; } -struct file_operations cfi_ops = { - .read = mem_read, - .write = cfi_write, - .lseek = dev_lseek_default, - .erase = cfi_erase, - .protect = cfi_protect, - .memmap = generic_memmap_ro, -}; - static int cfi_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { @@ -943,10 +915,9 @@ static int cfi_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, static int cfi_mtd_erase(struct mtd_info *mtd, struct erase_info *instr) { struct flash_info *info = container_of(mtd, struct flash_info, mtd); - struct cdev *cdev = &info->cdev; int ret; - ret = __cfi_erase(cdev, instr->len, instr->addr, 0); + ret = cfi_erase(info, instr->len, instr->addr); if (ret) { instr->state = MTD_ERASE_FAILED; @@ -966,21 +937,23 @@ static void cfi_init_mtd(struct flash_info *info) mtd->read = cfi_mtd_read; mtd->write = cfi_mtd_write; mtd->erase = cfi_mtd_erase; + mtd->lock = cfi_mtd_lock; + mtd->unlock = cfi_mtd_unlock; mtd->size = info->size; - mtd->name = info->cdev.name; mtd->erasesize = info->eraseregions[1].erasesize; /* FIXME */ mtd->writesize = 1; mtd->subpage_sft = 0; mtd->eraseregions = info->eraseregions; mtd->numeraseregions = info->numeraseregions; mtd->flags = MTD_CAP_NORFLASH; - info->cdev.mtd = mtd; + mtd->type = MTD_NORFLASH; + + add_mtd_device(mtd, "nor"); } static int cfi_probe (struct device_d *dev) { struct flash_info *info = xzalloc(sizeof(*info)); - int cfinum; dev->priv = (void *)info; @@ -999,24 +972,7 @@ static int cfi_probe (struct device_d *dev) dev_info(dev, "found cfi flash at %p, size %ld\n", info->base, info->size); - if (dev->id < 0) - cfinum = cdev_find_free_index("nor"); - else - cfinum = dev->id; - - info->cdev.name = asprintf("nor%d", cfinum); - info->cdev.size = info->size; - info->cdev.dev = dev; - info->cdev.ops = &cfi_ops; - info->cdev.priv = info; - - if (IS_ENABLED(CONFIG_PARTITION_NEED_MTD)) - cfi_init_mtd(info); - - devfs_create(&info->cdev); - - if (dev->device_node) - of_parse_partitions(info->cdev.name, dev->device_node); + cfi_init_mtd(info); return 0; } diff --git a/drivers/nor/cfi_flash.h b/drivers/mtd/nor/cfi_flash.h similarity index 99% rename from drivers/nor/cfi_flash.h rename to drivers/mtd/nor/cfi_flash.h index 944cdde66..bcf5c40c7 100644 --- a/drivers/nor/cfi_flash.h +++ b/drivers/mtd/nor/cfi_flash.h @@ -74,7 +74,6 @@ struct flash_info { ulong addr_unlock1; /* unlock address 1 for AMD flash roms */ ulong addr_unlock2; /* unlock address 2 for AMD flash roms */ struct cfi_cmd_set *cfi_cmd_set; - struct cdev cdev; struct mtd_info mtd; int numeraseregions; struct mtd_erase_region_info *eraseregions; diff --git a/drivers/nor/cfi_flash_amd.c b/drivers/mtd/nor/cfi_flash_amd.c similarity index 100% rename from drivers/nor/cfi_flash_amd.c rename to drivers/mtd/nor/cfi_flash_amd.c diff --git a/drivers/nor/cfi_flash_intel.c b/drivers/mtd/nor/cfi_flash_intel.c similarity index 100% rename from drivers/nor/cfi_flash_intel.c rename to drivers/mtd/nor/cfi_flash_intel.c diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index e3598b9d9..000fc5d92 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -151,7 +151,7 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, addr = (loff_t)pnum * ubi->peb_size + offset; retry: - err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); + err = mtd_read(ubi->mtd, addr, len, &read, buf); if (err) { if (err == -EUCLEAN) { /* @@ -265,7 +265,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, } addr = (loff_t)pnum * ubi->peb_size + offset; - err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf); + err = mtd_write(ubi->mtd, addr, len, &written, buf); if (err) { ubi_err("error %d while writing %d bytes to PEB %d:%d, written" " %zd bytes", err, len, pnum, offset, written); @@ -315,7 +315,7 @@ retry: ei.callback = erase_callback; ei.priv = (unsigned long)&wq; - err = ubi->mtd->erase(ubi->mtd, &ei); + err = mtd_erase(ubi->mtd, &ei); if (err) { if (retries++ < UBI_IO_RETRIES) { dbg_io("error %d while erasing PEB %d, retry", @@ -1239,7 +1239,7 @@ static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, loff_t addr = (loff_t)pnum * ubi->peb_size + offset; mutex_lock(&ubi->dbg_buf_mutex); - err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf); + err = mtd_read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf); if (err && err != -EUCLEAN) { ubi_err("error %d while reading %d bytes from PEB %d:%d, " "read %zd bytes", err, len, pnum, offset, read); diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index bd059baf8..e5568377b 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -207,6 +207,12 @@ struct mtd_info { char *size_str; }; +int mtd_erase(struct mtd_info *mtd, struct erase_info *instr); +int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, + u_char *buf); +int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, + const u_char *buf); + static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd) { do_div(sz, mtd->erasesize); @@ -251,7 +257,10 @@ static inline void mtd_erase_callback(struct erase_info *instr) } #endif +int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); +int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs); +int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs); int mtd_all_ff(const void *buf, unsigned int len); diff --git a/include/mtd/libmtd.h b/include/mtd/libmtd.h index e88a9a249..65c390aff 100644 --- a/include/mtd/libmtd.h +++ b/include/mtd/libmtd.h @@ -69,7 +69,7 @@ struct mtd_dev_info int mtd_get_dev_info(const char *node, struct mtd_dev_info *mtd); /** - * mtd_erase - erase an eraseblock. + * libmtd_erase - erase an eraseblock. * @desc: MTD library descriptor * @mtd: MTD device description object * @fd: MTD device node file descriptor @@ -78,7 +78,7 @@ int mtd_get_dev_info(const char *node, struct mtd_dev_info *mtd); * This function erases eraseblock @eb of MTD device described by @fd. Returns * %0 in case of success and %-1 in case of failure. */ -int mtd_erase(const struct mtd_dev_info *mtd, int fd, int eb); +int libmtd_erase(const struct mtd_dev_info *mtd, int fd, int eb); /** * mtd_torture - torture an eraseblock. @@ -127,7 +127,7 @@ int mtd_mark_bad(const struct mtd_dev_info *mtd, int fd, int eb); * of the MTD device defined by @mtd and stores the read data at buffer @buf. * Returns %0 in case of success and %-1 in case of failure. */ -int mtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs, +int libmtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs, void *buf, int len); /** @@ -143,7 +143,7 @@ int mtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs, * of the MTD device defined by @mtd. Returns %0 in case of success and %-1 in * case of failure. */ -int mtd_write(const struct mtd_dev_info *mtd, int fd, int eb, int offs, +int libmtd_write(const struct mtd_dev_info *mtd, int fd, int eb, int offs, void *buf, int len); #endif /* __LIBMTD_H__ */ diff --git a/lib/libmtd.c b/lib/libmtd.c index 8c4152eb7..eecc76054 100644 --- a/lib/libmtd.c +++ b/lib/libmtd.c @@ -56,7 +56,7 @@ static int mtd_valid_erase_block(const struct mtd_dev_info *mtd, int eb) return 0; } -int mtd_erase(const struct mtd_dev_info *mtd, int fd, int eb) +int libmtd_erase(const struct mtd_dev_info *mtd, int fd, int eb) { int ret; struct erase_info_user ei; @@ -107,12 +107,12 @@ int mtd_torture(const struct mtd_dev_info *mtd, int fd, int eb) buf = xmalloc(mtd->eb_size); for (i = 0; i < patt_count; i++) { - err = mtd_erase(mtd, fd, eb); + err = libmtd_erase(mtd, fd, eb); if (err) goto out; /* Make sure the PEB contains only 0xFF bytes */ - err = mtd_read(mtd, fd, eb, 0, buf, mtd->eb_size); + err = libmtd_read(mtd, fd, eb, 0, buf, mtd->eb_size); if (err) goto out; @@ -125,12 +125,12 @@ int mtd_torture(const struct mtd_dev_info *mtd, int fd, int eb) /* Write a pattern and check it */ memset(buf, patterns[i], mtd->eb_size); - err = mtd_write(mtd, fd, eb, 0, buf, mtd->eb_size); + err = libmtd_write(mtd, fd, eb, 0, buf, mtd->eb_size); if (err) goto out; memset(buf, ~patterns[i], mtd->eb_size); - err = mtd_read(mtd, fd, eb, 0, buf, mtd->eb_size); + err = libmtd_read(mtd, fd, eb, 0, buf, mtd->eb_size); if (err) goto out; @@ -191,7 +191,7 @@ int mtd_mark_bad(const struct mtd_dev_info *mtd, int fd, int eb) return 0; } -int mtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs, +int libmtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs, void *buf, int len) { int ret, rd = 0; @@ -225,7 +225,7 @@ int mtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs, return 0; } -int mtd_write(const struct mtd_dev_info *mtd, int fd, int eb, int offs, +int libmtd_write(const struct mtd_dev_info *mtd, int fd, int eb, int offs, void *buf, int len) { int ret; diff --git a/lib/libscan.c b/lib/libscan.c index af55269ec..c59acfa61 100644 --- a/lib/libscan.c +++ b/lib/libscan.c @@ -90,7 +90,7 @@ int libscan_ubi_scan(struct mtd_dev_info *mtd, int fd, struct ubi_scan_info **in continue; } - ret = mtd_read(mtd, fd, eb, 0, &ech, sizeof(struct ubi_ec_hdr)); + ret = libmtd_read(mtd, fd, eb, 0, &ech, sizeof(struct ubi_ec_hdr)); if (ret < 0) goto out_ec;