From 2ff5e1532dd37e1bd8ac72da3f7f0e2b310102fb Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Mon, 9 Jan 2012 16:58:25 -0500 Subject: mtd: pmc551: fix signedness bug in init_pmc551() Since "length" is a u32, the error handling below didn't work when fixup_pmc551() returns -ENODEV. if ((length = fixup_pmc551(PCI_Device)) <= 0) This patch changes both the type of "length" and the return type of fixup_pmc551() to int. Signed-off-by: Xi Wang Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/pmc551.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index ecff765579dd..cfccf6510411 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c @@ -359,7 +359,7 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len, * mechanism * returns the size of the memory region found. */ -static u32 fixup_pmc551(struct pci_dev *dev) +static int fixup_pmc551(struct pci_dev *dev) { #ifdef CONFIG_MTD_PMC551_BUGFIX u32 dram_data; @@ -669,7 +669,7 @@ static int __init init_pmc551(void) struct mypriv *priv; int found = 0; struct mtd_info *mtd; - u32 length = 0; + int length = 0; if (msize) { msize = (1 << (ffs(msize) - 1)) << 20; -- cgit v1.2.3 From f18dbbb1bfe06ea3995b55c2f533057da9e9294a Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Thu, 12 Jan 2012 14:38:57 +0100 Subject: mtd: ST SPEAr: Add SMI driver for serial NOR flash SPEAr platforms (spear3xx/spear6xx/spear13xx) provide SMI (Serial Memory Interface) controller to access serial NOR flash. SMI provides a simple interface for SPI/serial NOR flashes and has certain inbuilt commands and features to support these flashes easily. It also makes it possible to map an address range in order to directly access (read/write) the SNOR over address bus. This patch intends to provide serial nor driver support for spear platforms which are accessed through SMI. Signed-off-by: Shiraz Hashim Signed-off-by: Viresh Kumar Signed-off-by: Stefan Roese Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/Kconfig | 7 + drivers/mtd/devices/Makefile | 1 + drivers/mtd/devices/spear_smi.c | 1112 +++++++++++++++++++++++++++++++++++++++ include/linux/mtd/spear_smi.h | 60 +++ 4 files changed, 1180 insertions(+) create mode 100644 drivers/mtd/devices/spear_smi.c create mode 100644 include/linux/mtd/spear_smi.h (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index 37b05c3f2792..98206b034c01 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig @@ -102,6 +102,13 @@ config M25PXX_USE_FAST_READ help This option enables FAST_READ access supported by ST M25Pxx. +config MTD_SPEAR_SMI + tristate "SPEAR MTD NOR Support through SMI controller" + depends on PLAT_SPEAR + default y + help + This enable SNOR support on SPEAR platforms using SMI controller + config MTD_SST25L tristate "Support SST25L (non JEDEC) SPI Flash chips" depends on SPI_MASTER diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile index 56c7cd462f11..a4dd1d822b6c 100644 --- a/drivers/mtd/devices/Makefile +++ b/drivers/mtd/devices/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_MTD_LART) += lart.o obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o obj-$(CONFIG_MTD_M25P80) += m25p80.o +obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o obj-$(CONFIG_MTD_SST25L) += sst25l.o CFLAGS_docg3.o += -I$(src) \ No newline at end of file diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c new file mode 100644 index 000000000000..1eac56cf8ed6 --- /dev/null +++ b/drivers/mtd/devices/spear_smi.c @@ -0,0 +1,1112 @@ +/* + * SMI (Serial Memory Controller) device driver for Serial NOR Flash on + * SPEAr platform + * The serial nor interface is largely based on drivers/mtd/m25p80.c, + * however the SPI interface has been replaced by SMI. + * + * Copyright © 2010 STMicroelectronics. + * Ashish Priyadarshi + * Shiraz Hashim + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* max possible slots for serial-nor flash chip in the SMI controller */ +#define MAX_NUM_FLASH_CHIP 4 + +/* SMI clock rate */ +#define SMI_MAX_CLOCK_FREQ 50000000 /* 50 MHz */ + +/* MAX time out to safely come out of a erase or write busy conditions */ +#define SMI_PROBE_TIMEOUT (HZ / 10) +#define SMI_MAX_TIME_OUT (3 * HZ) + +/* timeout for command completion */ +#define SMI_CMD_TIMEOUT (HZ / 10) + +/* registers of smi */ +#define SMI_CR1 0x0 /* SMI control register 1 */ +#define SMI_CR2 0x4 /* SMI control register 2 */ +#define SMI_SR 0x8 /* SMI status register */ +#define SMI_TR 0xC /* SMI transmit register */ +#define SMI_RR 0x10 /* SMI receive register */ + +/* defines for control_reg 1 */ +#define BANK_EN (0xF << 0) /* enables all banks */ +#define DSEL_TIME (0x6 << 4) /* Deselect time 6 + 1 SMI_CK periods */ +#define SW_MODE (0x1 << 28) /* enables SW Mode */ +#define WB_MODE (0x1 << 29) /* Write Burst Mode */ +#define FAST_MODE (0x1 << 15) /* Fast Mode */ +#define HOLD1 (0x1 << 16) /* Clock Hold period selection */ + +/* defines for control_reg 2 */ +#define SEND (0x1 << 7) /* Send data */ +#define TFIE (0x1 << 8) /* Transmission Flag Interrupt Enable */ +#define WCIE (0x1 << 9) /* Write Complete Interrupt Enable */ +#define RD_STATUS_REG (0x1 << 10) /* reads status reg */ +#define WE (0x1 << 11) /* Write Enable */ + +#define TX_LEN_SHIFT 0 +#define RX_LEN_SHIFT 4 +#define BANK_SHIFT 12 + +/* defines for status register */ +#define SR_WIP 0x1 /* Write in progress */ +#define SR_WEL 0x2 /* Write enable latch */ +#define SR_BP0 0x4 /* Block protect 0 */ +#define SR_BP1 0x8 /* Block protect 1 */ +#define SR_BP2 0x10 /* Block protect 2 */ +#define SR_SRWD 0x80 /* SR write protect */ +#define TFF 0x100 /* Transfer Finished Flag */ +#define WCF 0x200 /* Transfer Finished Flag */ +#define ERF1 0x400 /* Forbidden Write Request */ +#define ERF2 0x800 /* Forbidden Access */ + +#define WM_SHIFT 12 + +/* flash opcodes */ +#define OPCODE_RDID 0x9f /* Read JEDEC ID */ + +/* Flash Device Ids maintenance section */ + +/* data structure to maintain flash ids from different vendors */ +struct flash_device { + char *name; + u8 erase_cmd; + u32 device_id; + u32 pagesize; + unsigned long sectorsize; + unsigned long size_in_bytes; +}; + +#define FLASH_ID(n, es, id, psize, ssize, size) \ +{ \ + .name = n, \ + .erase_cmd = es, \ + .device_id = id, \ + .pagesize = psize, \ + .sectorsize = ssize, \ + .size_in_bytes = size \ +} + +static struct flash_device flash_devices[] = { + FLASH_ID("st m25p16" , 0xd8, 0x00152020, 0x100, 0x10000, 0x200000), + FLASH_ID("st m25p32" , 0xd8, 0x00162020, 0x100, 0x10000, 0x400000), + FLASH_ID("st m25p64" , 0xd8, 0x00172020, 0x100, 0x10000, 0x800000), + FLASH_ID("st m25p128" , 0xd8, 0x00182020, 0x100, 0x40000, 0x1000000), + FLASH_ID("st m25p05" , 0xd8, 0x00102020, 0x80 , 0x8000 , 0x10000), + FLASH_ID("st m25p10" , 0xd8, 0x00112020, 0x80 , 0x8000 , 0x20000), + FLASH_ID("st m25p20" , 0xd8, 0x00122020, 0x100, 0x10000, 0x40000), + FLASH_ID("st m25p40" , 0xd8, 0x00132020, 0x100, 0x10000, 0x80000), + FLASH_ID("st m25p80" , 0xd8, 0x00142020, 0x100, 0x10000, 0x100000), + FLASH_ID("st m45pe10" , 0xd8, 0x00114020, 0x100, 0x10000, 0x20000), + FLASH_ID("st m45pe20" , 0xd8, 0x00124020, 0x100, 0x10000, 0x40000), + FLASH_ID("st m45pe40" , 0xd8, 0x00134020, 0x100, 0x10000, 0x80000), + FLASH_ID("st m45pe80" , 0xd8, 0x00144020, 0x100, 0x10000, 0x100000), + FLASH_ID("sp s25fl004" , 0xd8, 0x00120201, 0x100, 0x10000, 0x80000), + FLASH_ID("sp s25fl008" , 0xd8, 0x00130201, 0x100, 0x10000, 0x100000), + FLASH_ID("sp s25fl016" , 0xd8, 0x00140201, 0x100, 0x10000, 0x200000), + FLASH_ID("sp s25fl032" , 0xd8, 0x00150201, 0x100, 0x10000, 0x400000), + FLASH_ID("sp s25fl064" , 0xd8, 0x00160201, 0x100, 0x10000, 0x800000), + FLASH_ID("atmel 25f512" , 0x52, 0x0065001F, 0x80 , 0x8000 , 0x10000), + FLASH_ID("atmel 25f1024" , 0x52, 0x0060001F, 0x100, 0x8000 , 0x20000), + FLASH_ID("atmel 25f2048" , 0x52, 0x0063001F, 0x100, 0x10000, 0x40000), + FLASH_ID("atmel 25f4096" , 0x52, 0x0064001F, 0x100, 0x10000, 0x80000), + FLASH_ID("atmel 25fs040" , 0xd7, 0x0004661F, 0x100, 0x10000, 0x80000), + FLASH_ID("mac 25l512" , 0xd8, 0x001020C2, 0x010, 0x10000, 0x10000), + FLASH_ID("mac 25l1005" , 0xd8, 0x001120C2, 0x010, 0x10000, 0x20000), + FLASH_ID("mac 25l2005" , 0xd8, 0x001220C2, 0x010, 0x10000, 0x40000), + FLASH_ID("mac 25l4005" , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000), + FLASH_ID("mac 25l4005a" , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000), + FLASH_ID("mac 25l8005" , 0xd8, 0x001420C2, 0x010, 0x10000, 0x100000), + FLASH_ID("mac 25l1605" , 0xd8, 0x001520C2, 0x100, 0x10000, 0x200000), + FLASH_ID("mac 25l1605a" , 0xd8, 0x001520C2, 0x010, 0x10000, 0x200000), + FLASH_ID("mac 25l3205" , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000), + FLASH_ID("mac 25l3205a" , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000), + FLASH_ID("mac 25l6405" , 0xd8, 0x001720C2, 0x100, 0x10000, 0x800000), +}; + +/* These partitions would be used if platform doesn't pass one */ +static struct mtd_partition part_info_8M[] = { + DEFINE_PARTS("Xloader", 0x00, 0x10000), + DEFINE_PARTS("UBoot", MTDPART_OFS_APPEND, 0x40000), + DEFINE_PARTS("Kernel", MTDPART_OFS_APPEND, 0x2C0000), + DEFINE_PARTS("Root File System", MTDPART_OFS_APPEND, MTDPART_SIZ_FULL), +}; + +static struct mtd_partition part_info_16M[] = { + DEFINE_PARTS("Xloader", 0x00, 0x40000), + DEFINE_PARTS("UBoot", MTDPART_OFS_APPEND, 0x100000), + DEFINE_PARTS("Kernel", MTDPART_OFS_APPEND, 0x300000), + DEFINE_PARTS("Root File System", MTDPART_OFS_APPEND, MTDPART_SIZ_FULL), +}; + +/* Define spear specific structures */ + +struct spear_snor_flash; + +/** + * struct spear_smi - Structure for SMI Device + * + * @clk: functional clock + * @status: current status register of SMI. + * @clk_rate: functional clock rate of SMI (default: SMI_MAX_CLOCK_FREQ) + * @lock: lock to prevent parallel access of SMI. + * @io_base: base address for registers of SMI. + * @pdev: platform device + * @cmd_complete: queue to wait for command completion of NOR-flash. + * @num_flashes: number of flashes actually present on board. + * @flash: separate structure for each Serial NOR-flash attached to SMI. + */ +struct spear_smi { + struct clk *clk; + u32 status; + unsigned long clk_rate; + struct mutex lock; + void __iomem *io_base; + struct platform_device *pdev; + wait_queue_head_t cmd_complete; + u32 num_flashes; + struct spear_snor_flash *flash[MAX_NUM_FLASH_CHIP]; +}; + +/** + * struct spear_snor_flash - Structure for Serial NOR Flash + * + * @bank: Bank number(0, 1, 2, 3) for each NOR-flash. + * @dev_id: Device ID of NOR-flash. + * @lock: lock to manage flash read, write and erase operations + * @mtd: MTD info for each NOR-flash. + * @num_parts: Total number of partition in each bank of NOR-flash. + * @parts: Partition info for each bank of NOR-flash. + * @page_size: Page size of NOR-flash. + * @base_addr: Base address of NOR-flash. + * @erase_cmd: erase command may vary on different flash types + * @fast_mode: flash supports read in fast mode + */ +struct spear_snor_flash { + u32 bank; + u32 dev_id; + struct mutex lock; + struct mtd_info mtd; + u32 num_parts; + struct mtd_partition *parts; + u32 page_size; + void __iomem *base_addr; + u8 erase_cmd; + u8 fast_mode; +}; + +static inline struct spear_snor_flash *get_flash_data(struct mtd_info *mtd) +{ + return container_of(mtd, struct spear_snor_flash, mtd); +} + +/** + * spear_smi_read_sr - Read status register of flash through SMI + * @dev: structure of SMI information. + * @bank: bank to which flash is connected + * + * This routine will return the status register of the flash chip present at the + * given bank. + */ +static int spear_smi_read_sr(struct spear_smi *dev, u32 bank) +{ + int ret; + u32 ctrlreg1; + + mutex_lock(&dev->lock); + dev->status = 0; /* Will be set in interrupt handler */ + + ctrlreg1 = readl(dev->io_base + SMI_CR1); + /* program smi in hw mode */ + writel(ctrlreg1 & ~(SW_MODE | WB_MODE), dev->io_base + SMI_CR1); + + /* performing a rsr instruction in hw mode */ + writel((bank << BANK_SHIFT) | RD_STATUS_REG | TFIE, + dev->io_base + SMI_CR2); + + /* wait for tff */ + ret = wait_event_interruptible_timeout(dev->cmd_complete, + dev->status & TFF, SMI_CMD_TIMEOUT); + + /* copy dev->status (lower 16 bits) in order to release lock */ + if (ret > 0) + ret = dev->status & 0xffff; + else + ret = -EIO; + + /* restore the ctrl regs state */ + writel(ctrlreg1, dev->io_base + SMI_CR1); + writel(0, dev->io_base + SMI_CR2); + mutex_unlock(&dev->lock); + + return ret; +} + +/** + * spear_smi_wait_till_ready - wait till flash is ready + * @dev: structure of SMI information. + * @bank: flash corresponding to this bank + * @timeout: timeout for busy wait condition + * + * This routine checks for WIP (write in progress) bit in Status register + * If successful the routine returns 0 else -EBUSY + */ +static int spear_smi_wait_till_ready(struct spear_smi *dev, u32 bank, + unsigned long timeout) +{ + unsigned long finish; + int status; + + finish = jiffies + timeout; + do { + status = spear_smi_read_sr(dev, bank); + if (status < 0) + continue; /* try till timeout */ + else if (!(status & SR_WIP)) + return 0; + + cond_resched(); + } while (!time_after_eq(jiffies, finish)); + + dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n"); + return status; +} + +/** + * spear_smi_int_handler - SMI Interrupt Handler. + * @irq: irq number + * @dev_id: structure of SMI device, embedded in dev_id. + * + * The handler clears all interrupt conditions and records the status in + * dev->status which is used by the driver later. + */ +static irqreturn_t spear_smi_int_handler(int irq, void *dev_id) +{ + u32 status = 0; + struct spear_smi *dev = dev_id; + + status = readl(dev->io_base + SMI_SR); + + if (unlikely(!status)) + return IRQ_NONE; + + /* clear all interrupt conditions */ + writel(0, dev->io_base + SMI_SR); + + /* copy the status register in dev->status */ + dev->status |= status; + + /* send the completion */ + wake_up_interruptible(&dev->cmd_complete); + + return IRQ_HANDLED; +} + +/** + * spear_smi_hw_init - initializes the smi controller. + * @dev: structure of smi device + * + * this routine initializes the smi controller wit the default values + */ +static void spear_smi_hw_init(struct spear_smi *dev) +{ + unsigned long rate = 0; + u32 prescale = 0; + u32 val; + + rate = clk_get_rate(dev->clk); + + /* functional clock of smi */ + prescale = DIV_ROUND_UP(rate, dev->clk_rate); + + /* + * setting the standard values, fast mode, prescaler for + * SMI_MAX_CLOCK_FREQ (50MHz) operation and bank enable + */ + val = HOLD1 | BANK_EN | DSEL_TIME | (prescale << 8); + + mutex_lock(&dev->lock); + writel(val, dev->io_base + SMI_CR1); + mutex_unlock(&dev->lock); +} + +/** + * get_flash_index - match chip id from a flash list. + * @flash_id: a valid nor flash chip id obtained from board. + * + * try to validate the chip id by matching from a list, if not found then simply + * returns negative. In case of success returns index in to the flash devices + * array. + */ +static int get_flash_index(u32 flash_id) +{ + int index; + + /* Matches chip-id to entire list of 'serial-nor flash' ids */ + for (index = 0; index < ARRAY_SIZE(flash_devices); index++) { + if (flash_devices[index].device_id == flash_id) + return index; + } + + /* Memory chip is not listed and not supported */ + return -ENODEV; +} + +/** + * spear_smi_write_enable - Enable the flash to do write operation + * @dev: structure of SMI device + * @bank: enable write for flash connected to this bank + * + * Set write enable latch with Write Enable command. + * Returns 0 on success. + */ +static int spear_smi_write_enable(struct spear_smi *dev, u32 bank) +{ + int ret; + u32 ctrlreg1; + + mutex_lock(&dev->lock); + dev->status = 0; /* Will be set in interrupt handler */ + + ctrlreg1 = readl(dev->io_base + SMI_CR1); + /* program smi in h/w mode */ + writel(ctrlreg1 & ~SW_MODE, dev->io_base + SMI_CR1); + + /* give the flash, write enable command */ + writel((bank << BANK_SHIFT) | WE | TFIE, dev->io_base + SMI_CR2); + + ret = wait_event_interruptible_timeout(dev->cmd_complete, + dev->status & TFF, SMI_CMD_TIMEOUT); + + /* restore the ctrl regs state */ + writel(ctrlreg1, dev->io_base + SMI_CR1); + writel(0, dev->io_base + SMI_CR2); + + if (ret <= 0) { + ret = -EIO; + dev_err(&dev->pdev->dev, + "smi controller failed on write enable\n"); + } else { + /* check whether write mode status is set for required bank */ + if (dev->status & (1 << (bank + WM_SHIFT))) + ret = 0; + else { + dev_err(&dev->pdev->dev, "couldn't enable write\n"); + ret = -EIO; + } + } + + mutex_unlock(&dev->lock); + return ret; +} + +static inline u32 +get_sector_erase_cmd(struct spear_snor_flash *flash, u32 offset) +{ + u32 cmd; + u8 *x = (u8 *)&cmd; + + x[0] = flash->erase_cmd; + x[1] = offset >> 16; + x[2] = offset >> 8; + x[3] = offset; + + return cmd; +} + +/** + * spear_smi_erase_sector - erase one sector of flash + * @dev: structure of SMI information + * @command: erase command to be send + * @bank: bank to which this command needs to be send + * @bytes: size of command + * + * Erase one sector of flash memory at offset ``offset'' which is any + * address within the sector which should be erased. + * Returns 0 if successful, non-zero otherwise. + */ +static int spear_smi_erase_sector(struct spear_smi *dev, + u32 bank, u32 command, u32 bytes) +{ + u32 ctrlreg1 = 0; + int ret; + + ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT); + if (ret) + return ret; + + ret = spear_smi_write_enable(dev, bank); + if (ret) + return ret; + + mutex_lock(&dev->lock); + + ctrlreg1 = readl(dev->io_base + SMI_CR1); + writel((ctrlreg1 | SW_MODE) & ~WB_MODE, dev->io_base + SMI_CR1); + + /* send command in sw mode */ + writel(command, dev->io_base + SMI_TR); + + writel((bank << BANK_SHIFT) | SEND | TFIE | (bytes << TX_LEN_SHIFT), + dev->io_base + SMI_CR2); + + ret = wait_event_interruptible_timeout(dev->cmd_complete, + dev->status & TFF, SMI_CMD_TIMEOUT); + + if (ret <= 0) { + ret = -EIO; + dev_err(&dev->pdev->dev, "sector erase failed\n"); + } else + ret = 0; /* success */ + + /* restore ctrl regs */ + writel(ctrlreg1, dev->io_base + SMI_CR1); + writel(0, dev->io_base + SMI_CR2); + + mutex_unlock(&dev->lock); + return ret; +} + +/** + * spear_mtd_erase - perform flash erase operation as requested by user + * @mtd: Provides the memory characteristics + * @e_info: Provides the erase information + * + * Erase an address range on the flash chip. The address range may extend + * one or more erase sectors. Return an error is there is a problem erasing. + */ +static int spear_mtd_erase(struct mtd_info *mtd, struct erase_info *e_info) +{ + struct spear_snor_flash *flash = get_flash_data(mtd); + struct spear_smi *dev = mtd->priv; + u32 addr, command, bank; + int len, ret; + + if (!flash || !dev) + return -ENODEV; + + /* do not allow erase past end of device */ + if (e_info->addr + e_info->len > flash->mtd.size) + return -EINVAL; + + bank = flash->bank; + if (bank > dev->num_flashes - 1) { + dev_err(&dev->pdev->dev, "Invalid Bank Num"); + return -EINVAL; + } + + addr = e_info->addr; + len = e_info->len; + + mutex_lock(&flash->lock); + + /* now erase sectors in loop */ + while (len) { + command = get_sector_erase_cmd(flash, addr); + /* preparing the command for flash */ + ret = spear_smi_erase_sector(dev, bank, command, 4); + if (ret) { + e_info->state = MTD_ERASE_FAILED; + mutex_unlock(&flash->lock); + return ret; + } + addr += mtd->erasesize; + len -= mtd->erasesize; + } + + mutex_unlock(&flash->lock); + e_info->state = MTD_ERASE_DONE; + mtd_erase_callback(e_info); + + return 0; +} + +/** + * spear_mtd_read - performs flash read operation as requested by the user + * @mtd: MTD information of the memory bank + * @from: Address from which to start read + * @len: Number of bytes to be read + * @retlen: Fills the Number of bytes actually read + * @buf: Fills this after reading + * + * Read an address range from the flash chip. The address range + * may be any size provided it is within the physical boundaries. + * Returns 0 on success, non zero otherwise + */ +static int spear_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u8 *buf) +{ + struct spear_snor_flash *flash = get_flash_data(mtd); + struct spear_smi *dev = mtd->priv; + void *src; + u32 ctrlreg1, val; + int ret; + + if (!len) + return 0; + + if (!flash || !dev) + return -ENODEV; + + /* do not allow reads past end of device */ + if (from + len > flash->mtd.size) + return -EINVAL; + + if (flash->bank > dev->num_flashes - 1) { + dev_err(&dev->pdev->dev, "Invalid Bank Num"); + return -EINVAL; + } + + if (!retlen) + return -EINVAL; + else + *retlen = 0; + + /* select address as per bank number */ + src = flash->base_addr + from; + + mutex_lock(&flash->lock); + + /* wait till previous write/erase is done. */ + ret = spear_smi_wait_till_ready(dev, flash->bank, SMI_MAX_TIME_OUT); + if (ret) { + mutex_unlock(&flash->lock); + return ret; + } + + mutex_lock(&dev->lock); + /* put smi in hw mode not wbt mode */ + ctrlreg1 = val = readl(dev->io_base + SMI_CR1); + val &= ~(SW_MODE | WB_MODE); + if (flash->fast_mode) + val |= FAST_MODE; + + writel(val, dev->io_base + SMI_CR1); + + memcpy_fromio(buf, (u8 *)src, len); + + /* restore ctrl reg1 */ + writel(ctrlreg1, dev->io_base + SMI_CR1); + mutex_unlock(&dev->lock); + + *retlen = len; + mutex_unlock(&flash->lock); + + return 0; +} + +static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank, + void *dest, const void *src, size_t len) +{ + int ret; + u32 ctrlreg1; + + /* wait until finished previous write command. */ + ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT); + if (ret) + return ret; + + /* put smi in write enable */ + ret = spear_smi_write_enable(dev, bank); + if (ret) + return ret; + + /* put smi in hw, write burst mode */ + mutex_lock(&dev->lock); + + ctrlreg1 = readl(dev->io_base + SMI_CR1); + writel((ctrlreg1 | WB_MODE) & ~SW_MODE, dev->io_base + SMI_CR1); + + memcpy_toio(dest, src, len); + + writel(ctrlreg1, dev->io_base + SMI_CR1); + + mutex_unlock(&dev->lock); + return 0; +} + +/** + * spear_mtd_write - performs write operation as requested by the user. + * @mtd: MTD information of the memory bank. + * @to: Address to write. + * @len: Number of bytes to be written. + * @retlen: Number of bytes actually wrote. + * @buf: Buffer from which the data to be taken. + * + * Write an address range to the flash chip. Data must be written in + * flash_page_size chunks. The address range may be any size provided + * it is within the physical boundaries. + * Returns 0 on success, non zero otherwise + */ +static int spear_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u8 *buf) +{ + struct spear_snor_flash *flash = get_flash_data(mtd); + struct spear_smi *dev = mtd->priv; + void *dest; + u32 page_offset, page_size; + int ret; + + if (!flash || !dev) + return -ENODEV; + + if (!len) + return 0; + + /* do not allow write past end of page */ + if (to + len > flash->mtd.size) + return -EINVAL; + + if (flash->bank > dev->num_flashes - 1) { + dev_err(&dev->pdev->dev, "Invalid Bank Num"); + return -EINVAL; + } + + if (!retlen) + return -EINVAL; + else + *retlen = 0; + + /* select address as per bank number */ + dest = flash->base_addr + to; + mutex_lock(&flash->lock); + + page_offset = (u32)to % flash->page_size; + + /* do if all the bytes fit onto one page */ + if (page_offset + len <= flash->page_size) { + ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf, len); + if (!ret) + *retlen += len; + } else { + u32 i; + + /* the size of data remaining on the first page */ + page_size = flash->page_size - page_offset; + + ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf, + page_size); + if (ret) + goto err_write; + else + *retlen += page_size; + + /* write everything in pagesize chunks */ + for (i = page_size; i < len; i += page_size) { + page_size = len - i; + if (page_size > flash->page_size) + page_size = flash->page_size; + + ret = spear_smi_cpy_toio(dev, flash->bank, dest + i, + buf + i, page_size); + if (ret) + break; + else + *retlen += page_size; + } + } + +err_write: + mutex_unlock(&flash->lock); + + return ret; +} + +/** + * spear_smi_probe_flash - Detects the NOR Flash chip. + * @dev: structure of SMI information. + * @bank: bank on which flash must be probed + * + * This routine will check whether there exists a flash chip on a given memory + * bank ID. + * Return index of the probed flash in flash devices structure + */ +static int spear_smi_probe_flash(struct spear_smi *dev, u32 bank) +{ + int ret; + u32 val = 0; + + ret = spear_smi_wait_till_ready(dev, bank, SMI_PROBE_TIMEOUT); + if (ret) + return ret; + + mutex_lock(&dev->lock); + + dev->status = 0; /* Will be set in interrupt handler */ + /* put smi in sw mode */ + val = readl(dev->io_base + SMI_CR1); + writel(val | SW_MODE, dev->io_base + SMI_CR1); + + /* send readid command in sw mode */ + writel(OPCODE_RDID, dev->io_base + SMI_TR); + + val = (bank << BANK_SHIFT) | SEND | (1 << TX_LEN_SHIFT) | + (3 << RX_LEN_SHIFT) | TFIE; + writel(val, dev->io_base + SMI_CR2); + + /* wait for TFF */ + ret = wait_event_interruptible_timeout(dev->cmd_complete, + dev->status & TFF, SMI_CMD_TIMEOUT); + if (ret <= 0) { + ret = -ENODEV; + goto err_probe; + } + + /* get memory chip id */ + val = readl(dev->io_base + SMI_RR); + val &= 0x00ffffff; + ret = get_flash_index(val); + +err_probe: + /* clear sw mode */ + val = readl(dev->io_base + SMI_CR1); + writel(val & ~SW_MODE, dev->io_base + SMI_CR1); + + mutex_unlock(&dev->lock); + return ret; +} + +static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank) +{ + struct spear_smi *dev = platform_get_drvdata(pdev); + struct spear_smi_flash_info *flash_info; + struct spear_smi_plat_data *pdata; + struct spear_snor_flash *flash; + struct mtd_partition *parts; + int count; + int flash_index; + int ret = 0; + + pdata = dev_get_platdata(&pdev->dev); + if (bank > pdata->num_flashes - 1) + return -EINVAL; + + flash_info = &pdata->board_flash_info[bank]; + if (!flash_info) + return -ENODEV; + + flash = kzalloc(sizeof(*flash), GFP_ATOMIC); + if (!flash) + return -ENOMEM; + flash->bank = bank; + flash->fast_mode = flash_info->fast_mode ? 1 : 0; + mutex_init(&flash->lock); + + /* verify whether nor flash is really present on board */ + flash_index = spear_smi_probe_flash(dev, bank); + if (flash_index < 0) { + dev_info(&dev->pdev->dev, "smi-nor%d not found\n", bank); + ret = flash_index; + goto err_probe; + } + /* map the memory for nor flash chip */ + flash->base_addr = ioremap(flash_info->mem_base, flash_info->size); + if (!flash->base_addr) { + ret = -EIO; + goto err_probe; + } + + dev->flash[bank] = flash; + flash->mtd.priv = dev; + + if (flash_info->name) + flash->mtd.name = flash_info->name; + else + flash->mtd.name = flash_devices[flash_index].name; + + flash->mtd.type = MTD_NORFLASH; + flash->mtd.writesize = 1; + flash->mtd.flags = MTD_CAP_NORFLASH; + flash->mtd.size = flash_info->size; + flash->mtd.erasesize = flash_devices[flash_index].sectorsize; + flash->page_size = flash_devices[flash_index].pagesize; + flash->erase_cmd = flash_devices[flash_index].erase_cmd; + flash->mtd.erase = spear_mtd_erase; + flash->mtd.read = spear_mtd_read; + flash->mtd.write = spear_mtd_write; + flash->dev_id = flash_devices[flash_index].device_id; + + dev_info(&dev->pdev->dev, "mtd .name=%s .size=%llx(%lluM)\n", + flash->mtd.name, flash->mtd.size, + flash->mtd.size / (1024 * 1024)); + + dev_info(&dev->pdev->dev, ".erasesize = 0x%x(%uK)\n", + flash->mtd.erasesize, flash->mtd.erasesize / 1024); + + if (flash_info->partitions) { + parts = flash_info->partitions; + count = flash_info->nr_partitions; + } else { + /* choose from default ones */ + switch (flash->mtd.size) { + case 0x800000:/* 8MB */ + parts = part_info_8M; + count = ARRAY_SIZE(part_info_8M); + break; + case 0x1000000:/* 16MB */ + parts = part_info_16M; + count = ARRAY_SIZE(part_info_16M); + break; + default: + dev_err(&pdev->dev, "undefined partition\n"); + ret = ENODEV; + goto err_map; + } + } + ret = mtd_device_parse_register(&flash->mtd, NULL, 0, parts, count); + if (ret) + dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret); + + return ret; + +err_map: + iounmap(flash->base_addr); + +err_probe: + kfree(flash); + return ret; +} + +/** + * spear_smi_probe - Entry routine + * @pdev: platform device structure + * + * This is the first routine which gets invoked during booting and does all + * initialization/allocation work. The routine looks for available memory banks, + * and do proper init for any found one. + * Returns 0 on success, non zero otherwise + */ +static int __devinit spear_smi_probe(struct platform_device *pdev) +{ + struct spear_smi_plat_data *pdata; + struct spear_smi *dev; + struct resource *smi_base; + int irq, ret = 0; + int i; + + pdata = dev_get_platdata(&pdev->dev); + if (pdata < 0) { + ret = -ENODEV; + dev_err(&pdev->dev, "no platform data\n"); + goto err; + } + + smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!smi_base) { + ret = -ENODEV; + dev_err(&pdev->dev, "invalid smi base address\n"); + goto err; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + ret = -ENODEV; + dev_err(&pdev->dev, "invalid smi irq\n"); + goto err; + } + + dev = kzalloc(sizeof(*dev), GFP_ATOMIC); + if (!dev) { + ret = -ENOMEM; + dev_err(&pdev->dev, "mem alloc fail\n"); + goto err; + } + + smi_base = request_mem_region(smi_base->start, resource_size(smi_base), + pdev->name); + if (!smi_base) { + ret = -EBUSY; + dev_err(&pdev->dev, "request mem region fail\n"); + goto err_mem; + } + + dev->io_base = ioremap(smi_base->start, resource_size(smi_base)); + if (!dev->io_base) { + ret = -EIO; + dev_err(&pdev->dev, "ioremap fail\n"); + goto err_ioremap; + } + + dev->pdev = pdev; + dev->clk_rate = pdata->clk_rate; + + if (dev->clk_rate < 0 || dev->clk_rate > SMI_MAX_CLOCK_FREQ) + dev->clk_rate = SMI_MAX_CLOCK_FREQ; + + dev->num_flashes = pdata->num_flashes; + + if (dev->num_flashes > MAX_NUM_FLASH_CHIP) { + dev_err(&pdev->dev, "exceeding max number of flashes\n"); + dev->num_flashes = MAX_NUM_FLASH_CHIP; + } + + dev->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(dev->clk)) { + ret = PTR_ERR(dev->clk); + goto err_clk; + } + + ret = clk_enable(dev->clk); + if (ret) + goto err_clk_enable; + + ret = request_irq(irq, spear_smi_int_handler, 0, pdev->name, dev); + if (ret) { + dev_err(&dev->pdev->dev, "SMI IRQ allocation failed\n"); + goto err_irq; + } + + mutex_init(&dev->lock); + init_waitqueue_head(&dev->cmd_complete); + spear_smi_hw_init(dev); + platform_set_drvdata(pdev, dev); + + /* loop for each serial nor-flash which is connected to smi */ + for (i = 0; i < dev->num_flashes; i++) { + ret = spear_smi_setup_banks(pdev, i); + if (ret) { + dev_err(&dev->pdev->dev, "bank setup failed\n"); + goto err_bank_setup; + } + } + + return 0; + +err_bank_setup: + free_irq(irq, dev); + platform_set_drvdata(pdev, NULL); +err_irq: + clk_disable(dev->clk); +err_clk_enable: + clk_put(dev->clk); +err_clk: + iounmap(dev->io_base); +err_ioremap: + release_mem_region(smi_base->start, resource_size(smi_base)); +err_mem: + kfree(dev); +err: + return ret; +} + +/** + * spear_smi_remove - Exit routine + * @pdev: platform device structure + * + * free all allocations and delete the partitions. + */ +static int __devexit spear_smi_remove(struct platform_device *pdev) +{ + struct spear_smi *dev; + struct spear_snor_flash *flash; + int ret; + int i, irq; + + dev = platform_get_drvdata(pdev); + if (!dev) { + dev_err(&pdev->dev, "dev is null\n"); + return -ENODEV; + } + + /* clean up for all nor flash */ + for (i = 0; i < dev->num_flashes; i++) { + flash = dev->flash[i]; + if (!flash) + continue; + + /* clean up mtd stuff */ + ret = mtd_device_unregister(&flash->mtd); + if (ret) + dev_err(&pdev->dev, "error removing mtd\n"); + + iounmap(flash->base_addr); + kfree(flash); + } + + irq = platform_get_irq(pdev, 0); + free_irq(irq, dev); + + clk_disable(dev->clk); + clk_put(dev->clk); + iounmap(dev->io_base); + kfree(dev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +int spear_smi_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct spear_smi *dev = platform_get_drvdata(pdev); + + if (dev && dev->clk) + clk_disable(dev->clk); + + return 0; +} + +int spear_smi_resume(struct platform_device *pdev) +{ + struct spear_smi *dev = platform_get_drvdata(pdev); + int ret = -EPERM; + + if (dev && dev->clk) + ret = clk_enable(dev->clk); + + if (!ret) + spear_smi_hw_init(dev); + return ret; +} + +static struct platform_driver spear_smi_driver = { + .driver = { + .name = "smi", + .bus = &platform_bus_type, + .owner = THIS_MODULE, + }, + .probe = spear_smi_probe, + .remove = __devexit_p(spear_smi_remove), + .suspend = spear_smi_suspend, + .resume = spear_smi_resume, +}; + +static int spear_smi_init(void) +{ + return platform_driver_register(&spear_smi_driver); +} +module_init(spear_smi_init); + +static void spear_smi_exit(void) +{ + platform_driver_unregister(&spear_smi_driver); +} +module_exit(spear_smi_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim "); +MODULE_DESCRIPTION("MTD SMI driver for serial nor flash chips"); diff --git a/include/linux/mtd/spear_smi.h b/include/linux/mtd/spear_smi.h new file mode 100644 index 000000000000..4e26b4e38da3 --- /dev/null +++ b/include/linux/mtd/spear_smi.h @@ -0,0 +1,60 @@ +/* + * Copyright © 2010 ST Microelectronics + * Shiraz Hashim + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __MTD_SPEAR_SMI_H +#define __MTD_SPEAR_SMI_H + +#include +#include +#include +#include + +/* macro to define partitions for flash devices */ +#define DEFINE_PARTS(n, of, s) \ +{ \ + .name = n, \ + .offset = of, \ + .size = s, \ +} + +/** + * struct spear_smi_flash_info - platform structure for passing flash + * information + * + * name: name of the serial nor flash for identification + * mem_base: the memory base on which the flash is mapped + * size: size of the flash in bytes + * partitions: parition details + * nr_partitions: number of partitions + * fast_mode: whether flash supports fast mode + */ + +struct spear_smi_flash_info { + char *name; + unsigned long mem_base; + unsigned long size; + struct mtd_partition *partitions; + int nr_partitions; + u8 fast_mode; +}; + +/** + * struct spear_smi_plat_data - platform structure for configuring smi + * + * clk_rate: clk rate at which SMI must operate + * num_flashes: number of flashes present on board + * board_flash_info: specific details of each flash present on board + */ +struct spear_smi_plat_data { + unsigned long clk_rate; + int num_flashes; + struct spear_smi_flash_info *board_flash_info; +}; + +#endif /* __MTD_SPEAR_SMI_H */ -- cgit v1.2.3 From 495c47d799d93ad688db9db170200eb71525ff45 Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Fri, 20 Jan 2012 11:35:19 +0100 Subject: mtd: spear_smi: release memory region during remove Driver must cleanup all held resources during remove. It wasn't releasing requested memory region. Signed-off-by: Shiraz Hashim Signed-off-by: Stefan Roese Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/spear_smi.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index 1eac56cf8ed6..0f0f1ac06493 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -1024,6 +1024,7 @@ static int __devexit spear_smi_remove(struct platform_device *pdev) { struct spear_smi *dev; struct spear_snor_flash *flash; + struct resource *smi_base; int ret; int i, irq; @@ -1055,6 +1056,9 @@ static int __devexit spear_smi_remove(struct platform_device *pdev) clk_put(dev->clk); iounmap(dev->io_base); kfree(dev); + + smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(smi_base->start, resource_size(smi_base)); platform_set_drvdata(pdev, NULL); return 0; -- cgit v1.2.3 From c9d1b752937244d77d98bbd8e7f486bb715bec50 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 27 Jan 2012 15:45:20 +0800 Subject: mtd: convert drivers/mtd/* to use module_spi_driver() This patch converts the drivers in drivers/mtd/* to use the module_spi_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: Axel Lin Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/m25p80.c | 16 +--------------- drivers/mtd/devices/mtd_dataflash.c | 13 +------------ drivers/mtd/devices/sst25l.c | 13 +------------ 3 files changed, 3 insertions(+), 39 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 7c60dddbefc0..230b02e336ab 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -1004,21 +1004,7 @@ static struct spi_driver m25p80_driver = { */ }; - -static int __init m25p80_init(void) -{ - return spi_register_driver(&m25p80_driver); -} - - -static void __exit m25p80_exit(void) -{ - spi_unregister_driver(&m25p80_driver); -} - - -module_init(m25p80_init); -module_exit(m25p80_exit); +module_spi_driver(m25p80_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Mike Lavender"); diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 236057ead0d2..5ec5fc9fe045 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -946,18 +946,7 @@ static struct spi_driver dataflash_driver = { /* FIXME: investigate suspend and resume... */ }; -static int __init dataflash_init(void) -{ - return spi_register_driver(&dataflash_driver); -} -module_init(dataflash_init); - -static void __exit dataflash_exit(void) -{ - spi_unregister_driver(&dataflash_driver); -} -module_exit(dataflash_exit); - +module_spi_driver(dataflash_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Andrew Victor, David Brownell"); diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index 5fc198350b94..196fd95b19d6 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c @@ -450,18 +450,7 @@ static struct spi_driver sst25l_driver = { .remove = __devexit_p(sst25l_remove), }; -static int __init sst25l_init(void) -{ - return spi_register_driver(&sst25l_driver); -} - -static void __exit sst25l_exit(void) -{ - spi_unregister_driver(&sst25l_driver); -} - -module_init(sst25l_init); -module_exit(sst25l_exit); +module_spi_driver(sst25l_driver); MODULE_DESCRIPTION("MTD SPI driver for SST25L Flash chips"); MODULE_AUTHOR("Andre Renaud , " -- cgit v1.2.3 From 3c3c10bba1e4ccb75b41442e45c1a072f6cded19 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 30 Jan 2012 14:58:32 +0200 Subject: mtd: add leading underscore to all mtd functions This patch renames all MTD functions by adding a "_" prefix: mtd->erase -> mtd->_erase mtd->read_oob -> mtd->_read_oob ... The reason is that we are re-working the MTD API and from now on it is an error to use MTD function pointers directly - we have a corresponding API call for every pointer. By adding a leading "_" we achieve the following: 1. Make sure we convert every direct pointer users 2. A leading "_" suggests that this interface is internal and it becomes less likely that people will use them directly 3. Make sure all the out-of-tree modules stop compiling and the owners spot the big API change and amend them. Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0001.c | 40 ++++----- drivers/mtd/chips/cfi_cmdset_0002.c | 26 +++--- drivers/mtd/chips/cfi_cmdset_0020.c | 18 ++-- drivers/mtd/chips/fwh_lock.h | 4 +- drivers/mtd/chips/map_absent.c | 8 +- drivers/mtd/chips/map_ram.c | 10 +-- drivers/mtd/chips/map_rom.c | 10 +-- drivers/mtd/devices/block2mtd.c | 10 +-- drivers/mtd/devices/doc2000.c | 10 +-- drivers/mtd/devices/doc2001.c | 10 +-- drivers/mtd/devices/doc2001plus.c | 10 +-- drivers/mtd/devices/docg3.c | 12 +-- drivers/mtd/devices/lart.c | 6 +- drivers/mtd/devices/m25p80.c | 8 +- drivers/mtd/devices/ms02-nv.c | 4 +- drivers/mtd/devices/mtd_dataflash.c | 16 ++-- drivers/mtd/devices/mtdram.c | 12 +-- drivers/mtd/devices/phram.c | 10 +-- drivers/mtd/devices/pmc551.c | 10 +-- drivers/mtd/devices/slram.c | 10 +-- drivers/mtd/devices/spear_smi.c | 6 +- drivers/mtd/devices/sst25l.c | 6 +- drivers/mtd/inftlcore.c | 2 +- drivers/mtd/lpddr/lpddr_cmds.c | 16 ++-- drivers/mtd/maps/uclinux.c | 2 +- drivers/mtd/maps/vmu-flash.c | 6 +- drivers/mtd/mtdchar.c | 4 +- drivers/mtd/mtdconcat.c | 42 ++++----- drivers/mtd/mtdcore.c | 14 +-- drivers/mtd/mtdpart.c | 91 +++++++++---------- drivers/mtd/nand/alauda.c | 8 +- drivers/mtd/nand/nand_base.c | 30 +++---- drivers/mtd/onenand/onenand_base.c | 42 ++++----- drivers/mtd/ubi/gluebi.c | 10 +-- drivers/net/ethernet/sfc/mtd.c | 8 +- include/linux/mtd/mtd.h | 168 ++++++++++++++++++------------------ 36 files changed, 350 insertions(+), 349 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index e1e122f2f929..152accf4bf85 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -262,9 +262,9 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd) static void fixup_use_point(struct mtd_info *mtd) { struct map_info *map = mtd->priv; - if (!mtd->point && map_is_linear(map)) { - mtd->point = cfi_intelext_point; - mtd->unpoint = cfi_intelext_unpoint; + if (!mtd->_point && map_is_linear(map)) { + mtd->_point = cfi_intelext_point; + mtd->_unpoint = cfi_intelext_unpoint; } } @@ -274,8 +274,8 @@ static void fixup_use_write_buffers(struct mtd_info *mtd) struct cfi_private *cfi = map->fldrv_priv; if (cfi->cfiq->BufWriteTimeoutTyp) { printk(KERN_INFO "Using buffer write method\n" ); - mtd->write = cfi_intelext_write_buffers; - mtd->writev = cfi_intelext_writev; + mtd->_write = cfi_intelext_write_buffers; + mtd->_writev = cfi_intelext_writev; } } @@ -443,15 +443,15 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) mtd->type = MTD_NORFLASH; /* Fill in the default mtd operations */ - mtd->erase = cfi_intelext_erase_varsize; - mtd->read = cfi_intelext_read; - mtd->write = cfi_intelext_write_words; - mtd->sync = cfi_intelext_sync; - mtd->lock = cfi_intelext_lock; - mtd->unlock = cfi_intelext_unlock; - mtd->is_locked = cfi_intelext_is_locked; - mtd->suspend = cfi_intelext_suspend; - mtd->resume = cfi_intelext_resume; + mtd->_erase = cfi_intelext_erase_varsize; + mtd->_read = cfi_intelext_read; + mtd->_write = cfi_intelext_write_words; + mtd->_sync = cfi_intelext_sync; + mtd->_lock = cfi_intelext_lock; + mtd->_unlock = cfi_intelext_unlock; + mtd->_is_locked = cfi_intelext_is_locked; + mtd->_suspend = cfi_intelext_suspend; + mtd->_resume = cfi_intelext_resume; mtd->flags = MTD_CAP_NORFLASH; mtd->name = map->name; mtd->writesize = 1; @@ -600,12 +600,12 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) } #ifdef CONFIG_MTD_OTP - mtd->read_fact_prot_reg = cfi_intelext_read_fact_prot_reg; - mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg; - mtd->write_user_prot_reg = cfi_intelext_write_user_prot_reg; - mtd->lock_user_prot_reg = cfi_intelext_lock_user_prot_reg; - mtd->get_fact_prot_info = cfi_intelext_get_fact_prot_info; - mtd->get_user_prot_info = cfi_intelext_get_user_prot_info; + mtd->_read_fact_prot_reg = cfi_intelext_read_fact_prot_reg; + mtd->_read_user_prot_reg = cfi_intelext_read_user_prot_reg; + mtd->_write_user_prot_reg = cfi_intelext_write_user_prot_reg; + mtd->_lock_user_prot_reg = cfi_intelext_lock_user_prot_reg; + mtd->_get_fact_prot_info = cfi_intelext_get_fact_prot_info; + mtd->_get_user_prot_info = cfi_intelext_get_user_prot_info; #endif /* This function has the potential to distort the reality diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index e2d94bb1d7c8..27ac0622abe3 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -192,7 +192,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd) struct cfi_private *cfi = map->fldrv_priv; if (cfi->cfiq->BufWriteTimeoutTyp) { pr_debug("Using buffer write method\n" ); - mtd->write = cfi_amdstd_write_buffers; + mtd->_write = cfi_amdstd_write_buffers; } } @@ -231,8 +231,8 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd) static void fixup_use_secsi(struct mtd_info *mtd) { /* Setup for chips with a secsi area */ - mtd->read_user_prot_reg = cfi_amdstd_secsi_read; - mtd->read_fact_prot_reg = cfi_amdstd_secsi_read; + mtd->_read_user_prot_reg = cfi_amdstd_secsi_read; + mtd->_read_fact_prot_reg = cfi_amdstd_secsi_read; } static void fixup_use_erase_chip(struct mtd_info *mtd) @@ -241,7 +241,7 @@ static void fixup_use_erase_chip(struct mtd_info *mtd) struct cfi_private *cfi = map->fldrv_priv; if ((cfi->cfiq->NumEraseRegions == 1) && ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) { - mtd->erase = cfi_amdstd_erase_chip; + mtd->_erase = cfi_amdstd_erase_chip; } } @@ -252,8 +252,8 @@ static void fixup_use_erase_chip(struct mtd_info *mtd) */ static void fixup_use_atmel_lock(struct mtd_info *mtd) { - mtd->lock = cfi_atmel_lock; - mtd->unlock = cfi_atmel_unlock; + mtd->_lock = cfi_atmel_lock; + mtd->_unlock = cfi_atmel_unlock; mtd->flags |= MTD_POWERUP_LOCK; } @@ -432,12 +432,12 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) mtd->type = MTD_NORFLASH; /* Fill in the default mtd operations */ - mtd->erase = cfi_amdstd_erase_varsize; - mtd->write = cfi_amdstd_write_words; - mtd->read = cfi_amdstd_read; - mtd->sync = cfi_amdstd_sync; - mtd->suspend = cfi_amdstd_suspend; - mtd->resume = cfi_amdstd_resume; + mtd->_erase = cfi_amdstd_erase_varsize; + mtd->_write = cfi_amdstd_write_words; + mtd->_read = cfi_amdstd_read; + mtd->_sync = cfi_amdstd_sync; + mtd->_suspend = cfi_amdstd_suspend; + mtd->_resume = cfi_amdstd_resume; mtd->flags = MTD_CAP_NORFLASH; mtd->name = map->name; mtd->writesize = 1; @@ -446,7 +446,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) pr_debug("MTD %s(): write buffer size %d\n", __func__, mtd->writebufsize); - mtd->panic_write = cfi_amdstd_panic_write; + mtd->_panic_write = cfi_amdstd_panic_write; mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot; if (cfi->cfi_mode==CFI_MODE_CFI){ diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index 85e80180b65b..3861cca97bb0 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c @@ -228,15 +228,15 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map) } /* Also select the correct geometry setup too */ - mtd->erase = cfi_staa_erase_varsize; - mtd->read = cfi_staa_read; - mtd->write = cfi_staa_write_buffers; - mtd->writev = cfi_staa_writev; - mtd->sync = cfi_staa_sync; - mtd->lock = cfi_staa_lock; - mtd->unlock = cfi_staa_unlock; - mtd->suspend = cfi_staa_suspend; - mtd->resume = cfi_staa_resume; + mtd->_erase = cfi_staa_erase_varsize; + mtd->_read = cfi_staa_read; + mtd->_write = cfi_staa_write_buffers; + mtd->_writev = cfi_staa_writev; + mtd->_sync = cfi_staa_sync; + mtd->_lock = cfi_staa_lock; + mtd->_unlock = cfi_staa_unlock; + mtd->_suspend = cfi_staa_suspend; + mtd->_resume = cfi_staa_resume; mtd->flags = MTD_CAP_NORFLASH & ~MTD_BIT_WRITEABLE; mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */ mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; diff --git a/drivers/mtd/chips/fwh_lock.h b/drivers/mtd/chips/fwh_lock.h index 89c6595454a5..800b0e853e86 100644 --- a/drivers/mtd/chips/fwh_lock.h +++ b/drivers/mtd/chips/fwh_lock.h @@ -101,7 +101,7 @@ static void fixup_use_fwh_lock(struct mtd_info *mtd) { printk(KERN_NOTICE "using fwh lock/unlock method\n"); /* Setup for the chips with the fwh lock method */ - mtd->lock = fwh_lock_varsize; - mtd->unlock = fwh_unlock_varsize; + mtd->_lock = fwh_lock_varsize; + mtd->_unlock = fwh_unlock_varsize; } #endif /* FWH_LOCK_H */ diff --git a/drivers/mtd/chips/map_absent.c b/drivers/mtd/chips/map_absent.c index f2b872946871..6be2eddfea45 100644 --- a/drivers/mtd/chips/map_absent.c +++ b/drivers/mtd/chips/map_absent.c @@ -55,10 +55,10 @@ static struct mtd_info *map_absent_probe(struct map_info *map) mtd->name = map->name; mtd->type = MTD_ABSENT; mtd->size = map->size; - mtd->erase = map_absent_erase; - mtd->read = map_absent_read; - mtd->write = map_absent_write; - mtd->sync = map_absent_sync; + mtd->_erase = map_absent_erase; + mtd->_read = map_absent_read; + mtd->_write = map_absent_write; + mtd->_sync = map_absent_sync; mtd->flags = 0; mtd->erasesize = PAGE_SIZE; mtd->writesize = 1; diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c index 67640ccb2d41..225307088dc0 100644 --- a/drivers/mtd/chips/map_ram.c +++ b/drivers/mtd/chips/map_ram.c @@ -64,11 +64,11 @@ static struct mtd_info *map_ram_probe(struct map_info *map) mtd->name = map->name; mtd->type = MTD_RAM; mtd->size = map->size; - mtd->erase = mapram_erase; - mtd->get_unmapped_area = mapram_unmapped_area; - mtd->read = mapram_read; - mtd->write = mapram_write; - mtd->sync = mapram_nop; + mtd->_erase = mapram_erase; + mtd->_get_unmapped_area = mapram_unmapped_area; + mtd->_read = mapram_read; + mtd->_write = mapram_write; + mtd->_sync = mapram_nop; mtd->flags = MTD_CAP_RAM; mtd->writesize = 1; diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c index 593f73d480d2..facb56092d39 100644 --- a/drivers/mtd/chips/map_rom.c +++ b/drivers/mtd/chips/map_rom.c @@ -41,11 +41,11 @@ static struct mtd_info *map_rom_probe(struct map_info *map) mtd->name = map->name; mtd->type = MTD_ROM; mtd->size = map->size; - mtd->get_unmapped_area = maprom_unmapped_area; - mtd->read = maprom_read; - mtd->write = maprom_write; - mtd->sync = maprom_nop; - mtd->erase = maprom_erase; + mtd->_get_unmapped_area = maprom_unmapped_area; + mtd->_read = maprom_read; + mtd->_write = maprom_write; + mtd->_sync = maprom_nop; + mtd->_erase = maprom_erase; mtd->flags = MTD_CAP_ROM; mtd->erasesize = map->size; mtd->writesize = 1; diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index e7e46d1e7463..d9e75dafdd45 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -285,11 +285,11 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) dev->mtd.writesize = 1; dev->mtd.type = MTD_RAM; dev->mtd.flags = MTD_CAP_RAM; - dev->mtd.erase = block2mtd_erase; - dev->mtd.write = block2mtd_write; - dev->mtd.writev = mtd_writev; - dev->mtd.sync = block2mtd_sync; - dev->mtd.read = block2mtd_read; + dev->mtd._erase = block2mtd_erase; + dev->mtd._write = block2mtd_write; + dev->mtd._writev = mtd_writev; + dev->mtd._sync = block2mtd_sync; + dev->mtd._read = block2mtd_read; dev->mtd.priv = dev; dev->mtd.owner = THIS_MODULE; diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index b1cdf6479019..ffd01a66a175 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c @@ -565,11 +565,11 @@ void DoC2k_init(struct mtd_info *mtd) mtd->writesize = 512; mtd->oobsize = 16; mtd->owner = THIS_MODULE; - mtd->erase = doc_erase; - mtd->read = doc_read; - mtd->write = doc_write; - mtd->read_oob = doc_read_oob; - mtd->write_oob = doc_write_oob; + mtd->_erase = doc_erase; + mtd->_read = doc_read; + mtd->_write = doc_write; + mtd->_read_oob = doc_read_oob; + mtd->_write_oob = doc_write_oob; this->curfloor = -1; this->curchip = -1; mutex_init(&this->lock); diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index 7543b98f46c4..3785733650cb 100644 --- a/drivers/mtd/devices/doc2001.c +++ b/drivers/mtd/devices/doc2001.c @@ -349,11 +349,11 @@ void DoCMil_init(struct mtd_info *mtd) mtd->writesize = 512; mtd->oobsize = 16; mtd->owner = THIS_MODULE; - mtd->erase = doc_erase; - mtd->read = doc_read; - mtd->write = doc_write; - mtd->read_oob = doc_read_oob; - mtd->write_oob = doc_write_oob; + mtd->_erase = doc_erase; + mtd->_read = doc_read; + mtd->_write = doc_write; + mtd->_read_oob = doc_read_oob; + mtd->_write_oob = doc_write_oob; this->curfloor = -1; this->curchip = -1; diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c index 177510d0e7ee..409fa3174cc4 100644 --- a/drivers/mtd/devices/doc2001plus.c +++ b/drivers/mtd/devices/doc2001plus.c @@ -470,11 +470,11 @@ void DoCMilPlus_init(struct mtd_info *mtd) mtd->writesize = 512; mtd->oobsize = 16; mtd->owner = THIS_MODULE; - mtd->erase = doc_erase; - mtd->read = doc_read; - mtd->write = doc_write; - mtd->read_oob = doc_read_oob; - mtd->write_oob = doc_write_oob; + mtd->_erase = doc_erase; + mtd->_read = doc_read; + mtd->_write = doc_write; + mtd->_read_oob = doc_read_oob; + mtd->_write_oob = doc_write_oob; this->curfloor = -1; this->curchip = -1; diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index ad11ef0a81f4..3746ae8ff0a2 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1820,12 +1820,12 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd) mtd->writesize = DOC_LAYOUT_PAGE_SIZE; mtd->oobsize = DOC_LAYOUT_OOB_SIZE; mtd->owner = THIS_MODULE; - mtd->erase = doc_erase; - mtd->read = doc_read; - mtd->write = doc_write; - mtd->read_oob = doc_read_oob; - mtd->write_oob = doc_write_oob; - mtd->block_isbad = doc_block_isbad; + mtd->_erase = doc_erase; + mtd->_read = doc_read; + mtd->_write = doc_write; + mtd->_read_oob = doc_read_oob; + mtd->_write_oob = doc_write_oob; + mtd->_block_isbad = doc_block_isbad; mtd->ecclayout = &docg3_oobinfo; } diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index 3a11ea628e58..a59584871af5 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -635,9 +635,9 @@ static int __init lart_flash_init (void) mtd.erasesize = FLASH_BLOCKSIZE_MAIN; mtd.numeraseregions = ARRAY_SIZE(erase_regions); mtd.eraseregions = erase_regions; - mtd.erase = flash_erase; - mtd.read = flash_read; - mtd.write = flash_write; + mtd._erase = flash_erase; + mtd._read = flash_read; + mtd._write = flash_write; mtd.owner = THIS_MODULE; #ifdef LART_DEBUG diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 230b02e336ab..f83e4d0366cc 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -908,14 +908,14 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.writesize = 1; flash->mtd.flags = MTD_CAP_NORFLASH; flash->mtd.size = info->sector_size * info->n_sectors; - flash->mtd.erase = m25p80_erase; - flash->mtd.read = m25p80_read; + flash->mtd._erase = m25p80_erase; + flash->mtd._read = m25p80_read; /* sst flash chips use AAI word program */ if (JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) - flash->mtd.write = sst_write; + flash->mtd._write = sst_write; else - flash->mtd.write = m25p80_write; + flash->mtd._write = m25p80_write; /* prefer "small sector" erase if possible */ if (info->flags & SECT_4K) { diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c index 8423fb6d4f26..3a05af529e7d 100644 --- a/drivers/mtd/devices/ms02-nv.c +++ b/drivers/mtd/devices/ms02-nv.c @@ -215,8 +215,8 @@ static int __init ms02nv_init_one(ulong addr) mtd->size = fixsize; mtd->name = (char *)ms02nv_name; mtd->owner = THIS_MODULE; - mtd->read = ms02nv_read; - mtd->write = ms02nv_write; + mtd->_read = ms02nv_read; + mtd->_write = ms02nv_write; mtd->writesize = 1; ret = -EIO; diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 5ec5fc9fe045..fd4a9fc0d8b8 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -611,16 +611,16 @@ static int dataflash_write_user_otp(struct mtd_info *mtd, static char *otp_setup(struct mtd_info *device, char revision) { - device->get_fact_prot_info = dataflash_get_otp_info; - device->read_fact_prot_reg = dataflash_read_fact_otp; - device->get_user_prot_info = dataflash_get_otp_info; - device->read_user_prot_reg = dataflash_read_user_otp; + device->_get_fact_prot_info = dataflash_get_otp_info; + device->_read_fact_prot_reg = dataflash_read_fact_otp; + device->_get_user_prot_info = dataflash_get_otp_info; + device->_read_user_prot_reg = dataflash_read_user_otp; /* rev c parts (at45db321c and at45db1281 only!) use a * different write procedure; not (yet?) implemented. */ if (revision > 'c') - device->write_user_prot_reg = dataflash_write_user_otp; + device->_write_user_prot_reg = dataflash_write_user_otp; return ", OTP"; } @@ -672,9 +672,9 @@ add_dataflash_otp(struct spi_device *spi, char *name, device->owner = THIS_MODULE; device->type = MTD_DATAFLASH; device->flags = MTD_WRITEABLE; - device->erase = dataflash_erase; - device->read = dataflash_read; - device->write = dataflash_write; + device->_erase = dataflash_erase; + device->_read = dataflash_read; + device->_write = dataflash_write; device->priv = priv; device->dev.parent = &spi->dev; diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c index 2562689ba6b4..91030cfb03b3 100644 --- a/drivers/mtd/devices/mtdram.c +++ b/drivers/mtd/devices/mtdram.c @@ -126,12 +126,12 @@ int mtdram_init_device(struct mtd_info *mtd, void *mapped_address, mtd->priv = mapped_address; mtd->owner = THIS_MODULE; - mtd->erase = ram_erase; - mtd->point = ram_point; - mtd->unpoint = ram_unpoint; - mtd->get_unmapped_area = ram_get_unmapped_area; - mtd->read = ram_read; - mtd->write = ram_write; + mtd->_erase = ram_erase; + mtd->_point = ram_point; + mtd->_unpoint = ram_unpoint; + mtd->_get_unmapped_area = ram_get_unmapped_area; + mtd->_read = ram_read; + mtd->_write = ram_write; if (mtd_device_register(mtd, NULL, 0)) return -EIO; diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 23423bd00b06..eff2b69864f5 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -142,11 +142,11 @@ static int register_device(char *name, unsigned long start, unsigned long len) new->mtd.name = name; new->mtd.size = len; new->mtd.flags = MTD_CAP_RAM; - new->mtd.erase = phram_erase; - new->mtd.point = phram_point; - new->mtd.unpoint = phram_unpoint; - new->mtd.read = phram_read; - new->mtd.write = phram_write; + new->mtd._erase = phram_erase; + new->mtd._point = phram_point; + new->mtd._unpoint = phram_unpoint; + new->mtd._read = phram_read; + new->mtd._write = phram_write; new->mtd.owner = THIS_MODULE; new->mtd.type = MTD_RAM; new->mtd.erasesize = PAGE_SIZE; diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index cfccf6510411..67d22e1cbc0e 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c @@ -787,11 +787,11 @@ static int __init init_pmc551(void) mtd->size = msize; mtd->flags = MTD_CAP_RAM; - mtd->erase = pmc551_erase; - mtd->read = pmc551_read; - mtd->write = pmc551_write; - mtd->point = pmc551_point; - mtd->unpoint = pmc551_unpoint; + mtd->_erase = pmc551_erase; + mtd->_read = pmc551_read; + mtd->_write = pmc551_write; + mtd->_point = pmc551_point; + mtd->_unpoint = pmc551_unpoint; mtd->type = MTD_RAM; mtd->name = "PMC551 RAM board"; mtd->erasesize = 0x10000; diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index e585263161b9..cbeb19522bbc 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c @@ -200,11 +200,11 @@ static int register_device(char *name, unsigned long start, unsigned long length (*curmtd)->mtdinfo->name = name; (*curmtd)->mtdinfo->size = length; (*curmtd)->mtdinfo->flags = MTD_CAP_RAM; - (*curmtd)->mtdinfo->erase = slram_erase; - (*curmtd)->mtdinfo->point = slram_point; - (*curmtd)->mtdinfo->unpoint = slram_unpoint; - (*curmtd)->mtdinfo->read = slram_read; - (*curmtd)->mtdinfo->write = slram_write; + (*curmtd)->mtdinfo->_erase = slram_erase; + (*curmtd)->mtdinfo->_point = slram_point; + (*curmtd)->mtdinfo->_unpoint = slram_unpoint; + (*curmtd)->mtdinfo->_read = slram_read; + (*curmtd)->mtdinfo->_write = slram_write; (*curmtd)->mtdinfo->owner = THIS_MODULE; (*curmtd)->mtdinfo->type = MTD_RAM; (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ; diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index 0f0f1ac06493..5f4254254641 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -846,9 +846,9 @@ static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank) flash->mtd.erasesize = flash_devices[flash_index].sectorsize; flash->page_size = flash_devices[flash_index].pagesize; flash->erase_cmd = flash_devices[flash_index].erase_cmd; - flash->mtd.erase = spear_mtd_erase; - flash->mtd.read = spear_mtd_read; - flash->mtd.write = spear_mtd_write; + flash->mtd._erase = spear_mtd_erase; + flash->mtd._read = spear_mtd_read; + flash->mtd._write = spear_mtd_write; flash->dev_id = flash_devices[flash_index].device_id; dev_info(&dev->pdev->dev, "mtd .name=%s .size=%llx(%lluM)\n", diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index 196fd95b19d6..a665eba96e7f 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c @@ -403,9 +403,9 @@ static int __devinit sst25l_probe(struct spi_device *spi) flash->mtd.erasesize = flash_info->erase_size; flash->mtd.writesize = flash_info->page_size; flash->mtd.size = flash_info->page_size * flash_info->nr_pages; - flash->mtd.erase = sst25l_erase; - flash->mtd.read = sst25l_read; - flash->mtd.write = sst25l_write; + flash->mtd._erase = sst25l_erase; + flash->mtd._read = sst25l_read; + flash->mtd._write = sst25l_write; dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name, (long long)flash->mtd.size >> 10); diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c index 28646c95cfb8..3af351484098 100644 --- a/drivers/mtd/inftlcore.c +++ b/drivers/mtd/inftlcore.c @@ -56,7 +56,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) if (memcmp(mtd->name, "DiskOnChip", 10)) return; - if (!mtd->block_isbad) { + if (!mtd->_block_isbad) { printk(KERN_ERR "INFTL no longer supports the old DiskOnChip drivers loaded via docprobe.\n" "Please use the new diskonchip driver under the NAND subsystem.\n"); diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index 536bbceaeaad..fd19d3b1ee90 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c @@ -63,18 +63,18 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) mtd->type = MTD_NORFLASH; /* Fill in the default mtd operations */ - mtd->read = lpddr_read; + mtd->_read = lpddr_read; mtd->type = MTD_NORFLASH; mtd->flags = MTD_CAP_NORFLASH; mtd->flags &= ~MTD_BIT_WRITEABLE; - mtd->erase = lpddr_erase; - mtd->write = lpddr_write_buffers; - mtd->writev = lpddr_writev; - mtd->lock = lpddr_lock; - mtd->unlock = lpddr_unlock; + mtd->_erase = lpddr_erase; + mtd->_write = lpddr_write_buffers; + mtd->_writev = lpddr_writev; + mtd->_lock = lpddr_lock; + mtd->_unlock = lpddr_unlock; if (map_is_linear(map)) { - mtd->point = lpddr_point; - mtd->unpoint = lpddr_unpoint; + mtd->_point = lpddr_point; + mtd->_unpoint = lpddr_unpoint; } mtd->size = 1 << lpddr->qinfo->DevSizeShift; mtd->erasesize = 1 << lpddr->qinfo->UniformBlockSizeShift; diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c index 6793074f3f40..cfff454f628b 100644 --- a/drivers/mtd/maps/uclinux.c +++ b/drivers/mtd/maps/uclinux.c @@ -85,7 +85,7 @@ static int __init uclinux_mtd_init(void) } mtd->owner = THIS_MODULE; - mtd->point = uclinux_point; + mtd->_point = uclinux_point; mtd->priv = mapp; uclinux_ram_mtdinfo = mtd; diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c index 3a04b078576a..48a803e2cd2e 100644 --- a/drivers/mtd/maps/vmu-flash.c +++ b/drivers/mtd/maps/vmu-flash.c @@ -544,9 +544,9 @@ static void vmu_queryblocks(struct mapleq *mq) mtd_cur->flags = MTD_WRITEABLE|MTD_NO_ERASE; mtd_cur->size = part_cur->numblocks * card->blocklen; mtd_cur->erasesize = card->blocklen; - mtd_cur->write = vmu_flash_write; - mtd_cur->read = vmu_flash_read; - mtd_cur->sync = vmu_flash_sync; + mtd_cur->_write = vmu_flash_write; + mtd_cur->_read = vmu_flash_read; + mtd_cur->_sync = vmu_flash_sync; mtd_cur->writesize = card->blocklen; mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL); diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 50c6a1e7f675..426640eaf818 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -405,7 +405,7 @@ static int mtdchar_writeoob(struct file *file, struct mtd_info *mtd, if (length > 4096) return -EINVAL; - if (!mtd->write_oob) + if (!mtd->_write_oob) ret = -EOPNOTSUPP; else ret = access_ok(VERIFY_READ, ptr, length) ? 0 : -EFAULT; @@ -576,7 +576,7 @@ static int mtdchar_write_ioctl(struct mtd_info *mtd, !access_ok(VERIFY_READ, req.usr_data, req.len) || !access_ok(VERIFY_READ, req.usr_oob, req.ooblen)) return -EFAULT; - if (!mtd->write_oob) + if (!mtd->_write_oob) return -EOPNOTSUPP; ops.mode = req.mode; diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index 1ed5103b219b..5c7eb69c4ed9 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c @@ -777,16 +777,16 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->mtd.subpage_sft = subdev[0]->subpage_sft; concat->mtd.oobsize = subdev[0]->oobsize; concat->mtd.oobavail = subdev[0]->oobavail; - if (subdev[0]->writev) - concat->mtd.writev = concat_writev; - if (subdev[0]->read_oob) - concat->mtd.read_oob = concat_read_oob; - if (subdev[0]->write_oob) - concat->mtd.write_oob = concat_write_oob; - if (subdev[0]->block_isbad) - concat->mtd.block_isbad = concat_block_isbad; - if (subdev[0]->block_markbad) - concat->mtd.block_markbad = concat_block_markbad; + if (subdev[0]->_writev) + concat->mtd._writev = concat_writev; + if (subdev[0]->_read_oob) + concat->mtd._read_oob = concat_read_oob; + if (subdev[0]->_write_oob) + concat->mtd._write_oob = concat_write_oob; + if (subdev[0]->_block_isbad) + concat->mtd._block_isbad = concat_block_isbad; + if (subdev[0]->_block_markbad) + concat->mtd._block_markbad = concat_block_markbad; concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks; @@ -833,8 +833,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c if (concat->mtd.writesize != subdev[i]->writesize || concat->mtd.subpage_sft != subdev[i]->subpage_sft || concat->mtd.oobsize != subdev[i]->oobsize || - !concat->mtd.read_oob != !subdev[i]->read_oob || - !concat->mtd.write_oob != !subdev[i]->write_oob) { + !concat->mtd._read_oob != !subdev[i]->_read_oob || + !concat->mtd._write_oob != !subdev[i]->_write_oob) { kfree(concat); printk("Incompatible OOB or ECC data on \"%s\"\n", subdev[i]->name); @@ -849,15 +849,15 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->num_subdev = num_devs; concat->mtd.name = name; - concat->mtd.erase = concat_erase; - concat->mtd.read = concat_read; - concat->mtd.write = concat_write; - concat->mtd.sync = concat_sync; - concat->mtd.lock = concat_lock; - concat->mtd.unlock = concat_unlock; - concat->mtd.suspend = concat_suspend; - concat->mtd.resume = concat_resume; - concat->mtd.get_unmapped_area = concat_get_unmapped_area; + concat->mtd._erase = concat_erase; + concat->mtd._read = concat_read; + concat->mtd._write = concat_write; + concat->mtd._sync = concat_sync; + concat->mtd._lock = concat_lock; + concat->mtd._unlock = concat_unlock; + concat->mtd._suspend = concat_suspend; + concat->mtd._resume = concat_resume; + concat->mtd._get_unmapped_area = concat_get_unmapped_area; /* * Combine the erase block size info of the subdevices: diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index de96865b4f96..aafe0ee9c9f3 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -126,7 +126,7 @@ static int mtd_cls_resume(struct device *dev) { struct mtd_info *mtd = dev_get_drvdata(dev); - if (mtd && mtd->resume) + if (mtd && mtd->_resume) mtd_resume(mtd); return 0; } @@ -610,8 +610,8 @@ int __get_mtd_device(struct mtd_info *mtd) if (!try_module_get(mtd->owner)) return -ENODEV; - if (mtd->get_device) { - err = mtd->get_device(mtd); + if (mtd->_get_device) { + err = mtd->_get_device(mtd); if (err) { module_put(mtd->owner); @@ -675,8 +675,8 @@ void __put_mtd_device(struct mtd_info *mtd) --mtd->usecount; BUG_ON(mtd->usecount < 0); - if (mtd->put_device) - mtd->put_device(mtd); + if (mtd->_put_device) + mtd->_put_device(mtd); module_put(mtd->owner); } @@ -729,9 +729,9 @@ int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { *retlen = 0; - if (!mtd->writev) + if (!mtd->_writev) return default_mtd_writev(mtd, vecs, count, to, retlen); - return mtd->writev(mtd, vecs, count, to, retlen); + return mtd->_writev(mtd, vecs, count, to, retlen); } EXPORT_SYMBOL_GPL(mtd_writev); diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 47d00f0bb36d..4f01079e357f 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -262,7 +262,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr) void mtd_erase_callback(struct erase_info *instr) { - if (instr->mtd->erase == part_erase) { + if (instr->mtd->_erase == part_erase) { struct mtd_part *part = PART(instr->mtd); if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) @@ -410,54 +410,55 @@ static struct mtd_part *allocate_partition(struct mtd_info *master, */ slave->mtd.dev.parent = master->dev.parent; - slave->mtd.read = part_read; - slave->mtd.write = part_write; + slave->mtd._read = part_read; + slave->mtd._write = part_write; - if (master->panic_write) - slave->mtd.panic_write = part_panic_write; + if (master->_panic_write) + slave->mtd._panic_write = part_panic_write; - if (master->point && master->unpoint) { - slave->mtd.point = part_point; - slave->mtd.unpoint = part_unpoint; + if (master->_point && master->_unpoint) { + slave->mtd._point = part_point; + slave->mtd._unpoint = part_unpoint; } - if (master->get_unmapped_area) - slave->mtd.get_unmapped_area = part_get_unmapped_area; - if (master->read_oob) - slave->mtd.read_oob = part_read_oob; - if (master->write_oob) - slave->mtd.write_oob = part_write_oob; - if (master->read_user_prot_reg) - slave->mtd.read_user_prot_reg = part_read_user_prot_reg; - if (master->read_fact_prot_reg) - slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; - if (master->write_user_prot_reg) - slave->mtd.write_user_prot_reg = part_write_user_prot_reg; - if (master->lock_user_prot_reg) - slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; - if (master->get_user_prot_info) - slave->mtd.get_user_prot_info = part_get_user_prot_info; - if (master->get_fact_prot_info) - slave->mtd.get_fact_prot_info = part_get_fact_prot_info; - if (master->sync) - slave->mtd.sync = part_sync; - if (!partno && !master->dev.class && master->suspend && master->resume) { - slave->mtd.suspend = part_suspend; - slave->mtd.resume = part_resume; + if (master->_get_unmapped_area) + slave->mtd._get_unmapped_area = part_get_unmapped_area; + if (master->_read_oob) + slave->mtd._read_oob = part_read_oob; + if (master->_write_oob) + slave->mtd._write_oob = part_write_oob; + if (master->_read_user_prot_reg) + slave->mtd._read_user_prot_reg = part_read_user_prot_reg; + if (master->_read_fact_prot_reg) + slave->mtd._read_fact_prot_reg = part_read_fact_prot_reg; + if (master->_write_user_prot_reg) + slave->mtd._write_user_prot_reg = part_write_user_prot_reg; + if (master->_lock_user_prot_reg) + slave->mtd._lock_user_prot_reg = part_lock_user_prot_reg; + if (master->_get_user_prot_info) + slave->mtd._get_user_prot_info = part_get_user_prot_info; + if (master->_get_fact_prot_info) + slave->mtd._get_fact_prot_info = part_get_fact_prot_info; + if (master->_sync) + slave->mtd._sync = part_sync; + if (!partno && !master->dev.class && master->_suspend && + master->_resume) { + slave->mtd._suspend = part_suspend; + slave->mtd._resume = part_resume; } - if (master->writev) - slave->mtd.writev = part_writev; - if (master->lock) - slave->mtd.lock = part_lock; - if (master->unlock) - slave->mtd.unlock = part_unlock; - if (master->is_locked) - slave->mtd.is_locked = part_is_locked; - if (master->block_isbad) - slave->mtd.block_isbad = part_block_isbad; - if (master->block_markbad) - slave->mtd.block_markbad = part_block_markbad; - slave->mtd.erase = part_erase; + if (master->_writev) + slave->mtd._writev = part_writev; + if (master->_lock) + slave->mtd._lock = part_lock; + if (master->_unlock) + slave->mtd._unlock = part_unlock; + if (master->_is_locked) + slave->mtd._is_locked = part_is_locked; + if (master->_block_isbad) + slave->mtd._block_isbad = part_block_isbad; + if (master->_block_markbad) + slave->mtd._block_markbad = part_block_markbad; + slave->mtd._erase = part_erase; slave->master = master; slave->offset = part->offset; @@ -549,7 +550,7 @@ static struct mtd_part *allocate_partition(struct mtd_info *master, } slave->mtd.ecclayout = master->ecclayout; - if (master->block_isbad) { + if (master->_block_isbad) { uint64_t offs = 0; while (offs < slave->mtd.size) { diff --git a/drivers/mtd/nand/alauda.c b/drivers/mtd/nand/alauda.c index 6a5ff64a139e..ac38f73fde3b 100644 --- a/drivers/mtd/nand/alauda.c +++ b/drivers/mtd/nand/alauda.c @@ -585,10 +585,10 @@ static int alauda_init_media(struct alauda *al) mtd->writesize = 1<pageshift; mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; - mtd->read = alauda_read; - mtd->write = alauda_write; - mtd->erase = alauda_erase; - mtd->block_isbad = alauda_isbad; + mtd->_read = alauda_read; + mtd->_write = alauda_write; + mtd->_erase = alauda_erase; + mtd->_block_isbad = alauda_isbad; mtd->priv = al; mtd->owner = THIS_MODULE; diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index b90206613108..05f8243ed1d3 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3483,21 +3483,21 @@ int nand_scan_tail(struct mtd_info *mtd) mtd->type = MTD_NANDFLASH; mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM : MTD_CAP_NANDFLASH; - mtd->erase = nand_erase; - mtd->point = NULL; - mtd->unpoint = NULL; - mtd->read = nand_read; - mtd->write = nand_write; - mtd->panic_write = panic_nand_write; - mtd->read_oob = nand_read_oob; - mtd->write_oob = nand_write_oob; - mtd->sync = nand_sync; - mtd->lock = NULL; - mtd->unlock = NULL; - mtd->suspend = nand_suspend; - mtd->resume = nand_resume; - mtd->block_isbad = nand_block_isbad; - mtd->block_markbad = nand_block_markbad; + mtd->_erase = nand_erase; + mtd->_point = NULL; + mtd->_unpoint = NULL; + mtd->_read = nand_read; + mtd->_write = nand_write; + mtd->_panic_write = panic_nand_write; + mtd->_read_oob = nand_read_oob; + mtd->_write_oob = nand_write_oob; + mtd->_sync = nand_sync; + mtd->_lock = NULL; + mtd->_unlock = NULL; + mtd->_suspend = nand_suspend; + mtd->_resume = nand_resume; + mtd->_block_isbad = nand_block_isbad; + mtd->_block_markbad = nand_block_markbad; mtd->writebufsize = mtd->writesize; /* propagate ecc.layout to mtd_info */ diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index a061bc163da2..914c49bdf2b6 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -4107,29 +4107,29 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) /* Fill in remaining MTD driver data */ mtd->type = ONENAND_IS_MLC(this) ? MTD_MLCNANDFLASH : MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; - mtd->erase = onenand_erase; - mtd->point = NULL; - mtd->unpoint = NULL; - mtd->read = onenand_read; - mtd->write = onenand_write; - mtd->read_oob = onenand_read_oob; - mtd->write_oob = onenand_write_oob; - mtd->panic_write = onenand_panic_write; + mtd->_erase = onenand_erase; + mtd->_point = NULL; + mtd->_unpoint = NULL; + mtd->_read = onenand_read; + mtd->_write = onenand_write; + mtd->_read_oob = onenand_read_oob; + mtd->_write_oob = onenand_write_oob; + mtd->_panic_write = onenand_panic_write; #ifdef CONFIG_MTD_ONENAND_OTP - mtd->get_fact_prot_info = onenand_get_fact_prot_info; - mtd->read_fact_prot_reg = onenand_read_fact_prot_reg; - mtd->get_user_prot_info = onenand_get_user_prot_info; - mtd->read_user_prot_reg = onenand_read_user_prot_reg; - mtd->write_user_prot_reg = onenand_write_user_prot_reg; - mtd->lock_user_prot_reg = onenand_lock_user_prot_reg; + mtd->_get_fact_prot_info = onenand_get_fact_prot_info; + mtd->_read_fact_prot_reg = onenand_read_fact_prot_reg; + mtd->_get_user_prot_info = onenand_get_user_prot_info; + mtd->_read_user_prot_reg = onenand_read_user_prot_reg; + mtd->_write_user_prot_reg = onenand_write_user_prot_reg; + mtd->_lock_user_prot_reg = onenand_lock_user_prot_reg; #endif - mtd->sync = onenand_sync; - mtd->lock = onenand_lock; - mtd->unlock = onenand_unlock; - mtd->suspend = onenand_suspend; - mtd->resume = onenand_resume; - mtd->block_isbad = onenand_block_isbad; - mtd->block_markbad = onenand_block_markbad; + mtd->_sync = onenand_sync; + mtd->_lock = onenand_lock; + mtd->_unlock = onenand_unlock; + mtd->_suspend = onenand_suspend; + mtd->_resume = onenand_resume; + mtd->_block_isbad = onenand_block_isbad; + mtd->_block_markbad = onenand_block_markbad; mtd->owner = THIS_MODULE; mtd->writebufsize = mtd->writesize; diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index 941bc3c05d6e..0101dce90c45 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c @@ -340,11 +340,11 @@ static int gluebi_create(struct ubi_device_info *di, mtd->owner = THIS_MODULE; mtd->writesize = di->min_io_size; mtd->erasesize = vi->usable_leb_size; - mtd->read = gluebi_read; - mtd->write = gluebi_write; - mtd->erase = gluebi_erase; - mtd->get_device = gluebi_get_device; - mtd->put_device = gluebi_put_device; + mtd->_read = gluebi_read; + mtd->_write = gluebi_write; + mtd->_erase = gluebi_erase; + mtd->_get_device = gluebi_get_device; + mtd->_put_device = gluebi_put_device; /* * In case of dynamic a volume, MTD device size is just volume size. In diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c index bc9dcd6b30d7..6622eca09cbe 100644 --- a/drivers/net/ethernet/sfc/mtd.c +++ b/drivers/net/ethernet/sfc/mtd.c @@ -263,10 +263,10 @@ static int efx_mtd_probe_device(struct efx_nic *efx, struct efx_mtd *efx_mtd) part->mtd.owner = THIS_MODULE; part->mtd.priv = efx_mtd; part->mtd.name = part->name; - part->mtd.erase = efx_mtd_erase; - part->mtd.read = efx_mtd->ops->read; - part->mtd.write = efx_mtd->ops->write; - part->mtd.sync = efx_mtd_sync; + part->mtd._erase = efx_mtd_erase; + part->mtd._read = efx_mtd->ops->read; + part->mtd._write = efx_mtd->ops->write; + part->mtd._sync = efx_mtd_sync; if (mtd_device_register(&part->mtd, NULL, 0)) goto fail; diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index d43dc25af82e..e2e545616b2a 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -174,52 +174,52 @@ struct mtd_info { * Do not call via these pointers, use corresponding mtd_*() * wrappers instead. */ - int (*erase) (struct mtd_info *mtd, struct erase_info *instr); - int (*point) (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys); - void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len); - unsigned long (*get_unmapped_area) (struct mtd_info *mtd, - unsigned long len, - unsigned long offset, - unsigned long flags); - int (*read) (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf); - int (*write) (struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf); - int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf); - int (*read_oob) (struct mtd_info *mtd, loff_t from, - struct mtd_oob_ops *ops); - int (*write_oob) (struct mtd_info *mtd, loff_t to, + int (*_erase) (struct mtd_info *mtd, struct erase_info *instr); + int (*_point) (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, void **virt, resource_size_t *phys); + void (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len); + unsigned long (*_get_unmapped_area) (struct mtd_info *mtd, + unsigned long len, + unsigned long offset, + unsigned long flags); + int (*_read) (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf); + int (*_write) (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf); + int (*_panic_write) (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf); + int (*_read_oob) (struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops); - int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, - size_t len); - int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, - size_t len, size_t *retlen, u_char *buf); - int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, - size_t len); - int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, - size_t len, size_t *retlen, u_char *buf); - int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, u_char *buf); - int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, - size_t len); - int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, + int (*_write_oob) (struct mtd_info *mtd, loff_t to, + struct mtd_oob_ops *ops); + int (*_get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, + size_t len); + int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, + size_t len, size_t *retlen, u_char *buf); + int (*_get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, + size_t len); + int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from, + size_t len, size_t *retlen, u_char *buf); + int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to, + size_t len, size_t *retlen, u_char *buf); + int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, + size_t len); + int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); - void (*sync) (struct mtd_info *mtd); - int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); - int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); - int (*is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len); - int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); - int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); - int (*suspend) (struct mtd_info *mtd); - void (*resume) (struct mtd_info *mtd); + void (*_sync) (struct mtd_info *mtd); + int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); + int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); + int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len); + int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs); + int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs); + int (*_suspend) (struct mtd_info *mtd); + void (*_resume) (struct mtd_info *mtd); /* * If the driver is something smart, like UBI, it may need to maintain * its own reference counting. The below functions are only for driver. */ - int (*get_device) (struct mtd_info *mtd); - void (*put_device) (struct mtd_info *mtd); + int (*_get_device) (struct mtd_info *mtd); + void (*_put_device) (struct mtd_info *mtd); /* Backing device capabilities for this device * - provides mmap capabilities @@ -249,7 +249,7 @@ struct mtd_info { */ static inline int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) { - return mtd->erase(mtd, instr); + return mtd->_erase(mtd, instr); } /* @@ -259,15 +259,15 @@ static inline int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys) { *retlen = 0; - if (!mtd->point) + if (!mtd->_point) return -EOPNOTSUPP; - return mtd->point(mtd, from, len, retlen, virt, phys); + return mtd->_point(mtd, from, len, retlen, virt, phys); } /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ static inline void mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { - return mtd->unpoint(mtd, from, len); + return mtd->_unpoint(mtd, from, len); } /* @@ -280,24 +280,24 @@ static inline unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long offset, unsigned long flags) { - if (!mtd->get_unmapped_area) + if (!mtd->_get_unmapped_area) return -EOPNOTSUPP; - return mtd->get_unmapped_area(mtd, len, offset, flags); + return mtd->_get_unmapped_area(mtd, len, offset, flags); } static inline 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); + return mtd->_read(mtd, from, len, retlen, buf); } static inline int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { *retlen = 0; - if (!mtd->write) + if (!mtd->_write) return -EROFS; - return mtd->write(mtd, to, len, retlen, buf); + return mtd->_write(mtd, to, len, retlen, buf); } /* @@ -311,27 +311,27 @@ static inline int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { *retlen = 0; - if (!mtd->panic_write) + if (!mtd->_panic_write) return -EOPNOTSUPP; - return mtd->panic_write(mtd, to, len, retlen, buf); + return mtd->_panic_write(mtd, to, len, retlen, buf); } static inline int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { ops->retlen = ops->oobretlen = 0; - if (!mtd->read_oob) + if (!mtd->_read_oob) return -EOPNOTSUPP; - return mtd->read_oob(mtd, from, ops); + return mtd->_read_oob(mtd, from, ops); } static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) { ops->retlen = ops->oobretlen = 0; - if (!mtd->write_oob) + if (!mtd->_write_oob) return -EOPNOTSUPP; - return mtd->write_oob(mtd, to, ops); + return mtd->_write_oob(mtd, to, ops); } /* @@ -342,9 +342,9 @@ static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to, static inline int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf, size_t len) { - if (!mtd->get_fact_prot_info) + if (!mtd->_get_fact_prot_info) return -EOPNOTSUPP; - return mtd->get_fact_prot_info(mtd, buf, len); + return mtd->_get_fact_prot_info(mtd, buf, len); } static inline int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, @@ -352,18 +352,18 @@ static inline int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, u_char *buf) { *retlen = 0; - if (!mtd->read_fact_prot_reg) + if (!mtd->_read_fact_prot_reg) return -EOPNOTSUPP; - return mtd->read_fact_prot_reg(mtd, from, len, retlen, buf); + return mtd->_read_fact_prot_reg(mtd, from, len, retlen, buf); } static inline int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf, size_t len) { - if (!mtd->get_user_prot_info) + if (!mtd->_get_user_prot_info) return -EOPNOTSUPP; - return mtd->get_user_prot_info(mtd, buf, len); + return mtd->_get_user_prot_info(mtd, buf, len); } static inline int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, @@ -371,9 +371,9 @@ static inline int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, u_char *buf) { *retlen = 0; - if (!mtd->read_user_prot_reg) + if (!mtd->_read_user_prot_reg) return -EOPNOTSUPP; - return mtd->read_user_prot_reg(mtd, from, len, retlen, buf); + return mtd->_read_user_prot_reg(mtd, from, len, retlen, buf); } static inline int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, @@ -381,17 +381,17 @@ static inline int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, u_char *buf) { *retlen = 0; - if (!mtd->write_user_prot_reg) + if (!mtd->_write_user_prot_reg) return -EOPNOTSUPP; - return mtd->write_user_prot_reg(mtd, to, len, retlen, buf); + return mtd->_write_user_prot_reg(mtd, to, len, retlen, buf); } static inline int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len) { - if (!mtd->lock_user_prot_reg) + if (!mtd->_lock_user_prot_reg) return -EOPNOTSUPP; - return mtd->lock_user_prot_reg(mtd, from, len); + return mtd->_lock_user_prot_reg(mtd, from, len); } int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, @@ -399,55 +399,55 @@ int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, static inline void mtd_sync(struct mtd_info *mtd) { - if (mtd->sync) - mtd->sync(mtd); + if (mtd->_sync) + mtd->_sync(mtd); } /* Chip-supported device locking */ static inline int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { - if (!mtd->lock) + if (!mtd->_lock) return -EOPNOTSUPP; - return mtd->lock(mtd, ofs, len); + return mtd->_lock(mtd, ofs, len); } static inline int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { - if (!mtd->unlock) + if (!mtd->_unlock) return -EOPNOTSUPP; - return mtd->unlock(mtd, ofs, len); + return mtd->_unlock(mtd, ofs, len); } static inline int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) { - if (!mtd->is_locked) + if (!mtd->_is_locked) return -EOPNOTSUPP; - return mtd->is_locked(mtd, ofs, len); + return mtd->_is_locked(mtd, ofs, len); } static inline int mtd_suspend(struct mtd_info *mtd) { - return mtd->suspend ? mtd->suspend(mtd) : 0; + return mtd->_suspend ? mtd->_suspend(mtd) : 0; } static inline void mtd_resume(struct mtd_info *mtd) { - if (mtd->resume) - mtd->resume(mtd); + if (mtd->_resume) + mtd->_resume(mtd); } static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) { - if (!mtd->block_isbad) + if (!mtd->_block_isbad) return 0; - return mtd->block_isbad(mtd, ofs); + return mtd->_block_isbad(mtd, ofs); } static inline int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs) { - if (!mtd->block_markbad) + if (!mtd->_block_markbad) return -EOPNOTSUPP; - return mtd->block_markbad(mtd, ofs); + return mtd->_block_markbad(mtd, ofs); } static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd) @@ -482,12 +482,12 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd) static inline int mtd_has_oob(const struct mtd_info *mtd) { - return mtd->read_oob && mtd->write_oob; + return mtd->_read_oob && mtd->_write_oob; } static inline int mtd_can_have_bb(const struct mtd_info *mtd) { - return !!mtd->block_isbad; + return !!mtd->_block_isbad; } /* Kernel-side ioctl definitions */ -- cgit v1.2.3 From b54f47c8bcfc5f766bf13ec31bd7dd1d4726d33b Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 31 Jan 2012 00:06:03 -0800 Subject: mtd: m25p80: set writebufsize Using UBI on m25p80 can give messages like: UBI error: io_init: bad write buffer size 0 for 1 min. I/O unit We need to initialize writebufsize; I think "page_size" is the correct "bufsize", although I'm not sure. Comments? Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/m25p80.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index f83e4d0366cc..8808da9ee31f 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -932,6 +932,7 @@ static int __devinit m25p_probe(struct spi_device *spi) ppdata.of_node = spi->dev.of_node; flash->mtd.dev.parent = &spi->dev; flash->page_size = info->page_size; + flash->mtd.writebufsize = flash->page_size; if (info->addr_width) flash->addr_width = info->addr_width; -- cgit v1.2.3 From b604387411ec6a072e95910099262616edd2bd2f Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 09:32:44 +0200 Subject: mtd: block2mtd: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. However, we forgot to set this parameter for block2mtd. Set it to PAGE_SIZE because this is actually the amount of data we write at a time. Signed-off-by: Artem Bityutskiy Acked-by: Joern Engel Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/block2mtd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index d9e75dafdd45..0fccf149f5aa 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -283,6 +283,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; dev->mtd.erasesize = erase_size; dev->mtd.writesize = 1; + dev->mtd.writebufsize = PAGE_SIZE; dev->mtd.type = MTD_RAM; dev->mtd.flags = MTD_CAP_RAM; dev->mtd._erase = block2mtd_erase; -- cgit v1.2.3 From cd1986a3c111f7ed597619705290fa52a975014f Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 09:38:43 +0200 Subject: mtd: doc2000: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. Set it to be equivalent to mtd->writesize because this is the maximum amount of data the driver writes at a time. Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/doc2000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index ffd01a66a175..115d890e9919 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c @@ -562,7 +562,7 @@ void DoC2k_init(struct mtd_info *mtd) mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; - mtd->writesize = 512; + mtd->writebufsize = mtd->writesize = 512; mtd->oobsize = 16; mtd->owner = THIS_MODULE; mtd->_erase = doc_erase; -- cgit v1.2.3 From cca84b569ebe3372b28949e00b0a3a17f87e2970 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 09:42:39 +0200 Subject: mtd: doc2001: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. Set it to be equivalent to mtd->writesize because this is the maximum amount of data the driver writes at a time. Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/doc2001.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index 3785733650cb..b1185f938711 100644 --- a/drivers/mtd/devices/doc2001.c +++ b/drivers/mtd/devices/doc2001.c @@ -346,7 +346,7 @@ void DoCMil_init(struct mtd_info *mtd) /* FIXME: erase size is not always 8KiB */ mtd->erasesize = 0x2000; - mtd->writesize = 512; + mtd->writebufsize = mtd->writesize = 512; mtd->oobsize = 16; mtd->owner = THIS_MODULE; mtd->_erase = doc_erase; -- cgit v1.2.3 From 71f60fbebf0f18dd4e855335a009efda251b1697 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 09:43:14 +0200 Subject: mtd: doc2001plus: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. Set it to be equivalent to mtd->writesize because this is the maximum amount of data the driver writes at a time. Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/doc2001plus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c index 409fa3174cc4..c9fbadd3303e 100644 --- a/drivers/mtd/devices/doc2001plus.c +++ b/drivers/mtd/devices/doc2001plus.c @@ -467,7 +467,7 @@ void DoCMilPlus_init(struct mtd_info *mtd) mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; - mtd->writesize = 512; + mtd->writebufsize = mtd->writesize = 512; mtd->oobsize = 16; mtd->owner = THIS_MODULE; mtd->_erase = doc_erase; -- cgit v1.2.3 From 82c4c58d6f1a78e8de875272a19ab9220b8066aa Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 09:44:32 +0200 Subject: mtd: docg3: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. Set it to be equivalent to mtd->writesize because this is the maximum amount of data the driver writes at a time. Signed-off-by: Artem Bityutskiy Acked-by: Robert Jarzmik Cc: stable@kernel.org [3.2+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/docg3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 3746ae8ff0a2..fc7932b33da4 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1817,7 +1817,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd) mtd->erasesize = DOC_LAYOUT_BLOCK_SIZE * DOC_LAYOUT_NBPLANES; if (docg3->reliable == 2) mtd->erasesize /= 2; - mtd->writesize = DOC_LAYOUT_PAGE_SIZE; + mtd->writebufsize = mtd->writesize = DOC_LAYOUT_PAGE_SIZE; mtd->oobsize = DOC_LAYOUT_OOB_SIZE; mtd->owner = THIS_MODULE; mtd->_erase = doc_erase; -- cgit v1.2.3 From fcc44a07dae0af16e84e93425fc8afe642ddc603 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 09:53:28 +0200 Subject: mtd: lart: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. Set writebufsize to 4 because this drivers writes at max 4 bytes at a time. Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/lart.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index a59584871af5..6d6502c2ec35 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -630,6 +630,7 @@ static int __init lart_flash_init (void) mtd.name = module_name; mtd.type = MTD_NORFLASH; mtd.writesize = 1; + mtd.writebufsize = 4; mtd.flags = MTD_CAP_NORFLASH; mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; mtd.erasesize = FLASH_BLOCKSIZE_MAIN; -- cgit v1.2.3 From 81fefdf2efa599df9e8b362bb04d5fe5a83bc353 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 10:14:12 +0200 Subject: mtd: spear_smi: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. Set writebufsize to the flash page size because it is the maximum amount of data it writes at a time. Signed-off-by: Artem Bityutskiy Acked-by: Stefan Roese Signed-off-by: David Woodhouse --- drivers/mtd/devices/spear_smi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index 5f4254254641..b80cb5b5ebbd 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -845,6 +845,7 @@ static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank) flash->mtd.size = flash_info->size; flash->mtd.erasesize = flash_devices[flash_index].sectorsize; flash->page_size = flash_devices[flash_index].pagesize; + flash->mtd.writebufsize = flash->page_size; flash->erase_cmd = flash_devices[flash_index].erase_cmd; flash->mtd._erase = spear_mtd_erase; flash->mtd._read = spear_mtd_read; -- cgit v1.2.3 From c4cc625ea5958d065c21cc0fcea29e9ed8f3d2bc Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 10:16:50 +0200 Subject: mtd: sst25l: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. Set writebufsize to the flash page size because it is the maximum amount of data it writes at a time. Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/sst25l.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index a665eba96e7f..8b9ffafcc401 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c @@ -402,6 +402,7 @@ static int __devinit sst25l_probe(struct spi_device *spi) flash->mtd.flags = MTD_CAP_NORFLASH; flash->mtd.erasesize = flash_info->erase_size; flash->mtd.writesize = flash_info->page_size; + flash->mtd.writebufsize = flash_info->page_size; flash->mtd.size = flash_info->page_size * flash_info->nr_pages; flash->mtd._erase = sst25l_erase; flash->mtd._read = sst25l_read; -- cgit v1.2.3 From 5e4e6e3fdf48c1b012e2b6e80ed1d7e99d4fa6d1 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 13:20:43 +0200 Subject: mtd: return error code from mtd_unpoint The 'mtd_unpoint()' API function should be able to return an error code because it may fail if you specify incorrect offset. This patch changes this MTD API function and amends all the drivers correspondingly. Also return '-EOPNOTSUPP' from 'mtd_unpoint()' when the '->unpoint()' method is undefined. We do not really need this currently, but this just makes sense to be consistent with 'mtd_point()'. Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0001.c | 16 ++++++++++------ drivers/mtd/devices/mtdram.c | 3 ++- drivers/mtd/devices/phram.c | 3 ++- drivers/mtd/devices/pmc551.c | 3 ++- drivers/mtd/devices/slram.c | 5 +++-- drivers/mtd/lpddr/lpddr_cmds.c | 12 ++++++++---- drivers/mtd/mtdpart.c | 4 ++-- include/linux/mtd/mtd.h | 6 ++++-- include/linux/mtd/pmc551.h | 1 - 9 files changed, 33 insertions(+), 20 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 152accf4bf85..4d04551cffd7 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -87,7 +87,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *, struct cfi_private ** static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys); -static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len); +static int cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len); static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode); static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode); @@ -1369,12 +1369,12 @@ static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len, return 0; } -static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static int cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; unsigned long ofs; - int chipnum; + int chipnum, err = 0; /* Now unlock the chip(s) POINT state */ @@ -1382,7 +1382,7 @@ static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) chipnum = (from >> cfi->chipshift); ofs = from - (chipnum << cfi->chipshift); - while (len) { + while (len && !err) { unsigned long thislen; struct flchip *chip; @@ -1400,8 +1400,10 @@ static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) chip->ref_point_counter--; if(chip->ref_point_counter == 0) chip->state = FL_READY; - } else - printk(KERN_ERR "%s: Warning: unpoint called on non pointed region\n", map->name); /* Should this give an error? */ + } else { + printk(KERN_ERR "%s: Error: unpoint called on non pointed region\n", map->name); + err = -EINVAL; + } put_chip(map, chip, chip->start); mutex_unlock(&chip->mutex); @@ -1410,6 +1412,8 @@ static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) ofs = 0; chipnum++; } + + return err; } static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c index 91030cfb03b3..e1f017bf0777 100644 --- a/drivers/mtd/devices/mtdram.c +++ b/drivers/mtd/devices/mtdram.c @@ -60,8 +60,9 @@ static int ram_point(struct mtd_info *mtd, loff_t from, size_t len, return 0; } -static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static int ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { + return 0; } /* diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index eff2b69864f5..38035551a7d2 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -70,8 +70,9 @@ static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, return 0; } -static void phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static int phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { + return 0; } static int phram_read(struct mtd_info *mtd, loff_t from, size_t len, diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index 67d22e1cbc0e..933127ecebe5 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c @@ -206,11 +206,12 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, return 0; } -static void pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static int pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { #ifdef CONFIG_MTD_PMC551_DEBUG printk(KERN_DEBUG "pmc551_unpoint()\n"); #endif + return 0; } static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len, diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index cbeb19522bbc..9431ffc761c2 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c @@ -76,7 +76,7 @@ static slram_mtd_list_t *slram_mtdlist = NULL; static int slram_erase(struct mtd_info *, struct erase_info *); static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, void **, resource_size_t *); -static void slram_unpoint(struct mtd_info *, loff_t, size_t); +static int slram_unpoint(struct mtd_info *, loff_t, size_t); static int slram_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int slram_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); @@ -119,8 +119,9 @@ static int slram_point(struct mtd_info *mtd, loff_t from, size_t len, return(0); } -static void slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static int slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { + return 0; } static int slram_read(struct mtd_info *mtd, loff_t from, size_t len, diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index fd19d3b1ee90..de960b1d395a 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c @@ -40,7 +40,7 @@ static int lpddr_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); static int lpddr_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, size_t *retlen, void **mtdbuf, resource_size_t *phys); -static void lpddr_unpoint(struct mtd_info *mtd, loff_t adr, size_t len); +static int lpddr_unpoint(struct mtd_info *mtd, loff_t adr, size_t len); static int get_chip(struct map_info *map, struct flchip *chip, int mode); static int chip_ready(struct map_info *map, struct flchip *chip, int mode); static void put_chip(struct map_info *map, struct flchip *chip); @@ -575,11 +575,11 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, return 0; } -static void lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) +static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) { struct map_info *map = mtd->priv; struct lpddr_private *lpddr = map->fldrv_priv; - int chipnum = adr >> lpddr->chipshift; + int chipnum = adr >> lpddr->chipshift, err = 0; unsigned long ofs; /* ofs: offset within the first chip that the first read should start */ @@ -603,9 +603,11 @@ static void lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) chip->ref_point_counter--; if (chip->ref_point_counter == 0) chip->state = FL_READY; - } else + } else { printk(KERN_WARNING "%s: Warning: unpoint called on non" "pointed region\n", map->name); + err = -EINVAL; + } put_chip(map, chip); mutex_unlock(&chip->mutex); @@ -614,6 +616,8 @@ static void lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) ofs = 0; chipnum++; } + + return err; } static int lpddr_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 4f01079e357f..da8a0b28316c 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -92,11 +92,11 @@ static int part_point(struct mtd_info *mtd, loff_t from, size_t len, virt, phys); } -static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static int part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { struct mtd_part *part = PART(mtd); - mtd_unpoint(part->master, from + part->offset, len); + return mtd_unpoint(part->master, from + part->offset, len); } static unsigned long part_get_unmapped_area(struct mtd_info *mtd, diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index e2e545616b2a..8c243117c087 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -177,7 +177,7 @@ struct mtd_info { int (*_erase) (struct mtd_info *mtd, struct erase_info *instr); int (*_point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys); - void (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len); + int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len); unsigned long (*_get_unmapped_area) (struct mtd_info *mtd, unsigned long len, unsigned long offset, @@ -265,8 +265,10 @@ static inline int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, } /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ -static inline void mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static inline int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { + if (!mtd->_point) + return -EOPNOTSUPP; return mtd->_unpoint(mtd, from, len); } diff --git a/include/linux/mtd/pmc551.h b/include/linux/mtd/pmc551.h index 27ad40aed19f..da8b98d1b330 100644 --- a/include/linux/mtd/pmc551.h +++ b/include/linux/mtd/pmc551.h @@ -34,7 +34,6 @@ struct mypriv { * Function Prototypes */ static int pmc551_erase(struct mtd_info *, struct erase_info *); -static void pmc551_unpoint(struct mtd_info *, loff_t, size_t); static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys); static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); -- cgit v1.2.3 From 5def48982b778aaebe201f85af7170b7d0a6619f Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 16:23:52 +0200 Subject: mtd: do not duplicate length and offset checks in drivers We already verify that offset and length are within the MTD device size in the MTD API functions. Let's remove the duplicated checks in drivers. This patch only affects the following API's: 'mtd_erase()' 'mtd_point()' 'mtd_unpoint()' 'mtd_get_unmapped_area()' 'mtd_read()' 'mtd_write()' 'mtd_panic_write()' 'mtd_lock()' 'mtd_unlock()' 'mtd_is_locked()' 'mtd_block_isbad()' 'mtd_block_markbad()' This patch adds a bit of noise by removing too sparse empty lines, but this is not too bad. Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0001.c | 2 +- drivers/mtd/chips/cfi_cmdset_0020.c | 9 --------- drivers/mtd/chips/cfi_util.c | 6 ------ drivers/mtd/devices/block2mtd.c | 9 --------- drivers/mtd/devices/doc2000.c | 8 -------- drivers/mtd/devices/doc2001.c | 8 -------- drivers/mtd/devices/doc2001plus.c | 8 -------- drivers/mtd/devices/lart.c | 5 ----- drivers/mtd/devices/m25p80.c | 12 ------------ drivers/mtd/devices/ms02-nv.c | 8 -------- drivers/mtd/devices/mtd_dataflash.c | 7 ------- drivers/mtd/devices/mtdram.c | 17 ----------------- drivers/mtd/devices/phram.c | 23 ---------------------- drivers/mtd/devices/pmc551.c | 38 ------------------------------------- drivers/mtd/devices/slram.c | 23 ---------------------- drivers/mtd/devices/spear_smi.c | 12 ------------ drivers/mtd/devices/sst25l.c | 9 --------- drivers/mtd/lpddr/lpddr_cmds.c | 5 +---- drivers/mtd/mtdconcat.c | 26 ------------------------- drivers/mtd/mtdpart.c | 30 +---------------------------- drivers/mtd/nand/nand_base.c | 28 --------------------------- drivers/mtd/onenand/onenand_base.c | 20 ------------------- drivers/mtd/ubi/gluebi.c | 11 ----------- 23 files changed, 3 insertions(+), 321 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 4d04551cffd7..27008ae8f695 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -1324,7 +1324,7 @@ static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len, int chipnum; int ret = 0; - if (!map->virt || (from + len > mtd->size)) + if (!map->virt) return -EINVAL; /* Now lock the chip(s) to POINT state */ diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index 3861cca97bb0..160402fb65d1 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c @@ -904,12 +904,6 @@ static int cfi_staa_erase_varsize(struct mtd_info *mtd, int i, first; struct mtd_erase_region_info *regions = mtd->eraseregions; - if (instr->addr > mtd->size) - return -EINVAL; - - if ((instr->len + instr->addr) > mtd->size) - return -EINVAL; - /* Check that both start and end of the requested erase are * aligned with the erasesize at the appropriate addresses. */ @@ -1155,9 +1149,6 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (len & (mtd->erasesize -1)) return -EINVAL; - if ((len + ofs) > mtd->size) - return -EINVAL; - chipnum = ofs >> cfi->chipshift; adr = ofs - (chipnum << cfi->chipshift); diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index 8e464054a631..f992418f40a8 100644 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c @@ -173,12 +173,6 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob, int i, first; struct mtd_erase_region_info *regions = mtd->eraseregions; - if (ofs > mtd->size) - return -EINVAL; - - if ((len + ofs) > mtd->size) - return -EINVAL; - /* Check that both start and end of the requested erase are * aligned with the erasesize at the appropriate addresses. */ diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 0fccf149f5aa..4c2f84c2a7c7 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -104,11 +104,6 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len, int offset = from & (PAGE_SIZE-1); int cpylen; - if (from > mtd->size) - return -EINVAL; - if (from + len > mtd->size) - len = mtd->size - from; - if (retlen) *retlen = 0; @@ -190,10 +185,6 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len, if (!len) return 0; - if (to >= mtd->size) - return -ENOSPC; - if (to + len > mtd->size) - len = mtd->size - to; mutex_lock(&dev->write_mutex); err = _block2mtd_write(dev, buf, to, len, retlen); diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index 115d890e9919..ee4ee0b8440d 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c @@ -602,10 +602,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, int i, len256 = 0, ret=0; size_t left = len; - /* Don't allow read past end of device */ - if (from >= this->totlen) - return -EINVAL; - mutex_lock(&this->lock); *retlen = 0; @@ -748,10 +744,6 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, size_t left = len; int status; - /* Don't allow write past end of device */ - if (to >= this->totlen) - return -EINVAL; - mutex_lock(&this->lock); *retlen = 0; diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index b1185f938711..17844155a685 100644 --- a/drivers/mtd/devices/doc2001.c +++ b/drivers/mtd/devices/doc2001.c @@ -383,10 +383,6 @@ static int doc_read (struct mtd_info *mtd, loff_t from, size_t len, void __iomem *docptr = this->virtadr; struct Nand *mychip = &this->chips[from >> (this->chipshift)]; - /* Don't allow read past end of device */ - if (from >= this->totlen) - return -EINVAL; - /* Don't allow a single read to cross a 512-byte block boundary */ if (from + len > ((from | 0x1ff) + 1)) len = ((from | 0x1ff) + 1) - from; @@ -494,10 +490,6 @@ static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, void __iomem *docptr = this->virtadr; struct Nand *mychip = &this->chips[to >> (this->chipshift)]; - /* Don't allow write past end of device */ - if (to >= this->totlen) - return -EINVAL; - #if 0 /* Don't allow a single write to cross a 512-byte block boundary */ if (to + len > ( (to | 0x1ff) + 1)) diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c index c9fbadd3303e..a472bab7ef2b 100644 --- a/drivers/mtd/devices/doc2001plus.c +++ b/drivers/mtd/devices/doc2001plus.c @@ -581,10 +581,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, void __iomem * docptr = this->virtadr; struct Nand *mychip = &this->chips[from >> (this->chipshift)]; - /* Don't allow read past end of device */ - if (from >= this->totlen) - return -EINVAL; - /* Don't allow a single read to cross a 512-byte block boundary */ if (from + len > ((from | 0x1ff) + 1)) len = ((from | 0x1ff) + 1) - from; @@ -700,10 +696,6 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, void __iomem * docptr = this->virtadr; struct Nand *mychip = &this->chips[to >> (this->chipshift)]; - /* Don't allow write past end of device */ - if (to >= this->totlen) - return -EINVAL; - /* Don't allow writes which aren't exactly one block (512 bytes) */ if ((to & 0x1ff) || (len != 0x200)) return -EINVAL; diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index 6d6502c2ec35..c9ae60112a90 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -367,9 +367,6 @@ static int flash_erase (struct mtd_info *mtd,struct erase_info *instr) printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n", __func__, instr->addr, instr->len); #endif - /* sanity checks */ - if (instr->addr + instr->len > mtd->size) return (-EINVAL); - /* * check that both start and end of the requested erase are * aligned with the erasesize at the appropriate addresses. @@ -442,7 +439,6 @@ static int flash_read (struct mtd_info *mtd,loff_t from,size_t len,size_t *retle /* sanity checks */ if (!len) return (0); - if (from + len > mtd->size) return (-EINVAL); /* we always read len bytes */ *retlen = len; @@ -526,7 +522,6 @@ static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen /* sanity checks */ if (!len) return (0); - if (to + len > mtd->size) return (-EINVAL); /* first, we write a 0xFF.... padded byte until we reach a dword boundary */ if (to & (BUSWIDTH - 1)) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 8808da9ee31f..0955a8f4fd25 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -288,9 +288,6 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) __func__, (long long)instr->addr, (long long)instr->len); - /* sanity checks */ - if (instr->addr + instr->len > flash->mtd.size) - return -EINVAL; div_u64_rem(instr->len, mtd->erasesize, &rem); if (rem) return -EINVAL; @@ -353,9 +350,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, if (!len) return 0; - if (from + len > flash->mtd.size) - return -EINVAL; - spi_message_init(&m); memset(t, 0, (sizeof t)); @@ -423,9 +417,6 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, if (!len) return(0); - if (to + len > flash->mtd.size) - return -EINVAL; - spi_message_init(&m); memset(t, 0, (sizeof t)); @@ -515,9 +506,6 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, if (!len) return 0; - if (to + len > flash->mtd.size) - return -EINVAL; - spi_message_init(&m); memset(t, 0, (sizeof t)); diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c index 3a05af529e7d..182849d39c61 100644 --- a/drivers/mtd/devices/ms02-nv.c +++ b/drivers/mtd/devices/ms02-nv.c @@ -59,12 +59,8 @@ static int ms02nv_read(struct mtd_info *mtd, loff_t from, { struct ms02nv_private *mp = mtd->priv; - if (from + len > mtd->size) - return -EINVAL; - memcpy(buf, mp->uaddr + from, len); *retlen = len; - return 0; } @@ -73,12 +69,8 @@ static int ms02nv_write(struct mtd_info *mtd, loff_t to, { struct ms02nv_private *mp = mtd->priv; - if (to + len > mtd->size) - return -EINVAL; - memcpy(mp->uaddr + to, buf, len); *retlen = len; - return 0; } diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index fd4a9fc0d8b8..fc5c78171844 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -164,9 +164,6 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) dev_name(&spi->dev), (long long)instr->addr, (long long)instr->len); - /* Sanity checks */ - if (instr->addr + instr->len > mtd->size) - return -EINVAL; div_u64_rem(instr->len, priv->page_size, &rem); if (rem) return -EINVAL; @@ -257,8 +254,6 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, /* Sanity checks */ if (!len) return 0; - if (from + len > mtd->size) - return -EINVAL; /* Calculate flash page/byte address */ addr = (((unsigned)from / priv->page_size) << priv->page_offset) @@ -333,8 +328,6 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, /* Sanity checks */ if (!len) return 0; - if ((to + len) > mtd->size) - return -EINVAL; spi_message_init(&msg); diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c index e1f017bf0777..0e0e6ed4443c 100644 --- a/drivers/mtd/devices/mtdram.c +++ b/drivers/mtd/devices/mtdram.c @@ -34,27 +34,18 @@ static struct mtd_info *mtd_info; static int ram_erase(struct mtd_info *mtd, struct erase_info *instr) { - if (instr->addr + instr->len > mtd->size) - return -EINVAL; - memset((char *)mtd->priv + instr->addr, 0xff, instr->len); - instr->state = MTD_ERASE_DONE; mtd_erase_callback(instr); - return 0; } static int ram_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys) { - if (from + len > mtd->size) - return -EINVAL; - /* can we return a physical address with this driver? */ if (phys) return -EINVAL; - *virt = mtd->priv + from; *retlen = len; return 0; @@ -81,11 +72,7 @@ static unsigned long ram_get_unmapped_area(struct mtd_info *mtd, static int ram_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { - if (from + len > mtd->size) - return -EINVAL; - memcpy(buf, mtd->priv + from, len); - *retlen = len; return 0; } @@ -93,11 +80,7 @@ static int ram_read(struct mtd_info *mtd, loff_t from, size_t len, static int ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { - if (to + len > mtd->size) - return -EINVAL; - memcpy((char *)mtd->priv + to, buf, len); - *retlen = len; return 0; } diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 38035551a7d2..36add7ce4632 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -38,29 +38,20 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) { u_char *start = mtd->priv; - if (instr->addr + instr->len > mtd->size) - return -EINVAL; - memset(start + instr->addr, 0xff, instr->len); /* This'll catch a few races. Free the thing before returning :) * I don't feel at all ashamed. This kind of thing is possible anyway * with flash, but unlikely. */ - instr->state = MTD_ERASE_DONE; - mtd_erase_callback(instr); - return 0; } static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys) { - if (from + len > mtd->size) - return -EINVAL; - /* can we return a physical address with this driver? */ if (phys) return -EINVAL; @@ -80,14 +71,7 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len, { u_char *start = mtd->priv; - if (from >= mtd->size) - return -EINVAL; - - if (len > mtd->size - from) - len = mtd->size - from; - memcpy(buf, start + from, len); - *retlen = len; return 0; } @@ -97,14 +81,7 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len, { u_char *start = mtd->priv; - if (to >= mtd->size) - return -EINVAL; - - if (len > mtd->size - to) - len = mtd->size - to; - memcpy(start + to, buf, len); - *retlen = len; return 0; } diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index 933127ecebe5..d394e06e4279 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c @@ -116,16 +116,6 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) #endif end = instr->addr + instr->len - 1; - - /* Is it past the end? */ - if (end > mtd->size) { -#ifdef CONFIG_MTD_PMC551_DEBUG - printk(KERN_DEBUG "pmc551_erase() out of bounds (%ld > %ld)\n", - (long)end, (long)mtd->size); -#endif - return -EINVAL; - } - eoff_hi = end & ~(priv->asize - 1); soff_hi = instr->addr & ~(priv->asize - 1); eoff_lo = end & (priv->asize - 1); @@ -179,14 +169,6 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len); #endif - if (from + len > mtd->size) { -#ifdef CONFIG_MTD_PMC551_DEBUG - printk(KERN_DEBUG "pmc551_point() out of bounds (%ld > %ld)\n", - (long)from + len, (long)mtd->size); -#endif - return -EINVAL; - } - /* can we return a physical address with this driver? */ if (phys) return -EINVAL; @@ -230,16 +212,6 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len, #endif end = from + len - 1; - - /* Is it past the end? */ - if (end > mtd->size) { -#ifdef CONFIG_MTD_PMC551_DEBUG - printk(KERN_DEBUG "pmc551_read() out of bounds (%ld > %ld)\n", - (long)end, (long)mtd->size); -#endif - return -EINVAL; - } - soff_hi = from & ~(priv->asize - 1); eoff_hi = end & ~(priv->asize - 1); soff_lo = from & (priv->asize - 1); @@ -297,16 +269,6 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len, #endif end = to + len - 1; - /* Is it past the end? or did the u32 wrap? */ - if (end > mtd->size) { -#ifdef CONFIG_MTD_PMC551_DEBUG - printk(KERN_DEBUG "pmc551_write() out of bounds (end: %ld, " - "size: %ld, to: %ld)\n", (long)end, (long)mtd->size, - (long)to); -#endif - return -EINVAL; - } - soff_hi = to & ~(priv->asize - 1); eoff_hi = end & ~(priv->asize - 1); soff_lo = to & (priv->asize - 1); diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index 9431ffc761c2..842e4890d771 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c @@ -84,21 +84,13 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr) { slram_priv_t *priv = mtd->priv; - if (instr->addr + instr->len > mtd->size) { - return(-EINVAL); - } - memset(priv->start + instr->addr, 0xff, instr->len); - /* This'll catch a few races. Free the thing before returning :) * I don't feel at all ashamed. This kind of thing is possible anyway * with flash, but unlikely. */ - instr->state = MTD_ERASE_DONE; - mtd_erase_callback(instr); - return(0); } @@ -110,10 +102,6 @@ static int slram_point(struct mtd_info *mtd, loff_t from, size_t len, /* can we return a physical address with this driver? */ if (phys) return -EINVAL; - - if (from + len > mtd->size) - return -EINVAL; - *virt = priv->start + from; *retlen = len; return(0); @@ -129,14 +117,7 @@ static int slram_read(struct mtd_info *mtd, loff_t from, size_t len, { slram_priv_t *priv = mtd->priv; - if (from > mtd->size) - return -EINVAL; - - if (from + len > mtd->size) - len = mtd->size - from; - memcpy(buf, priv->start + from, len); - *retlen = len; return(0); } @@ -146,11 +127,7 @@ static int slram_write(struct mtd_info *mtd, loff_t to, size_t len, { slram_priv_t *priv = mtd->priv; - if (to + len > mtd->size) - return -EINVAL; - memcpy(priv->start + to, buf, len); - *retlen = len; return(0); } diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index b80cb5b5ebbd..2238ab916a06 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -510,10 +510,6 @@ static int spear_mtd_erase(struct mtd_info *mtd, struct erase_info *e_info) if (!flash || !dev) return -ENODEV; - /* do not allow erase past end of device */ - if (e_info->addr + e_info->len > flash->mtd.size) - return -EINVAL; - bank = flash->bank; if (bank > dev->num_flashes - 1) { dev_err(&dev->pdev->dev, "Invalid Bank Num"); @@ -573,10 +569,6 @@ static int spear_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, if (!flash || !dev) return -ENODEV; - /* do not allow reads past end of device */ - if (from + len > flash->mtd.size) - return -EINVAL; - if (flash->bank > dev->num_flashes - 1) { dev_err(&dev->pdev->dev, "Invalid Bank Num"); return -EINVAL; @@ -678,10 +670,6 @@ static int spear_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, if (!len) return 0; - /* do not allow write past end of page */ - if (to + len > flash->mtd.size) - return -EINVAL; - if (flash->bank > dev->num_flashes - 1) { dev_err(&dev->pdev->dev, "Invalid Bank Num"); return -EINVAL; diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index 8b9ffafcc401..99d4a3c510d7 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c @@ -175,9 +175,6 @@ static int sst25l_erase(struct mtd_info *mtd, struct erase_info *instr) int err; /* Sanity checks */ - if (instr->addr + instr->len > flash->mtd.size) - return -EINVAL; - if ((uint32_t)instr->len % mtd->erasesize) return -EINVAL; @@ -227,9 +224,6 @@ static int sst25l_read(struct mtd_info *mtd, loff_t from, size_t len, if (len == 0) return 0; - if (from + len > flash->mtd.size) - return -EINVAL; - if (retlen) *retlen = 0; @@ -278,9 +272,6 @@ static int sst25l_write(struct mtd_info *mtd, loff_t to, size_t len, if (!len) return 0; - if (to + len > flash->mtd.size) - return -EINVAL; - if ((uint32_t)to % mtd->writesize) return -EINVAL; diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index de960b1d395a..0f3731c6b3f6 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c @@ -530,7 +530,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, struct flchip *chip = &lpddr->chips[chipnum]; int ret = 0; - if (!map->virt || (adr + len > mtd->size)) + if (!map->virt) return -EINVAL; /* ofs: offset within the first chip that the first read should start */ @@ -692,9 +692,6 @@ static int lpddr_erase(struct mtd_info *mtd, struct erase_info *instr) ofs = instr->addr; len = instr->len; - if (ofs > mtd->size || (len + ofs) > mtd->size) - return -EINVAL; - while (len > 0) { ret = do_erase_oneblock(mtd, ofs); if (ret) diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index d826a8a50e73..1f2071803931 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c @@ -185,10 +185,6 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs, for (i = 0; i < count; i++) total_len += vecs[i].iov_len; - /* Do not allow write past end of device */ - if ((to + total_len) > mtd->size) - return -EINVAL; - /* Check alignment */ if (mtd->writesize > 1) { uint64_t __to = to; @@ -406,12 +402,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; - if (instr->addr > concat->mtd.size) - return -EINVAL; - - if (instr->len + instr->addr > concat->mtd.size) - return -EINVAL; - /* * Check for proper erase block alignment of the to-be-erased area. * It is easier to do this based on the super device's erase @@ -538,9 +528,6 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) struct mtd_concat *concat = CONCAT(mtd); int i, err = -EINVAL; - if ((len + ofs) > mtd->size) - return -EINVAL; - for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; uint64_t size; @@ -575,9 +562,6 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) struct mtd_concat *concat = CONCAT(mtd); int i, err = 0; - if ((len + ofs) > mtd->size) - return -EINVAL; - for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; uint64_t size; @@ -650,9 +634,6 @@ static int concat_block_isbad(struct mtd_info *mtd, loff_t ofs) if (!mtd_can_have_bb(concat->subdev[0])) return res; - if (ofs > mtd->size) - return -EINVAL; - for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; @@ -673,9 +654,6 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs) struct mtd_concat *concat = CONCAT(mtd); int i, err = -EINVAL; - if (ofs > mtd->size) - return -EINVAL; - for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; @@ -713,10 +691,6 @@ static unsigned long concat_get_unmapped_area(struct mtd_info *mtd, continue; } - /* we've found the subdev over which the mapping will reside */ - if (offset + len > subdev->size) - return (unsigned long) -EINVAL; - return mtd_get_unmapped_area(subdev, len, offset, flags); } diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index da8a0b28316c..fbe2c8a22e1c 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -65,11 +65,6 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len, int res; stats = part->master->ecc_stats; - - if (from >= mtd->size) - len = 0; - else if (from + len > mtd->size) - len = mtd->size - from; res = mtd_read(part->master, from + part->offset, len, retlen, buf); if (unlikely(res)) { if (mtd_is_bitflip(res)) @@ -84,10 +79,7 @@ static int part_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys) { struct mtd_part *part = PART(mtd); - if (from >= mtd->size) - len = 0; - else if (from + len > mtd->size) - len = mtd->size - from; + return mtd_point(part->master, from + part->offset, len, retlen, virt, phys); } @@ -182,10 +174,6 @@ static int part_write(struct mtd_info *mtd, loff_t to, size_t len, struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; - if (to >= mtd->size) - len = 0; - else if (to + len > mtd->size) - len = mtd->size - to; return mtd_write(part->master, to + part->offset, len, retlen, buf); } @@ -195,10 +183,6 @@ static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; - if (to >= mtd->size) - len = 0; - else if (to + len > mtd->size) - len = mtd->size - to; return mtd_panic_write(part->master, to + part->offset, len, retlen, buf); } @@ -248,8 +232,6 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr) int ret; if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; - if (instr->addr >= mtd->size) - return -EINVAL; instr->addr += part->offset; ret = mtd_erase(part->master, instr); if (ret) { @@ -277,24 +259,18 @@ EXPORT_SYMBOL_GPL(mtd_erase_callback); static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { struct mtd_part *part = PART(mtd); - if ((len + ofs) > mtd->size) - return -EINVAL; return mtd_lock(part->master, ofs + part->offset, len); } static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { struct mtd_part *part = PART(mtd); - if ((len + ofs) > mtd->size) - return -EINVAL; return mtd_unlock(part->master, ofs + part->offset, len); } static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) { struct mtd_part *part = PART(mtd); - if ((len + ofs) > mtd->size) - return -EINVAL; return mtd_is_locked(part->master, ofs + part->offset, len); } @@ -319,8 +295,6 @@ static void part_resume(struct mtd_info *mtd) static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) { struct mtd_part *part = PART(mtd); - if (ofs >= mtd->size) - return -EINVAL; ofs += part->offset; return mtd_block_isbad(part->master, ofs); } @@ -332,8 +306,6 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; - if (ofs >= mtd->size) - return -EINVAL; ofs += part->offset; res = mtd_block_markbad(part->master, ofs); if (!res) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 13a56d3e8aec..dd182c8591a9 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -123,12 +123,6 @@ static int check_offs_len(struct mtd_info *mtd, ret = -EINVAL; } - /* Do not allow past end of device */ - if (ofs + len > mtd->size) { - pr_debug("%s: past end of device\n", __func__); - ret = -EINVAL; - } - return ret; } @@ -1620,25 +1614,17 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, struct mtd_oob_ops ops; int ret; - /* Do not allow reads past end of device */ - if ((from + len) > mtd->size) - return -EINVAL; if (!len) return 0; nand_get_device(chip, mtd, FL_READING); - ops.len = len; ops.datbuf = buf; ops.oobbuf = NULL; ops.mode = 0; - ret = nand_do_read_ops(mtd, from, &ops); - *retlen = ops.retlen; - nand_release_device(mtd); - return ret; } @@ -2328,8 +2314,6 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, int ret; /* Do not allow reads past end of device */ - if ((to + len) > mtd->size) - return -EINVAL; if (!len) return 0; @@ -2367,25 +2351,17 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, struct mtd_oob_ops ops; int ret; - /* Do not allow reads past end of device */ - if ((to + len) > mtd->size) - return -EINVAL; if (!len) return 0; nand_get_device(chip, mtd, FL_WRITING); - ops.len = len; ops.datbuf = (uint8_t *)buf; ops.oobbuf = NULL; ops.mode = 0; - ret = nand_do_write_ops(mtd, to, &ops); - *retlen = ops.retlen; - nand_release_device(mtd); - return ret; } @@ -2749,10 +2725,6 @@ static void nand_sync(struct mtd_info *mtd) */ static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) { - /* Check for invalid offset */ - if (offs > mtd->size) - return -EINVAL; - return nand_block_checkbad(mtd, offs, 1, 0); } diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 914c49bdf2b6..9c6445d372ce 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1756,13 +1756,6 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len, /* Initialize retlen, in case of early exit */ *retlen = 0; - /* Do not allow writes past end of device */ - if (unlikely((to + len) > mtd->size)) { - printk(KERN_ERR "%s: Attempt write to past end of device\n", - __func__); - return -EINVAL; - } - /* Reject writes, which are not page aligned */ if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) { printk(KERN_ERR "%s: Attempt to write not page aligned data\n", @@ -1890,13 +1883,6 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, ops->retlen = 0; ops->oobretlen = 0; - /* Do not allow writes past end of device */ - if (unlikely((to + len) > mtd->size)) { - printk(KERN_ERR "%s: Attempt write to past end of device\n", - __func__); - return -EINVAL; - } - /* Reject writes, which are not page aligned */ if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) { printk(KERN_ERR "%s: Attempt to write not page aligned data\n", @@ -2493,12 +2479,6 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) (unsigned long long)instr->addr, (unsigned long long)instr->len); - /* Do not allow erase past end of device */ - if (unlikely((len + addr) > mtd->size)) { - printk(KERN_ERR "%s: Erase past end of device\n", __func__); - return -EINVAL; - } - if (FLEXONENAND(this)) { /* Find the eraseregion of this address */ int i = flexonenand_region(mtd, addr); diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index 0101dce90c45..b875c2c50d82 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c @@ -174,11 +174,7 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, int err = 0, lnum, offs, total_read; struct gluebi_device *gluebi; - if (len < 0 || from < 0 || from + len > mtd->size) - return -EINVAL; - gluebi = container_of(mtd, struct gluebi_device, mtd); - lnum = div_u64_rem(from, mtd->erasesize, &offs); total_read = len; while (total_read) { @@ -218,9 +214,6 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, int err = 0, lnum, offs, total_written; struct gluebi_device *gluebi; - if (len < 0 || to < 0 || len + to > mtd->size) - return -EINVAL; - gluebi = container_of(mtd, struct gluebi_device, mtd); if (!(mtd->flags & MTD_WRITEABLE)) @@ -265,10 +258,6 @@ static int gluebi_erase(struct mtd_info *mtd, struct erase_info *instr) int err, i, lnum, count; struct gluebi_device *gluebi; - if (instr->addr < 0 || instr->addr > mtd->size - mtd->erasesize) - return -EINVAL; - if (instr->len < 0 || instr->addr + instr->len > mtd->size) - return -EINVAL; if (mtd_mod_by_ws(instr->addr, mtd) || mtd_mod_by_ws(instr->len, mtd)) return -EINVAL; -- cgit v1.2.3 From 664addc248d2fed68d013d26ff2fc796d7134259 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 18:13:23 +0200 Subject: mtd: remove R/O checking duplication Many drivers check whether the partition is R/O and return -EROFS if yes. Let's stop having duplicated checks and move them to the API functions instead. And again a bit of noise - deleted few too sparse newlines, sorry. Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/chips/map_ram.c | 4 ---- drivers/mtd/chips/map_rom.c | 3 +-- drivers/mtd/devices/phram.c | 1 - drivers/mtd/mtdconcat.c | 27 +++------------------------ drivers/mtd/mtdcore.c | 12 ++++++++++-- drivers/mtd/mtdpart.c | 14 +------------- drivers/mtd/ubi/gluebi.c | 8 -------- include/linux/mtd/mtd.h | 2 ++ 8 files changed, 17 insertions(+), 54 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c index 225307088dc0..991c2a1c05d3 100644 --- a/drivers/mtd/chips/map_ram.c +++ b/drivers/mtd/chips/map_ram.c @@ -122,14 +122,10 @@ static int mapram_erase (struct mtd_info *mtd, struct erase_info *instr) unsigned long i; allff = map_word_ff(map); - for (i=0; ilen; i += map_bankwidth(map)) map_write(map, allff, instr->addr + i); - instr->state = MTD_ERASE_DONE; - mtd_erase_callback(instr); - return 0; } diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c index facb56092d39..47a43cf7e5c6 100644 --- a/drivers/mtd/chips/map_rom.c +++ b/drivers/mtd/chips/map_rom.c @@ -85,8 +85,7 @@ static void maprom_nop(struct mtd_info *mtd) static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { - printk(KERN_NOTICE "maprom_write called\n"); - return -EIO; + return -EROFS; } static int maprom_erase (struct mtd_info *mtd, struct erase_info *info) diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 36add7ce4632..d0e8dc69fe1c 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -33,7 +33,6 @@ struct phram_mtd_list { static LIST_HEAD(phram_list); - static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) { u_char *start = mtd->priv; diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index 1f2071803931..dd24232265e6 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c @@ -126,9 +126,6 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len, int err = -EINVAL; int i; - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - *retlen = 0; for (i = 0; i < concat->num_subdev; i++) { @@ -145,11 +142,7 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len, else size = len; - if (!(subdev->flags & MTD_WRITEABLE)) - err = -EROFS; - else - err = mtd_write(subdev, to, size, &retsize, buf); - + err = mtd_write(subdev, to, size, &retsize, buf); if (err) break; @@ -176,9 +169,6 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs, int i; int err = -EINVAL; - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - *retlen = 0; /* Calculate total length of data */ @@ -220,12 +210,8 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs, old_iov_len = vecs_copy[entry_high].iov_len; vecs_copy[entry_high].iov_len = size; - if (!(subdev->flags & MTD_WRITEABLE)) - err = -EROFS; - else - err = mtd_writev(subdev, &vecs_copy[entry_low], - entry_high - entry_low + 1, to, - &retsize); + err = mtd_writev(subdev, &vecs_copy[entry_low], + entry_high - entry_low + 1, to, &retsize); vecs_copy[entry_high].iov_len = old_iov_len - size; vecs_copy[entry_high].iov_base += size; @@ -399,9 +385,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) uint64_t length, offset = 0; struct erase_info *erase; - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - /* * Check for proper erase block alignment of the to-be-erased area. * It is easier to do this based on the super device's erase @@ -489,10 +472,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) else erase->len = length; - if (!(subdev->flags & MTD_WRITEABLE)) { - err = -EROFS; - break; - } length -= erase->len; if ((err = concat_dev_erase(subdev, erase))) { /* sanity check: should never happen since diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 8d5e103695f9..b9b28647adef 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -693,6 +693,8 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) { if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr) return -EINVAL; + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; return mtd->_erase(mtd, instr); } EXPORT_SYMBOL_GPL(mtd_erase); @@ -752,10 +754,10 @@ int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { *retlen = 0; - if (!mtd->_write) - return -EROFS; if (to < 0 || to > mtd->size || len > mtd->size - to) return -EINVAL; + if (!mtd->_write || !(mtd->flags & MTD_WRITEABLE)) + return -EROFS; return mtd->_write(mtd, to, len, retlen, buf); } EXPORT_SYMBOL_GPL(mtd_write); @@ -775,6 +777,8 @@ int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, return -EOPNOTSUPP; if (to < 0 || to > mtd->size || len > mtd->size - to) return -EINVAL; + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; return mtd->_panic_write(mtd, to, len, retlen, buf); } EXPORT_SYMBOL_GPL(mtd_panic_write); @@ -826,6 +830,8 @@ int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs) return -EOPNOTSUPP; if (ofs < 0 || ofs > mtd->size) return -EINVAL; + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; return mtd->_block_markbad(mtd, ofs); } EXPORT_SYMBOL_GPL(mtd_block_markbad); @@ -877,6 +883,8 @@ int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { *retlen = 0; + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; if (!mtd->_writev) return default_mtd_writev(mtd, vecs, count, to, retlen); return mtd->_writev(mtd, vecs, count, to, retlen); diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index fbe2c8a22e1c..33d32c6f4f58 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -172,8 +172,6 @@ static int part_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { struct mtd_part *part = PART(mtd); - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; return mtd_write(part->master, to + part->offset, len, retlen, buf); } @@ -181,8 +179,6 @@ static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { struct mtd_part *part = PART(mtd); - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; return mtd_panic_write(part->master, to + part->offset, len, retlen, buf); } @@ -192,9 +188,6 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to, { struct mtd_part *part = PART(mtd); - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - if (to >= mtd->size) return -EINVAL; if (ops->datbuf && to + ops->len > mtd->size) @@ -220,8 +213,6 @@ static int part_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { struct mtd_part *part = PART(mtd); - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; return mtd_writev(part->master, vecs, count, to + part->offset, retlen); } @@ -230,8 +221,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr) { struct mtd_part *part = PART(mtd); int ret; - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; + instr->addr += part->offset; ret = mtd_erase(part->master, instr); if (ret) { @@ -304,8 +294,6 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) struct mtd_part *part = PART(mtd); int res; - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; ofs += part->offset; res = mtd_block_markbad(part->master, ofs); if (!res) diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index b875c2c50d82..90b98822d9a4 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c @@ -215,10 +215,6 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, struct gluebi_device *gluebi; gluebi = container_of(mtd, struct gluebi_device, mtd); - - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - lnum = div_u64_rem(to, mtd->erasesize, &offs); if (len % mtd->writesize || offs % mtd->writesize) @@ -263,12 +259,8 @@ static int gluebi_erase(struct mtd_info *mtd, struct erase_info *instr) lnum = mtd_div_by_eb(instr->addr, mtd); count = mtd_div_by_eb(instr->len, mtd); - gluebi = container_of(mtd, struct gluebi_device, mtd); - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - for (i = 0; i < count - 1; i++) { err = ubi_leb_unmap(gluebi->desc, lnum + i); if (err) diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 317a80c4d54c..fa20a8f0463a 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -268,6 +268,8 @@ static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to, ops->retlen = ops->oobretlen = 0; if (!mtd->_write_oob) return -EOPNOTSUPP; + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; return mtd->_write_oob(mtd, to, ops); } -- cgit v1.2.3 From 834247ec7e281dee839fe4a04bc1bbf0c7395172 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 6 Feb 2012 12:39:07 +0200 Subject: mtd: remove retlen zeroing duplication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MTD API function now zero the 'retlen' parameter before calling the driver's method — do not do this again in drivers. This removes duplicated '*retlen = 0' assignent from the following methods: 'mtd_point()' 'mtd_read()' 'mtd_write()' 'mtd_writev()' 'mtd_panic_write()' Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0001.c | 5 ----- drivers/mtd/chips/cfi_cmdset_0002.c | 12 ------------ drivers/mtd/chips/cfi_cmdset_0020.c | 3 --- drivers/mtd/chips/map_absent.c | 2 -- drivers/mtd/devices/block2mtd.c | 5 ----- drivers/mtd/devices/doc2000.c | 4 ---- drivers/mtd/devices/doc2001.c | 1 - drivers/mtd/devices/doc2001plus.c | 1 - drivers/mtd/devices/lart.c | 2 -- drivers/mtd/devices/m25p80.c | 7 ------- drivers/mtd/devices/mtd_dataflash.c | 4 ---- drivers/mtd/devices/phram.c | 2 -- drivers/mtd/devices/spear_smi.c | 10 ---------- drivers/mtd/devices/sst25l.c | 3 --- drivers/mtd/lpddr/lpddr_cmds.c | 3 --- drivers/mtd/mtdconcat.c | 6 ------ drivers/mtd/mtdcore.c | 1 + drivers/mtd/onenand/onenand_base.c | 3 --- 18 files changed, 1 insertion(+), 73 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 27008ae8f695..dc66df6ab58a 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -1334,7 +1334,6 @@ static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len, ofs = from - (chipnum << cfi->chipshift); *virt = map->virt + cfi->chips[chipnum].start + ofs; - *retlen = 0; if (phys) *phys = map->phys + cfi->chips[chipnum].start + ofs; @@ -1460,8 +1459,6 @@ static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, siz chipnum = (from >> cfi->chipshift); ofs = from - (chipnum << cfi->chipshift); - *retlen = 0; - while (len) { unsigned long thislen; @@ -1569,7 +1566,6 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le int chipnum; unsigned long ofs; - *retlen = 0; if (!len) return 0; @@ -1817,7 +1813,6 @@ static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs, for (i = 0; i < count; i++) len += vecs[i].iov_len; - *retlen = 0; if (!len) return 0; diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 27ac0622abe3..a89d899efad4 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -1017,13 +1017,9 @@ static int cfi_amdstd_read (struct mtd_info *mtd, loff_t from, size_t len, size_ int ret = 0; /* ofs: offset within the first chip that the first read should start */ - chipnum = (from >> cfi->chipshift); ofs = from - (chipnum << cfi->chipshift); - - *retlen = 0; - while (len) { unsigned long thislen; @@ -1101,16 +1097,11 @@ static int cfi_amdstd_secsi_read (struct mtd_info *mtd, loff_t from, size_t len, int chipnum; int ret = 0; - /* ofs: offset within the first chip that the first read should start */ - /* 8 secsi bytes per chip */ chipnum=from>>3; ofs=from & 7; - - *retlen = 0; - while (len) { unsigned long thislen; @@ -1255,7 +1246,6 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len, unsigned long ofs, chipstart; DECLARE_WAITQUEUE(wait, current); - *retlen = 0; if (!len) return 0; @@ -1497,7 +1487,6 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, int chipnum; unsigned long ofs; - *retlen = 0; if (!len) return 0; @@ -1708,7 +1697,6 @@ static int cfi_amdstd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, int ret = 0; int chipnum; - *retlen = 0; if (!len) return 0; diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index 160402fb65d1..d690b7d6952b 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c @@ -394,8 +394,6 @@ static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t chipnum = (from >> cfi->chipshift); ofs = from - (chipnum << cfi->chipshift); - *retlen = 0; - while (len) { unsigned long thislen; @@ -617,7 +615,6 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, int chipnum; unsigned long ofs; - *retlen = 0; if (!len) return 0; diff --git a/drivers/mtd/chips/map_absent.c b/drivers/mtd/chips/map_absent.c index 6be2eddfea45..f7a5bca92aef 100644 --- a/drivers/mtd/chips/map_absent.c +++ b/drivers/mtd/chips/map_absent.c @@ -70,13 +70,11 @@ static struct mtd_info *map_absent_probe(struct map_info *map) static int map_absent_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { - *retlen = 0; return -ENODEV; } static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { - *retlen = 0; return -ENODEV; } diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 4c2f84c2a7c7..ba2d74b01c7e 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -104,9 +104,6 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len, int offset = from & (PAGE_SIZE-1); int cpylen; - if (retlen) - *retlen = 0; - while (len) { if ((offset + len) > PAGE_SIZE) cpylen = PAGE_SIZE - offset; // multiple pages @@ -143,8 +140,6 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf, int offset = to & ~PAGE_MASK; // page offset int cpylen; - if (retlen) - *retlen = 0; while (len) { if ((offset+len) > PAGE_SIZE) cpylen = PAGE_SIZE - offset; // multiple pages diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index ee4ee0b8440d..7ad7b054800c 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c @@ -603,8 +603,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, size_t left = len; mutex_lock(&this->lock); - - *retlen = 0; while (left) { len = left; @@ -745,8 +743,6 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, int status; mutex_lock(&this->lock); - - *retlen = 0; while (left) { len = left; diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index 17844155a685..7bff54e62cd5 100644 --- a/drivers/mtd/devices/doc2001.c +++ b/drivers/mtd/devices/doc2001.c @@ -591,7 +591,6 @@ static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, printk("Error programming flash\n"); /* Error in programming FIXME: implement Bad Block Replacement (in nftl.c ??) */ - *retlen = 0; ret = -EIO; } dummy = ReadDOC(docptr, LastDataRead); diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c index a472bab7ef2b..4a03d869ad03 100644 --- a/drivers/mtd/devices/doc2001plus.c +++ b/drivers/mtd/devices/doc2001plus.c @@ -792,7 +792,6 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, printk("MTD: Error 0x%x programming at 0x%x\n", dummy, (int)to); /* Error in programming FIXME: implement Bad Block Replacement (in nftl.c ??) */ - *retlen = 0; ret = -EIO; } dummy = ReadDOC(docptr, Mplus_LastDataRead); diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index c9ae60112a90..6fb8dba76959 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -518,8 +518,6 @@ static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n", __func__, (__u32)to, len); #endif - *retlen = 0; - /* sanity checks */ if (!len) return (0); diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 0955a8f4fd25..45cc4a1ae5b0 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -365,9 +365,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, t[1].len = len; spi_message_add_tail(&t[1], &m); - /* Byte count starts at zero. */ - *retlen = 0; - mutex_lock(&flash->lock); /* Wait till previous write/erase is done. */ @@ -411,8 +408,6 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev), __func__, (u32)to, len); - *retlen = 0; - /* sanity checks */ if (!len) return(0); @@ -500,8 +495,6 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev), __func__, (u32)to, len); - *retlen = 0; - /* sanity checks */ if (!len) return 0; diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index fc5c78171844..c76b4464e8b9 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -249,8 +249,6 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, pr_debug("%s: read 0x%x..0x%x\n", dev_name(&priv->spi->dev), (unsigned)from, (unsigned)(from + len)); - *retlen = 0; - /* Sanity checks */ if (!len) return 0; @@ -323,8 +321,6 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, pr_debug("%s: write 0x%x..0x%x\n", dev_name(&spi->dev), (unsigned)to, (unsigned)(to + len)); - *retlen = 0; - /* Sanity checks */ if (!len) return 0; diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index d0e8dc69fe1c..d3474a48d097 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -85,8 +85,6 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len, return 0; } - - static void unregister_devices(void) { struct phram_mtd_list *this, *safe; diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index 2238ab916a06..2cdbcc65b39f 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -574,11 +574,6 @@ static int spear_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, return -EINVAL; } - if (!retlen) - return -EINVAL; - else - *retlen = 0; - /* select address as per bank number */ src = flash->base_addr + from; @@ -675,11 +670,6 @@ static int spear_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, return -EINVAL; } - if (!retlen) - return -EINVAL; - else - *retlen = 0; - /* select address as per bank number */ dest = flash->base_addr + to; mutex_lock(&flash->lock); diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index 99d4a3c510d7..5c2613c99e4a 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c @@ -224,9 +224,6 @@ static int sst25l_read(struct mtd_info *mtd, loff_t from, size_t len, if (len == 0) return 0; - if (retlen) - *retlen = 0; - spi_message_init(&message); memset(&transfer, 0, sizeof(transfer)); diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index 0f3731c6b3f6..a92906ba535d 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c @@ -535,9 +535,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, /* ofs: offset within the first chip that the first read should start */ ofs = adr - (chipnum << lpddr->chipshift); - *mtdbuf = (void *)map->virt + chip->start + ofs; - *retlen = 0; while (len) { unsigned long thislen; @@ -647,7 +645,6 @@ static int lpddr_writev(struct mtd_info *mtd, const struct kvec *vecs, for (i = 0; i < count; i++) len += vecs[i].iov_len; - *retlen = 0; if (!len) return 0; diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index dd24232265e6..f7a31cc44480 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c @@ -72,8 +72,6 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len, int ret = 0, err; int i; - *retlen = 0; - for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; size_t size, retsize; @@ -126,8 +124,6 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len, int err = -EINVAL; int i; - *retlen = 0; - for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; size_t size, retsize; @@ -169,8 +165,6 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs, int i; int err = -EINVAL; - *retlen = 0; - /* Calculate total length of data */ for (i = 0; i < count; i++) total_len += vecs[i].iov_len; diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index b9b28647adef..ead52b388492 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -744,6 +744,7 @@ EXPORT_SYMBOL_GPL(mtd_get_unmapped_area); int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { + *retlen = 0; if (from < 0 || from > mtd->size || len > mtd->size - from) return -EINVAL; return mtd->_read(mtd, from, len, retlen, buf); diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 9c6445d372ce..a1592cf755f3 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1753,9 +1753,6 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len, pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to, (int)len); - /* Initialize retlen, in case of early exit */ - *retlen = 0; - /* Reject writes, which are not page aligned */ if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) { printk(KERN_ERR "%s: Attempt to write not page aligned data\n", -- cgit v1.2.3 From c3faac4a74c2126e2b68f39d6e8791e88b5f7dbe Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 6 Feb 2012 13:44:27 +0200 Subject: mtd: remove junk pmc551.h This header is tiny and contains only pmc551-private stuff, so it should not live in 'include/linux' - let's just merge it with pmc551.c. Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/pmc551.c | 40 +++++++++++++++++++++-- include/linux/mtd/pmc551.h | 77 -------------------------------------------- 2 files changed, 38 insertions(+), 79 deletions(-) delete mode 100644 include/linux/mtd/pmc551.h (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index d394e06e4279..6269a434f304 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c @@ -95,12 +95,48 @@ #include #include #include - #include -#include + +#define PMC551_VERSION \ + "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n" + +#define PCI_VENDOR_ID_V3_SEMI 0x11b0 +#define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200 + +#define PMC551_PCI_MEM_MAP0 0x50 +#define PMC551_PCI_MEM_MAP1 0x54 +#define PMC551_PCI_MEM_MAP_MAP_ADDR_MASK 0x3ff00000 +#define PMC551_PCI_MEM_MAP_APERTURE_MASK 0x000000f0 +#define PMC551_PCI_MEM_MAP_REG_EN 0x00000002 +#define PMC551_PCI_MEM_MAP_ENABLE 0x00000001 + +#define PMC551_SDRAM_MA 0x60 +#define PMC551_SDRAM_CMD 0x62 +#define PMC551_DRAM_CFG 0x64 +#define PMC551_SYS_CTRL_REG 0x78 + +#define PMC551_DRAM_BLK0 0x68 +#define PMC551_DRAM_BLK1 0x6c +#define PMC551_DRAM_BLK2 0x70 +#define PMC551_DRAM_BLK3 0x74 +#define PMC551_DRAM_BLK_GET_SIZE(x) (524288 << ((x >> 4) & 0x0f)) +#define PMC551_DRAM_BLK_SET_COL_MUX(x, v) (((x) & ~0x00007000) | (((v) & 0x7) << 12)) +#define PMC551_DRAM_BLK_SET_ROW_MUX(x, v) (((x) & ~0x00000f00) | (((v) & 0xf) << 8)) + +struct mypriv { + struct pci_dev *dev; + u_char *start; + u32 base_map0; + u32 curr_map0; + u32 asize; + struct mtd_info *nextpmc551; +}; static struct mtd_info *pmc551list; +static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, void **virt, resource_size_t *phys); + static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) { struct mypriv *priv = mtd->priv; diff --git a/include/linux/mtd/pmc551.h b/include/linux/mtd/pmc551.h deleted file mode 100644 index da8b98d1b330..000000000000 --- a/include/linux/mtd/pmc551.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * PMC551 PCI Mezzanine Ram Device - * - * Author: - * Mark Ferrell - * Copyright 1999,2000 Nortel Networks - * - * License: - * As part of this driver was derrived from the slram.c driver it falls - * under the same license, which is GNU General Public License v2 - */ - -#ifndef __MTD_PMC551_H__ -#define __MTD_PMC551_H__ - -#include - -#define PMC551_VERSION \ - "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n" - -/* - * Our personal and private information - */ -struct mypriv { - struct pci_dev *dev; - u_char *start; - u32 base_map0; - u32 curr_map0; - u32 asize; - struct mtd_info *nextpmc551; -}; - -/* - * Function Prototypes - */ -static int pmc551_erase(struct mtd_info *, struct erase_info *); -static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys); -static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); -static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); - - -/* - * Define the PCI ID's if the kernel doesn't define them for us - */ -#ifndef PCI_VENDOR_ID_V3_SEMI -#define PCI_VENDOR_ID_V3_SEMI 0x11b0 -#endif - -#ifndef PCI_DEVICE_ID_V3_SEMI_V370PDC -#define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200 -#endif - - -#define PMC551_PCI_MEM_MAP0 0x50 -#define PMC551_PCI_MEM_MAP1 0x54 -#define PMC551_PCI_MEM_MAP_MAP_ADDR_MASK 0x3ff00000 -#define PMC551_PCI_MEM_MAP_APERTURE_MASK 0x000000f0 -#define PMC551_PCI_MEM_MAP_REG_EN 0x00000002 -#define PMC551_PCI_MEM_MAP_ENABLE 0x00000001 - -#define PMC551_SDRAM_MA 0x60 -#define PMC551_SDRAM_CMD 0x62 -#define PMC551_DRAM_CFG 0x64 -#define PMC551_SYS_CTRL_REG 0x78 - -#define PMC551_DRAM_BLK0 0x68 -#define PMC551_DRAM_BLK1 0x6c -#define PMC551_DRAM_BLK2 0x70 -#define PMC551_DRAM_BLK3 0x74 -#define PMC551_DRAM_BLK_GET_SIZE(x) (524288<<((x>>4)&0x0f)) -#define PMC551_DRAM_BLK_SET_COL_MUX(x,v) (((x) & ~0x00007000) | (((v) & 0x7) << 12)) -#define PMC551_DRAM_BLK_SET_ROW_MUX(x,v) (((x) & ~0x00000f00) | (((v) & 0xf) << 8)) - - -#endif /* __MTD_PMC551_H__ */ - -- cgit v1.2.3 From 0dd5235f51fb0eb0b8cef3fed35be39b8a06d7bd Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 8 Feb 2012 15:13:26 +0200 Subject: mtd: harmonize mtd_point interface implementation Some MTD drivers return -EINVAL if the 'phys' parameter is not NULL, trying to convey that they cannot return the physical address. However, this is not very logical because they still can return the virtual address ('virt'). But some drivers (lpddr) just ignore the 'phys' parameter instead, which is a more logical thing to do. Let's harmonize this and: 1. Always initialize 'virt' and 'phys' to 'NULL' in 'mtd_point()'. 2. Do not return an error if the physical address cannot be found. So as a result, all drivers will set 'phys' to 'NULL' if it is not supported. None of the 'mtd_point()' users use 'phys' anyway, so this should not break anything. I guess we could also just delete this parameter later. Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/mtdram.c | 3 --- drivers/mtd/devices/phram.c | 4 ---- drivers/mtd/devices/pmc551.c | 4 ---- drivers/mtd/devices/slram.c | 3 --- drivers/mtd/mtdcore.c | 3 +++ 5 files changed, 3 insertions(+), 14 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c index 0e0e6ed4443c..ec59d65897fb 100644 --- a/drivers/mtd/devices/mtdram.c +++ b/drivers/mtd/devices/mtdram.c @@ -43,9 +43,6 @@ static int ram_erase(struct mtd_info *mtd, struct erase_info *instr) static int ram_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys) { - /* can we return a physical address with this driver? */ - if (phys) - return -EINVAL; *virt = mtd->priv + from; *retlen = len; return 0; diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index d3474a48d097..9d2bf1741fb2 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -51,10 +51,6 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys) { - /* can we return a physical address with this driver? */ - if (phys) - return -EINVAL; - *virt = mtd->priv + from; *retlen = len; return 0; diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index 6269a434f304..c4368ec39d5c 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c @@ -205,10 +205,6 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len); #endif - /* can we return a physical address with this driver? */ - if (phys) - return -EINVAL; - soff_hi = from & ~(priv->asize - 1); soff_lo = from & (priv->asize - 1); diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index 842e4890d771..ccd39ff509b1 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c @@ -99,9 +99,6 @@ static int slram_point(struct mtd_info *mtd, loff_t from, size_t len, { slram_priv_t *priv = mtd->priv; - /* can we return a physical address with this driver? */ - if (phys) - return -EINVAL; *virt = priv->start + from; *retlen = len; return(0); diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index ead52b388492..b20346e9fecb 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -706,6 +706,9 @@ int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys) { *retlen = 0; + *virt = NULL; + if (phys) + *phys = 0; if (!mtd->_point) return -EOPNOTSUPP; if (from < 0 || from > mtd->size || len > mtd->size - from) -- cgit v1.2.3 From bcb1d238716d138c9e16347fc32b3c1ae006339e Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 6 Feb 2012 13:27:43 +0200 Subject: mtd: move zero length verification to MTD API functions In many places in drivers we verify for the zero length, but this is very inconsistent across drivers. This is obviously the right thing to do, though. This patch moves the check to the MTD API functions instead and removes a lot of duplication. Signed-off-by: Artem Bityutskiy Reviewed-by: Shmulik Ladkani Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0001.c | 3 --- drivers/mtd/chips/cfi_cmdset_0002.c | 9 --------- drivers/mtd/chips/cfi_cmdset_0020.c | 3 --- drivers/mtd/devices/block2mtd.c | 3 --- drivers/mtd/devices/lart.c | 3 --- drivers/mtd/devices/m25p80.c | 12 ------------ drivers/mtd/devices/mtd_dataflash.c | 10 ---------- drivers/mtd/devices/spear_smi.c | 6 ------ drivers/mtd/devices/sst25l.c | 8 -------- drivers/mtd/lpddr/lpddr_cmds.c | 1 - drivers/mtd/maps/vmu-flash.c | 8 -------- drivers/mtd/mtdcore.c | 21 +++++++++++++++++++++ drivers/mtd/nand/nand_base.c | 10 ---------- 13 files changed, 21 insertions(+), 76 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index dc66df6ab58a..2d9669047ed4 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -1566,9 +1566,6 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le int chipnum; unsigned long ofs; - if (!len) - return 0; - chipnum = to >> cfi->chipshift; ofs = to - (chipnum << cfi->chipshift); diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index a89d899efad4..c1d4624ce6e7 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -1246,9 +1246,6 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len, unsigned long ofs, chipstart; DECLARE_WAITQUEUE(wait, current); - if (!len) - return 0; - chipnum = to >> cfi->chipshift; ofs = to - (chipnum << cfi->chipshift); chipstart = cfi->chips[chipnum].start; @@ -1487,9 +1484,6 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, int chipnum; unsigned long ofs; - if (!len) - return 0; - chipnum = to >> cfi->chipshift; ofs = to - (chipnum << cfi->chipshift); @@ -1697,9 +1691,6 @@ static int cfi_amdstd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, int ret = 0; int chipnum; - if (!len) - return 0; - chipnum = to >> cfi->chipshift; ofs = to - (chipnum << cfi->chipshift); chipstart = cfi->chips[chipnum].start; diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index d690b7d6952b..096993f9711e 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c @@ -615,9 +615,6 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, int chipnum; unsigned long ofs; - if (!len) - return 0; - chipnum = to >> cfi->chipshift; ofs = to - (chipnum << cfi->chipshift); diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index ba2d74b01c7e..a4a80b742e65 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -178,9 +178,6 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len, struct block2mtd_dev *dev = mtd->priv; int err; - if (!len) - return 0; - mutex_lock(&dev->write_mutex); err = _block2mtd_write(dev, buf, to, len, retlen); mutex_unlock(&dev->write_mutex); diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index 6fb8dba76959..82bd00af5cc3 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -437,9 +437,6 @@ static int flash_read (struct mtd_info *mtd,loff_t from,size_t len,size_t *retle printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n", __func__, (__u32)from, len); #endif - /* sanity checks */ - if (!len) return (0); - /* we always read len bytes */ *retlen = len; diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 45cc4a1ae5b0..1924d247c1cb 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -346,10 +346,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), __func__, (u32)from, len); - /* sanity checks */ - if (!len) - return 0; - spi_message_init(&m); memset(t, 0, (sizeof t)); @@ -408,10 +404,6 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev), __func__, (u32)to, len); - /* sanity checks */ - if (!len) - return(0); - spi_message_init(&m); memset(t, 0, (sizeof t)); @@ -495,10 +487,6 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev), __func__, (u32)to, len); - /* sanity checks */ - if (!len) - return 0; - spi_message_init(&m); memset(t, 0, (sizeof t)); diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index c76b4464e8b9..928fb0e6d73a 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -249,10 +249,6 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, pr_debug("%s: read 0x%x..0x%x\n", dev_name(&priv->spi->dev), (unsigned)from, (unsigned)(from + len)); - /* Sanity checks */ - if (!len) - return 0; - /* Calculate flash page/byte address */ addr = (((unsigned)from / priv->page_size) << priv->page_offset) + ((unsigned)from % priv->page_size); @@ -321,10 +317,6 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, pr_debug("%s: write 0x%x..0x%x\n", dev_name(&spi->dev), (unsigned)to, (unsigned)(to + len)); - /* Sanity checks */ - if (!len) - return 0; - spi_message_init(&msg); x[0].tx_buf = command = priv->command; @@ -479,8 +471,6 @@ static ssize_t otp_read(struct spi_device *spi, unsigned base, if ((off + len) > 64) len = 64 - off; - if (len == 0) - return len; spi_message_init(&m); diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index 2cdbcc65b39f..f45dd37b771e 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -563,9 +563,6 @@ static int spear_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, u32 ctrlreg1, val; int ret; - if (!len) - return 0; - if (!flash || !dev) return -ENODEV; @@ -662,9 +659,6 @@ static int spear_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, if (!flash || !dev) return -ENODEV; - if (!len) - return 0; - if (flash->bank > dev->num_flashes - 1) { dev_err(&dev->pdev->dev, "Invalid Bank Num"); return -EINVAL; diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index 5c2613c99e4a..51b2df33b8e9 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c @@ -220,10 +220,6 @@ static int sst25l_read(struct mtd_info *mtd, loff_t from, size_t len, unsigned char command[4]; int ret; - /* Sanity checking */ - if (len == 0) - return 0; - spi_message_init(&message); memset(&transfer, 0, sizeof(transfer)); @@ -265,10 +261,6 @@ static int sst25l_write(struct mtd_info *mtd, loff_t to, size_t len, int i, j, ret, bytes, copied = 0; unsigned char command[5]; - /* Sanity checks */ - if (!len) - return 0; - if ((uint32_t)to % mtd->writesize) return -EINVAL; diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index a92906ba535d..d3cfe26beeaa 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c @@ -639,7 +639,6 @@ static int lpddr_writev(struct mtd_info *mtd, const struct kvec *vecs, int chipnum; unsigned long ofs, vec_seek, i; int wbufsize = 1 << lpddr->qinfo->BufSizeShift; - size_t len = 0; for (i = 0; i < count; i++) diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c index 48a803e2cd2e..2e2b0945edc7 100644 --- a/drivers/mtd/maps/vmu-flash.c +++ b/drivers/mtd/maps/vmu-flash.c @@ -360,9 +360,6 @@ static int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len, int index = 0, retval, partition, leftover, numblocks; unsigned char cx; - if (len < 1) - return -EIO; - mpart = mtd->priv; mdev = mpart->mdev; partition = mpart->partition; @@ -434,11 +431,6 @@ static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len, partition = mpart->partition; card = maple_get_drvdata(mdev); - /* simple sanity checks */ - if (len < 1) { - error = -EIO; - goto failed; - } numblocks = card->parts[partition].numblocks; if (to + len > numblocks * card->blocklen) len = numblocks * card->blocklen - to; diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index b20346e9fecb..6acc4fb254e2 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -695,6 +695,11 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) return -EINVAL; if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; + if (!instr->len) { + instr->state = MTD_ERASE_DONE; + mtd_erase_callback(instr); + return 0; + } return mtd->_erase(mtd, instr); } EXPORT_SYMBOL_GPL(mtd_erase); @@ -713,6 +718,8 @@ int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, return -EOPNOTSUPP; if (from < 0 || from > mtd->size || len > mtd->size - from) return -EINVAL; + if (!len) + return 0; return mtd->_point(mtd, from, len, retlen, virt, phys); } EXPORT_SYMBOL_GPL(mtd_point); @@ -724,6 +731,8 @@ int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len) return -EOPNOTSUPP; if (from < 0 || from > mtd->size || len > mtd->size - from) return -EINVAL; + if (!len) + return 0; return mtd->_unpoint(mtd, from, len); } EXPORT_SYMBOL_GPL(mtd_unpoint); @@ -750,6 +759,8 @@ int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, *retlen = 0; if (from < 0 || from > mtd->size || len > mtd->size - from) return -EINVAL; + if (!len) + return 0; return mtd->_read(mtd, from, len, retlen, buf); } EXPORT_SYMBOL_GPL(mtd_read); @@ -762,6 +773,8 @@ int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, return -EINVAL; if (!mtd->_write || !(mtd->flags & MTD_WRITEABLE)) return -EROFS; + if (!len) + return 0; return mtd->_write(mtd, to, len, retlen, buf); } EXPORT_SYMBOL_GPL(mtd_write); @@ -783,6 +796,8 @@ int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, return -EINVAL; if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; + if (!len) + return 0; return mtd->_panic_write(mtd, to, len, retlen, buf); } EXPORT_SYMBOL_GPL(mtd_panic_write); @@ -794,6 +809,8 @@ int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) return -EOPNOTSUPP; if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) return -EINVAL; + if (!len) + return 0; return mtd->_lock(mtd, ofs, len); } EXPORT_SYMBOL_GPL(mtd_lock); @@ -804,6 +821,8 @@ int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) return -EOPNOTSUPP; if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) return -EINVAL; + if (!len) + return 0; return mtd->_unlock(mtd, ofs, len); } EXPORT_SYMBOL_GPL(mtd_unlock); @@ -814,6 +833,8 @@ int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) return -EOPNOTSUPP; if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) return -EINVAL; + if (!len) + return 0; return mtd->_is_locked(mtd, ofs, len); } EXPORT_SYMBOL_GPL(mtd_is_locked); diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index dd182c8591a9..5822e3a47ded 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -1614,9 +1614,6 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, struct mtd_oob_ops ops; int ret; - if (!len) - return 0; - nand_get_device(chip, mtd, FL_READING); ops.len = len; ops.datbuf = buf; @@ -2313,10 +2310,6 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, struct mtd_oob_ops ops; int ret; - /* Do not allow reads past end of device */ - if (!len) - return 0; - /* Wait for the device to get ready */ panic_nand_wait(mtd, chip, 400); @@ -2351,9 +2344,6 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, struct mtd_oob_ops ops; int ret; - if (!len) - return 0; - nand_get_device(chip, mtd, FL_WRITING); ops.len = len; ops.datbuf = (uint8_t *)buf; -- cgit v1.2.3 From 31716a5ad32771be8339832b62aa030c263c6dac Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Sat, 3 Mar 2012 21:57:33 +0100 Subject: mtd: docg3 trivial renaming Change the name of the mtd so that it is simpler, and is easier to cope with by mtdparts. Signed-off-by: Robert Jarzmik Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/docg3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index fc7932b33da4..3eafef383a39 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1804,7 +1804,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd) switch (chip_id) { case DOC_CHIPID_G3: - mtd->name = kasprintf(GFP_KERNEL, "DiskOnChip G3 floor %d", + mtd->name = kasprintf(GFP_KERNEL, "docg3.%d", docg3->device_id); docg3->max_block = 2047; break; -- cgit v1.2.3 From 42d7fbe223ab878b23de9e3b0166f8cd665a2aa5 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 9 Mar 2012 19:24:26 +0200 Subject: mtd: do not use plain 0 as NULL The first 3 arguments of 'mtd_device_parse_register()' are pointers, but many callers pass '0' instead of 'NULL'. Fix this globally. Thanks to coccinelle for making it easy to do with the following semantic patch: @@ expression mtd, types, parser_data, parts, nr_parts; @@ ( -mtd_device_parse_register(mtd, 0, parser_data, parts, nr_parts) +mtd_device_parse_register(mtd, NULL, parser_data, parts, nr_parts) | -mtd_device_parse_register(mtd, types, 0, parts, nr_parts) +mtd_device_parse_register(mtd, types, NULL, parts, nr_parts) | -mtd_device_parse_register(mtd, types, parser_data, 0, nr_parts) +mtd_device_parse_register(mtd, types, parser_data, NULL, nr_parts) ) Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- arch/mips/cavium-octeon/flash_setup.c | 2 +- drivers/mtd/devices/spear_smi.c | 2 +- drivers/mtd/devices/sst25l.c | 6 +++--- drivers/mtd/maps/bfin-async-flash.c | 4 ++-- drivers/mtd/maps/dc21285.c | 2 +- drivers/mtd/maps/gpio-addr-flash.c | 4 ++-- drivers/mtd/maps/h720x-flash.c | 4 ++-- drivers/mtd/maps/impa7.c | 2 +- drivers/mtd/maps/intel_vr_nor.c | 2 +- drivers/mtd/maps/ixp2000.c | 2 +- drivers/mtd/maps/lantiq-flash.c | 5 +++-- drivers/mtd/maps/latch-addr-flash.c | 5 +++-- drivers/mtd/maps/physmap.c | 2 +- drivers/mtd/maps/plat-ram.c | 5 +++-- drivers/mtd/maps/pxa2xx-flash.c | 3 ++- drivers/mtd/maps/rbtx4939-flash.c | 4 ++-- drivers/mtd/maps/sa1100-flash.c | 4 ++-- drivers/mtd/maps/solutionengine.c | 4 ++-- drivers/mtd/maps/wr_sbc82xx_flash.c | 2 +- drivers/mtd/nand/atmel_nand.c | 4 ++-- drivers/mtd/nand/bcm_umi_nand.c | 2 +- drivers/mtd/nand/cafe_nand.c | 2 +- drivers/mtd/nand/cmx270_nand.c | 2 +- drivers/mtd/nand/cs553x_nand.c | 2 +- drivers/mtd/nand/davinci_nand.c | 4 ++-- drivers/mtd/nand/fsmc_nand.c | 14 +++++++------- drivers/mtd/nand/h1910.c | 4 ++-- drivers/mtd/nand/jz4740_nand.c | 6 +++--- drivers/mtd/nand/mxc_nand.c | 4 ++-- drivers/mtd/nand/omap2.c | 4 ++-- drivers/mtd/nand/orion_nand.c | 4 ++-- drivers/mtd/nand/plat_nand.c | 5 +++-- drivers/mtd/nand/ppchameleonevb.c | 18 ++++++++---------- drivers/mtd/nand/pxa3xx_nand.c | 5 +++-- drivers/mtd/nand/s3c2410.c | 4 ++-- drivers/mtd/nand/sharpsl.c | 4 ++-- drivers/mtd/nand/tmio_nand.c | 6 +++--- drivers/mtd/nand/txx9ndfmc.c | 2 +- drivers/mtd/onenand/generic.c | 6 +++--- drivers/mtd/onenand/omap2.c | 6 +++--- drivers/mtd/onenand/samsung.c | 2 +- 41 files changed, 89 insertions(+), 85 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/arch/mips/cavium-octeon/flash_setup.c b/arch/mips/cavium-octeon/flash_setup.c index 0a430e06f5e5..e44a55bc7f0d 100644 --- a/arch/mips/cavium-octeon/flash_setup.c +++ b/arch/mips/cavium-octeon/flash_setup.c @@ -60,7 +60,7 @@ static int __init flash_init(void) if (mymtd) { mymtd->owner = THIS_MODULE; mtd_device_parse_register(mymtd, part_probe_types, - 0, NULL, 0); + NULL, NULL, 0); } else { pr_err("Failed to register MTD device for flash\n"); } diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index f45dd37b771e..f2016b5f59b6 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -851,7 +851,7 @@ static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank) goto err_map; } } - ret = mtd_device_parse_register(&flash->mtd, NULL, 0, parts, count); + ret = mtd_device_parse_register(&flash->mtd, NULL, NULL, parts, count); if (ret) dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret); diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index 51b2df33b8e9..ab8a2f4c8d60 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c @@ -399,9 +399,9 @@ static int __devinit sst25l_probe(struct spi_device *spi) flash->mtd.numeraseregions); - ret = mtd_device_parse_register(&flash->mtd, NULL, 0, - data ? data->parts : NULL, - data ? data->nr_parts : 0); + ret = mtd_device_parse_register(&flash->mtd, NULL, NULL, + data ? data->parts : NULL, + data ? data->nr_parts : 0); if (ret) { kfree(flash); dev_set_drvdata(&spi->dev, NULL); diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c index 650126c361f1..ef5cde84a8b3 100644 --- a/drivers/mtd/maps/bfin-async-flash.c +++ b/drivers/mtd/maps/bfin-async-flash.c @@ -164,8 +164,8 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev) return -ENXIO; } - mtd_device_parse_register(state->mtd, part_probe_types, 0, - pdata->parts, pdata->nr_parts); + mtd_device_parse_register(state->mtd, part_probe_types, NULL, + pdata->parts, pdata->nr_parts); platform_set_drvdata(pdev, state); diff --git a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c index f43b365b848c..080f06053bd4 100644 --- a/drivers/mtd/maps/dc21285.c +++ b/drivers/mtd/maps/dc21285.c @@ -196,7 +196,7 @@ static int __init init_dc21285(void) dc21285_mtd->owner = THIS_MODULE; - mtd_device_parse_register(dc21285_mtd, probes, 0, NULL, 0); + mtd_device_parse_register(dc21285_mtd, probes, NULL, NULL, 0); if(machine_is_ebsa285()) { /* diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c index 33cce895859f..e4de96ba52b3 100644 --- a/drivers/mtd/maps/gpio-addr-flash.c +++ b/drivers/mtd/maps/gpio-addr-flash.c @@ -252,8 +252,8 @@ static int __devinit gpio_flash_probe(struct platform_device *pdev) } - mtd_device_parse_register(state->mtd, part_probe_types, 0, - pdata->parts, pdata->nr_parts); + mtd_device_parse_register(state->mtd, part_probe_types, NULL, + pdata->parts, pdata->nr_parts); return 0; } diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c index 49c14187fc66..8ed6cb4529d8 100644 --- a/drivers/mtd/maps/h720x-flash.c +++ b/drivers/mtd/maps/h720x-flash.c @@ -85,8 +85,8 @@ static int __init h720x_mtd_init(void) if (mymtd) { mymtd->owner = THIS_MODULE; - mtd_device_parse_register(mymtd, NULL, 0, - h720x_partitions, NUM_PARTITIONS); + mtd_device_parse_register(mymtd, NULL, NULL, + h720x_partitions, NUM_PARTITIONS); return 0; } diff --git a/drivers/mtd/maps/impa7.c b/drivers/mtd/maps/impa7.c index f47aedb24366..834a06c56f56 100644 --- a/drivers/mtd/maps/impa7.c +++ b/drivers/mtd/maps/impa7.c @@ -91,7 +91,7 @@ static int __init init_impa7(void) if (impa7_mtd[i]) { impa7_mtd[i]->owner = THIS_MODULE; devicesfound++; - mtd_device_parse_register(impa7_mtd[i], NULL, 0, + mtd_device_parse_register(impa7_mtd[i], NULL, NULL, partitions, ARRAY_SIZE(partitions)); } diff --git a/drivers/mtd/maps/intel_vr_nor.c b/drivers/mtd/maps/intel_vr_nor.c index 08c239604ee4..92e1f41634c7 100644 --- a/drivers/mtd/maps/intel_vr_nor.c +++ b/drivers/mtd/maps/intel_vr_nor.c @@ -72,7 +72,7 @@ static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p) { /* register the flash bank */ /* partition the flash bank */ - return mtd_device_parse_register(p->info, NULL, 0, NULL, 0); + return mtd_device_parse_register(p->info, NULL, NULL, NULL, 0); } static void __devexit vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p) diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c index fc7d4d0d9a4e..4a41ced0f710 100644 --- a/drivers/mtd/maps/ixp2000.c +++ b/drivers/mtd/maps/ixp2000.c @@ -226,7 +226,7 @@ static int ixp2000_flash_probe(struct platform_device *dev) } info->mtd->owner = THIS_MODULE; - err = mtd_device_parse_register(info->mtd, probes, 0, NULL, 0); + err = mtd_device_parse_register(info->mtd, probes, NULL, NULL, 0); if (err) goto Error; diff --git a/drivers/mtd/maps/lantiq-flash.c b/drivers/mtd/maps/lantiq-flash.c index cf7a3cddad35..b5401e355745 100644 --- a/drivers/mtd/maps/lantiq-flash.c +++ b/drivers/mtd/maps/lantiq-flash.c @@ -169,8 +169,9 @@ ltq_mtd_probe(struct platform_device *pdev) cfi->addr_unlock1 ^= 1; cfi->addr_unlock2 ^= 1; - err = mtd_device_parse_register(ltq_mtd->mtd, ltq_probe_types, 0, - ltq_mtd_data->parts, ltq_mtd_data->nr_parts); + err = mtd_device_parse_register(ltq_mtd->mtd, ltq_probe_types, NULL, + ltq_mtd_data->parts, + ltq_mtd_data->nr_parts); if (err) { dev_err(&pdev->dev, "failed to add partitions\n"); goto err_destroy; diff --git a/drivers/mtd/maps/latch-addr-flash.c b/drivers/mtd/maps/latch-addr-flash.c index 8fed58e3a4a8..3c7ad17fca78 100644 --- a/drivers/mtd/maps/latch-addr-flash.c +++ b/drivers/mtd/maps/latch-addr-flash.c @@ -199,8 +199,9 @@ static int __devinit latch_addr_flash_probe(struct platform_device *dev) } info->mtd->owner = THIS_MODULE; - mtd_device_parse_register(info->mtd, NULL, 0, - latch_addr_data->parts, latch_addr_data->nr_parts); + mtd_device_parse_register(info->mtd, NULL, NULL, + latch_addr_data->parts, + latch_addr_data->nr_parts); return 0; iounmap: diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 7e9233c503ab..21b0b713cacb 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -192,7 +192,7 @@ static int physmap_flash_probe(struct platform_device *dev) part_types = physmap_data->part_probe_types ? : part_probe_types; - mtd_device_parse_register(info->cmtd, part_types, 0, + mtd_device_parse_register(info->cmtd, part_types, NULL, physmap_data->parts, physmap_data->nr_parts); return 0; diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c index 45876d0e5b8e..891558de3ec1 100644 --- a/drivers/mtd/maps/plat-ram.c +++ b/drivers/mtd/maps/plat-ram.c @@ -222,8 +222,9 @@ static int platram_probe(struct platform_device *pdev) /* check to see if there are any available partitions, or wether * to add this device whole */ - err = mtd_device_parse_register(info->mtd, pdata->probes, 0, - pdata->partitions, pdata->nr_partitions); + err = mtd_device_parse_register(info->mtd, pdata->probes, NULL, + pdata->partitions, + pdata->nr_partitions); if (!err) dev_info(&pdev->dev, "registered mtd device\n"); diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index 436d121185b1..81884c277405 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c @@ -98,7 +98,8 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev) } info->mtd->owner = THIS_MODULE; - mtd_device_parse_register(info->mtd, probes, 0, flash->parts, flash->nr_parts); + mtd_device_parse_register(info->mtd, probes, NULL, flash->parts, + flash->nr_parts); platform_set_drvdata(pdev, info); return 0; diff --git a/drivers/mtd/maps/rbtx4939-flash.c b/drivers/mtd/maps/rbtx4939-flash.c index 3da63fc6f16e..6f52e1f288b6 100644 --- a/drivers/mtd/maps/rbtx4939-flash.c +++ b/drivers/mtd/maps/rbtx4939-flash.c @@ -102,8 +102,8 @@ static int rbtx4939_flash_probe(struct platform_device *dev) info->mtd->owner = THIS_MODULE; if (err) goto err_out; - err = mtd_device_parse_register(info->mtd, NULL, 0, - pdata->parts, pdata->nr_parts); + err = mtd_device_parse_register(info->mtd, NULL, NULL, pdata->parts, + pdata->nr_parts); if (err) goto err_out; diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 1eaf7b6c35e5..a675bdbcb0fe 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -264,8 +264,8 @@ static int __devinit sa1100_mtd_probe(struct platform_device *pdev) /* * Partition selection stuff. */ - mtd_device_parse_register(info->mtd, part_probes, 0, - plat->parts, plat->nr_parts); + mtd_device_parse_register(info->mtd, part_probes, NULL, plat->parts, + plat->nr_parts); platform_set_drvdata(pdev, info); err = 0; diff --git a/drivers/mtd/maps/solutionengine.c b/drivers/mtd/maps/solutionengine.c index 496c40704aff..9d900ada6708 100644 --- a/drivers/mtd/maps/solutionengine.c +++ b/drivers/mtd/maps/solutionengine.c @@ -92,8 +92,8 @@ static int __init init_soleng_maps(void) mtd_device_register(eprom_mtd, NULL, 0); } - mtd_device_parse_register(flash_mtd, probes, 0, - superh_se_partitions, NUM_PARTITIONS); + mtd_device_parse_register(flash_mtd, probes, NULL, + superh_se_partitions, NUM_PARTITIONS); return 0; } diff --git a/drivers/mtd/maps/wr_sbc82xx_flash.c b/drivers/mtd/maps/wr_sbc82xx_flash.c index aa7e0cb2893c..71b0ba797912 100644 --- a/drivers/mtd/maps/wr_sbc82xx_flash.c +++ b/drivers/mtd/maps/wr_sbc82xx_flash.c @@ -142,7 +142,7 @@ static int __init init_sbc82xx_flash(void) nr_parts = ARRAY_SIZE(smallflash_parts); } - mtd_device_parse_register(sbcmtd[i], part_probes, 0, + mtd_device_parse_register(sbcmtd[i], part_probes, NULL, defparts, nr_parts); } return 0; diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 35b4fb55dbd6..7769519a54a7 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -650,8 +650,8 @@ static int __init atmel_nand_probe(struct platform_device *pdev) } mtd->name = "atmel_nand"; - res = mtd_device_parse_register(mtd, NULL, 0, - host->board->parts, host->board->num_parts); + res = mtd_device_parse_register(mtd, NULL, NULL, host->board->parts, + host->board->num_parts); if (!res) return res; diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c index 50387fd4009b..ee81b6333f6a 100644 --- a/drivers/mtd/nand/bcm_umi_nand.c +++ b/drivers/mtd/nand/bcm_umi_nand.c @@ -488,7 +488,7 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev) /* Register the partitions */ board_mtd->name = "bcm_umi-nand"; - mtd_device_parse_register(board_mtd, NULL, 0, NULL, 0); + mtd_device_parse_register(board_mtd, NULL, NULL, NULL, 0); /* Return happy */ return 0; diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 72d3f23490c5..c23c07c5b391 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -799,7 +799,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, mtd); mtd->name = "cafe_nand"; - mtd_device_parse_register(mtd, part_probes, 0, NULL, 0); + mtd_device_parse_register(mtd, part_probes, NULL, NULL, 0); goto out; diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c index 737ef9a04fdb..1024bfc05c86 100644 --- a/drivers/mtd/nand/cmx270_nand.c +++ b/drivers/mtd/nand/cmx270_nand.c @@ -219,7 +219,7 @@ static int __init cmx270_init(void) } /* Register the partitions */ - ret = mtd_device_parse_register(cmx270_nand_mtd, NULL, 0, + ret = mtd_device_parse_register(cmx270_nand_mtd, NULL, NULL, partition_info, NUM_PARTITIONS); if (ret) goto err_scan; diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index 414afa793563..e2b7c9e4c5c2 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c @@ -313,7 +313,7 @@ static int __init cs553x_init(void) for (i = 0; i < NR_CS553X_CONTROLLERS; i++) { if (cs553x_mtd[i]) { /* If any devices registered, return success. Else the last error. */ - mtd_device_parse_register(cs553x_mtd[i], NULL, 0, + mtd_device_parse_register(cs553x_mtd[i], NULL, NULL, NULL, 0); err = 0; } diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 6e566156956f..b81afc748fff 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -752,8 +752,8 @@ syndrome_done: if (ret < 0) goto err_scan; - ret = mtd_device_parse_register(&info->mtd, NULL, 0, - pdata->parts, pdata->nr_parts); + ret = mtd_device_parse_register(&info->mtd, NULL, NULL, pdata->parts, + pdata->nr_parts); if (ret < 0) goto err_scan; diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 4a018d0b7034..341086c22e90 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -940,13 +940,13 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) * Check for partition info passed */ host->mtd.name = "nand"; - ret = mtd_device_parse_register(&host->mtd, NULL, 0, - host->mtd.size <= 0x04000000 ? - partition_info_16KB_blk : - partition_info_128KB_blk, - host->mtd.size <= 0x04000000 ? - ARRAY_SIZE(partition_info_16KB_blk) : - ARRAY_SIZE(partition_info_128KB_blk)); + ret = mtd_device_parse_register(&host->mtd, NULL, NULL, + host->mtd.size <= 0x04000000 ? + partition_info_16KB_blk : + partition_info_128KB_blk, + host->mtd.size <= 0x04000000 ? + ARRAY_SIZE(partition_info_16KB_blk) : + ARRAY_SIZE(partition_info_128KB_blk)); if (ret) goto err_probe; diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c index 5dc6f0d92f1a..11e487813428 100644 --- a/drivers/mtd/nand/h1910.c +++ b/drivers/mtd/nand/h1910.c @@ -135,8 +135,8 @@ static int __init h1910_init(void) } /* Register the partitions */ - mtd_device_parse_register(h1910_nand_mtd, NULL, 0, - partition_info, NUM_PARTITIONS); + mtd_device_parse_register(h1910_nand_mtd, NULL, NULL, partition_info, + NUM_PARTITIONS); /* Return happy */ return 0; diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index ac3b9f255e00..cc50e35cdc3d 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -367,9 +367,9 @@ static int __devinit jz_nand_probe(struct platform_device *pdev) goto err_gpio_free; } - ret = mtd_device_parse_register(mtd, NULL, 0, - pdata ? pdata->partitions : NULL, - pdata ? pdata->num_partitions : 0); + ret = mtd_device_parse_register(mtd, NULL, NULL, + pdata ? pdata->partitions : NULL, + pdata ? pdata->num_partitions : 0); if (ret) { dev_err(&pdev->dev, "Failed to add mtd device\n"); diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 74a43b818d0e..3c4c0533191d 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1226,8 +1226,8 @@ static int __init mxcnd_probe(struct platform_device *pdev) } /* Register the partitions */ - mtd_device_parse_register(mtd, part_probes, 0, - pdata->parts, pdata->nr_parts); + mtd_device_parse_register(mtd, part_probes, NULL, pdata->parts, + pdata->nr_parts); platform_set_drvdata(pdev, host); diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index b3a883e2a22f..d2e7a7da81f8 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -1101,8 +1101,8 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) goto out_release_mem_region; } - mtd_device_parse_register(&info->mtd, NULL, 0, - pdata->parts, pdata->nr_parts); + mtd_device_parse_register(&info->mtd, NULL, NULL, pdata->parts, + pdata->nr_parts); platform_set_drvdata(pdev, &info->mtd); diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 29f505adaf84..1d3bfb26080c 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -129,8 +129,8 @@ static int __init orion_nand_probe(struct platform_device *pdev) } mtd->name = "orion_nand"; - ret = mtd_device_parse_register(mtd, NULL, 0, - board->parts, board->nr_parts); + ret = mtd_device_parse_register(mtd, NULL, NULL, board->parts, + board->nr_parts); if (ret) { nand_release(mtd); goto no_dev; diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index 7f2da6953357..6404e6e81b10 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c @@ -99,8 +99,9 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) } err = mtd_device_parse_register(&data->mtd, - pdata->chip.part_probe_types, 0, - pdata->chip.partitions, pdata->chip.nr_partitions); + pdata->chip.part_probe_types, NULL, + pdata->chip.partitions, + pdata->chip.nr_partitions); if (!err) return err; diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c index 7e52af51a198..0ddd90e5788f 100644 --- a/drivers/mtd/nand/ppchameleonevb.c +++ b/drivers/mtd/nand/ppchameleonevb.c @@ -275,11 +275,10 @@ static int __init ppchameleonevb_init(void) ppchameleon_mtd->name = "ppchameleon-nand"; /* Register the partitions */ - mtd_device_parse_register(ppchameleon_mtd, NULL, 0, - ppchameleon_mtd->size == NAND_SMALL_SIZE ? - partition_info_me : - partition_info_hi, - NUM_PARTITIONS); + mtd_device_parse_register(ppchameleon_mtd, NULL, NULL, + ppchameleon_mtd->size == NAND_SMALL_SIZE ? + partition_info_me : partition_info_hi, + NUM_PARTITIONS); nand_evb_init: /**************************** @@ -365,11 +364,10 @@ static int __init ppchameleonevb_init(void) ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME; /* Register the partitions */ - mtd_device_parse_register(ppchameleonevb_mtd, NULL, 0, - ppchameleon_mtd->size == NAND_SMALL_SIZE ? - partition_info_me : - partition_info_hi, - NUM_PARTITIONS); + mtd_device_parse_register(ppchameleonevb_mtd, NULL, NULL, + ppchameleon_mtd->size == NAND_SMALL_SIZE ? + partition_info_me : partition_info_hi, + NUM_PARTITIONS); /* Return happy */ return 0; diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 5c3d719c37e6..d3bdc909c939 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1228,8 +1228,9 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) continue; } - ret = mtd_device_parse_register(info->host[cs]->mtd, NULL, 0, - pdata->parts[cs], pdata->nr_parts[cs]); + ret = mtd_device_parse_register(info->host[cs]->mtd, NULL, + NULL, pdata->parts[cs], + pdata->nr_parts[cs]); if (!ret) probe_success = 1; } diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 868685db6712..97623be04e0f 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -751,8 +751,8 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, if (set) mtd->mtd.name = set->name; - return mtd_device_parse_register(&mtd->mtd, NULL, 0, - set->partitions, set->nr_partitions); + return mtd_device_parse_register(&mtd->mtd, NULL, NULL, + set->partitions, set->nr_partitions); } /** diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index b175c0fd8b93..2d269a53f8bb 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c @@ -181,8 +181,8 @@ static int __devinit sharpsl_nand_probe(struct platform_device *pdev) /* Register the partitions */ sharpsl->mtd.name = "sharpsl-nand"; - err = mtd_device_parse_register(&sharpsl->mtd, NULL, 0, - data->partitions, data->nr_partitions); + err = mtd_device_parse_register(&sharpsl->mtd, NULL, NULL, + data->partitions, data->nr_partitions); if (err) goto err_add; diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c index 6caa0cd9d6a7..060848a91db7 100644 --- a/drivers/mtd/nand/tmio_nand.c +++ b/drivers/mtd/nand/tmio_nand.c @@ -456,9 +456,9 @@ static int tmio_probe(struct platform_device *dev) goto err_scan; } /* Register the partitions */ - retval = mtd_device_parse_register(mtd, NULL, 0, - data ? data->partition : NULL, - data ? data->num_partitions : 0); + retval = mtd_device_parse_register(mtd, NULL, NULL, + data ? data->partition : NULL, + data ? data->num_partitions : 0); if (!retval) return retval; diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c index c7c4f1d11c77..8db0acbae6fa 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/txx9ndfmc.c @@ -386,7 +386,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) } mtd->name = txx9_priv->mtdname; - mtd_device_parse_register(mtd, NULL, 0, NULL, 0); + mtd_device_parse_register(mtd, NULL, NULL, NULL, 0); drvdata->mtds[i] = mtd; } diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c index 0ccd5bff2544..1c4f97c63e62 100644 --- a/drivers/mtd/onenand/generic.c +++ b/drivers/mtd/onenand/generic.c @@ -70,9 +70,9 @@ static int __devinit generic_onenand_probe(struct platform_device *pdev) goto out_iounmap; } - err = mtd_device_parse_register(&info->mtd, NULL, 0, - pdata ? pdata->parts : NULL, - pdata ? pdata->nr_parts : 0); + err = mtd_device_parse_register(&info->mtd, NULL, NULL, + pdata ? pdata->parts : NULL, + pdata ? pdata->nr_parts : 0); platform_set_drvdata(pdev, info); diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 7e9ea6852b67..398a82783848 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -751,9 +751,9 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev) if ((r = onenand_scan(&c->mtd, 1)) < 0) goto err_release_regulator; - r = mtd_device_parse_register(&c->mtd, NULL, 0, - pdata ? pdata->parts : NULL, - pdata ? pdata->nr_parts : 0); + r = mtd_device_parse_register(&c->mtd, NULL, NULL, + pdata ? pdata->parts : NULL, + pdata ? pdata->nr_parts : 0); if (r) goto err_release_onenand; diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c index deaf7628773f..8e4b3f2742ba 100644 --- a/drivers/mtd/onenand/samsung.c +++ b/drivers/mtd/onenand/samsung.c @@ -1014,7 +1014,7 @@ static int s3c_onenand_probe(struct platform_device *pdev) if (s3c_read_reg(MEM_CFG_OFFSET) & ONENAND_SYS_CFG1_SYNC_READ) dev_info(&onenand->pdev->dev, "OneNAND Sync. Burst Read enabled\n"); - err = mtd_device_parse_register(mtd, NULL, 0, + err = mtd_device_parse_register(mtd, NULL, NULL, pdata ? pdata->parts : NULL, pdata ? pdata->nr_parts : 0); -- cgit v1.2.3 From d107bc34f4953852834f086968fc7963125d6943 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Sun, 11 Mar 2012 11:28:45 +0100 Subject: mtd: docg3 reduce read alignment burden The read function was so far requiring the reads to be aligned on page boundaries, and be page length multiples in size. Relieve these constraints to ease the userspace ubifs programs runs, which read ubifs headers of 64 bytes. Artem: squashed a later fix from Robert Jarzmik into this patch. Signed-off-by: Robert Jarzmik Signed-off-by: David Woodhouse --- drivers/mtd/devices/docg3.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 3eafef383a39..2c1d0fca6757 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -734,7 +734,7 @@ err: * doc_read_page_getbytes - Reads bytes from a prepared page * @docg3: the device * @len: the number of bytes to be read (must be a multiple of 4) - * @buf: the buffer to be filled in + * @buf: the buffer to be filled in (or NULL is forget bytes) * @first: 1 if first time read, DOC_READADDRESS should be set * */ @@ -849,7 +849,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { struct docg3 *docg3 = mtd->priv; - int block0, block1, page, ret, ofs = 0; + int block0, block1, page, ret, skip, ofs = 0; u8 *oobbuf = ops->oobbuf; u8 *buf = ops->datbuf; size_t len, ooblen, nbdata, nboob; @@ -869,8 +869,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, doc_dbg("doc_read_oob(from=%lld, mode=%d, data=(%p:%zu), oob=(%p:%zu))\n", from, ops->mode, buf, len, oobbuf, ooblen); - if ((len % DOC_LAYOUT_PAGE_SIZE) || (ooblen % DOC_LAYOUT_OOB_SIZE) || - (from % DOC_LAYOUT_PAGE_SIZE)) + if (ooblen % DOC_LAYOUT_OOB_SIZE) return -EINVAL; ret = -EINVAL; @@ -882,10 +881,11 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, ops->oobretlen = 0; ops->retlen = 0; ret = 0; + skip = from % DOC_LAYOUT_PAGE_SIZE; while (!ret && (len > 0 || ooblen > 0)) { - calc_block_sector(from, &block0, &block1, &page, &ofs, + calc_block_sector(from - skip, &block0, &block1, &page, &ofs, docg3->reliable); - nbdata = min_t(size_t, len, (size_t)DOC_LAYOUT_PAGE_SIZE); + nbdata = min_t(size_t, len, DOC_LAYOUT_PAGE_SIZE - skip); nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE); ret = doc_read_page_prepare(docg3, block0, block1, page, ofs); if (ret < 0) @@ -893,10 +893,14 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES); if (ret < 0) goto err_in_read; - ret = doc_read_page_getbytes(docg3, nbdata, buf, 1); + ret = doc_read_page_getbytes(docg3, skip, NULL, 1); + if (ret < skip) + goto err_in_read; + ret = doc_read_page_getbytes(docg3, nbdata, buf, 0); if (ret < nbdata) goto err_in_read; - doc_read_page_getbytes(docg3, DOC_LAYOUT_PAGE_SIZE - nbdata, + doc_read_page_getbytes(docg3, + DOC_LAYOUT_PAGE_SIZE - nbdata - skip, NULL, 0); ret = doc_read_page_getbytes(docg3, nboob, oobbuf, 0); if (ret < nboob) @@ -950,6 +954,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, len -= nbdata; ooblen -= nboob; from += DOC_LAYOUT_PAGE_SIZE; + skip = 0; } return ret; -- cgit v1.2.3 From 6a918bade9dab40aaef80559bd1169c69e8d69cb Mon Sep 17 00:00:00 2001 From: Mike Dunn Date: Sun, 11 Mar 2012 14:21:11 -0700 Subject: mtd: flash drivers set ecc strength Flash device drivers initialize 'ecc_strength' in struct mtd_info, which is the maximum number of bit errors that can be corrected in one writesize region. Drivers using the nand interface intitialize 'strength' in struct nand_ecc_ctrl, which is the maximum number of bit errors that can be corrected in one ecc step. Nand infrastructure code translates this to 'ecc_strength'. Also for nand drivers, the nand infrastructure code sets ecc.strength for ecc modes NAND_ECC_SOFT, NAND_ECC_SOFT_BCH, and NAND_ECC_NONE. It is set in the driver for all other modes. Signed-off-by: Mike Dunn Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/doc2000.c | 1 + drivers/mtd/devices/doc2001.c | 1 + drivers/mtd/devices/doc2001plus.c | 1 + drivers/mtd/devices/docg3.c | 1 + drivers/mtd/mtdpart.c | 1 + drivers/mtd/nand/alauda.c | 1 + drivers/mtd/nand/atmel_nand.c | 1 + drivers/mtd/nand/bcm_umi_nand.c | 8 ++++++++ drivers/mtd/nand/bf5xx_nand.c | 2 ++ drivers/mtd/nand/cafe_nand.c | 1 + drivers/mtd/nand/cs553x_nand.c | 2 ++ drivers/mtd/nand/davinci_nand.c | 1 + drivers/mtd/nand/denali.c | 3 +++ drivers/mtd/nand/diskonchip.c | 1 + drivers/mtd/nand/docg4.c | 1 + drivers/mtd/nand/fsl_elbc_nand.c | 6 ++++++ drivers/mtd/nand/fsmc_nand.c | 2 ++ drivers/mtd/nand/jz4740_nand.c | 5 +++++ drivers/mtd/nand/mxc_nand.c | 7 +++++++ drivers/mtd/nand/nand_base.c | 7 ++++++- drivers/mtd/nand/ndfc.c | 1 + drivers/mtd/nand/omap2.c | 1 + drivers/mtd/nand/pxa3xx_nand.c | 1 + drivers/mtd/nand/r852.c | 1 + drivers/mtd/nand/rtc_from4.c | 1 + drivers/mtd/nand/s3c2410.c | 1 + drivers/mtd/nand/sh_flctl.c | 1 + drivers/mtd/nand/sharpsl.c | 1 + drivers/mtd/nand/tmio_nand.c | 1 + drivers/mtd/nand/txx9ndfmc.c | 1 + drivers/mtd/onenand/onenand_base.c | 1 + 31 files changed, 63 insertions(+), 1 deletion(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index 7ad7b054800c..a4eb8b5b85ec 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c @@ -564,6 +564,7 @@ void DoC2k_init(struct mtd_info *mtd) mtd->flags = MTD_CAP_NANDFLASH; mtd->writebufsize = mtd->writesize = 512; mtd->oobsize = 16; + mtd->ecc_strength = 2; mtd->owner = THIS_MODULE; mtd->_erase = doc_erase; mtd->_read = doc_read; diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index 7bff54e62cd5..f6927955dab0 100644 --- a/drivers/mtd/devices/doc2001.c +++ b/drivers/mtd/devices/doc2001.c @@ -348,6 +348,7 @@ void DoCMil_init(struct mtd_info *mtd) mtd->erasesize = 0x2000; mtd->writebufsize = mtd->writesize = 512; mtd->oobsize = 16; + mtd->ecc_strength = 2; mtd->owner = THIS_MODULE; mtd->_erase = doc_erase; mtd->_read = doc_read; diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c index 4a03d869ad03..04eb2e4aa50f 100644 --- a/drivers/mtd/devices/doc2001plus.c +++ b/drivers/mtd/devices/doc2001plus.c @@ -469,6 +469,7 @@ void DoCMilPlus_init(struct mtd_info *mtd) mtd->flags = MTD_CAP_NANDFLASH; mtd->writebufsize = mtd->writesize = 512; mtd->oobsize = 16; + mtd->ecc_strength = 2; mtd->owner = THIS_MODULE; mtd->_erase = doc_erase; mtd->_read = doc_read; diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 2c1d0fca6757..349bbfa74d0d 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1832,6 +1832,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd) mtd->_write_oob = doc_write_oob; mtd->_block_isbad = doc_block_isbad; mtd->ecclayout = &docg3_oobinfo; + mtd->ecc_strength = DOC_ECC_BCH_T; } /** diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 226d28a618d8..9651c06de0a9 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -516,6 +516,7 @@ static struct mtd_part *allocate_partition(struct mtd_info *master, } slave->mtd.ecclayout = master->ecclayout; + slave->mtd.ecc_strength = master->ecc_strength; if (master->_block_isbad) { uint64_t offs = 0; diff --git a/drivers/mtd/nand/alauda.c b/drivers/mtd/nand/alauda.c index ac38f73fde3b..4f20e1d8bef1 100644 --- a/drivers/mtd/nand/alauda.c +++ b/drivers/mtd/nand/alauda.c @@ -591,6 +591,7 @@ static int alauda_init_media(struct alauda *al) mtd->_block_isbad = alauda_isbad; mtd->priv = al; mtd->owner = THIS_MODULE; + mtd->ecc_strength = 1; err = mtd_device_register(mtd, NULL, 0); if (err) { diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 7769519a54a7..662abf08061a 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -554,6 +554,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) nand_chip->ecc.hwctl = atmel_nand_hwctl; nand_chip->ecc.read_page = atmel_nand_read_page; nand_chip->ecc.bytes = 4; + nand_chip->ecc.strength = 1; } nand_chip->chip_delay = 20; /* 20us command delay time */ diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c index ee81b6333f6a..fc600431f519 100644 --- a/drivers/mtd/nand/bcm_umi_nand.c +++ b/drivers/mtd/nand/bcm_umi_nand.c @@ -476,6 +476,14 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev) largepage_bbt.options = NAND_BBT_SCAN2NDPAGE; this->badblock_pattern = &largepage_bbt; } + + /* + * FIXME: ecc strength value of 6 bits per 512 bytes of data is a + * conservative guess, given 13 ecc bytes and using bch alg. + * (Assume Galois field order m=15 to allow a margin of error.) + */ + this->ecc.strength = 6; + #endif /* Now finish off the scan, now that ecc.layout has been initialized. */ diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index dd899cb5d366..d7b86b925de5 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c @@ -702,9 +702,11 @@ static int bf5xx_nand_scan(struct mtd_info *mtd) if (likely(mtd->writesize >= 512)) { chip->ecc.size = 512; chip->ecc.bytes = 6; + chip->ecc.strength = 2; } else { chip->ecc.size = 256; chip->ecc.bytes = 3; + chip->ecc.strength = 1; bfin_write_NFC_CTL(bfin_read_NFC_CTL() & ~(1 << NFC_PG_SIZE_OFFSET)); SSYNC(); } diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index c23c07c5b391..2a96e1a12062 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -783,6 +783,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, cafe->nand.ecc.mode = NAND_ECC_HW_SYNDROME; cafe->nand.ecc.size = mtd->writesize; cafe->nand.ecc.bytes = 14; + cafe->nand.ecc.strength = 4; cafe->nand.ecc.hwctl = (void *)cafe_nand_bug; cafe->nand.ecc.calculate = (void *)cafe_nand_bug; cafe->nand.ecc.correct = (void *)cafe_nand_bug; diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index e2b7c9e4c5c2..821c34c62500 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c @@ -248,6 +248,8 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) goto out_ior; } + this->ecc.strength = 1; + new_mtd->name = kasprintf(GFP_KERNEL, "cs553x_nand_cs%d", cs); cs553x_mtd[cs] = new_mtd; diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index b81afc748fff..d94b03c207af 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -641,6 +641,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) info->chip.ecc.bytes = 3; } info->chip.ecc.size = 512; + info->chip.ecc.strength = pdata->ecc_bits; break; default: ret = -EINVAL; diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 3984d488f9ab..a9e57d686297 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -1590,6 +1590,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) ECC_15BITS * (denali->mtd.writesize / ECC_SECTOR_SIZE)))) { /* if MLC OOB size is large enough, use 15bit ECC*/ + denali->nand.ecc.strength = 15; denali->nand.ecc.layout = &nand_15bit_oob; denali->nand.ecc.bytes = ECC_15BITS; iowrite32(15, denali->flash_reg + ECC_CORRECTION); @@ -1600,12 +1601,14 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) " contain 8bit ECC correction codes"); goto failed_req_irq; } else { + denali->nand.ecc.strength = 8; denali->nand.ecc.layout = &nand_8bit_oob; denali->nand.ecc.bytes = ECC_8BITS; iowrite32(8, denali->flash_reg + ECC_CORRECTION); } denali->nand.ecc.bytes *= denali->devnum; + denali->nand.ecc.strength *= denali->devnum; denali->nand.ecc.layout->eccbytes *= denali->mtd.writesize / ECC_SECTOR_SIZE; denali->nand.ecc.layout->oobfree[0].offset = diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index df921e7a496c..e2ca067631cf 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -1653,6 +1653,7 @@ static int __init doc_probe(unsigned long physadr) nand->ecc.mode = NAND_ECC_HW_SYNDROME; nand->ecc.size = 512; nand->ecc.bytes = 6; + nand->ecc.strength = 2; nand->bbt_options = NAND_BBT_USE_FLASH; doc->physadr = physadr; diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index 9b3a64904668..b08202664543 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c @@ -1191,6 +1191,7 @@ static void __init init_mtd_structs(struct mtd_info *mtd) nand->ecc.size = DOCG4_PAGE_SIZE; nand->ecc.prepad = 8; nand->ecc.bytes = 8; + nand->ecc.strength = DOCG4_T; nand->options = NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE | NAND_NO_AUTOINCR; nand->IO_ADDR_R = nand->IO_ADDR_W = doc->virtadr + DOC_IOSPACE_DATA; diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 7195ee6efe12..80b5264f0a32 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -813,6 +813,12 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) &fsl_elbc_oob_sp_eccm1 : &fsl_elbc_oob_sp_eccm0; chip->ecc.size = 512; chip->ecc.bytes = 3; + chip->ecc.strength = 1; + /* + * FIXME: can hardware ecc correct 4 bitflips if page size is + * 2k? Then does hardware report number of corrections for this + * case? If so, ecc_stats reporting needs to be fixed as well. + */ } else { /* otherwise fall back to default software ECC */ chip->ecc.mode = NAND_ECC_SOFT; diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 341086c22e90..588e3733c3a4 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -863,10 +863,12 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) nand->ecc.calculate = fsmc_read_hwecc_ecc4; nand->ecc.correct = fsmc_bch8_correct_data; nand->ecc.bytes = 13; + nand->ecc.strength = 8; } else { nand->ecc.calculate = fsmc_read_hwecc_ecc1; nand->ecc.correct = nand_correct_data; nand->ecc.bytes = 3; + nand->ecc.strength = 1; } /* diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index cc50e35cdc3d..e4147e8acb7c 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -332,6 +332,11 @@ static int __devinit jz_nand_probe(struct platform_device *pdev) chip->ecc.mode = NAND_ECC_HW_OOB_FIRST; chip->ecc.size = 512; chip->ecc.bytes = 9; + chip->ecc.strength = 2; + /* + * FIXME: ecc_strength value of 2 bits per 512 bytes of data is a + * conservative guess, given 9 ecc bytes and reed-solomon alg. + */ if (pdata) chip->ecc.layout = pdata->ecc_layout; diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 3c4c0533191d..cc0678a967c1 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1225,6 +1225,13 @@ static int __init mxcnd_probe(struct platform_device *pdev) goto escan; } + if (this->ecc.mode == NAND_ECC_HW) { + if (nfc_is_v1()) + this->ecc.strength = 1; + else + this->ecc.strength = (host->eccsize == 4) ? 4 : 8; + } + /* Register the partitions */ mtd_device_parse_register(mtd, part_probes, NULL, pdata->parts, pdata->nr_parts); diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 1e907dc8638a..8008853756c9 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3350,6 +3350,7 @@ int nand_scan_tail(struct mtd_info *mtd) if (!chip->ecc.size) chip->ecc.size = 256; chip->ecc.bytes = 3; + chip->ecc.strength = 1; break; case NAND_ECC_SOFT_BCH: @@ -3384,6 +3385,8 @@ int nand_scan_tail(struct mtd_info *mtd) pr_warn("BCH ECC initialization failed!\n"); BUG(); } + chip->ecc.strength = + chip->ecc.bytes*8 / fls(8*chip->ecc.size); break; case NAND_ECC_NONE: @@ -3397,6 +3400,7 @@ int nand_scan_tail(struct mtd_info *mtd) chip->ecc.write_oob = nand_write_oob_std; chip->ecc.size = mtd->writesize; chip->ecc.bytes = 0; + chip->ecc.strength = 0; break; default: @@ -3478,8 +3482,9 @@ int nand_scan_tail(struct mtd_info *mtd) mtd->_block_markbad = nand_block_markbad; mtd->writebufsize = mtd->writesize; - /* propagate ecc.layout to mtd_info */ + /* propagate ecc info to mtd_info */ mtd->ecclayout = chip->ecc.layout; + mtd->ecc_strength = chip->ecc.strength * chip->ecc.steps; /* Check, if we should skip the bad block table scan */ if (chip->options & NAND_SKIP_BBTSCAN) diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index ec688548c880..2b6f632cf274 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -179,6 +179,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, chip->ecc.mode = NAND_ECC_HW; chip->ecc.size = 256; chip->ecc.bytes = 3; + chip->ecc.strength = 1; chip->priv = ndfc; ndfc->mtd.priv = chip; diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index d2e7a7da81f8..c2b0bba9d8b3 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -1058,6 +1058,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) { info->nand.ecc.bytes = 3; info->nand.ecc.size = 512; + info->nand.ecc.strength = 1; info->nand.ecc.calculate = omap_calculate_ecc; info->nand.ecc.hwctl = omap_enable_hwecc; info->nand.ecc.correct = omap_correct_data; diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index d3bdc909c939..def50caa6f84 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1002,6 +1002,7 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) KEEP_CONFIG: chip->ecc.mode = NAND_ECC_HW; chip->ecc.size = host->page_size; + chip->ecc.strength = 1; chip->options = NAND_NO_AUTOINCR; chip->options |= NAND_NO_READRDY; diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index 769a4e096b3c..c2040187c813 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -891,6 +891,7 @@ int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) chip->ecc.mode = NAND_ECC_HW_SYNDROME; chip->ecc.size = R852_DMA_LEN; chip->ecc.bytes = SM_OOB_SIZE; + chip->ecc.strength = 2; chip->ecc.hwctl = r852_ecc_hwctl; chip->ecc.calculate = r852_ecc_calculate; chip->ecc.correct = r852_ecc_correct; diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c index f309addc2fa0..e55b5cfbe145 100644 --- a/drivers/mtd/nand/rtc_from4.c +++ b/drivers/mtd/nand/rtc_from4.c @@ -527,6 +527,7 @@ static int __init rtc_from4_init(void) this->ecc.mode = NAND_ECC_HW_SYNDROME; this->ecc.size = 512; this->ecc.bytes = 8; + this->ecc.strength = 3; /* return the status of extra status and ECC checks */ this->errstat = rtc_from4_errstat; /* set the nand_oobinfo to support FPGA H/W error detection */ diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 97623be04e0f..91121f33f743 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -823,6 +823,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, chip->ecc.calculate = s3c2410_nand_calculate_ecc; chip->ecc.correct = s3c2410_nand_correct_data; chip->ecc.mode = NAND_ECC_HW; + chip->ecc.strength = 1; switch (info->cpu_type) { case TYPE_S3C2410: diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index 2ee9a1b50a22..e9b2b260de3a 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c @@ -825,6 +825,7 @@ static int flctl_chip_init_tail(struct mtd_info *mtd) chip->ecc.size = 512; chip->ecc.bytes = 10; + chip->ecc.strength = 4; chip->ecc.read_page = flctl_read_page_hwecc; chip->ecc.write_page = flctl_write_page_hwecc; chip->ecc.mode = NAND_ECC_HW; diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 2d269a53f8bb..3421e3762a5a 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c @@ -167,6 +167,7 @@ static int __devinit sharpsl_nand_probe(struct platform_device *pdev) this->ecc.mode = NAND_ECC_HW; this->ecc.size = 256; this->ecc.bytes = 3; + this->ecc.strength = 1; this->badblock_pattern = data->badblock_pattern; this->ecc.layout = data->ecc_layout; this->ecc.hwctl = sharpsl_nand_enable_hwecc; diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c index 060848a91db7..5aa518081c51 100644 --- a/drivers/mtd/nand/tmio_nand.c +++ b/drivers/mtd/nand/tmio_nand.c @@ -430,6 +430,7 @@ static int tmio_probe(struct platform_device *dev) nand_chip->ecc.mode = NAND_ECC_HW; nand_chip->ecc.size = 512; nand_chip->ecc.bytes = 6; + nand_chip->ecc.strength = 2; nand_chip->ecc.hwctl = tmio_nand_enable_hwecc; nand_chip->ecc.calculate = tmio_nand_calculate_ecc; nand_chip->ecc.correct = tmio_nand_correct_data; diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c index 8db0acbae6fa..26398dcf21cf 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/txx9ndfmc.c @@ -356,6 +356,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) /* txx9ndfmc_nand_scan will overwrite ecc.size and ecc.bytes */ chip->ecc.size = 256; chip->ecc.bytes = 3; + chip->ecc.strength = 1; chip->chip_delay = 100; chip->controller = &drvdata->hw_control; diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index a1592cf755f3..3d781b87b358 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -4080,6 +4080,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) mtd->oobavail = this->ecclayout->oobavail; mtd->ecclayout = this->ecclayout; + mtd->ecc_strength = 1; /* Fill in remaining MTD driver data */ mtd->type = ONENAND_IS_MLC(this) ? MTD_MLCNANDFLASH : MTD_NANDFLASH; -- cgit v1.2.3 From b2a2a84d35e0f42ad26e326ec4258f6a8b8eecbe Mon Sep 17 00:00:00 2001 From: Hervé Fache Date: Tue, 13 Mar 2012 16:07:53 +0100 Subject: mtd: phram: dot not crash when built-in and passing boot param MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch is based on Ville Herva's similar patch to block2mtd. Trying to pass a parameter through the kernel command line when built-in would crash the kernel, as phram_setup() was called so early that kmalloc() was not functional yet. This patch only saves the parameter string at the early boot stage, and parses it later when init_phram() is called. The same happens in both module and built-in cases. With this patch, I can boot with a statically-compiled phram, and mount a ext2 root fs from physical RAM, without the need for a initrd. This has been tested in built-in and module cases, with and without a parameter string. Artem: amended comments a bit Signed-off-by: Hervé Fache Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/phram.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 9d2bf1741fb2..3d91ace1ee4c 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -39,7 +39,8 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) memset(start + instr->addr, 0xff, instr->len); - /* This'll catch a few races. Free the thing before returning :) + /* + * This'll catch a few races. Free the thing before returning :) * I don't feel at all ashamed. This kind of thing is possible anyway * with flash, but unlikely. */ @@ -204,7 +205,17 @@ static inline void kill_final_newline(char *str) return 1; \ } while (0) -static int phram_setup(const char *val, struct kernel_param *kp) +/* + * This shall contain the module parameter if any. It is of the form: + * - phram=,
, for module case + * - phram.phram=,
, for built-in case + * We leave 64 bytes for the device name, 12 for the address and 12 for the + * size. + * Example: phram.phram=rootfs,0xa0000000,512Mi + */ +static __initdata char phram_paramline[64+12+12]; + +static int phram_setup(const char *val) { char buf[64+12+12], *str = buf; char *token[3]; @@ -253,12 +264,28 @@ static int phram_setup(const char *val, struct kernel_param *kp) return ret; } -module_param_call(phram, phram_setup, NULL, NULL, 000); +static int __init phram_param_call(const char *val, struct kernel_param *kp) +{ + /* + * This function is always called before 'init_phram()', whether + * built-in or module. + */ + if (strlen(val) >= sizeof(phram_paramline)) + return -ENOSPC; + strcpy(phram_paramline, val); + + return 0; +} + +module_param_call(phram, phram_param_call, NULL, NULL, 000); MODULE_PARM_DESC(phram, "Memory region to map. \"phram=,,\""); static int __init init_phram(void) { + if (phram_paramline[0]) + return phram_setup(phram_paramline); + return 0; } -- cgit v1.2.3 From 30053b87d5b97aca28dd7a59982cbb161eaf01c6 Mon Sep 17 00:00:00 2001 From: Ryosuke Saito Date: Thu, 15 Mar 2012 19:19:03 +0900 Subject: mtd: fix section mismatch for doc_probe_device doc_probe_device() is only called from docg3_probe() which is in .init.text, so it must be in the same section to avoid a section mismatch warning. Signed-off-by: Ryosuke Saito Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/docg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 349bbfa74d0d..f5930caa38e7 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1847,8 +1847,8 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd) * if a memory allocation failed. If floor 0 is checked, a reset of the ASIC is * launched. */ -static struct mtd_info *doc_probe_device(void __iomem *base, int floor, - struct device *dev) +static struct mtd_info * __init +doc_probe_device(void __iomem *base, int floor, struct device *dev) { int ret, bbt_nbpages; u16 chip_id, chip_id_inv; -- cgit v1.2.3 From f7e3dd8f48faad24334f7bea048ea59a2c766587 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 16 Mar 2012 11:41:40 +0100 Subject: mtd: spear_smi: Remove default partition information from driver Additionally, after failing in mtd_device_parse_register(), the driver unmap/free code is now executed. Signed-off-by: Stefan Roese Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/spear_smi.c | 41 ++++++----------------------------------- 1 file changed, 6 insertions(+), 35 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index f2016b5f59b6..f7f34fd1a3e5 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -149,21 +149,6 @@ static struct flash_device flash_devices[] = { FLASH_ID("mac 25l6405" , 0xd8, 0x001720C2, 0x100, 0x10000, 0x800000), }; -/* These partitions would be used if platform doesn't pass one */ -static struct mtd_partition part_info_8M[] = { - DEFINE_PARTS("Xloader", 0x00, 0x10000), - DEFINE_PARTS("UBoot", MTDPART_OFS_APPEND, 0x40000), - DEFINE_PARTS("Kernel", MTDPART_OFS_APPEND, 0x2C0000), - DEFINE_PARTS("Root File System", MTDPART_OFS_APPEND, MTDPART_SIZ_FULL), -}; - -static struct mtd_partition part_info_16M[] = { - DEFINE_PARTS("Xloader", 0x00, 0x40000), - DEFINE_PARTS("UBoot", MTDPART_OFS_APPEND, 0x100000), - DEFINE_PARTS("Kernel", MTDPART_OFS_APPEND, 0x300000), - DEFINE_PARTS("Root File System", MTDPART_OFS_APPEND, MTDPART_SIZ_FULL), -}; - /* Define spear specific structures */ struct spear_snor_flash; @@ -769,8 +754,8 @@ static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank) struct spear_smi_flash_info *flash_info; struct spear_smi_plat_data *pdata; struct spear_snor_flash *flash; - struct mtd_partition *parts; - int count; + struct mtd_partition *parts = NULL; + int count = 0; int flash_index; int ret = 0; @@ -834,28 +819,14 @@ static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank) if (flash_info->partitions) { parts = flash_info->partitions; count = flash_info->nr_partitions; - } else { - /* choose from default ones */ - switch (flash->mtd.size) { - case 0x800000:/* 8MB */ - parts = part_info_8M; - count = ARRAY_SIZE(part_info_8M); - break; - case 0x1000000:/* 16MB */ - parts = part_info_16M; - count = ARRAY_SIZE(part_info_16M); - break; - default: - dev_err(&pdev->dev, "undefined partition\n"); - ret = ENODEV; - goto err_map; - } } ret = mtd_device_parse_register(&flash->mtd, NULL, NULL, parts, count); - if (ret) + if (ret) { dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret); + goto err_map; + } - return ret; + return 0; err_map: iounmap(flash->base_addr); -- cgit v1.2.3 From 6551ab5d30d6bf0cea0c6cb294686ce3c7fc6042 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 16 Mar 2012 11:42:11 +0100 Subject: mtd: add device-tree support to spear_smi This patch adds support to configure the SPEAr SMI driver via device-tree instead of platform_data. Signed-off-by: Stefan Roese Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- .../devicetree/bindings/mtd/spear_smi.txt | 31 ++++++ drivers/mtd/devices/spear_smi.c | 111 ++++++++++++++++++--- include/linux/mtd/spear_smi.h | 5 + 3 files changed, 135 insertions(+), 12 deletions(-) create mode 100644 Documentation/devicetree/bindings/mtd/spear_smi.txt (limited to 'drivers/mtd/devices') diff --git a/Documentation/devicetree/bindings/mtd/spear_smi.txt b/Documentation/devicetree/bindings/mtd/spear_smi.txt new file mode 100644 index 000000000000..7248aadd89e4 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/spear_smi.txt @@ -0,0 +1,31 @@ +* SPEAr SMI + +Required properties: +- compatible : "st,spear600-smi" +- reg : Address range of the mtd chip +- #address-cells, #size-cells : Must be present if the device has sub-nodes + representing partitions. +- interrupt-parent: Should be the phandle for the interrupt controller + that services interrupts for this device +- interrupts: Should contain the STMMAC interrupts +- clock-rate : Functional clock rate of SMI in Hz + +Optional properties: +- st,smi-fast-mode : Flash supports read in fast mode + +Example: + + smi: flash@fc000000 { + compatible = "st,spear600-smi"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xfc000000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <12>; + clock-rate = <50000000>; /* 50MHz */ + + flash@f8000000 { + st,smi-fast-mode; + ... + }; + }; diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index f7f34fd1a3e5..797d43cd3550 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -33,9 +33,8 @@ #include #include #include - -/* max possible slots for serial-nor flash chip in the SMI controller */ -#define MAX_NUM_FLASH_CHIP 4 +#include +#include /* SMI clock rate */ #define SMI_MAX_CLOCK_FREQ 50000000 /* 50 MHz */ @@ -748,9 +747,63 @@ err_probe: return ret; } -static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank) + +#ifdef CONFIG_OF +static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev, + struct device_node *np) +{ + struct spear_smi_plat_data *pdata = dev_get_platdata(&pdev->dev); + struct device_node *pp = NULL; + const __be32 *addr; + u32 val; + int len; + int i = 0; + + if (!np) + return -ENODEV; + + of_property_read_u32(np, "clock-rate", &val); + pdata->clk_rate = val; + + pdata->board_flash_info = devm_kzalloc(&pdev->dev, + sizeof(*pdata->board_flash_info), + GFP_KERNEL); + + /* Fill structs for each subnode (flash device) */ + while ((pp = of_get_next_child(np, pp))) { + struct spear_smi_flash_info *flash_info; + + flash_info = &pdata->board_flash_info[i]; + pdata->np[i] = pp; + + /* Read base-addr and size from DT */ + addr = of_get_property(pp, "reg", &len); + pdata->board_flash_info->mem_base = be32_to_cpup(&addr[0]); + pdata->board_flash_info->size = be32_to_cpup(&addr[1]); + + if (of_get_property(pp, "st,smi-fast-mode", NULL)) + pdata->board_flash_info->fast_mode = 1; + + i++; + } + + pdata->num_flashes = i; + + return 0; +} +#else +static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev, + struct device_node *np) +{ + return -ENOSYS; +} +#endif + +static int spear_smi_setup_banks(struct platform_device *pdev, + u32 bank, struct device_node *np) { struct spear_smi *dev = platform_get_drvdata(pdev); + struct mtd_part_parser_data ppdata = {}; struct spear_smi_flash_info *flash_info; struct spear_smi_plat_data *pdata; struct spear_snor_flash *flash; @@ -816,11 +869,16 @@ static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank) dev_info(&dev->pdev->dev, ".erasesize = 0x%x(%uK)\n", flash->mtd.erasesize, flash->mtd.erasesize / 1024); +#ifndef CONFIG_OF if (flash_info->partitions) { parts = flash_info->partitions; count = flash_info->nr_partitions; } - ret = mtd_device_parse_register(&flash->mtd, NULL, NULL, parts, count); +#endif + ppdata.of_node = np; + + ret = mtd_device_parse_register(&flash->mtd, NULL, &ppdata, parts, + count); if (ret) { dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret); goto err_map; @@ -847,17 +905,34 @@ err_probe: */ static int __devinit spear_smi_probe(struct platform_device *pdev) { - struct spear_smi_plat_data *pdata; + struct device_node *np = pdev->dev.of_node; + struct spear_smi_plat_data *pdata = NULL; struct spear_smi *dev; struct resource *smi_base; int irq, ret = 0; int i; - pdata = dev_get_platdata(&pdev->dev); - if (pdata < 0) { - ret = -ENODEV; - dev_err(&pdev->dev, "no platform data\n"); - goto err; + if (np) { + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + pr_err("%s: ERROR: no memory", __func__); + ret = -ENOMEM; + goto err; + } + pdev->dev.platform_data = pdata; + ret = spear_smi_probe_config_dt(pdev, np); + if (ret) { + ret = -ENODEV; + dev_err(&pdev->dev, "no platform data\n"); + goto err; + } + } else { + pdata = dev_get_platdata(&pdev->dev); + if (pdata < 0) { + ret = -ENODEV; + dev_err(&pdev->dev, "no platform data\n"); + goto err; + } } smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -932,7 +1007,7 @@ static int __devinit spear_smi_probe(struct platform_device *pdev) /* loop for each serial nor-flash which is connected to smi */ for (i = 0; i < dev->num_flashes; i++) { - ret = spear_smi_setup_banks(pdev, i); + ret = spear_smi_setup_banks(pdev, i, pdata->np[i]); if (ret) { dev_err(&dev->pdev->dev, "bank setup failed\n"); goto err_bank_setup; @@ -967,6 +1042,7 @@ err: static int __devexit spear_smi_remove(struct platform_device *pdev) { struct spear_smi *dev; + struct spear_smi_plat_data *pdata; struct spear_snor_flash *flash; struct resource *smi_base; int ret; @@ -978,6 +1054,8 @@ static int __devexit spear_smi_remove(struct platform_device *pdev) return -ENODEV; } + pdata = dev_get_platdata(&pdev->dev); + /* clean up for all nor flash */ for (i = 0; i < dev->num_flashes; i++) { flash = dev->flash[i]; @@ -1031,11 +1109,20 @@ int spear_smi_resume(struct platform_device *pdev) return ret; } +#ifdef CONFIG_OF +static const struct of_device_id spear_smi_id_table[] = { + { .compatible = "st,spear600-smi" }, + {} +}; +MODULE_DEVICE_TABLE(of, spear_smi_id_table); +#endif + static struct platform_driver spear_smi_driver = { .driver = { .name = "smi", .bus = &platform_bus_type, .owner = THIS_MODULE, + .of_match_table = of_match_ptr(spear_smi_id_table), }, .probe = spear_smi_probe, .remove = __devexit_p(spear_smi_remove), diff --git a/include/linux/mtd/spear_smi.h b/include/linux/mtd/spear_smi.h index 4e26b4e38da3..8ae1726044c3 100644 --- a/include/linux/mtd/spear_smi.h +++ b/include/linux/mtd/spear_smi.h @@ -14,6 +14,10 @@ #include #include #include +#include + +/* max possible slots for serial-nor flash chip in the SMI controller */ +#define MAX_NUM_FLASH_CHIP 4 /* macro to define partitions for flash devices */ #define DEFINE_PARTS(n, of, s) \ @@ -55,6 +59,7 @@ struct spear_smi_plat_data { unsigned long clk_rate; int num_flashes; struct spear_smi_flash_info *board_flash_info; + struct device_node *np[MAX_NUM_FLASH_CHIP]; }; #endif /* __MTD_SPEAR_SMI_H */ -- cgit v1.2.3 From b11ec57fc6e6d4882ef01a0c09a1dde58f50492e Mon Sep 17 00:00:00 2001 From: Ryosuke Saito Date: Wed, 21 Mar 2012 18:47:47 +0900 Subject: mtd: phram: fix section mismatch for phram_setup phram_setup() is only called from init_phram() which is in .init.text, so it must be in the same section to avoid a section mismatch warning. Signed-off-by: Ryosuke Saito Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/phram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 3d91ace1ee4c..67823de68db6 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -215,7 +215,7 @@ static inline void kill_final_newline(char *str) */ static __initdata char phram_paramline[64+12+12]; -static int phram_setup(const char *val) +static int __init phram_setup(const char *val) { char buf[64+12+12], *str = buf; char *token[3]; -- cgit v1.2.3 From a7baef1211b0ac218299965481e7cff9d68c1edd Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Thu, 22 Mar 2012 21:00:50 +0100 Subject: mtd: docg3 fix inbound calculations The last erase block was not accessible, as the out of bound check was incorrectly rejecting the last block. The read/write/erase offset checks were forbidding the usage of the last block, because of the calculation which was considering the byte after the last instead of the last byte. Signed-off-by: Robert Jarzmik Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/docg3.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index f5930caa38e7..62e01113c317 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -872,11 +872,8 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, if (ooblen % DOC_LAYOUT_OOB_SIZE) return -EINVAL; - ret = -EINVAL; - calc_block_sector(from + len, &block0, &block1, &page, &ofs, - docg3->reliable); - if (block1 > docg3->max_block) - goto err; + if (from + len > mtd->size) + return -EINVAL; ops->oobretlen = 0; ops->retlen = 0; @@ -1207,7 +1204,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *info) calc_block_sector(info->addr + info->len, &block0, &block1, &page, &ofs, docg3->reliable); ret = -EINVAL; - if (block1 > docg3->max_block || page || ofs) + if (info->addr + info->len > mtd->size || page || ofs) goto reset_err; ret = 0; @@ -1443,12 +1440,8 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, if (len && ooblen && (len / DOC_LAYOUT_PAGE_SIZE) != (ooblen / oobdelta)) return -EINVAL; - - ret = -EINVAL; - calc_block_sector(ofs + len, &block0, &block1, &page, &pofs, - docg3->reliable); - if (block1 > docg3->max_block) - goto err; + if (ofs + len > mtd->size) + return -EINVAL; ops->oobretlen = 0; ops->retlen = 0; -- cgit v1.2.3 From a2b3d284ed65b9ada18fd2ffb66daffe9c0ff168 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Thu, 22 Mar 2012 21:00:51 +0100 Subject: mtd: docg3 increase write/erase timeout After several tries with ubifs, it appears empirically that constructor provided figures for erase/write timeouts are underestimated. A timeout of 100ms seems to work with a 5 years worn chip, and no timeouts occur anymore. Signed-off-by: Robert Jarzmik Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/docg3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 62e01113c317..be88eb6217cb 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1116,10 +1116,10 @@ static int doc_get_op_status(struct docg3 *docg3) */ static int doc_write_erase_wait_status(struct docg3 *docg3) { - int status, ret = 0; + int i, status, ret = 0; - if (!doc_is_ready(docg3)) - usleep_range(3000, 3000); + for (i = 0; !doc_is_ready(docg3) && i < 5; i++) + msleep(20); if (!doc_is_ready(docg3)) { doc_dbg("Timeout reached and the chip is still not ready\n"); ret = -EAGAIN; -- cgit v1.2.3 From 1b15a5f93bbd9a6f5346cfa449720a7e32115f86 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Thu, 22 Mar 2012 21:00:52 +0100 Subject: mtd: docg3 refactor cascade floors structure Group floors into a common cascade structure. This will provide a common structure to store common data to all cascaded docg3 chips, like IO addressing, locking protection. Signed-off-by: Robert Jarzmik Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/docg3.c | 88 +++++++++++++++++++++++---------------------- drivers/mtd/devices/docg3.h | 18 ++++++++-- 2 files changed, 61 insertions(+), 45 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index be88eb6217cb..935d4c6e9321 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -80,14 +80,9 @@ static struct nand_ecclayout docg3_oobinfo = { .oobavail = 8, }; -/** - * struct docg3_bch - BCH engine - */ -static struct bch_control *docg3_bch; - static inline u8 doc_readb(struct docg3 *docg3, u16 reg) { - u8 val = readb(docg3->base + reg); + u8 val = readb(docg3->cascade->base + reg); trace_docg3_io(0, 8, reg, (int)val); return val; @@ -95,7 +90,7 @@ static inline u8 doc_readb(struct docg3 *docg3, u16 reg) static inline u16 doc_readw(struct docg3 *docg3, u16 reg) { - u16 val = readw(docg3->base + reg); + u16 val = readw(docg3->cascade->base + reg); trace_docg3_io(0, 16, reg, (int)val); return val; @@ -103,13 +98,13 @@ static inline u16 doc_readw(struct docg3 *docg3, u16 reg) static inline void doc_writeb(struct docg3 *docg3, u8 val, u16 reg) { - writeb(val, docg3->base + reg); + writeb(val, docg3->cascade->base + reg); trace_docg3_io(1, 8, reg, val); } static inline void doc_writew(struct docg3 *docg3, u16 val, u16 reg) { - writew(val, docg3->base + reg); + writew(val, docg3->cascade->base + reg); trace_docg3_io(1, 16, reg, val); } @@ -643,7 +638,8 @@ static int doc_ecc_bch_fix_data(struct docg3 *docg3, void *buf, u8 *hwecc) for (i = 0; i < DOC_ECC_BCH_SIZE; i++) ecc[i] = bitrev8(hwecc[i]); - numerrs = decode_bch(docg3_bch, NULL, DOC_ECC_BCH_COVERED_BYTES, + numerrs = decode_bch(docg3->cascade->bch, NULL, + DOC_ECC_BCH_COVERED_BYTES, NULL, ecc, NULL, errorpos); BUG_ON(numerrs == -EINVAL); if (numerrs < 0) @@ -1599,13 +1595,13 @@ static struct device_attribute doc_sys_attrs[DOC_MAX_NBFLOORS][4] = { }; static int doc_register_sysfs(struct platform_device *pdev, - struct mtd_info **floors) + struct docg3_cascade *cascade) { int ret = 0, floor, i = 0; struct device *dev = &pdev->dev; - for (floor = 0; !ret && floor < DOC_MAX_NBFLOORS && floors[floor]; - floor++) + for (floor = 0; !ret && floor < DOC_MAX_NBFLOORS && + cascade->floors[floor]; floor++) for (i = 0; !ret && i < 4; i++) ret = device_create_file(dev, &doc_sys_attrs[floor][i]); if (!ret) @@ -1619,12 +1615,12 @@ static int doc_register_sysfs(struct platform_device *pdev, } static void doc_unregister_sysfs(struct platform_device *pdev, - struct mtd_info **floors) + struct docg3_cascade *cascade) { struct device *dev = &pdev->dev; int floor, i; - for (floor = 0; floor < DOC_MAX_NBFLOORS && floors[floor]; + for (floor = 0; floor < DOC_MAX_NBFLOORS && cascade->floors[floor]; floor++) for (i = 0; i < 4; i++) device_remove_file(dev, &doc_sys_attrs[floor][i]); @@ -1833,6 +1829,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd) * @base: the io space where the device is probed * @floor: the floor of the probed device * @dev: the device + * @cascade: the cascade of chips this devices will belong to * * Checks whether a device at the specified IO range, and floor is available. * @@ -1841,7 +1838,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd) * launched. */ static struct mtd_info * __init -doc_probe_device(void __iomem *base, int floor, struct device *dev) +doc_probe_device(struct docg3_cascade *cascade, int floor, struct device *dev) { int ret, bbt_nbpages; u16 chip_id, chip_id_inv; @@ -1864,7 +1861,7 @@ doc_probe_device(void __iomem *base, int floor, struct device *dev) docg3->dev = dev; docg3->device_id = floor; - docg3->base = base; + docg3->cascade = cascade; doc_set_device_id(docg3, docg3->device_id); if (!floor) doc_set_asic_mode(docg3, DOC_ASICMODE_RESET); @@ -1881,7 +1878,7 @@ doc_probe_device(void __iomem *base, int floor, struct device *dev) switch (chip_id) { case DOC_CHIPID_G3: doc_info("Found a G3 DiskOnChip at addr %p, floor %d\n", - base, floor); + docg3->cascade->base, floor); break; default: doc_err("Chip id %04x is not a DiskOnChip G3 chip\n", chip_id); @@ -1926,10 +1923,12 @@ static void doc_release_device(struct mtd_info *mtd) static int docg3_resume(struct platform_device *pdev) { int i; + struct docg3_cascade *cascade; struct mtd_info **docg3_floors, *mtd; struct docg3 *docg3; - docg3_floors = platform_get_drvdata(pdev); + cascade = platform_get_drvdata(pdev); + docg3_floors = cascade->floors; mtd = docg3_floors[0]; docg3 = mtd->priv; @@ -1951,11 +1950,13 @@ static int docg3_resume(struct platform_device *pdev) static int docg3_suspend(struct platform_device *pdev, pm_message_t state) { int floor, i; + struct docg3_cascade *cascade; struct mtd_info **docg3_floors, *mtd; struct docg3 *docg3; u8 ctrl, pwr_down; - docg3_floors = platform_get_drvdata(pdev); + cascade = platform_get_drvdata(pdev); + docg3_floors = cascade->floors; for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { mtd = docg3_floors[floor]; if (!mtd) @@ -2005,7 +2006,7 @@ static int __init docg3_probe(struct platform_device *pdev) struct resource *ress; void __iomem *base; int ret, floor, found = 0; - struct mtd_info **docg3_floors; + struct docg3_cascade *cascade; ret = -ENXIO; ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -2016,17 +2017,18 @@ static int __init docg3_probe(struct platform_device *pdev) base = ioremap(ress->start, DOC_IOSPACE_SIZE); ret = -ENOMEM; - docg3_floors = kzalloc(sizeof(*docg3_floors) * DOC_MAX_NBFLOORS, - GFP_KERNEL); - if (!docg3_floors) + cascade = kzalloc(sizeof(*cascade) * DOC_MAX_NBFLOORS, + GFP_KERNEL); + if (!cascade) goto nomem1; - docg3_bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T, + cascade->base = base; + cascade->bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T, DOC_ECC_BCH_PRIMPOLY); - if (!docg3_bch) + if (!cascade->bch) goto nomem2; for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { - mtd = doc_probe_device(base, floor, dev); + mtd = doc_probe_device(cascade, floor, dev); if (IS_ERR(mtd)) { ret = PTR_ERR(mtd); goto err_probe; @@ -2037,7 +2039,7 @@ static int __init docg3_probe(struct platform_device *pdev) else continue; } - docg3_floors[floor] = mtd; + cascade->floors[floor] = mtd; ret = mtd_device_parse_register(mtd, part_probes, NULL, NULL, 0); if (ret) @@ -2045,26 +2047,26 @@ static int __init docg3_probe(struct platform_device *pdev) found++; } - ret = doc_register_sysfs(pdev, docg3_floors); + ret = doc_register_sysfs(pdev, cascade); if (ret) goto err_probe; if (!found) goto notfound; - platform_set_drvdata(pdev, docg3_floors); - doc_dbg_register(docg3_floors[0]->priv); + platform_set_drvdata(pdev, cascade); + doc_dbg_register(cascade->floors[0]->priv); return 0; notfound: ret = -ENODEV; dev_info(dev, "No supported DiskOnChip found\n"); err_probe: - free_bch(docg3_bch); + kfree(cascade->bch); for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) - if (docg3_floors[floor]) - doc_release_device(docg3_floors[floor]); + if (cascade->floors[floor]) + doc_release_device(cascade->floors[floor]); nomem2: - kfree(docg3_floors); + kfree(cascade); nomem1: iounmap(base); noress: @@ -2079,19 +2081,19 @@ noress: */ static int __exit docg3_release(struct platform_device *pdev) { - struct mtd_info **docg3_floors = platform_get_drvdata(pdev); - struct docg3 *docg3 = docg3_floors[0]->priv; - void __iomem *base = docg3->base; + struct docg3_cascade *cascade = platform_get_drvdata(pdev); + struct docg3 *docg3 = cascade->floors[0]->priv; + void __iomem *base = cascade->base; int floor; - doc_unregister_sysfs(pdev, docg3_floors); + doc_unregister_sysfs(pdev, cascade); doc_dbg_unregister(docg3); for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) - if (docg3_floors[floor]) - doc_release_device(docg3_floors[floor]); + if (cascade->floors[floor]) + doc_release_device(cascade->floors[floor]); - kfree(docg3_floors); - free_bch(docg3_bch); + free_bch(docg3->cascade->bch); + kfree(cascade); iounmap(base); return 0; } diff --git a/drivers/mtd/devices/docg3.h b/drivers/mtd/devices/docg3.h index db0da436b493..642e60667cfd 100644 --- a/drivers/mtd/devices/docg3.h +++ b/drivers/mtd/devices/docg3.h @@ -22,6 +22,8 @@ #ifndef _MTD_DOCG3_H #define _MTD_DOCG3_H +#include + /* * Flash memory areas : * - 0x0000 .. 0x07ff : IPL @@ -266,10 +268,22 @@ */ #define DOC_LAYOUT_DPS_KEY_LENGTH 8 +/** + * struct docg3_cascade - Cascade of 1 to 4 docg3 chips + * @floors: floors (ie. one physical docg3 chip is one floor) + * @base: IO space to access all chips in the cascade + * @bch: the BCH correcting control structure + */ +struct docg3_cascade { + struct mtd_info *floors[DOC_MAX_NBFLOORS]; + void __iomem *base; + struct bch_control *bch; +}; + /** * struct docg3 - DiskOnChip driver private data * @dev: the device currently under control - * @base: mapped IO space + * @cascade: the cascade this device belongs to * @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3) * @if_cfg: if true, reads are on 16bits, else reads are on 8bits @@ -287,7 +301,7 @@ */ struct docg3 { struct device *dev; - void __iomem *base; + struct docg3_cascade *cascade; unsigned int device_id:4; unsigned int if_cfg:1; unsigned int reliable:2; -- cgit v1.2.3 From 7b0e67f604e1829e5292e1ad7743eb18dc42ea7c Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Thu, 22 Mar 2012 21:00:53 +0100 Subject: mtd: docg3 add protection against concurrency As docg3 is intolerant against reentrancy, especially because of its weird register access (ie. a register read is performed by a first register write), each access to the docg3 IO space must be locked. Lock the IO space with a mutex, shared by all chips on the same cascade, as they all share the same IO space. Signed-off-by: Robert Jarzmik Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/docg3.c | 50 +++++++++++++++++++++++++++++++++++---------- drivers/mtd/devices/docg3.h | 2 ++ 2 files changed, 41 insertions(+), 11 deletions(-) (limited to 'drivers/mtd/devices') diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 935d4c6e9321..8272c02668d6 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -875,6 +875,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, ops->retlen = 0; ret = 0; skip = from % DOC_LAYOUT_PAGE_SIZE; + mutex_lock(&docg3->cascade->lock); while (!ret && (len > 0 || ooblen > 0)) { calc_block_sector(from - skip, &block0, &block1, &page, &ofs, docg3->reliable); @@ -882,7 +883,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE); ret = doc_read_page_prepare(docg3, block0, block1, page, ofs); if (ret < 0) - goto err; + goto out; ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES); if (ret < 0) goto err_in_read; @@ -950,11 +951,12 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, skip = 0; } +out: + mutex_unlock(&docg3->cascade->lock); return ret; err_in_read: doc_read_page_finish(docg3); -err: - return ret; + goto out; } /** @@ -1194,7 +1196,6 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *info) int block0, block1, page, ret, ofs = 0; doc_dbg("doc_erase(from=%lld, len=%lld\n", info->addr, info->len); - doc_set_device_id(docg3, docg3->device_id); info->state = MTD_ERASE_PENDING; calc_block_sector(info->addr + info->len, &block0, &block1, &page, @@ -1206,6 +1207,8 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *info) ret = 0; calc_block_sector(info->addr, &block0, &block1, &page, &ofs, docg3->reliable); + mutex_lock(&docg3->cascade->lock); + doc_set_device_id(docg3, docg3->device_id); doc_set_reliable_mode(docg3); for (len = info->len; !ret && len > 0; len -= mtd->erasesize) { info->state = MTD_ERASING; @@ -1213,6 +1216,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *info) block0 += 2; block1 += 2; } + mutex_unlock(&docg3->cascade->lock); if (ret) goto reset_err; @@ -1399,7 +1403,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, struct mtd_oob_ops *ops) { struct docg3 *docg3 = mtd->priv; - int block0, block1, page, ret, pofs = 0, autoecc, oobdelta; + int ret, autoecc, oobdelta; u8 *oobbuf = ops->oobbuf; u8 *buf = ops->datbuf; size_t len, ooblen; @@ -1451,6 +1455,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, if (autoecc < 0) return autoecc; + mutex_lock(&docg3->cascade->lock); while (!ret && len > 0) { memset(oob, 0, sizeof(oob)); if (ofs == docg3->oob_write_ofs) @@ -1471,8 +1476,9 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, } ops->retlen += DOC_LAYOUT_PAGE_SIZE; } -err: + doc_set_device_id(docg3, 0); + mutex_unlock(&docg3->cascade->lock); return ret; } @@ -1529,9 +1535,11 @@ static ssize_t dps0_is_key_locked(struct device *dev, struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); int dps0; + mutex_lock(&docg3->cascade->lock); doc_set_device_id(docg3, docg3->device_id); dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS); doc_set_device_id(docg3, 0); + mutex_unlock(&docg3->cascade->lock); return sprintf(buf, "%d\n", !(dps0 & DOC_DPS_KEY_OK)); } @@ -1542,9 +1550,11 @@ static ssize_t dps1_is_key_locked(struct device *dev, struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); int dps1; + mutex_lock(&docg3->cascade->lock); doc_set_device_id(docg3, docg3->device_id); dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS); doc_set_device_id(docg3, 0); + mutex_unlock(&docg3->cascade->lock); return sprintf(buf, "%d\n", !(dps1 & DOC_DPS_KEY_OK)); } @@ -1559,10 +1569,12 @@ static ssize_t dps0_insert_key(struct device *dev, if (count != DOC_LAYOUT_DPS_KEY_LENGTH) return -EINVAL; + mutex_lock(&docg3->cascade->lock); doc_set_device_id(docg3, docg3->device_id); for (i = 0; i < DOC_LAYOUT_DPS_KEY_LENGTH; i++) doc_writeb(docg3, buf[i], DOC_DPS0_KEY); doc_set_device_id(docg3, 0); + mutex_unlock(&docg3->cascade->lock); return count; } @@ -1576,10 +1588,12 @@ static ssize_t dps1_insert_key(struct device *dev, if (count != DOC_LAYOUT_DPS_KEY_LENGTH) return -EINVAL; + mutex_lock(&docg3->cascade->lock); doc_set_device_id(docg3, docg3->device_id); for (i = 0; i < DOC_LAYOUT_DPS_KEY_LENGTH; i++) doc_writeb(docg3, buf[i], DOC_DPS1_KEY); doc_set_device_id(docg3, 0); + mutex_unlock(&docg3->cascade->lock); return count; } @@ -1634,7 +1648,11 @@ static int dbg_flashctrl_show(struct seq_file *s, void *p) struct docg3 *docg3 = (struct docg3 *)s->private; int pos = 0; - u8 fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); + u8 fctrl; + + mutex_lock(&docg3->cascade->lock); + fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); + mutex_unlock(&docg3->cascade->lock); pos += seq_printf(s, "FlashControl : 0x%02x (%s,CE# %s,%s,%s,flash %s)\n", @@ -1652,9 +1670,12 @@ static int dbg_asicmode_show(struct seq_file *s, void *p) { struct docg3 *docg3 = (struct docg3 *)s->private; - int pos = 0; - int pctrl = doc_register_readb(docg3, DOC_ASICMODE); - int mode = pctrl & 0x03; + int pos = 0, pctrl, mode; + + mutex_lock(&docg3->cascade->lock); + pctrl = doc_register_readb(docg3, DOC_ASICMODE); + mode = pctrl & 0x03; + mutex_unlock(&docg3->cascade->lock); pos += seq_printf(s, "%04x : RAM_WE=%d,RSTIN_RESET=%d,BDETCT_RESET=%d,WRITE_ENABLE=%d,POWERDOWN=%d,MODE=%d%d (", @@ -1686,7 +1707,11 @@ static int dbg_device_id_show(struct seq_file *s, void *p) { struct docg3 *docg3 = (struct docg3 *)s->private; int pos = 0; - int id = doc_register_readb(docg3, DOC_DEVICESELECT); + int id; + + mutex_lock(&docg3->cascade->lock); + id = doc_register_readb(docg3, DOC_DEVICESELECT); + mutex_unlock(&docg3->cascade->lock); pos += seq_printf(s, "DeviceId = %d\n", id); return pos; @@ -1699,6 +1724,7 @@ static int dbg_protection_show(struct seq_file *s, void *p) int pos = 0; int protect, dps0, dps0_low, dps0_high, dps1, dps1_low, dps1_high; + mutex_lock(&docg3->cascade->lock); protect = doc_register_readb(docg3, DOC_PROTECTION); dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS); dps0_low = doc_register_readw(docg3, DOC_DPS0_ADDRLOW); @@ -1706,6 +1732,7 @@ static int dbg_protection_show(struct seq_file *s, void *p) dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS); dps1_low = doc_register_readw(docg3, DOC_DPS1_ADDRLOW); dps1_high = doc_register_readw(docg3, DOC_DPS1_ADDRHIGH); + mutex_unlock(&docg3->cascade->lock); pos += seq_printf(s, "Protection = 0x%02x (", protect); @@ -2022,6 +2049,7 @@ static int __init docg3_probe(struct platform_device *pdev) if (!cascade) goto nomem1; cascade->base = base; + mutex_init(&cascade->lock); cascade->bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T, DOC_ECC_BCH_PRIMPOLY); if (!cascade->bch) diff --git a/drivers/mtd/devices/docg3.h b/drivers/mtd/devices/docg3.h index 642e60667cfd..19fb93f96a3a 100644 --- a/drivers/mtd/devices/docg3.h +++ b/drivers/mtd/devices/docg3.h @@ -273,11 +273,13 @@ * @floors: floors (ie. one physical docg3 chip is one floor) * @base: IO space to access all chips in the cascade * @bch: the BCH correcting control structure + * @lock: lock to protect docg3 IO space from concurrent accesses */ struct docg3_cascade { struct mtd_info *floors[DOC_MAX_NBFLOORS]; void __iomem *base; struct bch_control *bch; + struct mutex lock; }; /** -- cgit v1.2.3