diff options
Diffstat (limited to 'drivers/mtd')
93 files changed, 2292 insertions, 1632 deletions
diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c index 94539312995..7c057a05adb 100644 --- a/drivers/mtd/ar7part.c +++ b/drivers/mtd/ar7part.c @@ -26,19 +26,16 @@  #include <linux/mtd/mtd.h>  #include <linux/mtd/partitions.h>  #include <linux/bootmem.h> -#include <linux/magic.h>  #include <linux/module.h> +#include <uapi/linux/magic.h> +  #define AR7_PARTS	4  #define ROOT_OFFSET	0xe0000  #define LOADER_MAGIC1	le32_to_cpu(0xfeedfa42)  #define LOADER_MAGIC2	le32_to_cpu(0xfeed1281) -#ifndef SQUASHFS_MAGIC -#define SQUASHFS_MAGIC	0x73717368 -#endif -  struct ar7_bin_rec {  	unsigned int checksum;  	unsigned int length; diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index 63d2a64331f..6eeb84c81bc 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c @@ -37,8 +37,7 @@  #define BCM63XX_EXTENDED_SIZE	0xBFC00000	/* Extended flash address */ -#define BCM63XX_MIN_CFE_SIZE	0x10000		/* always at least 64KiB */ -#define BCM63XX_MIN_NVRAM_SIZE	0x10000		/* always at least 64KiB */ +#define BCM63XX_CFE_BLOCK_SIZE	0x10000		/* always at least 64KiB */  #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 @@ -79,7 +78,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,  	unsigned int rootfsaddr, kerneladdr, spareaddr;  	unsigned int rootfslen, kernellen, sparelen, totallen;  	unsigned int cfelen, nvramlen; -	int namelen = 0; +	unsigned int cfe_erasesize;  	int i;  	u32 computed_crc;  	bool rootfs_first = false; @@ -87,8 +86,11 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,  	if (bcm63xx_detect_cfe(master))  		return -EINVAL; -	cfelen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_CFE_SIZE); -	nvramlen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_NVRAM_SIZE); +	cfe_erasesize = max_t(uint32_t, master->erasesize, +			      BCM63XX_CFE_BLOCK_SIZE); + +	cfelen = cfe_erasesize; +	nvramlen = cfe_erasesize;  	/* Allocate memory for buffer */  	buf = vmalloc(sizeof(struct bcm_tag)); @@ -121,7 +123,6 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,  		kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;  		rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE;  		spareaddr = roundup(totallen, master->erasesize) + cfelen; -		sparelen = master->size - spareaddr - nvramlen;  		if (rootfsaddr < kerneladdr) {  			/* default Broadcom layout */ @@ -139,19 +140,15 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,  		rootfslen = 0;  		rootfsaddr = 0;  		spareaddr = cfelen; -		sparelen = master->size - cfelen - nvramlen;  	} +	sparelen = master->size - spareaddr - nvramlen;  	/* Determine number of partitions */ -	namelen = 8; -	if (rootfslen > 0) { +	if (rootfslen > 0)  		nrparts++; -		namelen += 6; -	} -	if (kernellen > 0) { + +	if (kernellen > 0)  		nrparts++; -		namelen += 6; -	}  	/* Ask kernel for more memory */  	parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); @@ -193,17 +190,16 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,  	parts[curpart].name = "nvram";  	parts[curpart].offset = master->size - nvramlen;  	parts[curpart].size = nvramlen; +	curpart++;  	/* Global partition "linux" to make easy firmware upgrade */ -	curpart++;  	parts[curpart].name = "linux";  	parts[curpart].offset = cfelen;  	parts[curpart].size = master->size - cfelen - nvramlen;  	for (i = 0; i < nrparts; i++) -		pr_info("Partition %d is %s offset %lx and length %lx\n", i, -			parts[i].name, (long unsigned int)(parts[i].offset), -			(long unsigned int)(parts[i].size)); +		pr_info("Partition %d is %s offset %llx and length %llx\n", i, +			parts[i].name, parts[i].offset,	parts[i].size);  	pr_info("Spare partition is offset %x and length %x\n",	spareaddr,  		sparelen); diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 5ff5c4a1694..b86197286f2 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -1536,8 +1536,20 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,  		UDELAY(map, chip, adr, 1);  	} -	/* reset on all failures. */ -	map_write( map, CMD(0xF0), chip->start ); +	/* +	 * Recovery from write-buffer programming failures requires +	 * the write-to-buffer-reset sequence.  Since the last part +	 * of the sequence also works as a normal reset, we can run +	 * the same commands regardless of why we are here. +	 * See e.g. +	 * http://www.spansion.com/Support/Application%20Notes/MirrorBit_Write_Buffer_Prog_Page_Buffer_Read_AN.pdf +	 */ +	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, +			 cfi->device_type, NULL); +	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, +			 cfi->device_type, NULL); +	cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, chip->start, map, cfi, +			 cfi->device_type, NULL);  	xip_enable(map, chip, adr);  	/* FIXME - should have reset delay before continuing */ diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index aed1b8a63c9..c533f27d863 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c @@ -56,8 +56,8 @@  /* special size referring to all the remaining space in a partition */ -#define SIZE_REMAINING UINT_MAX -#define OFFSET_CONTINUOUS UINT_MAX +#define SIZE_REMAINING ULLONG_MAX +#define OFFSET_CONTINUOUS ULLONG_MAX  struct cmdline_mtd_partition {  	struct cmdline_mtd_partition *next; @@ -89,7 +89,7 @@ static struct mtd_partition * newpart(char *s,  				      int extra_mem_size)  {  	struct mtd_partition *parts; -	unsigned long size, offset = OFFSET_CONTINUOUS; +	unsigned long long size, offset = OFFSET_CONTINUOUS;  	char *name;  	int name_len;  	unsigned char *extra_mem; @@ -104,7 +104,8 @@ static struct mtd_partition * newpart(char *s,  	} else {  		size = memparse(s, &s);  		if (size < PAGE_SIZE) { -			printk(KERN_ERR ERRP "partition size too small (%lx)\n", size); +			printk(KERN_ERR ERRP "partition size too small (%llx)\n", +			       size);  			return ERR_PTR(-EINVAL);  		}  	} @@ -296,7 +297,7 @@ static int parse_cmdline_partitions(struct mtd_info *master,  				    struct mtd_partition **pparts,  				    struct mtd_part_parser_data *data)  { -	unsigned long offset; +	unsigned long long offset;  	int i, err;  	struct cmdline_mtd_partition *part;  	const char *mtd_id = master->name; @@ -308,48 +309,52 @@ static int parse_cmdline_partitions(struct mtd_info *master,  			return err;  	} +	/* +	 * Search for the partition definition matching master->name. +	 * If master->name is not set, stop at first partition definition. +	 */  	for (part = partitions; part; part = part->next) { -		if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id))) { -			for (i = 0, offset = 0; i < part->num_parts; i++) { -				if (part->parts[i].offset == OFFSET_CONTINUOUS) -					part->parts[i].offset = offset; -				else -					offset = part->parts[i].offset; +		if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id))) +			break; +	} -				if (part->parts[i].size == SIZE_REMAINING) -					part->parts[i].size = master->size - offset; +	if (!part) +		return 0; -				if (part->parts[i].size == 0) { -					printk(KERN_WARNING ERRP -					       "%s: skipping zero sized partition\n", -					       part->mtd_id); -					part->num_parts--; -					memmove(&part->parts[i], -						&part->parts[i + 1], -						sizeof(*part->parts) * (part->num_parts - i)); -					continue; -				} +	for (i = 0, offset = 0; i < part->num_parts; i++) { +		if (part->parts[i].offset == OFFSET_CONTINUOUS) +			part->parts[i].offset = offset; +		else +			offset = part->parts[i].offset; -				if (offset + part->parts[i].size > master->size) { -					printk(KERN_WARNING ERRP -					       "%s: partitioning exceeds flash size, truncating\n", -					       part->mtd_id); -					part->parts[i].size = master->size - offset; -				} -				offset += part->parts[i].size; -			} +		if (part->parts[i].size == SIZE_REMAINING) +			part->parts[i].size = master->size - offset; -			*pparts = kmemdup(part->parts, -					sizeof(*part->parts) * part->num_parts, -					GFP_KERNEL); -			if (!*pparts) -				return -ENOMEM; +		if (part->parts[i].size == 0) { +			printk(KERN_WARNING ERRP +			       "%s: skipping zero sized partition\n", +			       part->mtd_id); +			part->num_parts--; +			memmove(&part->parts[i], &part->parts[i + 1], +				sizeof(*part->parts) * (part->num_parts - i)); +			continue; +		} -			return part->num_parts; +		if (offset + part->parts[i].size > master->size) { +			printk(KERN_WARNING ERRP +			       "%s: partitioning exceeds flash size, truncating\n", +			       part->mtd_id); +			part->parts[i].size = master->size - offset;  		} +		offset += part->parts[i].size;  	} -	return 0; +	*pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts, +			  GFP_KERNEL); +	if (!*pparts) +		return -ENOMEM; + +	return part->num_parts;  } diff --git a/drivers/mtd/devices/bcm47xxsflash.c b/drivers/mtd/devices/bcm47xxsflash.c index 2dc5a6f3fd5..4714584aa99 100644 --- a/drivers/mtd/devices/bcm47xxsflash.c +++ b/drivers/mtd/devices/bcm47xxsflash.c @@ -66,7 +66,7 @@ out:  	return err;  } -static int __devexit bcm47xxsflash_remove(struct platform_device *pdev) +static int bcm47xxsflash_remove(struct platform_device *pdev)  {  	struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev); @@ -77,7 +77,7 @@ static int __devexit bcm47xxsflash_remove(struct platform_device *pdev)  }  static struct platform_driver bcma_sflash_driver = { -	.remove = __devexit_p(bcm47xxsflash_remove), +	.remove = bcm47xxsflash_remove,  	.driver = {  		.name = "bcma_sflash",  		.owner = THIS_MODULE, diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 681e2ee0f2d..e081bfeaaf7 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -62,6 +62,7 @@ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len)  				memset(page_address(page), 0xff, PAGE_SIZE);  				set_page_dirty(page);  				unlock_page(page); +				balance_dirty_pages_ratelimited(mapping);  				break;  			} @@ -152,6 +153,7 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,  			memcpy(page_address(page) + offset, buf, cpylen);  			set_page_dirty(page);  			unlock_page(page); +			balance_dirty_pages_ratelimited(mapping);  		}  		page_cache_release(page); @@ -433,7 +435,7 @@ static int __init block2mtd_init(void)  } -static void __devexit block2mtd_exit(void) +static void block2mtd_exit(void)  {  	struct list_head *pos, *next; diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index d34d83b8f9c..8510ccb9c6f 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1440,7 +1440,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,  		oobdelta = mtd->ecclayout->oobavail;  		break;  	default: -		oobdelta = 0; +		return -EINVAL;  	}  	if ((len % DOC_LAYOUT_PAGE_SIZE) || (ooblen % oobdelta) ||  	    (ofs % DOC_LAYOUT_PAGE_SIZE)) diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c index 706b847b46b..88b3fd3e18a 100644 --- a/drivers/mtd/devices/docprobe.c +++ b/drivers/mtd/devices/docprobe.c @@ -70,8 +70,6 @@ static unsigned long __initdata doc_locations[] = {  	0xe0000, 0xe2000, 0xe4000, 0xe6000,  	0xe8000, 0xea000, 0xec000, 0xee000,  #endif /*  CONFIG_MTD_DOCPROBE_HIGH */ -#else -#warning Unknown architecture for DiskOnChip. No default probe locations defined  #endif  	0xffffffff }; diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 03838bab1f5..4eeeb2d7f6e 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -73,14 +73,6 @@  #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */  #define	MAX_CMD_SIZE		5 -#ifdef CONFIG_M25PXX_USE_FAST_READ -#define OPCODE_READ 	OPCODE_FAST_READ -#define FAST_READ_DUMMY_BYTE 1 -#else -#define OPCODE_READ 	OPCODE_NORM_READ -#define FAST_READ_DUMMY_BYTE 0 -#endif -  #define JEDEC_MFR(_jedec_id)	((_jedec_id) >> 16)  /****************************************************************************/ @@ -93,6 +85,7 @@ struct m25p {  	u16			addr_width;  	u8			erase_opcode;  	u8			*command; +	bool			fast_read;  };  static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) @@ -168,6 +161,7 @@ static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable)  {  	switch (JEDEC_MFR(jedec_id)) {  	case CFI_MFR_MACRONIX: +	case 0xEF /* winbond */:  		flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B;  		return spi_write(flash->spi, flash->command, 1);  	default: @@ -342,6 +336,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,  	struct m25p *flash = mtd_to_m25p(mtd);  	struct spi_transfer t[2];  	struct spi_message m; +	uint8_t opcode;  	pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),  			__func__, (u32)from, len); @@ -354,7 +349,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,  	 * Should add 1 byte DUMMY_BYTE.  	 */  	t[0].tx_buf = flash->command; -	t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE; +	t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0);  	spi_message_add_tail(&t[0], &m);  	t[1].rx_buf = buf; @@ -376,12 +371,14 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,  	 */  	/* Set up the write data buffer. */ -	flash->command[0] = OPCODE_READ; +	opcode = flash->fast_read ? OPCODE_FAST_READ : OPCODE_NORM_READ; +	flash->command[0] = opcode;  	m25p_addr2cmd(flash, from, flash->command);  	spi_sync(flash->spi, &m); -	*retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE; +	*retlen = m.actual_length - m25p_cmdsz(flash) - +			(flash->fast_read ? 1 : 0);  	mutex_unlock(&flash->lock); @@ -664,7 +661,8 @@ static const struct spi_device_id m25p_ids[] = {  	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },  	/* Micron */ -	{ "n25q128",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) }, +	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) }, +	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },  	{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },  	/* Spansion -- single (large) sector size only, at least @@ -745,6 +743,8 @@ static const struct spi_device_id m25p_ids[] = {  	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },  	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },  	{ "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SECT_4K) }, +	{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) }, +	{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) },  	/* Catalyst / On Semiconductor -- non-JEDEC */  	{ "cat25c11", CAT25_INFO(  16, 8, 16, 1) }, @@ -756,7 +756,7 @@ static const struct spi_device_id m25p_ids[] = {  };  MODULE_DEVICE_TABLE(spi, m25p_ids); -static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) +static const struct spi_device_id *jedec_probe(struct spi_device *spi)  {  	int			tmp;  	u8			code = OPCODE_RDID; @@ -801,7 +801,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)   * matches what the READ command supports, at least until this driver   * understands FAST_READ (for clocks over 25 MHz).   */ -static int __devinit m25p_probe(struct spi_device *spi) +static int m25p_probe(struct spi_device *spi)  {  	const struct spi_device_id	*id = spi_get_device_id(spi);  	struct flash_platform_data	*data; @@ -809,9 +809,10 @@ static int __devinit m25p_probe(struct spi_device *spi)  	struct flash_info		*info;  	unsigned			i;  	struct mtd_part_parser_data	ppdata; +	struct device_node __maybe_unused *np = spi->dev.of_node;  #ifdef CONFIG_MTD_OF_PARTS -	if (!of_device_is_available(spi->dev.of_node)) +	if (!of_device_is_available(np))  		return -ENODEV;  #endif @@ -863,7 +864,8 @@ static int __devinit m25p_probe(struct spi_device *spi)  	flash = kzalloc(sizeof *flash, GFP_KERNEL);  	if (!flash)  		return -ENOMEM; -	flash->command = kmalloc(MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL); +	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0), +					GFP_KERNEL);  	if (!flash->command) {  		kfree(flash);  		return -ENOMEM; @@ -920,6 +922,16 @@ static int __devinit m25p_probe(struct spi_device *spi)  	flash->page_size = info->page_size;  	flash->mtd.writebufsize = flash->page_size; +	flash->fast_read = false; +#ifdef CONFIG_OF +	if (np && of_property_read_bool(np, "m25p,fast-read")) +		flash->fast_read = true; +#endif + +#ifdef CONFIG_M25PXX_USE_FAST_READ +	flash->fast_read = true; +#endif +  	if (info->addr_width)  		flash->addr_width = info->addr_width;  	else { @@ -961,7 +973,7 @@ static int __devinit m25p_probe(struct spi_device *spi)  } -static int __devexit m25p_remove(struct spi_device *spi) +static int m25p_remove(struct spi_device *spi)  {  	struct m25p	*flash = dev_get_drvdata(&spi->dev);  	int		status; @@ -983,7 +995,7 @@ static struct spi_driver m25p80_driver = {  	},  	.id_table	= m25p_ids,  	.probe	= m25p_probe, -	.remove	= __devexit_p(m25p_remove), +	.remove	= m25p_remove,  	/* REVISIT: many of these chips have deep power-down modes, which  	 * should clearly be entered on suspend() to minimize power use. diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 928fb0e6d73..ea7ea7b595d 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -618,7 +618,7 @@ static char *otp_setup(struct mtd_info *device, char revision)  /*   * Register DataFlash device with MTD subsystem.   */ -static int __devinit +static int  add_dataflash_otp(struct spi_device *spi, char *name,  		int nr_pages, int pagesize, int pageoffset, char revision)  { @@ -679,7 +679,7 @@ add_dataflash_otp(struct spi_device *spi, char *name,  	return err;  } -static inline int __devinit +static inline int  add_dataflash(struct spi_device *spi, char *name,  		int nr_pages, int pagesize, int pageoffset)  { @@ -705,7 +705,7 @@ struct flash_info {  #define IS_POW2PS	0x0001		/* uses 2^N byte pages */  }; -static struct flash_info __devinitdata dataflash_data [] = { +static struct flash_info dataflash_data[] = {  	/*  	 * NOTE:  chips with SUP_POW2PS (rev D and up) need two entries, @@ -740,7 +740,7 @@ static struct flash_info __devinitdata dataflash_data [] = {  	{ "at45db642d",  0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS},  }; -static struct flash_info *__devinit jedec_probe(struct spi_device *spi) +static struct flash_info *jedec_probe(struct spi_device *spi)  {  	int			tmp;  	uint8_t			code = OP_READ_ID; @@ -823,7 +823,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)   *   AT45DB0642  64Mbit  (8M)    xx111xxx (0x3c)   8192   1056     11   *   AT45DB1282  128Mbit (16M)   xx0100xx (0x10)  16384   1056     11   */ -static int __devinit dataflash_probe(struct spi_device *spi) +static int dataflash_probe(struct spi_device *spi)  {  	int status;  	struct flash_info	*info; @@ -897,7 +897,7 @@ static int __devinit dataflash_probe(struct spi_device *spi)  	return status;  } -static int __devexit dataflash_remove(struct spi_device *spi) +static int dataflash_remove(struct spi_device *spi)  {  	struct dataflash	*flash = dev_get_drvdata(&spi->dev);  	int			status; @@ -920,7 +920,7 @@ static struct spi_driver dataflash_driver = {  	},  	.probe		= dataflash_probe, -	.remove		= __devexit_p(dataflash_remove), +	.remove		= dataflash_remove,  	/* FIXME:  investigate suspend and resume... */  }; diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index dcc3c951153..2d2c2a5d4d2 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -756,7 +756,7 @@ err_probe:  #ifdef CONFIG_OF -static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev, +static int spear_smi_probe_config_dt(struct platform_device *pdev,  					       struct device_node *np)  {  	struct spear_smi_plat_data *pdata = dev_get_platdata(&pdev->dev); @@ -799,7 +799,7 @@ static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev,  	return 0;  }  #else -static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev, +static int spear_smi_probe_config_dt(struct platform_device *pdev,  					       struct device_node *np)  {  	return -ENOSYS; @@ -901,7 +901,7 @@ static int spear_smi_setup_banks(struct platform_device *pdev,   * 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) +static int spear_smi_probe(struct platform_device *pdev)  {  	struct device_node *np = pdev->dev.of_node;  	struct spear_smi_plat_data *pdata = NULL; @@ -1016,7 +1016,7 @@ err:   *   * free all allocations and delete the partitions.   */ -static int __devexit spear_smi_remove(struct platform_device *pdev) +static int spear_smi_remove(struct platform_device *pdev)  {  	struct spear_smi *dev;  	struct spear_snor_flash *flash; @@ -1092,20 +1092,9 @@ static struct platform_driver spear_smi_driver = {  #endif  	},  	.probe = spear_smi_probe, -	.remove = __devexit_p(spear_smi_remove), +	.remove = spear_smi_remove,  }; - -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_platform_driver(spear_smi_driver);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.hashim@st.com>"); diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index ab8a2f4c8d6..8091b016369 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c @@ -64,7 +64,7 @@ struct flash_info {  #define to_sst25l_flash(x) container_of(x, struct sst25l_flash, mtd) -static struct flash_info __devinitdata sst25l_flash_info[] = { +static struct flash_info sst25l_flash_info[] = {  	{"sst25lf020a", 0xbf43, 256, 1024, 4096},  	{"sst25lf040a",	0xbf44,	256, 2048, 4096},  }; @@ -313,7 +313,7 @@ out:  	return ret;  } -static struct flash_info *__devinit sst25l_match_device(struct spi_device *spi) +static struct flash_info *sst25l_match_device(struct spi_device *spi)  {  	struct flash_info *flash_info = NULL;  	struct spi_message m; @@ -353,7 +353,7 @@ static struct flash_info *__devinit sst25l_match_device(struct spi_device *spi)  	return flash_info;  } -static int __devinit sst25l_probe(struct spi_device *spi) +static int sst25l_probe(struct spi_device *spi)  {  	struct flash_info *flash_info;  	struct sst25l_flash *flash; @@ -411,7 +411,7 @@ static int __devinit sst25l_probe(struct spi_device *spi)  	return 0;  } -static int __devexit sst25l_remove(struct spi_device *spi) +static int sst25l_remove(struct spi_device *spi)  {  	struct sst25l_flash *flash = dev_get_drvdata(&spi->dev);  	int ret; @@ -428,7 +428,7 @@ static struct spi_driver sst25l_driver = {  		.owner	= THIS_MODULE,  	},  	.probe		= sst25l_probe, -	.remove		= __devexit_p(sst25l_remove), +	.remove		= sst25l_remove,  };  module_spi_driver(sst25l_driver); diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index df304868beb..62ba82c396c 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -358,13 +358,6 @@ config MTD_IXP2000  	  IXP2000 based board and would like to use the flash chips on it,  	  say 'Y'. -config MTD_FORTUNET -	tristate "CFI Flash device mapped on the FortuNet board" -	depends on MTD_CFI && SA1100_FORTUNET -	help -	  This enables access to the Flash on the FortuNet board.  If you -	  have such a board, say 'Y'. -  config MTD_AUTCPU12  	bool "NV-RAM mapping AUTCPU12 board"  	depends on ARCH_AUTCPU12 diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index a0240edd196..4ded28711bc 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -39,7 +39,6 @@ obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o  obj-$(CONFIG_MTD_PCI)		+= pci.o  obj-$(CONFIG_MTD_AUTCPU12)	+= autcpu12-nvram.o  obj-$(CONFIG_MTD_IMPA7)		+= impa7.o -obj-$(CONFIG_MTD_FORTUNET)	+= fortunet.o  obj-$(CONFIG_MTD_UCLINUX)	+= uclinux.o  obj-$(CONFIG_MTD_NETtel)	+= nettel.o  obj-$(CONFIG_MTD_SCB2_FLASH)	+= scb2_flash.o diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c index e2875d6fe12..f7207b0a76d 100644 --- a/drivers/mtd/maps/amd76xrom.c +++ b/drivers/mtd/maps/amd76xrom.c @@ -100,8 +100,8 @@ static void amd76xrom_cleanup(struct amd76xrom_window *window)  } -static int __devinit amd76xrom_init_one (struct pci_dev *pdev, -	const struct pci_device_id *ent) +static int amd76xrom_init_one(struct pci_dev *pdev, +			      const struct pci_device_id *ent)  {  	static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };  	u8 byte; @@ -289,7 +289,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,  } -static void __devexit amd76xrom_remove_one (struct pci_dev *pdev) +static void amd76xrom_remove_one(struct pci_dev *pdev)  {  	struct amd76xrom_window *window = &amd76xrom_window; @@ -347,4 +347,3 @@ module_exit(cleanup_amd76xrom);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Eric Biederman <ebiederman@lnxi.com>");  MODULE_DESCRIPTION("MTD map driver for BIOS chips on the AMD76X southbridge"); - diff --git a/drivers/mtd/maps/autcpu12-nvram.c b/drivers/mtd/maps/autcpu12-nvram.c index 76fb594bb1d..a2dc2ae4b24 100644 --- a/drivers/mtd/maps/autcpu12-nvram.c +++ b/drivers/mtd/maps/autcpu12-nvram.c @@ -33,7 +33,7 @@ struct autcpu12_nvram_priv {  	struct map_info map;  }; -static int __devinit autcpu12_nvram_probe(struct platform_device *pdev) +static int autcpu12_nvram_probe(struct platform_device *pdev)  {  	map_word tmp, save0, save1;  	struct resource *res; @@ -105,7 +105,7 @@ static int __devinit autcpu12_nvram_probe(struct platform_device *pdev)  	return -ENOMEM;  } -static int __devexit autcpu12_nvram_remove(struct platform_device *pdev) +static int autcpu12_nvram_remove(struct platform_device *pdev)  {  	struct autcpu12_nvram_priv *priv = platform_get_drvdata(pdev); @@ -121,7 +121,7 @@ static struct platform_driver autcpu12_nvram_driver = {  		.owner	= THIS_MODULE,  	},  	.probe		= autcpu12_nvram_probe, -	.remove		= __devexit_p(autcpu12_nvram_remove), +	.remove		= autcpu12_nvram_remove,  };  module_platform_driver(autcpu12_nvram_driver); diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c index ef5cde84a8b..f833edfaab7 100644 --- a/drivers/mtd/maps/bfin-async-flash.c +++ b/drivers/mtd/maps/bfin-async-flash.c @@ -30,7 +30,8 @@  #include <linux/io.h>  #include <asm/unaligned.h> -#define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) +#define pr_devinit(fmt, args...) \ +		({ static const char __fmt[] = fmt; printk(__fmt, ## args); })  #define DRIVER_NAME "bfin-async-flash" @@ -123,7 +124,7 @@ static void bfin_flash_copy_to(struct map_info *map, unsigned long to, const voi  static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; -static int __devinit bfin_flash_probe(struct platform_device *pdev) +static int bfin_flash_probe(struct platform_device *pdev)  {  	int ret;  	struct physmap_flash_data *pdata = pdev->dev.platform_data; @@ -172,7 +173,7 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev)  	return 0;  } -static int __devexit bfin_flash_remove(struct platform_device *pdev) +static int bfin_flash_remove(struct platform_device *pdev)  {  	struct async_state *state = platform_get_drvdata(pdev);  	gpio_free(state->enet_flash_pin); @@ -184,7 +185,7 @@ static int __devexit bfin_flash_remove(struct platform_device *pdev)  static struct platform_driver bfin_flash_driver = {  	.probe		= bfin_flash_probe, -	.remove		= __devexit_p(bfin_flash_remove), +	.remove		= bfin_flash_remove,  	.driver		= {  		.name	= DRIVER_NAME,  	}, diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index 3d0e762fa5f..586a1c77e48 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c @@ -112,8 +112,8 @@ static void ck804xrom_cleanup(struct ck804xrom_window *window)  } -static int __devinit ck804xrom_init_one (struct pci_dev *pdev, -					 const struct pci_device_id *ent) +static int ck804xrom_init_one(struct pci_dev *pdev, +			      const struct pci_device_id *ent)  {  	static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };  	u8 byte; @@ -320,7 +320,7 @@ static int __devinit ck804xrom_init_one (struct pci_dev *pdev,  } -static void __devexit ck804xrom_remove_one (struct pci_dev *pdev) +static void ck804xrom_remove_one(struct pci_dev *pdev)  {  	struct ck804xrom_window *window = &ck804xrom_window; diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c index 08322b1c3e8..ff8681a2583 100644 --- a/drivers/mtd/maps/esb2rom.c +++ b/drivers/mtd/maps/esb2rom.c @@ -144,7 +144,7 @@ static void esb2rom_cleanup(struct esb2rom_window *window)  	pci_dev_put(window->pdev);  } -static int __devinit esb2rom_init_one(struct pci_dev *pdev, +static int esb2rom_init_one(struct pci_dev *pdev,  				      const struct pci_device_id *ent)  {  	static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; @@ -378,13 +378,13 @@ static int __devinit esb2rom_init_one(struct pci_dev *pdev,  	return 0;  } -static void __devexit esb2rom_remove_one (struct pci_dev *pdev) +static void esb2rom_remove_one(struct pci_dev *pdev)  {  	struct esb2rom_window *window = &esb2rom_window;  	esb2rom_cleanup(window);  } -static struct pci_device_id esb2rom_pci_tbl[] __devinitdata = { +static struct pci_device_id esb2rom_pci_tbl[] = {  	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,  	  PCI_ANY_ID, PCI_ANY_ID, },  	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, diff --git a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c deleted file mode 100644 index 956e2e4f30e..00000000000 --- a/drivers/mtd/maps/fortunet.c +++ /dev/null @@ -1,277 +0,0 @@ -/* fortunet.c memory map - * - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/string.h> - -#include <linux/mtd/mtd.h> -#include <linux/mtd/map.h> -#include <linux/mtd/partitions.h> - -#include <asm/io.h> - -#define MAX_NUM_REGIONS		4 -#define MAX_NUM_PARTITIONS	8 - -#define DEF_WINDOW_ADDR_PHY	0x00000000 -#define DEF_WINDOW_SIZE		0x00800000		// 8 Mega Bytes - -#define MTD_FORTUNET_PK		"MTD FortuNet: " - -#define MAX_NAME_SIZE		128 - -struct map_region -{ -	int			window_addr_physical; -	int			altbankwidth; -	struct map_info		map_info; -	struct mtd_info		*mymtd; -	struct mtd_partition	parts[MAX_NUM_PARTITIONS]; -	char			map_name[MAX_NAME_SIZE]; -	char			parts_name[MAX_NUM_PARTITIONS][MAX_NAME_SIZE]; -}; - -static struct map_region	map_regions[MAX_NUM_REGIONS]; -static int			map_regions_set[MAX_NUM_REGIONS] = {0,0,0,0}; -static int			map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0}; - - - -struct map_info default_map = { -	.size = DEF_WINDOW_SIZE, -	.bankwidth = 4, -}; - -static char * __init get_string_option(char *dest,int dest_size,char *sor) -{ -	if(!dest_size) -		return sor; -	dest_size--; -	while(*sor) -	{ -		if(*sor==',') -		{ -			sor++; -			break; -		} -		else if(*sor=='\"') -		{ -			sor++; -			while(*sor) -			{ -				if(*sor=='\"') -				{ -					sor++; -					break; -				} -				*dest = *sor; -				dest++; -				sor++; -				dest_size--; -				if(!dest_size) -				{ -					*dest = 0; -					return sor; -				} -			} -		} -		else -		{ -			*dest = *sor; -			dest++; -			sor++; -			dest_size--; -			if(!dest_size) -			{ -				*dest = 0; -				return sor; -			} -		} -	} -	*dest = 0; -	return sor; -} - -static int __init MTD_New_Region(char *line) -{ -	char	string[MAX_NAME_SIZE]; -	int	params[6]; -	get_options (get_string_option(string,sizeof(string),line),6,params); -	if(params[0]<1) -	{ -		printk(MTD_FORTUNET_PK "Bad parameters for MTD Region " -			" name,region-number[,base,size,bankwidth,altbankwidth]\n"); -		return 1; -	} -	if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS)) -	{ -		printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n", -			params[1],MAX_NUM_REGIONS-1); -		return 1; -	} -	memset(&map_regions[params[1]],0,sizeof(map_regions[params[1]])); -	memcpy(&map_regions[params[1]].map_info, -		&default_map,sizeof(map_regions[params[1]].map_info)); -        map_regions_set[params[1]] = 1; -        map_regions[params[1]].window_addr_physical = DEF_WINDOW_ADDR_PHY; -        map_regions[params[1]].altbankwidth = 2; -        map_regions[params[1]].mymtd = NULL; -	map_regions[params[1]].map_info.name = map_regions[params[1]].map_name; -	strcpy(map_regions[params[1]].map_info.name,string); -	if(params[0]>1) -	{ -		map_regions[params[1]].window_addr_physical = params[2]; -	} -	if(params[0]>2) -	{ -		map_regions[params[1]].map_info.size = params[3]; -	} -	if(params[0]>3) -	{ -		map_regions[params[1]].map_info.bankwidth = params[4]; -	} -	if(params[0]>4) -	{ -		map_regions[params[1]].altbankwidth = params[5]; -	} -	return 1; -} - -static int __init MTD_New_Partition(char *line) -{ -	char	string[MAX_NAME_SIZE]; -	int	params[4]; -	get_options (get_string_option(string,sizeof(string),line),4,params); -	if(params[0]<3) -	{ -		printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition " -			" name,region-number,size,offset\n"); -		return 1; -	} -	if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS)) -	{ -		printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n", -			params[1],MAX_NUM_REGIONS-1); -		return 1; -	} -	if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS) -	{ -		printk(MTD_FORTUNET_PK "Out of space for partition in this region\n"); -		return 1; -	} -	map_regions[params[1]].parts[map_regions_parts[params[1]]].name = -		map_regions[params[1]].	parts_name[map_regions_parts[params[1]]]; -	strcpy(map_regions[params[1]].parts[map_regions_parts[params[1]]].name,string); -	map_regions[params[1]].parts[map_regions_parts[params[1]]].size = -		params[2]; -	map_regions[params[1]].parts[map_regions_parts[params[1]]].offset = -		params[3]; -	map_regions[params[1]].parts[map_regions_parts[params[1]]].mask_flags = 0; -	map_regions_parts[params[1]]++; -	return 1; -} - -__setup("MTD_Region=", MTD_New_Region); -__setup("MTD_Partition=", MTD_New_Partition); - -/* Backwards-spelling-compatibility */ -__setup("MTD_Partion=", MTD_New_Partition); - -static int __init init_fortunet(void) -{ -	int	ix,iy; -	for(iy=ix=0;ix<MAX_NUM_REGIONS;ix++) -	{ -		if(map_regions_parts[ix]&&(!map_regions_set[ix])) -		{ -			printk(MTD_FORTUNET_PK "Region %d is not setup (Setting to default)\n", -				ix); -			memset(&map_regions[ix],0,sizeof(map_regions[ix])); -			memcpy(&map_regions[ix].map_info,&default_map, -				sizeof(map_regions[ix].map_info)); -			map_regions_set[ix] = 1; -			map_regions[ix].window_addr_physical = DEF_WINDOW_ADDR_PHY; -			map_regions[ix].altbankwidth = 2; -			map_regions[ix].mymtd = NULL; -			map_regions[ix].map_info.name = map_regions[ix].map_name; -			strcpy(map_regions[ix].map_info.name,"FORTUNET"); -		} -		if(map_regions_set[ix]) -		{ -			iy++; -			printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at physically " -				" address %x size %x\n", -				map_regions[ix].map_info.name, -				map_regions[ix].window_addr_physical, -				map_regions[ix].map_info.size); - -			map_regions[ix].map_info.phys =	map_regions[ix].window_addr_physical, - -			map_regions[ix].map_info.virt = -				ioremap_nocache( -				map_regions[ix].window_addr_physical, -				map_regions[ix].map_info.size); -			if(!map_regions[ix].map_info.virt) -			{ -				int j = 0; -				printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n", -					map_regions[ix].map_info.name); -				for (j = 0 ; j < ix; j++) -					iounmap(map_regions[j].map_info.virt); -				return -ENXIO; -			} -			simple_map_init(&map_regions[ix].map_info); - -			printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is virtually at: %x\n", -				map_regions[ix].map_info.name, -				map_regions[ix].map_info.virt); -			map_regions[ix].mymtd = do_map_probe("cfi_probe", -				&map_regions[ix].map_info); -			if((!map_regions[ix].mymtd)&&( -				map_regions[ix].altbankwidth!=map_regions[ix].map_info.bankwidth)) -			{ -				printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternate bankwidth " -					"for %s flash.\n", -					map_regions[ix].map_info.name); -				map_regions[ix].map_info.bankwidth = -					map_regions[ix].altbankwidth; -				map_regions[ix].mymtd = do_map_probe("cfi_probe", -					&map_regions[ix].map_info); -			} -			map_regions[ix].mymtd->owner = THIS_MODULE; -			mtd_device_register(map_regions[ix].mymtd, -					    map_regions[ix].parts, -					    map_regions_parts[ix]); -		} -	} -	if(iy) -		return 0; -	return -ENXIO; -} - -static void __exit cleanup_fortunet(void) -{ -	int	ix; -	for(ix=0;ix<MAX_NUM_REGIONS;ix++) -	{ -		if(map_regions_set[ix]) -		{ -			if( map_regions[ix].mymtd ) -			{ -				mtd_device_unregister(map_regions[ix].mymtd); -				map_destroy( map_regions[ix].mymtd ); -			} -			iounmap((void *)map_regions[ix].map_info.virt); -		} -	} -} - -module_init(init_fortunet); -module_exit(cleanup_fortunet); - -MODULE_AUTHOR("FortuNet, Inc."); -MODULE_DESCRIPTION("MTD map driver for FortuNet boards"); diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c index e4de96ba52b..7b643de2500 100644 --- a/drivers/mtd/maps/gpio-addr-flash.c +++ b/drivers/mtd/maps/gpio-addr-flash.c @@ -26,7 +26,8 @@  #include <linux/slab.h>  #include <linux/types.h> -#define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) +#define pr_devinit(fmt, args...) \ +	({ static const char __fmt[] = fmt; printk(__fmt, ## args); })  #define DRIVER_NAME "gpio-addr-flash"  #define PFX DRIVER_NAME ": " @@ -142,7 +143,8 @@ static void gf_write(struct map_info *map, map_word d1, unsigned long ofs)   *   * See gf_copy_from() caveat.   */ -static void gf_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +static void gf_copy_to(struct map_info *map, unsigned long to, +		       const void *from, ssize_t len)  {  	struct async_state *state = gf_map_info_to_state(map); @@ -185,7 +187,7 @@ static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };   *	...   * };   */ -static int __devinit gpio_flash_probe(struct platform_device *pdev) +static int gpio_flash_probe(struct platform_device *pdev)  {  	size_t i, arr_size;  	struct physmap_flash_data *pdata; @@ -258,7 +260,7 @@ static int __devinit gpio_flash_probe(struct platform_device *pdev)  	return 0;  } -static int __devexit gpio_flash_remove(struct platform_device *pdev) +static int gpio_flash_remove(struct platform_device *pdev)  {  	struct async_state *state = platform_get_drvdata(pdev);  	size_t i = 0; @@ -273,7 +275,7 @@ static int __devexit gpio_flash_remove(struct platform_device *pdev)  static struct platform_driver gpio_flash_driver = {  	.probe		= gpio_flash_probe, -	.remove		= __devexit_p(gpio_flash_remove), +	.remove		= gpio_flash_remove,  	.driver		= {  		.name	= DRIVER_NAME,  	}, diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c index 6689dcb3124..c7478e18f48 100644 --- a/drivers/mtd/maps/ichxrom.c +++ b/drivers/mtd/maps/ichxrom.c @@ -84,8 +84,8 @@ static void ichxrom_cleanup(struct ichxrom_window *window)  } -static int __devinit ichxrom_init_one (struct pci_dev *pdev, -	const struct pci_device_id *ent) +static int ichxrom_init_one(struct pci_dev *pdev, +			    const struct pci_device_id *ent)  {  	static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };  	struct ichxrom_window *window = &ichxrom_window; @@ -315,13 +315,13 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,  } -static void __devexit ichxrom_remove_one (struct pci_dev *pdev) +static void ichxrom_remove_one(struct pci_dev *pdev)  {  	struct ichxrom_window *window = &ichxrom_window;  	ichxrom_cleanup(window);  } -static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = { +static struct pci_device_id ichxrom_pci_tbl[] = {  	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,  	  PCI_ANY_ID, PCI_ANY_ID, },  	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, diff --git a/drivers/mtd/maps/intel_vr_nor.c b/drivers/mtd/maps/intel_vr_nor.c index 93f03175c82..3ee2ad1dcbe 100644 --- a/drivers/mtd/maps/intel_vr_nor.c +++ b/drivers/mtd/maps/intel_vr_nor.c @@ -63,24 +63,24 @@ struct vr_nor_mtd {  #define TIMING_BYTE_EN		(1 <<  0)	/* 8-bit vs 16-bit bus */  #define TIMING_MASK		0x3FFF0000 -static void __devexit vr_nor_destroy_partitions(struct vr_nor_mtd *p) +static void vr_nor_destroy_partitions(struct vr_nor_mtd *p)  {  	mtd_device_unregister(p->info);  } -static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p) +static int 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, NULL, NULL, 0);  } -static void __devexit vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p) +static void vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p)  {  	map_destroy(p->info);  } -static int __devinit vr_nor_mtd_setup(struct vr_nor_mtd *p) +static int vr_nor_mtd_setup(struct vr_nor_mtd *p)  {  	static const char *probe_types[] =  	    { "cfi_probe", "jedec_probe", NULL }; @@ -96,7 +96,7 @@ static int __devinit vr_nor_mtd_setup(struct vr_nor_mtd *p)  	return 0;  } -static void __devexit vr_nor_destroy_maps(struct vr_nor_mtd *p) +static void vr_nor_destroy_maps(struct vr_nor_mtd *p)  {  	unsigned int exp_timing_cs0; @@ -116,7 +116,7 @@ static void __devexit vr_nor_destroy_maps(struct vr_nor_mtd *p)   * Initialize the map_info structure and map the flash.   * Returns 0 on success, nonzero otherwise.   */ -static int __devinit vr_nor_init_maps(struct vr_nor_mtd *p) +static int vr_nor_init_maps(struct vr_nor_mtd *p)  {  	unsigned long csr_phys, csr_len;  	unsigned long win_phys, win_len; @@ -176,7 +176,7 @@ static struct pci_device_id vr_nor_pci_ids[] = {  	{0,}  }; -static void __devexit vr_nor_pci_remove(struct pci_dev *dev) +static void vr_nor_pci_remove(struct pci_dev *dev)  {  	struct vr_nor_mtd *p = pci_get_drvdata(dev); @@ -189,7 +189,7 @@ static void __devexit vr_nor_pci_remove(struct pci_dev *dev)  	pci_disable_device(dev);  } -static int __devinit +static int  vr_nor_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  {  	struct vr_nor_mtd *p = NULL; @@ -256,7 +256,7 @@ vr_nor_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  static struct pci_driver vr_nor_pci_driver = {  	.name = DRV_NAME,  	.probe = vr_nor_pci_probe, -	.remove = __devexit_p(vr_nor_pci_remove), +	.remove = vr_nor_pci_remove,  	.id_table = vr_nor_pci_ids,  }; diff --git a/drivers/mtd/maps/lantiq-flash.c b/drivers/mtd/maps/lantiq-flash.c index c03456f1700..3c3c791eb96 100644 --- a/drivers/mtd/maps/lantiq-flash.c +++ b/drivers/mtd/maps/lantiq-flash.c @@ -45,7 +45,7 @@ struct ltq_mtd {  };  static const char ltq_map_name[] = "ltq_nor"; -static const char *ltq_probe_types[] __devinitconst = { +static const char *ltq_probe_types[] = {  					"cmdlinepart", "ofpart", NULL };  static map_word @@ -109,7 +109,7 @@ ltq_copy_to(struct map_info *map, unsigned long to,  	spin_unlock_irqrestore(&ebu_lock, flags);  } -static int __devinit +static int  ltq_mtd_probe(struct platform_device *pdev)  {  	struct mtd_part_parser_data ppdata; @@ -185,7 +185,7 @@ err_out:  	return err;  } -static int __devexit +static int  ltq_mtd_remove(struct platform_device *pdev)  {  	struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev); @@ -209,7 +209,7 @@ MODULE_DEVICE_TABLE(of, ltq_mtd_match);  static struct platform_driver ltq_mtd_driver = {  	.probe = ltq_mtd_probe, -	.remove = __devexit_p(ltq_mtd_remove), +	.remove = ltq_mtd_remove,  	.driver = {  		.name = "ltq-nor",  		.owner = THIS_MODULE, diff --git a/drivers/mtd/maps/latch-addr-flash.c b/drivers/mtd/maps/latch-addr-flash.c index 3c7ad17fca7..ab0fead56b8 100644 --- a/drivers/mtd/maps/latch-addr-flash.c +++ b/drivers/mtd/maps/latch-addr-flash.c @@ -125,7 +125,7 @@ static int latch_addr_flash_remove(struct platform_device *dev)  	return 0;  } -static int __devinit latch_addr_flash_probe(struct platform_device *dev) +static int latch_addr_flash_probe(struct platform_device *dev)  {  	struct latch_addr_flash_data *latch_addr_data;  	struct latch_addr_flash_info *info; @@ -218,7 +218,7 @@ done:  static struct platform_driver latch_addr_flash_driver = {  	.probe		= latch_addr_flash_probe, -	.remove		= __devexit_p(latch_addr_flash_remove), +	.remove		= latch_addr_flash_remove,  	.driver		= {  		.name	= DRIVER_NAME,  	}, diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c index 1c30c1a307f..ed82914966f 100644 --- a/drivers/mtd/maps/pci.c +++ b/drivers/mtd/maps/pci.c @@ -253,7 +253,7 @@ static struct pci_device_id mtd_pci_ids[] = {   * Generic code follows.   */ -static int __devinit +static int  mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  {  	struct mtd_pci_info *info = (struct mtd_pci_info *)id->driver_data; @@ -308,7 +308,7 @@ out:  	return err;  } -static void __devexit +static void  mtd_pci_remove(struct pci_dev *dev)  {  	struct mtd_info *mtd = pci_get_drvdata(dev); @@ -326,7 +326,7 @@ mtd_pci_remove(struct pci_dev *dev)  static struct pci_driver mtd_pci_driver = {  	.name =		"MTD PCI",  	.probe =	mtd_pci_probe, -	.remove =	__devexit_p(mtd_pci_remove), +	.remove =	mtd_pci_remove,  	.id_table =	mtd_pci_ids,  }; diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 6f19acadb06..37cdc201652 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -77,7 +77,7 @@ static int of_flash_remove(struct platform_device *dev)  /* Helper function to handle probing of the obsolete "direct-mapped"   * compatible binding, which has an extra "probe-type" property   * describing the type of flash probe necessary. */ -static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev, +static struct mtd_info *obsolete_probe(struct platform_device *dev,  						  struct map_info *map)  {  	struct device_node *dp = dev->dev.of_node; @@ -116,7 +116,7 @@ static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev,     information. */  static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot",  					"ofpart", "ofoldpart", NULL }; -static const char ** __devinit of_get_probes(struct device_node *dp) +static const char **of_get_probes(struct device_node *dp)  {  	const char *cp;  	int cplen; @@ -145,14 +145,14 @@ static const char ** __devinit of_get_probes(struct device_node *dp)  	return res;  } -static void __devinit of_free_probes(const char **probes) +static void of_free_probes(const char **probes)  {  	if (probes != part_probe_types_def)  		kfree(probes);  }  static struct of_device_id of_flash_match[]; -static int __devinit of_flash_probe(struct platform_device *dev) +static int of_flash_probe(struct platform_device *dev)  {  	const char **part_probe_types;  	const struct of_device_id *match; @@ -170,6 +170,7 @@ static int __devinit of_flash_probe(struct platform_device *dev)  	resource_size_t res_size;  	struct mtd_part_parser_data ppdata;  	bool map_indirect; +	const char *mtd_name;  	match = of_match_device(of_flash_match, &dev->dev);  	if (!match) @@ -178,6 +179,8 @@ static int __devinit of_flash_probe(struct platform_device *dev)  	reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32); +	of_property_read_string(dp, "linux,mtd-name", &mtd_name); +  	/*  	 * Get number of "reg" tuples. Scan for MTD devices on area's  	 * described by each "reg" region. This makes it possible (including @@ -234,7 +237,7 @@ static int __devinit of_flash_probe(struct platform_device *dev)  			goto err_out;  		} -		info->list[i].map.name = dev_name(&dev->dev); +		info->list[i].map.name = mtd_name ?: dev_name(&dev->dev);  		info->list[i].map.phys = res.start;  		info->list[i].map.size = res_size;  		info->list[i].map.bankwidth = be32_to_cpup(width); @@ -282,6 +285,7 @@ static int __devinit of_flash_probe(struct platform_device *dev)  	}  	err = 0; +	info->cmtd = NULL;  	if (info->list_size == 1) {  		info->cmtd = info->list[0].mtd;  	} else if (info->list_size > 1) { @@ -290,9 +294,10 @@ static int __devinit of_flash_probe(struct platform_device *dev)  		 */  		info->cmtd = mtd_concat_create(mtd_list, info->list_size,  					       dev_name(&dev->dev)); -		if (info->cmtd == NULL) -			err = -ENXIO;  	} +	if (info->cmtd == NULL) +		err = -ENXIO; +  	if (err)  		goto err_out; diff --git a/drivers/mtd/maps/pismo.c b/drivers/mtd/maps/pismo.c index 65bd1cd4d62..afea93b515d 100644 --- a/drivers/mtd/maps/pismo.c +++ b/drivers/mtd/maps/pismo.c @@ -58,7 +58,7 @@ static void pismo_set_vpp(struct platform_device *pdev, int on)  	pismo->vpp(pismo->vpp_data, on);  } -static unsigned int __devinit pismo_width_to_bytes(unsigned int width) +static unsigned int pismo_width_to_bytes(unsigned int width)  {  	width &= 15;  	if (width > 2) @@ -66,7 +66,7 @@ static unsigned int __devinit pismo_width_to_bytes(unsigned int width)  	return 1 << width;  } -static int __devinit pismo_eeprom_read(struct i2c_client *client, void *buf, +static int pismo_eeprom_read(struct i2c_client *client, void *buf,  	u8 addr, size_t size)  {  	int ret; @@ -88,7 +88,7 @@ static int __devinit pismo_eeprom_read(struct i2c_client *client, void *buf,  	return ret == ARRAY_SIZE(msg) ? size : -EIO;  } -static int __devinit pismo_add_device(struct pismo_data *pismo, int i, +static int pismo_add_device(struct pismo_data *pismo, int i,  	struct pismo_mem *region, const char *name, void *pdata, size_t psize)  {  	struct platform_device *dev; @@ -129,7 +129,7 @@ static int __devinit pismo_add_device(struct pismo_data *pismo, int i,  	return ret;  } -static int __devinit pismo_add_nor(struct pismo_data *pismo, int i, +static int pismo_add_nor(struct pismo_data *pismo, int i,  	struct pismo_mem *region)  {  	struct physmap_flash_data data = { @@ -143,7 +143,7 @@ static int __devinit pismo_add_nor(struct pismo_data *pismo, int i,  		&data, sizeof(data));  } -static int __devinit pismo_add_sram(struct pismo_data *pismo, int i, +static int pismo_add_sram(struct pismo_data *pismo, int i,  	struct pismo_mem *region)  {  	struct platdata_mtd_ram data = { @@ -154,7 +154,7 @@ static int __devinit pismo_add_sram(struct pismo_data *pismo, int i,  		&data, sizeof(data));  } -static void __devinit pismo_add_one(struct pismo_data *pismo, int i, +static void pismo_add_one(struct pismo_data *pismo, int i,  	const struct pismo_cs_block *cs, phys_addr_t base)  {  	struct device *dev = &pismo->client->dev; @@ -197,7 +197,7 @@ static void __devinit pismo_add_one(struct pismo_data *pismo, int i,  	}  } -static int __devexit pismo_remove(struct i2c_client *client) +static int pismo_remove(struct i2c_client *client)  {  	struct pismo_data *pismo = i2c_get_clientdata(client);  	int i; @@ -210,7 +210,7 @@ static int __devexit pismo_remove(struct i2c_client *client)  	return 0;  } -static int __devinit pismo_probe(struct i2c_client *client, +static int pismo_probe(struct i2c_client *client,  				 const struct i2c_device_id *id)  {  	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); @@ -267,7 +267,7 @@ static struct i2c_driver pismo_driver = {  		.owner	= THIS_MODULE,  	},  	.probe		= pismo_probe, -	.remove		= __devexit_p(pismo_remove), +	.remove		= pismo_remove,  	.id_table	= pismo_id,  }; diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index 81884c27740..43e3dbb976d 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c @@ -49,7 +49,7 @@ struct pxa2xx_flash_info {  static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; -static int __devinit pxa2xx_flash_probe(struct platform_device *pdev) +static int pxa2xx_flash_probe(struct platform_device *pdev)  {  	struct flash_platform_data *flash = pdev->dev.platform_data;  	struct pxa2xx_flash_info *info; @@ -105,7 +105,7 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)  	return 0;  } -static int __devexit pxa2xx_flash_remove(struct platform_device *dev) +static int pxa2xx_flash_remove(struct platform_device *dev)  {  	struct pxa2xx_flash_info *info = platform_get_drvdata(dev); @@ -139,7 +139,7 @@ static struct platform_driver pxa2xx_flash_driver = {  		.owner		= THIS_MODULE,  	},  	.probe		= pxa2xx_flash_probe, -	.remove		= __devexit_p(pxa2xx_flash_remove), +	.remove		= pxa2xx_flash_remove,  	.shutdown	= pxa2xx_flash_shutdown,  }; diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index a675bdbcb0f..f694417cf7e 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -149,8 +149,8 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla  		plat->exit();  } -static struct sa_info *__devinit -sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) +static struct sa_info *sa1100_setup_mtd(struct platform_device *pdev, +					struct flash_platform_data *plat)  {  	struct sa_info *info;  	int nr, size, i, ret = 0; @@ -246,7 +246,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat)  static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; -static int __devinit sa1100_mtd_probe(struct platform_device *pdev) +static int sa1100_mtd_probe(struct platform_device *pdev)  {  	struct flash_platform_data *plat = pdev->dev.platform_data;  	struct sa_info *info; diff --git a/drivers/mtd/maps/scb2_flash.c b/drivers/mtd/maps/scb2_flash.c index 9dcbc684abd..71796137e97 100644 --- a/drivers/mtd/maps/scb2_flash.c +++ b/drivers/mtd/maps/scb2_flash.c @@ -69,7 +69,7 @@ static struct map_info scb2_map = {  };  static int region_fail; -static int __devinit +static int  scb2_fixup_mtd(struct mtd_info *mtd)  {  	int i; @@ -133,7 +133,7 @@ scb2_fixup_mtd(struct mtd_info *mtd)  /* CSB5's 'Function Control Register' has bits for decoding @ >= 0xffc00000 */  #define CSB5_FCR	0x41  #define CSB5_FCR_DECODE_ALL 0x0e -static int __devinit +static int  scb2_flash_probe(struct pci_dev *dev, const struct pci_device_id *ent)  {  	u8 reg; @@ -197,7 +197,7 @@ scb2_flash_probe(struct pci_dev *dev, const struct pci_device_id *ent)  	return 0;  } -static void __devexit +static void  scb2_flash_remove(struct pci_dev *dev)  {  	if (!scb2_mtd) @@ -231,7 +231,7 @@ static struct pci_driver scb2_flash_driver = {  	.name =     "Intel SCB2 BIOS Flash",  	.id_table = scb2_flash_pci_ids,  	.probe =    scb2_flash_probe, -	.remove =   __devexit_p(scb2_flash_remove), +	.remove =   scb2_flash_remove,  };  module_pci_driver(scb2_flash_driver); diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index 175e537b444..d467f3b11c9 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -108,7 +108,7 @@ int uflash_devinit(struct platform_device *op, struct device_node *dp)  	return 0;  } -static int __devinit uflash_probe(struct platform_device *op) +static int uflash_probe(struct platform_device *op)  {  	struct device_node *dp = op->dev.of_node; @@ -121,7 +121,7 @@ static int __devinit uflash_probe(struct platform_device *op)  	return uflash_devinit(op, dp);  } -static int __devexit uflash_remove(struct platform_device *op) +static int uflash_remove(struct platform_device *op)  {  	struct uflash_dev *up = dev_get_drvdata(&op->dev); @@ -155,7 +155,7 @@ static struct platform_driver uflash_driver = {  		.of_match_table = uflash_match,  	},  	.probe		= uflash_probe, -	.remove		= __devexit_p(uflash_remove), +	.remove		= uflash_remove,  };  module_platform_driver(uflash_driver); diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c index 2e2b0945edc..6b223cfe92b 100644 --- a/drivers/mtd/maps/vmu-flash.c +++ b/drivers/mtd/maps/vmu-flash.c @@ -596,7 +596,7 @@ fail_name:  }  /* Handles very basic info about the flash, queries for details */ -static int __devinit vmu_connect(struct maple_device *mdev) +static int vmu_connect(struct maple_device *mdev)  {  	unsigned long test_flash_data, basic_flash_data;  	int c, error; @@ -690,7 +690,7 @@ fail_nomem:  	return error;  } -static void __devexit vmu_disconnect(struct maple_device *mdev) +static void vmu_disconnect(struct maple_device *mdev)  {  	struct memcard *card;  	struct mdev_part *mpart; @@ -772,7 +772,7 @@ static void vmu_file_error(struct maple_device *mdev, void *recvbuf)  } -static int __devinit probe_maple_vmu(struct device *dev) +static int probe_maple_vmu(struct device *dev)  {  	int error;  	struct maple_device *mdev = to_maple_dev(dev); @@ -789,7 +789,7 @@ static int __devinit probe_maple_vmu(struct device *dev)  	return 0;  } -static int __devexit remove_maple_vmu(struct device *dev) +static int remove_maple_vmu(struct device *dev)  {  	struct maple_device *mdev = to_maple_dev(dev); @@ -802,7 +802,7 @@ static struct maple_driver vmu_flash_driver = {  	.drv = {  		.name =		"Dreamcast_visual_memory",  		.probe =	probe_maple_vmu, -		.remove = 	__devexit_p(remove_maple_vmu), +		.remove =	remove_maple_vmu,  	},  }; diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index f1f06715d4e..5ad39bb5ab4 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -32,7 +32,6 @@  #include <linux/hdreg.h>  #include <linux/init.h>  #include <linux/mutex.h> -#include <linux/kthread.h>  #include <asm/uaccess.h>  #include "mtdcore.h" @@ -121,16 +120,14 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,  int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev)  { -	if (kthread_should_stop()) -		return 1; -  	return dev->bg_stop;  }  EXPORT_SYMBOL_GPL(mtd_blktrans_cease_background); -static int mtd_blktrans_thread(void *arg) +static void mtd_blktrans_work(struct work_struct *work)  { -	struct mtd_blktrans_dev *dev = arg; +	struct mtd_blktrans_dev *dev = +		container_of(work, struct mtd_blktrans_dev, work);  	struct mtd_blktrans_ops *tr = dev->tr;  	struct request_queue *rq = dev->rq;  	struct request *req = NULL; @@ -138,7 +135,7 @@ static int mtd_blktrans_thread(void *arg)  	spin_lock_irq(rq->queue_lock); -	while (!kthread_should_stop()) { +	while (1) {  		int res;  		dev->bg_stop = false; @@ -156,15 +153,7 @@ static int mtd_blktrans_thread(void *arg)  				background_done = !dev->bg_stop;  				continue;  			} -			set_current_state(TASK_INTERRUPTIBLE); - -			if (kthread_should_stop()) -				set_current_state(TASK_RUNNING); - -			spin_unlock_irq(rq->queue_lock); -			schedule(); -			spin_lock_irq(rq->queue_lock); -			continue; +			break;  		}  		spin_unlock_irq(rq->queue_lock); @@ -185,8 +174,6 @@ static int mtd_blktrans_thread(void *arg)  		__blk_end_request_all(req, -EIO);  	spin_unlock_irq(rq->queue_lock); - -	return 0;  }  static void mtd_blktrans_request(struct request_queue *rq) @@ -199,10 +186,8 @@ static void mtd_blktrans_request(struct request_queue *rq)  	if (!dev)  		while ((req = blk_fetch_request(rq)) != NULL)  			__blk_end_request_all(req, -ENODEV); -	else { -		dev->bg_stop = true; -		wake_up_process(dev->thread); -	} +	else +		queue_work(dev->wq, &dev->work);  }  static int blktrans_open(struct block_device *bdev, fmode_t mode) @@ -325,7 +310,7 @@ unlock:  	return ret;  } -static const struct block_device_operations mtd_blktrans_ops = { +static const struct block_device_operations mtd_block_ops = {  	.owner		= THIS_MODULE,  	.open		= blktrans_open,  	.release	= blktrans_release, @@ -401,7 +386,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)  	gd->private_data = new;  	gd->major = tr->major;  	gd->first_minor = (new->devnum) << tr->part_bits; -	gd->fops = &mtd_blktrans_ops; +	gd->fops = &mtd_block_ops;  	if (tr->part_bits)  		if (new->devnum < 26) @@ -437,14 +422,13 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)  	gd->queue = new->rq; -	/* Create processing thread */ -	/* TODO: workqueue ? */ -	new->thread = kthread_run(mtd_blktrans_thread, new, -			"%s%d", tr->name, new->mtd->index); -	if (IS_ERR(new->thread)) { -		ret = PTR_ERR(new->thread); +	/* Create processing workqueue */ +	new->wq = alloc_workqueue("%s%d", 0, 0, +				  tr->name, new->mtd->index); +	if (!new->wq)  		goto error4; -	} +	INIT_WORK(&new->work, mtd_blktrans_work); +  	gd->driverfs_dev = &new->mtd->dev;  	if (new->readonly) @@ -484,9 +468,8 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)  	/* Stop new requests to arrive */  	del_gendisk(old->disk); - -	/* Stop the thread */ -	kthread_stop(old->thread); +	/* Stop workqueue. This will perform any pending request. */ +	destroy_workqueue(old->wq);  	/* Kill current requests */  	spin_lock_irqsave(&old->queue_lock, flags); diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index f5b3f91fa1c..97bb8f6304d 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -271,7 +271,7 @@ static void find_next_position(struct mtdoops_context *cxt)  		if (count[0] == 0xffffffff && count[1] == 0xffffffff)  			mark_page_unused(cxt, page); -		if (count[0] == 0xffffffff) +		if (count[0] == 0xffffffff || count[1] != MTDOOPS_KERNMSG_MAGIC)  			continue;  		if (maxcount == 0xffffffff) {  			maxcount = count[0]; @@ -289,14 +289,13 @@ static void find_next_position(struct mtdoops_context *cxt)  		}  	}  	if (maxcount == 0xffffffff) { -		cxt->nextpage = 0; -		cxt->nextcount = 1; -		schedule_work(&cxt->work_erase); -		return; +		cxt->nextpage = cxt->oops_pages - 1; +		cxt->nextcount = 0; +	} +	else { +		cxt->nextpage = maxpos; +		cxt->nextcount = maxcount;  	} - -	cxt->nextpage = maxpos; -	cxt->nextcount = maxcount;  	mtdoops_inc_counter(cxt);  } diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index dae191b3c08..5819eb57521 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -50,16 +50,30 @@ config MTD_NAND_MUSEUM_IDS  	  of these chips were reused by later, larger chips.  config MTD_NAND_DENALI -       depends on PCI +        tristate "Support Denali NAND controller" +        help +	  Enable support for the Denali NAND controller.  This should be +	  combined with either the PCI or platform drivers to provide device +	  registration. + +config MTD_NAND_DENALI_PCI          tristate "Support Denali NAND controller on Intel Moorestown" +	depends on PCI && MTD_NAND_DENALI          help            Enable the driver for NAND flash on Intel Moorestown, using the            Denali NAND controller core. -  + +config MTD_NAND_DENALI_DT +	tristate "Support Denali NAND controller as a DT device" +	depends on HAVE_CLK && MTD_NAND_DENALI +	help +	  Enable the driver for NAND flash on platforms using a Denali NAND +	  controller as a DT device. +  config MTD_NAND_DENALI_SCRATCH_REG_ADDR          hex "Denali NAND size scratch register address"          default "0xFF108018" -        depends on MTD_NAND_DENALI +        depends on MTD_NAND_DENALI_PCI          help            Some platforms place the NAND chip size in a scratch register            because (some versions of) the driver aren't able to automatically @@ -433,6 +447,14 @@ config MTD_NAND_GPMI_NAND  	 block, such as SD card. So pay attention to it when you enable  	 the GPMI. +config MTD_NAND_BCM47XXNFLASH +	tristate "Support for NAND flash on BCM4706 BCMA bus" +	depends on BCMA_NFLASH +	help +	  BCMA bus can have various flash memories attached, they are +	  registered by bcma as platform devices. This enables driver for +	  NAND flash memories. For now only BCM4706 is supported. +  config MTD_NAND_PLATFORM  	tristate "Support for generic platform NAND driver"  	depends on HAS_IOMEM @@ -499,12 +521,6 @@ config MTD_NAND_MXC  	  This enables the driver for the NAND flash controller on the  	  MXC processors. -config MTD_NAND_NOMADIK -	tristate "ST Nomadik 8815 NAND support" -	depends on ARCH_NOMADIK -	help -	  Driver for the NAND flash controller on the Nomadik, with ECC. -  config MTD_NAND_SH_FLCTL  	tristate "Support for NAND on Renesas SuperH FLCTL"  	depends on SUPERH || ARCH_SHMOBILE diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 6c7f2b3ca8a..d76d9120569 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -11,6 +11,8 @@ obj-$(CONFIG_MTD_SM_COMMON) 		+= sm_common.o  obj-$(CONFIG_MTD_NAND_CAFE)		+= cafe_nand.o  obj-$(CONFIG_MTD_NAND_AMS_DELTA)	+= ams-delta.o  obj-$(CONFIG_MTD_NAND_DENALI)		+= denali.o +obj-$(CONFIG_MTD_NAND_DENALI_PCI)	+= denali_pci.o +obj-$(CONFIG_MTD_NAND_DENALI_DT)	+= denali_dt.o  obj-$(CONFIG_MTD_NAND_AU1550)		+= au1550nd.o  obj-$(CONFIG_MTD_NAND_BF5XX)		+= bf5xx_nand.o  obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB)	+= ppchameleonevb.o @@ -45,11 +47,11 @@ obj-$(CONFIG_MTD_NAND_MXC)		+= mxc_nand.o  obj-$(CONFIG_MTD_NAND_SOCRATES)		+= socrates_nand.o  obj-$(CONFIG_MTD_NAND_TXX9NDFMC)	+= txx9ndfmc.o  obj-$(CONFIG_MTD_NAND_NUC900)		+= nuc900_nand.o -obj-$(CONFIG_MTD_NAND_NOMADIK)		+= nomadik_nand.o  obj-$(CONFIG_MTD_NAND_MPC5121_NFC)	+= mpc5121_nfc.o  obj-$(CONFIG_MTD_NAND_RICOH)		+= r852.o  obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o  obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/  obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o +obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/  nand-objs := nand_base.o nand_bbt.o diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index 9e7723aa7ac..f1d71cdc8aa 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c @@ -173,7 +173,7 @@ static const struct gpio _mandatory_gpio[] = {  /*   * Main initialization routine   */ -static int __devinit ams_delta_init(struct platform_device *pdev) +static int ams_delta_init(struct platform_device *pdev)  {  	struct nand_chip *this;  	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -270,7 +270,7 @@ out_free:  /*   * Clean up routine   */ -static int __devexit ams_delta_cleanup(struct platform_device *pdev) +static int ams_delta_cleanup(struct platform_device *pdev)  {  	void __iomem *io_base = platform_get_drvdata(pdev); @@ -289,7 +289,7 @@ static int __devexit ams_delta_cleanup(struct platform_device *pdev)  static struct platform_driver ams_delta_nand_driver = {  	.probe		= ams_delta_init, -	.remove		= __devexit_p(ams_delta_cleanup), +	.remove		= ams_delta_cleanup,  	.driver		= {  		.name	= "ams-delta-nand",  		.owner	= THIS_MODULE, diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 92623ac2015..90bdca61c79 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -331,13 +331,13 @@ static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len)   *               12-bits                20-bytes                 21-bytes   *               24-bits                39-bytes                 42-bytes   */ -static int __devinit pmecc_get_ecc_bytes(int cap, int sector_size) +static int pmecc_get_ecc_bytes(int cap, int sector_size)  {  	int m = 12 + sector_size / 512;  	return (m * cap + 7) / 8;  } -static void __devinit pmecc_config_ecc_layout(struct nand_ecclayout *layout, +static void pmecc_config_ecc_layout(struct nand_ecclayout *layout,  	int oobsize, int ecc_len)  {  	int i; @@ -353,7 +353,7 @@ static void __devinit pmecc_config_ecc_layout(struct nand_ecclayout *layout,  		oobsize - ecc_len - layout->oobfree[0].offset;  } -static void __devinit __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host) +static void __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)  {  	int table_size; @@ -375,7 +375,7 @@ static void pmecc_data_free(struct atmel_nand_host *host)  	kfree(host->pmecc_delta);  } -static int __devinit pmecc_data_alloc(struct atmel_nand_host *host) +static int pmecc_data_alloc(struct atmel_nand_host *host)  {  	const int cap = host->pmecc_corr_cap; @@ -724,6 +724,7 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf,  	struct atmel_nand_host *host = nand_chip->priv;  	int i, err_nbr, eccbytes;  	uint8_t *buf_pos; +	int total_err = 0;  	eccbytes = nand_chip->ecc.bytes;  	for (i = 0; i < eccbytes; i++) @@ -751,12 +752,13 @@ normal_check:  				pmecc_correct_data(mtd, buf_pos, ecc, i,  					host->pmecc_bytes_per_sector, err_nbr);  				mtd->ecc_stats.corrected += err_nbr; +				total_err += err_nbr;  			}  		}  		pmecc_stat >>= 1;  	} -	return 0; +	return total_err;  }  static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, @@ -768,6 +770,7 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,  	uint32_t *eccpos = chip->ecc.layout->eccpos;  	uint32_t stat;  	unsigned long end_time; +	int bitflips = 0;  	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);  	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE); @@ -790,11 +793,14 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,  	}  	stat = pmecc_readl_relaxed(host->ecc, ISR); -	if (stat != 0) -		if (pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]) != 0) -			return -EIO; +	if (stat != 0) { +		bitflips = pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]); +		if (bitflips < 0) +			/* uncorrectable errors */ +			return 0; +	} -	return 0; +	return bitflips;  }  static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, @@ -1206,7 +1212,7 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)  }  #if defined(CONFIG_OF) -static int __devinit atmel_of_init_port(struct atmel_nand_host *host, +static int atmel_of_init_port(struct atmel_nand_host *host,  					 struct device_node *np)  {  	u32 val, table_offset; @@ -1293,7 +1299,7 @@ static int __devinit atmel_of_init_port(struct atmel_nand_host *host,  	return 0;  }  #else -static int __devinit atmel_of_init_port(struct atmel_nand_host *host, +static int atmel_of_init_port(struct atmel_nand_host *host,  					 struct device_node *np)  {  	return -EINVAL; diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 5c47b200045..217459d02b2 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c @@ -382,7 +382,7 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i  	while(!this->dev_ready(mtd));  } -static int __devinit find_nand_cs(unsigned long nand_base) +static int find_nand_cs(unsigned long nand_base)  {  	void __iomem *base =  			(void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR); @@ -403,7 +403,7 @@ static int __devinit find_nand_cs(unsigned long nand_base)  	return -ENODEV;  } -static int __devinit au1550nd_probe(struct platform_device *pdev) +static int au1550nd_probe(struct platform_device *pdev)  {  	struct au1550nd_platdata *pd;  	struct au1550nd_ctx *ctx; @@ -491,7 +491,7 @@ out1:  	return ret;  } -static int __devexit au1550nd_remove(struct platform_device *pdev) +static int au1550nd_remove(struct platform_device *pdev)  {  	struct au1550nd_ctx *ctx = platform_get_drvdata(pdev);  	struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -509,7 +509,7 @@ static struct platform_driver au1550nd_driver = {  		.owner	= THIS_MODULE,  	},  	.probe		= au1550nd_probe, -	.remove		= __devexit_p(au1550nd_remove), +	.remove		= au1550nd_remove,  };  module_platform_driver(au1550nd_driver); diff --git a/drivers/mtd/nand/bcm47xxnflash/Makefile b/drivers/mtd/nand/bcm47xxnflash/Makefile new file mode 100644 index 00000000000..f05b119e134 --- /dev/null +++ b/drivers/mtd/nand/bcm47xxnflash/Makefile @@ -0,0 +1,4 @@ +bcm47xxnflash-y				+= main.o +bcm47xxnflash-y				+= ops_bcm4706.o + +obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash.o diff --git a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h new file mode 100644 index 00000000000..0bdb2ce4da7 --- /dev/null +++ b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h @@ -0,0 +1,22 @@ +#ifndef __BCM47XXNFLASH_H +#define __BCM47XXNFLASH_H + +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> + +struct bcm47xxnflash { +	struct bcma_drv_cc *cc; + +	struct nand_chip nand_chip; +	struct mtd_info mtd; + +	unsigned curr_command; +	int curr_page_addr; +	int curr_column; + +	u8 id_data[8]; +}; + +int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n); + +#endif /* BCM47XXNFLASH */ diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/bcm47xxnflash/main.c new file mode 100644 index 00000000000..2b8b05bec3d --- /dev/null +++ b/drivers/mtd/nand/bcm47xxnflash/main.c @@ -0,0 +1,108 @@ +/* + * BCM47XX NAND flash driver + * + * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/platform_device.h> +#include <linux/bcma/bcma.h> + +#include "bcm47xxnflash.h" + +MODULE_DESCRIPTION("NAND flash driver for BCMA bus"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Rafał Miłecki"); + +static const char *probes[] = { "bcm47xxpart", NULL }; + +static int bcm47xxnflash_probe(struct platform_device *pdev) +{ +	struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); +	struct bcm47xxnflash *b47n; +	int err = 0; + +	b47n = kzalloc(sizeof(*b47n), GFP_KERNEL); +	if (!b47n) { +		err = -ENOMEM; +		goto out; +	} + +	b47n->nand_chip.priv = b47n; +	b47n->mtd.owner = THIS_MODULE; +	b47n->mtd.priv = &b47n->nand_chip; /* Required */ +	b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash); + +	if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { +		err = bcm47xxnflash_ops_bcm4706_init(b47n); +	} else { +		pr_err("Device not supported\n"); +		err = -ENOTSUPP; +	} +	if (err) { +		pr_err("Initialization failed: %d\n", err); +		goto err_init; +	} + +	err = mtd_device_parse_register(&b47n->mtd, probes, NULL, NULL, 0); +	if (err) { +		pr_err("Failed to register MTD device: %d\n", err); +		goto err_dev_reg; +	} + +	return 0; + +err_dev_reg: +err_init: +	kfree(b47n); +out: +	return err; +} + +static int __devexit bcm47xxnflash_remove(struct platform_device *pdev) +{ +	struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); + +	if (nflash->mtd) +		mtd_device_unregister(nflash->mtd); + +	return 0; +} + +static struct platform_driver bcm47xxnflash_driver = { +	.remove = __devexit_p(bcm47xxnflash_remove), +	.driver = { +		.name = "bcma_nflash", +		.owner = THIS_MODULE, +	}, +}; + +static int __init bcm47xxnflash_init(void) +{ +	int err; + +	/* +	 * Platform device "bcma_nflash" exists on SoCs and is registered very +	 * early, it won't be added during runtime (use platform_driver_probe). +	 */ +	err = platform_driver_probe(&bcm47xxnflash_driver, bcm47xxnflash_probe); +	if (err) +		pr_err("Failed to register serial flash driver: %d\n", err); + +	return err; +} + +static void __exit bcm47xxnflash_exit(void) +{ +	platform_driver_unregister(&bcm47xxnflash_driver); +} + +module_init(bcm47xxnflash_init); +module_exit(bcm47xxnflash_exit); diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c new file mode 100644 index 00000000000..86c9a79b89b --- /dev/null +++ b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c @@ -0,0 +1,413 @@ +/* + * BCM47XX NAND flash driver + * + * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/bcma/bcma.h> + +#include "bcm47xxnflash.h" + +/* Broadcom uses 1'000'000 but it seems to be too many. Tests on WNDR4500 has + * shown 164 retries as maxiumum. */ +#define NFLASH_READY_RETRIES		1000 + +#define NFLASH_SECTOR_SIZE		512 + +#define NCTL_CMD0			0x00010000 +#define NCTL_CMD1W			0x00080000 +#define NCTL_READ			0x00100000 +#define NCTL_WRITE			0x00200000 +#define NCTL_SPECADDR			0x01000000 +#define NCTL_READY			0x04000000 +#define NCTL_ERR			0x08000000 +#define NCTL_CSA			0x40000000 +#define NCTL_START			0x80000000 + +/************************************************** + * Various helpers + **************************************************/ + +static inline u8 bcm47xxnflash_ops_bcm4706_ns_to_cycle(u16 ns, u16 clock) +{ +	return ((ns * 1000 * clock) / 1000000) + 1; +} + +static int bcm47xxnflash_ops_bcm4706_ctl_cmd(struct bcma_drv_cc *cc, u32 code) +{ +	int i = 0; + +	bcma_cc_write32(cc, BCMA_CC_NFLASH_CTL, NCTL_START | code); +	for (i = 0; i < NFLASH_READY_RETRIES; i++) { +		if (!(bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & NCTL_START)) { +			i = 0; +			break; +		} +	} +	if (i) { +		pr_err("NFLASH control command not ready!\n"); +		return -EBUSY; +	} +	return 0; +} + +static int bcm47xxnflash_ops_bcm4706_poll(struct bcma_drv_cc *cc) +{ +	int i; + +	for (i = 0; i < NFLASH_READY_RETRIES; i++) { +		if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & NCTL_READY) { +			if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & +			    BCMA_CC_NFLASH_CTL_ERR) { +				pr_err("Error on polling\n"); +				return -EBUSY; +			} else { +				return 0; +			} +		} +	} + +	pr_err("Polling timeout!\n"); +	return -EBUSY; +} + +/************************************************** + * R/W + **************************************************/ + +static void bcm47xxnflash_ops_bcm4706_read(struct mtd_info *mtd, uint8_t *buf, +					   int len) +{ +	struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; +	struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; + +	u32 ctlcode; +	u32 *dest = (u32 *)buf; +	int i; +	int toread; + +	BUG_ON(b47n->curr_page_addr & ~nand_chip->pagemask); +	/* Don't validate column using nand_chip->page_shift, it may be bigger +	 * when accessing OOB */ + +	while (len) { +		/* We can read maximum of 0x200 bytes at once */ +		toread = min(len, 0x200); + +		/* Set page and column */ +		bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_COL_ADDR, +				b47n->curr_column); +		bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_ROW_ADDR, +				b47n->curr_page_addr); + +		/* Prepare to read */ +		ctlcode = NCTL_CSA | NCTL_CMD1W | 0x00040000 | 0x00020000 | +			  NCTL_CMD0; +		ctlcode |= NAND_CMD_READSTART << 8; +		if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, ctlcode)) +			return; +		if (bcm47xxnflash_ops_bcm4706_poll(b47n->cc)) +			return; + +		/* Eventually read some data :) */ +		for (i = 0; i < toread; i += 4, dest++) { +			ctlcode = NCTL_CSA | 0x30000000 | NCTL_READ; +			if (i == toread - 4) /* Last read goes without that */ +				ctlcode &= ~NCTL_CSA; +			if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, +							      ctlcode)) +				return; +			*dest = bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA); +		} + +		b47n->curr_column += toread; +		len -= toread; +	} +} + +static void bcm47xxnflash_ops_bcm4706_write(struct mtd_info *mtd, +					    const uint8_t *buf, int len) +{ +	struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; +	struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; +	struct bcma_drv_cc *cc = b47n->cc; + +	u32 ctlcode; +	const u32 *data = (u32 *)buf; +	int i; + +	BUG_ON(b47n->curr_page_addr & ~nand_chip->pagemask); +	/* Don't validate column using nand_chip->page_shift, it may be bigger +	 * when accessing OOB */ + +	for (i = 0; i < len; i += 4, data++) { +		bcma_cc_write32(cc, BCMA_CC_NFLASH_DATA, *data); + +		ctlcode = NCTL_CSA | 0x30000000 | NCTL_WRITE; +		if (i == len - 4) /* Last read goes without that */ +			ctlcode &= ~NCTL_CSA; +		if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) { +			pr_err("%s ctl_cmd didn't work!\n", __func__); +			return; +		} +	} + +	b47n->curr_column += len; +} + +/************************************************** + * NAND chip ops + **************************************************/ + +/* Default nand_select_chip calls cmd_ctrl, which is not used in BCM4706 */ +static void bcm47xxnflash_ops_bcm4706_select_chip(struct mtd_info *mtd, +						  int chip) +{ +	return; +} + +/* + * Default nand_command and nand_command_lp don't match BCM4706 hardware layout. + * For example, reading chip id is performed in a non-standard way. + * Setting column and page is also handled differently, we use a special + * registers of ChipCommon core. Hacking cmd_ctrl to understand and convert + * standard commands would be much more complicated. + */ +static void bcm47xxnflash_ops_bcm4706_cmdfunc(struct mtd_info *mtd, +					      unsigned command, int column, +					      int page_addr) +{ +	struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; +	struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; +	struct bcma_drv_cc *cc = b47n->cc; +	u32 ctlcode; +	int i; + +	if (column != -1) +		b47n->curr_column = column; +	if (page_addr != -1) +		b47n->curr_page_addr = page_addr; + +	switch (command) { +	case NAND_CMD_RESET: +		pr_warn("Chip reset not implemented yet\n"); +		break; +	case NAND_CMD_READID: +		ctlcode = NCTL_CSA | 0x01000000 | NCTL_CMD1W | NCTL_CMD0; +		ctlcode |= NAND_CMD_READID; +		if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, ctlcode)) { +			pr_err("READID error\n"); +			break; +		} + +		/* +		 * Reading is specific, last one has to go without NCTL_CSA +		 * bit. We don't know how many reads NAND subsystem is going +		 * to perform, so cache everything. +		 */ +		for (i = 0; i < ARRAY_SIZE(b47n->id_data); i++) { +			ctlcode = NCTL_CSA | NCTL_READ; +			if (i == ARRAY_SIZE(b47n->id_data) - 1) +				ctlcode &= ~NCTL_CSA; +			if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, +							      ctlcode)) { +				pr_err("READID error\n"); +				break; +			} +			b47n->id_data[i] = +				bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA) +				& 0xFF; +		} + +		break; +	case NAND_CMD_STATUS: +		ctlcode = NCTL_CSA | NCTL_CMD0 | NAND_CMD_STATUS; +		if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) +			pr_err("STATUS command error\n"); +		break; +	case NAND_CMD_READ0: +		break; +	case NAND_CMD_READOOB: +		if (page_addr != -1) +			b47n->curr_column += mtd->writesize; +		break; +	case NAND_CMD_ERASE1: +		bcma_cc_write32(cc, BCMA_CC_NFLASH_ROW_ADDR, +				b47n->curr_page_addr); +		ctlcode = 0x00040000 | NCTL_CMD1W | NCTL_CMD0 | +			  NAND_CMD_ERASE1 | (NAND_CMD_ERASE2 << 8); +		if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) +			pr_err("ERASE1 failed\n"); +		break; +	case NAND_CMD_ERASE2: +		break; +	case NAND_CMD_SEQIN: +		/* Set page and column */ +		bcma_cc_write32(cc, BCMA_CC_NFLASH_COL_ADDR, +				b47n->curr_column); +		bcma_cc_write32(cc, BCMA_CC_NFLASH_ROW_ADDR, +				b47n->curr_page_addr); + +		/* Prepare to write */ +		ctlcode = 0x40000000 | 0x00040000 | 0x00020000 | 0x00010000; +		ctlcode |= NAND_CMD_SEQIN; +		if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) +			pr_err("SEQIN failed\n"); +		break; +	case NAND_CMD_PAGEPROG: +		if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, 0x00010000 | +							  NAND_CMD_PAGEPROG)) +			pr_err("PAGEPROG failed\n"); +		if (bcm47xxnflash_ops_bcm4706_poll(cc)) +			pr_err("PAGEPROG not ready\n"); +		break; +	default: +		pr_err("Command 0x%X unsupported\n", command); +		break; +	} +	b47n->curr_command = command; +} + +static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd) +{ +	struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; +	struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; +	struct bcma_drv_cc *cc = b47n->cc; +	u32 tmp = 0; + +	switch (b47n->curr_command) { +	case NAND_CMD_READID: +		if (b47n->curr_column >= ARRAY_SIZE(b47n->id_data)) { +			pr_err("Requested invalid id_data: %d\n", +			       b47n->curr_column); +			return 0; +		} +		return b47n->id_data[b47n->curr_column++]; +	case NAND_CMD_STATUS: +		if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, NCTL_READ)) +			return 0; +		return bcma_cc_read32(cc, BCMA_CC_NFLASH_DATA) & 0xff; +	case NAND_CMD_READOOB: +		bcm47xxnflash_ops_bcm4706_read(mtd, (u8 *)&tmp, 4); +		return tmp & 0xFF; +	} + +	pr_err("Invalid command for byte read: 0x%X\n", b47n->curr_command); +	return 0; +} + +static void bcm47xxnflash_ops_bcm4706_read_buf(struct mtd_info *mtd, +					       uint8_t *buf, int len) +{ +	struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; +	struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; + +	switch (b47n->curr_command) { +	case NAND_CMD_READ0: +	case NAND_CMD_READOOB: +		bcm47xxnflash_ops_bcm4706_read(mtd, buf, len); +		return; +	} + +	pr_err("Invalid command for buf read: 0x%X\n", b47n->curr_command); +} + +static void bcm47xxnflash_ops_bcm4706_write_buf(struct mtd_info *mtd, +						const uint8_t *buf, int len) +{ +	struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; +	struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; + +	switch (b47n->curr_command) { +	case NAND_CMD_SEQIN: +		bcm47xxnflash_ops_bcm4706_write(mtd, buf, len); +		return; +	} + +	pr_err("Invalid command for buf write: 0x%X\n", b47n->curr_command); +} + +/************************************************** + * Init + **************************************************/ + +int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n) +{ +	int err; +	u32 freq; +	u16 clock; +	u8 w0, w1, w2, w3, w4; + +	unsigned long chipsize; /* MiB */ +	u8 tbits, col_bits, col_size, row_bits, row_bsize; +	u32 val; + +	b47n->nand_chip.select_chip = bcm47xxnflash_ops_bcm4706_select_chip; +	b47n->nand_chip.cmdfunc = bcm47xxnflash_ops_bcm4706_cmdfunc; +	b47n->nand_chip.read_byte = bcm47xxnflash_ops_bcm4706_read_byte; +	b47n->nand_chip.read_buf = bcm47xxnflash_ops_bcm4706_read_buf; +	b47n->nand_chip.write_buf = bcm47xxnflash_ops_bcm4706_write_buf; +	b47n->nand_chip.bbt_options = NAND_BBT_USE_FLASH; +	b47n->nand_chip.ecc.mode = NAND_ECC_NONE; /* TODO: implement ECC */ + +	/* Enable NAND flash access */ +	bcma_cc_set32(b47n->cc, BCMA_CC_4706_FLASHSCFG, +		      BCMA_CC_4706_FLASHSCFG_NF1); + +	/* Configure wait counters */ +	if (b47n->cc->status & BCMA_CC_CHIPST_4706_PKG_OPTION) { +		freq = 100000000; +	} else { +		freq = bcma_chipco_pll_read(b47n->cc, 4); +		freq = (freq * 0xFFF) >> 3; +		freq = (freq * 25000000) >> 3; +	} +	clock = freq / 1000000; +	w0 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(15, clock); +	w1 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(20, clock); +	w2 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock); +	w3 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock); +	w4 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(100, clock); +	bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_WAITCNT0, +			(w4 << 24 | w3 << 18 | w2 << 12 | w1 << 6 | w0)); + +	/* Scan NAND */ +	err = nand_scan(&b47n->mtd, 1); +	if (err) { +		pr_err("Could not scan NAND flash: %d\n", err); +		goto exit; +	} + +	/* Configure FLASH */ +	chipsize = b47n->nand_chip.chipsize >> 20; +	tbits = ffs(chipsize); /* find first bit set */ +	if (!tbits || tbits != fls(chipsize)) { +		pr_err("Invalid flash size: 0x%lX\n", chipsize); +		err = -ENOTSUPP; +		goto exit; +	} +	tbits += 19; /* Broadcom increases *index* by 20, we increase *pos* */ + +	col_bits = b47n->nand_chip.page_shift + 1; +	col_size = (col_bits + 7) / 8; + +	row_bits = tbits - col_bits + 1; +	row_bsize = (row_bits + 7) / 8; + +	val = ((row_bsize - 1) << 6) | ((col_size - 1) << 4) | 2; +	bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_CONF, val); + +exit: +	if (err) +		bcma_cc_mask32(b47n->cc, BCMA_CC_4706_FLASHSCFG, +			       ~BCMA_CC_4706_FLASHSCFG_NF1); +	return err; +} diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index ab0caa74eb4..4271e948d1e 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c @@ -658,7 +658,7 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info)  /*   * Device management interface   */ -static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info) +static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info)  {  	struct mtd_info *mtd = &info->mtd;  	struct mtd_partition *parts = info->platform->partitions; @@ -667,7 +667,7 @@ static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info)  	return mtd_device_register(mtd, parts, nr);  } -static int __devexit bf5xx_nand_remove(struct platform_device *pdev) +static int bf5xx_nand_remove(struct platform_device *pdev)  {  	struct bf5xx_nand_info *info = to_nand_info(pdev); @@ -725,7 +725,7 @@ static int bf5xx_nand_scan(struct mtd_info *mtd)   * it can allocate all necessary resources then calls the   * nand layer to look for devices   */ -static int __devinit bf5xx_nand_probe(struct platform_device *pdev) +static int bf5xx_nand_probe(struct platform_device *pdev)  {  	struct bf5xx_nand_platform *plat = to_nand_plat(pdev);  	struct bf5xx_nand_info *info = NULL; @@ -865,7 +865,7 @@ static int bf5xx_nand_resume(struct platform_device *dev)  /* driver device registration */  static struct platform_driver bf5xx_nand_driver = {  	.probe		= bf5xx_nand_probe, -	.remove		= __devexit_p(bf5xx_nand_remove), +	.remove		= bf5xx_nand_remove,  	.suspend	= bf5xx_nand_suspend,  	.resume		= bf5xx_nand_resume,  	.driver		= { diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 2bb7170502c..010d6126653 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -585,7 +585,7 @@ static int cafe_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)  }  /* F_2[X]/(X**6+X+1)  */ -static unsigned short __devinit gf64_mul(u8 a, u8 b) +static unsigned short gf64_mul(u8 a, u8 b)  {  	u8 c;  	unsigned int i; @@ -604,7 +604,7 @@ static unsigned short __devinit gf64_mul(u8 a, u8 b)  }  /* F_64[X]/(X**2+X+A**-1) with A the generator of F_64[X]  */ -static u16 __devinit gf4096_mul(u16 a, u16 b) +static u16 gf4096_mul(u16 a, u16 b)  {  	u8 ah, al, bh, bl, ch, cl; @@ -619,14 +619,14 @@ static u16 __devinit gf4096_mul(u16 a, u16 b)  	return (ch << 6) ^ cl;  } -static int __devinit cafe_mul(int x) +static int cafe_mul(int x)  {  	if (x == 0)  		return 1;  	return gf4096_mul(x, 0xe01);  } -static int __devinit cafe_nand_probe(struct pci_dev *pdev, +static int cafe_nand_probe(struct pci_dev *pdev,  				     const struct pci_device_id *ent)  {  	struct mtd_info *mtd; @@ -821,7 +821,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,  	return err;  } -static void __devexit cafe_nand_remove(struct pci_dev *pdev) +static void cafe_nand_remove(struct pci_dev *pdev)  {  	struct mtd_info *mtd = pci_get_drvdata(pdev);  	struct cafe_priv *cafe = mtd->priv; @@ -887,7 +887,7 @@ static struct pci_driver cafe_nand_pci_driver = {  	.name = "CAFÉ NAND",  	.id_table = cafe_nand_tbl,  	.probe = cafe_nand_probe, -	.remove = __devexit_p(cafe_nand_remove), +	.remove = cafe_nand_remove,  	.resume = cafe_nand_resume,  }; diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index adb6c3ef37f..2cdeab8bebc 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c @@ -237,6 +237,7 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)  	this->ecc.hwctl  = cs_enable_hwecc;  	this->ecc.calculate = cs_calculate_ecc;  	this->ecc.correct  = nand_correct_data; +	this->ecc.strength = 1;  	/* Enable the following for a flash based bad block table */  	this->bbt_options = NAND_BBT_USE_FLASH; @@ -247,8 +248,6 @@ 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 945047ad095..3502606f648 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -821,9 +821,16 @@ syndrome_done:  	if (ret < 0)  		goto err_scan; -	ret = mtd_device_parse_register(&info->mtd, NULL, NULL, pdata->parts, -					pdata->nr_parts); +	if (pdata->parts) +		ret = mtd_device_parse_register(&info->mtd, NULL, NULL, +					pdata->parts, pdata->nr_parts); +	else { +		struct mtd_part_parser_data	ppdata; +		ppdata.of_node = pdev->dev.of_node; +		ret = mtd_device_parse_register(&info->mtd, NULL, &ppdata, +						NULL, 0); +	}  	if (ret < 0)  		goto err_scan; diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index e706a237170..0c8bb6bf842 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -16,14 +16,12 @@   * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.   *   */ -  #include <linux/interrupt.h>  #include <linux/delay.h>  #include <linux/dma-mapping.h>  #include <linux/wait.h>  #include <linux/mutex.h>  #include <linux/slab.h> -#include <linux/pci.h>  #include <linux/mtd/mtd.h>  #include <linux/module.h> @@ -89,13 +87,6 @@ MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting."   * format the bank into the proper bits for the controller */  #define BANK(x) ((x) << 24) -/* List of platforms this NAND controller has be integrated into */ -static const struct pci_device_id denali_pci_ids[] = { -	{ PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 }, -	{ PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST }, -	{ /* end: all zeroes */ } -}; -  /* forward declarations */  static void clear_interrupts(struct denali_nand_info *denali);  static uint32_t wait_for_irq(struct denali_nand_info *denali, @@ -699,7 +690,7 @@ static uint32_t wait_for_irq(struct denali_nand_info *denali, uint32_t irq_mask)  	if (comp_res == 0) {  		/* timeout */ -		printk(KERN_ERR "timeout occurred, status = 0x%x, mask = 0x%x\n", +		pr_err("timeout occurred, status = 0x%x, mask = 0x%x\n",  				intr_status, irq_mask);  		intr_status = 0; @@ -1305,8 +1296,7 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,  		/* TODO: Read OOB data */  		break;  	default: -		printk(KERN_ERR ": unsupported command" -				" received 0x%x\n", cmd); +		pr_err(": unsupported command received 0x%x\n", cmd);  		break;  	}  } @@ -1425,107 +1415,48 @@ void denali_drv_init(struct denali_nand_info *denali)  	denali->irq_status = 0;  } -/* driver entry point */ -static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +int denali_init(struct denali_nand_info *denali)  { -	int ret = -ENODEV; -	resource_size_t csr_base, mem_base; -	unsigned long csr_len, mem_len; -	struct denali_nand_info *denali; - -	denali = kzalloc(sizeof(*denali), GFP_KERNEL); -	if (!denali) -		return -ENOMEM; +	int ret; -	ret = pci_enable_device(dev); -	if (ret) { -		printk(KERN_ERR "Spectra: pci_enable_device failed.\n"); -		goto failed_alloc_memery; -	} - -	if (id->driver_data == INTEL_CE4100) { +	if (denali->platform == INTEL_CE4100) {  		/* Due to a silicon limitation, we can only support  		 * ONFI timing mode 1 and below.  		 */  		if (onfi_timing_mode < -1 || onfi_timing_mode > 1) { -			printk(KERN_ERR "Intel CE4100 only supports" -					" ONFI timing mode 1 or below\n"); -			ret = -EINVAL; -			goto failed_enable_dev; -		} -		denali->platform = INTEL_CE4100; -		mem_base = pci_resource_start(dev, 0); -		mem_len = pci_resource_len(dev, 1); -		csr_base = pci_resource_start(dev, 1); -		csr_len = pci_resource_len(dev, 1); -	} else { -		denali->platform = INTEL_MRST; -		csr_base = pci_resource_start(dev, 0); -		csr_len = pci_resource_len(dev, 0); -		mem_base = pci_resource_start(dev, 1); -		mem_len = pci_resource_len(dev, 1); -		if (!mem_len) { -			mem_base = csr_base + csr_len; -			mem_len = csr_len; +			pr_err("Intel CE4100 only supports ONFI timing mode 1 or below\n"); +			return -EINVAL;  		}  	}  	/* Is 32-bit DMA supported? */ -	ret = dma_set_mask(&dev->dev, DMA_BIT_MASK(32)); +	ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32));  	if (ret) { -		printk(KERN_ERR "Spectra: no usable DMA configuration\n"); -		goto failed_enable_dev; +		pr_err("Spectra: no usable DMA configuration\n"); +		return ret;  	} -	denali->buf.dma_buf = dma_map_single(&dev->dev, denali->buf.buf, +	denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf,  					     DENALI_BUF_SIZE,  					     DMA_BIDIRECTIONAL); -	if (dma_mapping_error(&dev->dev, denali->buf.dma_buf)) { -		dev_err(&dev->dev, "Spectra: failed to map DMA buffer\n"); -		goto failed_enable_dev; -	} - -	pci_set_master(dev); -	denali->dev = &dev->dev; -	denali->mtd.dev.parent = &dev->dev; - -	ret = pci_request_regions(dev, DENALI_NAND_NAME); -	if (ret) { -		printk(KERN_ERR "Spectra: Unable to request memory regions\n"); -		goto failed_dma_map; -	} - -	denali->flash_reg = ioremap_nocache(csr_base, csr_len); -	if (!denali->flash_reg) { -		printk(KERN_ERR "Spectra: Unable to remap memory region\n"); -		ret = -ENOMEM; -		goto failed_req_regions; -	} - -	denali->flash_mem = ioremap_nocache(mem_base, mem_len); -	if (!denali->flash_mem) { -		printk(KERN_ERR "Spectra: ioremap_nocache failed!"); -		ret = -ENOMEM; -		goto failed_remap_reg; +	if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) { +		dev_err(denali->dev, "Spectra: failed to map DMA buffer\n"); +		return -EIO;  	} - +	denali->mtd.dev.parent = denali->dev;  	denali_hw_init(denali);  	denali_drv_init(denali);  	/* denali_isr register is done after all the hardware  	 * initilization is finished*/ -	if (request_irq(dev->irq, denali_isr, IRQF_SHARED, +	if (request_irq(denali->irq, denali_isr, IRQF_SHARED,  			DENALI_NAND_NAME, denali)) { -		printk(KERN_ERR "Spectra: Unable to allocate IRQ\n"); -		ret = -ENODEV; -		goto failed_remap_mem; +		pr_err("Spectra: Unable to allocate IRQ\n"); +		return -ENODEV;  	}  	/* now that our ISR is registered, we can enable interrupts */  	denali_set_intr_modes(denali, true); - -	pci_set_drvdata(dev, denali); -  	denali->mtd.name = "denali-nand";  	denali->mtd.owner = THIS_MODULE;  	denali->mtd.priv = &denali->nand; @@ -1549,8 +1480,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	 */  	if (denali->mtd.writesize > NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) {  		ret = -ENODEV; -		printk(KERN_ERR "Spectra: device size not supported by this " -			"version of MTD."); +		pr_err("Spectra: device size not supported by this version of MTD.");  		goto failed_req_irq;  	} @@ -1602,8 +1532,8 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	} else if (denali->mtd.oobsize < (denali->bbtskipbytes +  			ECC_8BITS * (denali->mtd.writesize /  			ECC_SECTOR_SIZE))) { -		printk(KERN_ERR "Your NAND chip OOB is not large enough to" -				" contain 8bit ECC correction codes"); +		pr_err("Your NAND chip OOB is not large enough to \ +				contain 8bit ECC correction codes");  		goto failed_req_irq;  	} else {  		denali->nand.ecc.strength = 8; @@ -1655,56 +1585,24 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	ret = mtd_device_register(&denali->mtd, NULL, 0);  	if (ret) { -		dev_err(&dev->dev, "Spectra: Failed to register MTD: %d\n", +		dev_err(denali->dev, "Spectra: Failed to register MTD: %d\n",  				ret);  		goto failed_req_irq;  	}  	return 0;  failed_req_irq: -	denali_irq_cleanup(dev->irq, denali); -failed_remap_mem: -	iounmap(denali->flash_mem); -failed_remap_reg: -	iounmap(denali->flash_reg); -failed_req_regions: -	pci_release_regions(dev); -failed_dma_map: -	dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE, -			 DMA_BIDIRECTIONAL); -failed_enable_dev: -	pci_disable_device(dev); -failed_alloc_memery: -	kfree(denali); +	denali_irq_cleanup(denali->irq, denali); +  	return ret;  } +EXPORT_SYMBOL(denali_init);  /* driver exit point */ -static void denali_pci_remove(struct pci_dev *dev) +void denali_remove(struct denali_nand_info *denali)  { -	struct denali_nand_info *denali = pci_get_drvdata(dev); - -	nand_release(&denali->mtd); - -	denali_irq_cleanup(dev->irq, denali); - -	iounmap(denali->flash_reg); -	iounmap(denali->flash_mem); -	pci_release_regions(dev); -	pci_disable_device(dev); -	dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE, -			 DMA_BIDIRECTIONAL); -	pci_set_drvdata(dev, NULL); -	kfree(denali); +	denali_irq_cleanup(denali->irq, denali); +	dma_unmap_single(denali->dev, denali->buf.dma_buf, DENALI_BUF_SIZE, +			DMA_BIDIRECTIONAL);  } - -MODULE_DEVICE_TABLE(pci, denali_pci_ids); - -static struct pci_driver denali_pci_driver = { -	.name = DENALI_NAND_NAME, -	.id_table = denali_pci_ids, -	.probe = denali_pci_probe, -	.remove = denali_pci_remove, -}; - -module_pci_driver(denali_pci_driver); +EXPORT_SYMBOL(denali_remove); diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index fabb9d56b39..cec5712862c 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h @@ -466,6 +466,7 @@ struct nand_buf {  #define INTEL_CE4100	1  #define INTEL_MRST	2 +#define DT		3  struct denali_nand_info {  	struct mtd_info mtd; @@ -487,6 +488,7 @@ struct denali_nand_info {  	uint32_t irq_status;  	int irq_debug_array[32];  	int idx; +	int irq;  	uint32_t devnum;	/* represent how many nands connected */  	uint32_t fwblks; /* represent how many blocks FW used */ @@ -496,4 +498,7 @@ struct denali_nand_info {  	uint32_t max_banks;  }; +extern int denali_init(struct denali_nand_info *denali); +extern void denali_remove(struct denali_nand_info *denali); +  #endif /*_LLD_NAND_*/ diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c new file mode 100644 index 00000000000..546f8cb5688 --- /dev/null +++ b/drivers/mtd/nand/denali_dt.c @@ -0,0 +1,167 @@ +/* + * NAND Flash Controller Device Driver for DT + * + * Copyright © 2011, Picochip. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + */ +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/ioport.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/slab.h> + +#include "denali.h" + +struct denali_dt { +	struct denali_nand_info	denali; +	struct clk		*clk; +}; + +static void __iomem *request_and_map(struct device *dev, +				     const struct resource *res) +{ +	void __iomem *ptr; + +	if (!devm_request_mem_region(dev, res->start, resource_size(res), +				     "denali-dt")) { +		dev_err(dev, "unable to request %s\n", res->name); +		return NULL; +	} + +	ptr = devm_ioremap_nocache(dev, res->start, resource_size(res)); +	if (!res) +		dev_err(dev, "ioremap_nocache of %s failed!", res->name); + +	return ptr; +} + +static const struct of_device_id denali_nand_dt_ids[] = { +		{ .compatible = "denali,denali-nand-dt" }, +		{ /* sentinel */ } +	}; + +MODULE_DEVICE_TABLE(of, denali_nand_dt_ids); + +static u64 denali_dma_mask; + +static int denali_dt_probe(struct platform_device *ofdev) +{ +	struct resource *denali_reg, *nand_data; +	struct denali_dt *dt; +	struct denali_nand_info *denali; +	int ret; +	const struct of_device_id *of_id; + +	of_id = of_match_device(denali_nand_dt_ids, &ofdev->dev); +	if (of_id) { +		ofdev->id_entry = of_id->data; +	} else { +		pr_err("Failed to find the right device id.\n"); +		return -ENOMEM; +	} + +	dt = devm_kzalloc(&ofdev->dev, sizeof(*dt), GFP_KERNEL); +	if (!dt) +		return -ENOMEM; +	denali = &dt->denali; + +	denali_reg = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "denali_reg"); +	nand_data = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "nand_data"); +	if (!denali_reg || !nand_data) { +		dev_err(&ofdev->dev, "resources not completely defined\n"); +		return -EINVAL; +	} + +	denali->platform = DT; +	denali->dev = &ofdev->dev; +	denali->irq = platform_get_irq(ofdev, 0); +	if (denali->irq < 0) { +		dev_err(&ofdev->dev, "no irq defined\n"); +		return -ENXIO; +	} + +	denali->flash_reg = request_and_map(&ofdev->dev, denali_reg); +	if (!denali->flash_reg) +		return -ENOMEM; + +	denali->flash_mem = request_and_map(&ofdev->dev, nand_data); +	if (!denali->flash_mem) +		return -ENOMEM; + +	if (!of_property_read_u32(ofdev->dev.of_node, +		"dma-mask", (u32 *)&denali_dma_mask)) { +		denali->dev->dma_mask = &denali_dma_mask; +	} else { +		denali->dev->dma_mask = NULL; +	} + +	dt->clk = clk_get(&ofdev->dev, NULL); +	if (IS_ERR(dt->clk)) { +		dev_err(&ofdev->dev, "no clk available\n"); +		return PTR_ERR(dt->clk); +	} +	clk_prepare_enable(dt->clk); + +	ret = denali_init(denali); +	if (ret) +		goto out_disable_clk; + +	platform_set_drvdata(ofdev, dt); +	return 0; + +out_disable_clk: +	clk_disable_unprepare(dt->clk); +	clk_put(dt->clk); + +	return ret; +} + +static int denali_dt_remove(struct platform_device *ofdev) +{ +	struct denali_dt *dt = platform_get_drvdata(ofdev); + +	denali_remove(&dt->denali); +	clk_disable(dt->clk); +	clk_put(dt->clk); + +	return 0; +} + +static struct platform_driver denali_dt_driver = { +	.probe		= denali_dt_probe, +	.remove		= denali_dt_remove, +	.driver		= { +		.name	= "denali-nand-dt", +		.owner	= THIS_MODULE, +		.of_match_table	= of_match_ptr(denali_nand_dt_ids), +	}, +}; + +static int __init denali_init_dt(void) +{ +	return platform_driver_register(&denali_dt_driver); +} +module_init(denali_init_dt); + +static void __exit denali_exit_dt(void) +{ +	platform_driver_unregister(&denali_dt_driver); +} +module_exit(denali_exit_dt); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jamie Iles"); +MODULE_DESCRIPTION("DT driver for Denali NAND controller"); diff --git a/drivers/mtd/nand/denali_pci.c b/drivers/mtd/nand/denali_pci.c new file mode 100644 index 00000000000..e3e46623b2b --- /dev/null +++ b/drivers/mtd/nand/denali_pci.c @@ -0,0 +1,144 @@ +/* + * NAND Flash Controller Device Driver + * Copyright © 2009-2010, Intel Corporation and its suppliers. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + */ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include "denali.h" + +#define DENALI_NAND_NAME    "denali-nand-pci" + +/* List of platforms this NAND controller has be integrated into */ +static DEFINE_PCI_DEVICE_TABLE(denali_pci_ids) = { +	{ PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 }, +	{ PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST }, +	{ /* end: all zeroes */ } +}; +MODULE_DEVICE_TABLE(pci, denali_pci_ids); + +static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ +	int ret = -ENODEV; +	resource_size_t csr_base, mem_base; +	unsigned long csr_len, mem_len; +	struct denali_nand_info *denali; + +	denali = kzalloc(sizeof(*denali), GFP_KERNEL); +	if (!denali) +		return -ENOMEM; + +	ret = pci_enable_device(dev); +	if (ret) { +		pr_err("Spectra: pci_enable_device failed.\n"); +		goto failed_alloc_memery; +	} + +	if (id->driver_data == INTEL_CE4100) { +		denali->platform = INTEL_CE4100; +		mem_base = pci_resource_start(dev, 0); +		mem_len = pci_resource_len(dev, 1); +		csr_base = pci_resource_start(dev, 1); +		csr_len = pci_resource_len(dev, 1); +	} else { +		denali->platform = INTEL_MRST; +		csr_base = pci_resource_start(dev, 0); +		csr_len = pci_resource_len(dev, 0); +		mem_base = pci_resource_start(dev, 1); +		mem_len = pci_resource_len(dev, 1); +		if (!mem_len) { +			mem_base = csr_base + csr_len; +			mem_len = csr_len; +		} +	} + +	pci_set_master(dev); +	denali->dev = &dev->dev; +	denali->irq = dev->irq; + +	ret = pci_request_regions(dev, DENALI_NAND_NAME); +	if (ret) { +		pr_err("Spectra: Unable to request memory regions\n"); +		goto failed_enable_dev; +	} + +	denali->flash_reg = ioremap_nocache(csr_base, csr_len); +	if (!denali->flash_reg) { +		pr_err("Spectra: Unable to remap memory region\n"); +		ret = -ENOMEM; +		goto failed_req_regions; +	} + +	denali->flash_mem = ioremap_nocache(mem_base, mem_len); +	if (!denali->flash_mem) { +		pr_err("Spectra: ioremap_nocache failed!"); +		ret = -ENOMEM; +		goto failed_remap_reg; +	} + +	ret = denali_init(denali); +	if (ret) +		goto failed_remap_mem; + +	pci_set_drvdata(dev, denali); + +	return 0; + +failed_remap_mem: +	iounmap(denali->flash_mem); +failed_remap_reg: +	iounmap(denali->flash_reg); +failed_req_regions: +	pci_release_regions(dev); +failed_enable_dev: +	pci_disable_device(dev); +failed_alloc_memery: +	kfree(denali); + +	return ret; +} + +/* driver exit point */ +static void denali_pci_remove(struct pci_dev *dev) +{ +	struct denali_nand_info *denali = pci_get_drvdata(dev); + +	denali_remove(denali); +	iounmap(denali->flash_reg); +	iounmap(denali->flash_mem); +	pci_release_regions(dev); +	pci_disable_device(dev); +	pci_set_drvdata(dev, NULL); +	kfree(denali); +} + +static struct pci_driver denali_pci_driver = { +	.name = DENALI_NAND_NAME, +	.id_table = denali_pci_ids, +	.probe = denali_pci_probe, +	.remove = denali_pci_remove, +}; + +static int denali_init_pci(void) +{ +	pr_info("Spectra MTD driver built on %s @ %s\n", __DATE__, __TIME__); +	return pci_register_driver(&denali_pci_driver); +} +module_init(denali_init_pci); + +static void denali_exit_pci(void) +{ +	pci_unregister_driver(&denali_pci_driver); +} +module_exit(denali_exit_pci); diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index 256eb30f618..81fa5784f98 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -53,8 +53,6 @@ static unsigned long __initdata doc_locations[] = {  	0xe0000, 0xe2000, 0xe4000, 0xe6000,  	0xe8000, 0xea000, 0xec000, 0xee000,  #endif /*  CONFIG_MTD_DOCPROBE_HIGH */ -#else -#warning Unknown architecture for DiskOnChip. No default probe locations defined  #endif  	0xffffffff }; diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index 799da5d1c85..18fa4489e52 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c @@ -46,6 +46,25 @@  #include <linux/bitrev.h>  /* + * In "reliable mode" consecutive 2k pages are used in parallel (in some + * fashion) to store the same data.  The data can be read back from the + * even-numbered pages in the normal manner; odd-numbered pages will appear to + * contain junk.  Systems that boot from the docg4 typically write the secondary + * program loader (SPL) code in this mode.  The SPL is loaded by the initial + * program loader (IPL, stored in the docg4's 2k NOR-like region that is mapped + * to the reset vector address).  This module parameter enables you to use this + * driver to write the SPL.  When in this mode, no more than 2k of data can be + * written at a time, because the addresses do not increment in the normal + * manner, and the starting offset must be within an even-numbered 2k region; + * i.e., invalid starting offsets are 0x800, 0xa00, 0xc00, 0xe00, 0x1800, + * 0x1a00, ...  Reliable mode is a special case and should not be used unless + * you know what you're doing. + */ +static bool reliable_mode; +module_param(reliable_mode, bool, 0); +MODULE_PARM_DESC(reliable_mode, "pages are programmed in reliable mode"); + +/*   * You'll want to ignore badblocks if you're reading a partition that contains   * data written by the TrueFFS library (i.e., by PalmOS, Windows, etc), since   * it does not use mtd nand's method for marking bad blocks (using oob area). @@ -113,6 +132,7 @@ struct docg4_priv {  #define DOCG4_SEQ_PAGEWRITE		0x16  #define DOCG4_SEQ_PAGEPROG		0x1e  #define DOCG4_SEQ_BLOCKERASE		0x24 +#define DOCG4_SEQ_SETMODE		0x45  /* DOC_FLASHCOMMAND register commands */  #define DOCG4_CMD_PAGE_READ             0x00 @@ -122,6 +142,8 @@ struct docg4_priv {  #define DOC_CMD_PROG_BLOCK_ADDR		0x60  #define DOCG4_CMD_PAGEWRITE		0x80  #define DOC_CMD_PROG_CYCLE2		0x10 +#define DOCG4_CMD_FAST_MODE		0xa3 /* functionality guessed */ +#define DOC_CMD_RELIABLE_MODE		0x22  #define DOC_CMD_RESET			0xff  /* DOC_POWERMODE register bits */ @@ -190,17 +212,20 @@ struct docg4_priv {  #define DOCG4_T                4   /* BCH alg corrects up to 4 bit errors */  #define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */ +#define DOCG4_REDUNDANT_BBT_PAGE 24 /* page where redundant factory bbt lives */  /* - * Oob bytes 0 - 6 are available to the user. - * Byte 7 is hamming ecc for first 7 bytes.  Bytes 8 - 14 are hw-generated ecc. + * Bytes 0, 1 are used as badblock marker. + * Bytes 2 - 6 are available to the user. + * Byte 7 is hamming ecc for first 7 oob bytes only. + * Bytes 8 - 14 are hw-generated ecc covering entire page + oob bytes 0 - 14.   * Byte 15 (the last) is used by the driver as a "page written" flag.   */  static struct nand_ecclayout docg4_oobinfo = {  	.eccbytes = 9,  	.eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, -	.oobavail = 7, -	.oobfree = { {0, 7} } +	.oobavail = 5, +	.oobfree = { {.offset = 2, .length = 5} }  };  /* @@ -611,6 +636,14 @@ static void write_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr)  	dev_dbg(doc->dev,  	      "docg4: %s: g4 addr: %x\n", __func__, docg4_addr);  	sequence_reset(mtd); + +	if (unlikely(reliable_mode)) { +		writew(DOCG4_SEQ_SETMODE, docptr + DOC_FLASHSEQUENCE); +		writew(DOCG4_CMD_FAST_MODE, docptr + DOC_FLASHCOMMAND); +		writew(DOC_CMD_RELIABLE_MODE, docptr + DOC_FLASHCOMMAND); +		write_nop(docptr); +	} +  	writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE);  	writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND);  	write_nop(docptr); @@ -691,6 +724,15 @@ static void docg4_command(struct mtd_info *mtd, unsigned command, int column,  		break;  	case NAND_CMD_SEQIN: +		if (unlikely(reliable_mode)) { +			uint16_t g4_page = g4_addr >> 16; + +			/* writes to odd-numbered 2k pages are invalid */ +			if (g4_page & 0x01) +				dev_warn(doc->dev, +					 "invalid reliable mode address\n"); +		} +  		write_page_prologue(mtd, g4_addr);  		/* hack for deferred write of oob bytes */ @@ -979,16 +1021,15 @@ static int __init read_factory_bbt(struct mtd_info *mtd)  	struct docg4_priv *doc = nand->priv;  	uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0);  	uint8_t *buf; -	int i, block, status; +	int i, block; +	__u32 eccfailed_stats = mtd->ecc_stats.failed;  	buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL);  	if (buf == NULL)  		return -ENOMEM;  	read_page_prologue(mtd, g4_addr); -	status = docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE); -	if (status) -		goto exit; +	docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE);  	/*  	 * If no memory-based bbt was created, exit.  This will happen if module @@ -1000,6 +1041,20 @@ static int __init read_factory_bbt(struct mtd_info *mtd)  	if (nand->bbt == NULL)  /* no memory-based bbt */  		goto exit; +	if (mtd->ecc_stats.failed > eccfailed_stats) { +		/* +		 * Whoops, an ecc failure ocurred reading the factory bbt. +		 * It is stored redundantly, so we get another chance. +		 */ +		eccfailed_stats = mtd->ecc_stats.failed; +		docg4_read_page(mtd, nand, buf, 0, DOCG4_REDUNDANT_BBT_PAGE); +		if (mtd->ecc_stats.failed > eccfailed_stats) { +			dev_warn(doc->dev, +				 "The factory bbt could not be read!\n"); +			goto exit; +		} +	} +  	/*  	 * Parse factory bbt and update memory-based bbt.  Factory bbt format is  	 * simple: one bit per block, block numbers increase left to right (msb @@ -1019,7 +1074,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd)  	}   exit:  	kfree(buf); -	return status; +	return 0;  }  static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index cc1480a5e4c..20657209a47 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -109,20 +109,6 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = {  };  /* - * fsl_elbc_oob_lp_eccm* specify that LP NAND's OOB free area starts at offset - * 1, so we have to adjust bad block pattern. This pattern should be used for - * x8 chips only. So far hardware does not support x16 chips anyway. - */ -static u8 scan_ff_pattern[] = { 0xff, }; - -static struct nand_bbt_descr largepage_memorybased = { -	.options = 0, -	.offs = 0, -	.len = 1, -	.pattern = scan_ff_pattern, -}; - -/*   * ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt,   * interfere with ECC positions, that's why we implement our own descriptors.   * OOB {11, 5}, works for both SP and LP chips, with ECCM = 1 and ECCM = 0. @@ -699,7 +685,6 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)  			chip->ecc.layout = (priv->fmr & FMR_ECCM) ?  			                   &fsl_elbc_oob_lp_eccm1 :  			                   &fsl_elbc_oob_lp_eccm0; -			chip->badblock_pattern = &largepage_memorybased;  		}  	} else {  		dev_err(priv->dev, @@ -814,7 +799,7 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv)  static DEFINE_MUTEX(fsl_elbc_nand_mutex); -static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev) +static int fsl_elbc_nand_probe(struct platform_device *pdev)  {  	struct fsl_lbc_regs __iomem *lbc;  	struct fsl_elbc_mtd *priv; diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 3551a99076b..ad6222627fe 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -389,7 +389,7 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,  			timing = IFC_FIR_OP_RBCD;  		out_be32(&ifc->ifc_nand.nand_fir0, -				(IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) | +				(IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |  				(IFC_FIR_OP_UA  << IFC_NAND_FIR0_OP1_SHIFT) |  				(timing << IFC_NAND_FIR0_OP2_SHIFT));  		out_be32(&ifc->ifc_nand.nand_fcr0, @@ -754,7 +754,7 @@ static void fsl_ifc_sram_init(struct fsl_ifc_mtd *priv)  	/* READID */  	out_be32(&ifc->ifc_nand.nand_fir0, -			(IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) | +			(IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |  			(IFC_FIR_OP_UA  << IFC_NAND_FIR0_OP1_SHIFT) |  			(IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT));  	out_be32(&ifc->ifc_nand.nand_fcr0, @@ -922,7 +922,7 @@ static int match_bank(struct fsl_ifc_regs __iomem *ifc, int bank,  static DEFINE_MUTEX(fsl_ifc_nand_mutex); -static int __devinit fsl_ifc_nand_probe(struct platform_device *dev) +static int fsl_ifc_nand_probe(struct platform_device *dev)  {  	struct fsl_ifc_regs __iomem *ifc;  	struct fsl_ifc_mtd *priv; diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 45df542b9c6..5a8f5c4ce51 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -152,7 +152,7 @@ static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)  		fun_wait_rnb(fun);  } -static int __devinit fun_chip_init(struct fsl_upm_nand *fun, +static int fun_chip_init(struct fsl_upm_nand *fun,  				   const struct device_node *upm_np,  				   const struct resource *io_res)  { @@ -201,7 +201,7 @@ err:  	return ret;  } -static int __devinit fun_probe(struct platform_device *ofdev) +static int fun_probe(struct platform_device *ofdev)  {  	struct fsl_upm_nand *fun;  	struct resource io_res; @@ -318,7 +318,7 @@ err1:  	return ret;  } -static int __devexit fun_remove(struct platform_device *ofdev) +static int fun_remove(struct platform_device *ofdev)  {  	struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev);  	int i; @@ -350,7 +350,7 @@ static struct platform_driver of_fun_driver = {  		.of_match_table = of_fun_match,  	},  	.probe		= fun_probe, -	.remove		= __devexit_p(fun_remove), +	.remove		= fun_remove,  };  module_platform_driver(of_fun_driver); diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 38d26240d8b..1d7446434b0 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -361,7 +361,7 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)  	struct nand_chip *this = mtd->priv;  	struct fsmc_nand_data *host = container_of(mtd,  					struct fsmc_nand_data, mtd); -	void *__iomem *regs = host->regs_va; +	void __iomem *regs = host->regs_va;  	unsigned int bank = host->bank;  	if (ctrl & NAND_CTRL_CHANGE) { @@ -383,13 +383,13 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)  			pc |= FSMC_ENABLE;  		else  			pc &= ~FSMC_ENABLE; -		writel(pc, FSMC_NAND_REG(regs, bank, PC)); +		writel_relaxed(pc, FSMC_NAND_REG(regs, bank, PC));  	}  	mb();  	if (cmd != NAND_CMD_NONE) -		writeb(cmd, this->IO_ADDR_W); +		writeb_relaxed(cmd, this->IO_ADDR_W);  }  /* @@ -426,14 +426,18 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank,  	tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT;  	if (busw) -		writel(value | FSMC_DEVWID_16, FSMC_NAND_REG(regs, bank, PC)); +		writel_relaxed(value | FSMC_DEVWID_16, +				FSMC_NAND_REG(regs, bank, PC));  	else -		writel(value | FSMC_DEVWID_8, FSMC_NAND_REG(regs, bank, PC)); +		writel_relaxed(value | FSMC_DEVWID_8, +				FSMC_NAND_REG(regs, bank, PC)); -	writel(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar, +	writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar,  			FSMC_NAND_REG(regs, bank, PC)); -	writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, COMM)); -	writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, ATTRIB)); +	writel_relaxed(thiz | thold | twait | tset, +			FSMC_NAND_REG(regs, bank, COMM)); +	writel_relaxed(thiz | thold | twait | tset, +			FSMC_NAND_REG(regs, bank, ATTRIB));  }  /* @@ -446,11 +450,11 @@ static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)  	void __iomem *regs = host->regs_va;  	uint32_t bank = host->bank; -	writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256, +	writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256,  			FSMC_NAND_REG(regs, bank, PC)); -	writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN, +	writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN,  			FSMC_NAND_REG(regs, bank, PC)); -	writel(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN, +	writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN,  			FSMC_NAND_REG(regs, bank, PC));  } @@ -470,7 +474,7 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,  	unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT;  	do { -		if (readl(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY) +		if (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY)  			break;  		else  			cond_resched(); @@ -481,25 +485,25 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,  		return -ETIMEDOUT;  	} -	ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1)); +	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));  	ecc[0] = (uint8_t) (ecc_tmp >> 0);  	ecc[1] = (uint8_t) (ecc_tmp >> 8);  	ecc[2] = (uint8_t) (ecc_tmp >> 16);  	ecc[3] = (uint8_t) (ecc_tmp >> 24); -	ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC2)); +	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2));  	ecc[4] = (uint8_t) (ecc_tmp >> 0);  	ecc[5] = (uint8_t) (ecc_tmp >> 8);  	ecc[6] = (uint8_t) (ecc_tmp >> 16);  	ecc[7] = (uint8_t) (ecc_tmp >> 24); -	ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC3)); +	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3));  	ecc[8] = (uint8_t) (ecc_tmp >> 0);  	ecc[9] = (uint8_t) (ecc_tmp >> 8);  	ecc[10] = (uint8_t) (ecc_tmp >> 16);  	ecc[11] = (uint8_t) (ecc_tmp >> 24); -	ecc_tmp = readl(FSMC_NAND_REG(regs, bank, STS)); +	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, STS));  	ecc[12] = (uint8_t) (ecc_tmp >> 16);  	return 0; @@ -519,7 +523,7 @@ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data,  	uint32_t bank = host->bank;  	uint32_t ecc_tmp; -	ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1)); +	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));  	ecc[0] = (uint8_t) (ecc_tmp >> 0);  	ecc[1] = (uint8_t) (ecc_tmp >> 8);  	ecc[2] = (uint8_t) (ecc_tmp >> 16); @@ -601,7 +605,7 @@ static int dma_xfer(struct fsmc_nand_data *host, void *buffer, int len,  	dma_async_issue_pending(chan);  	ret = -	wait_for_completion_interruptible_timeout(&host->dma_access_complete, +	wait_for_completion_timeout(&host->dma_access_complete,  				msecs_to_jiffies(3000));  	if (ret <= 0) {  		chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); @@ -628,10 +632,10 @@ static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)  		uint32_t *p = (uint32_t *)buf;  		len = len >> 2;  		for (i = 0; i < len; i++) -			writel(p[i], chip->IO_ADDR_W); +			writel_relaxed(p[i], chip->IO_ADDR_W);  	} else {  		for (i = 0; i < len; i++) -			writeb(buf[i], chip->IO_ADDR_W); +			writeb_relaxed(buf[i], chip->IO_ADDR_W);  	}  } @@ -651,10 +655,10 @@ static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)  		uint32_t *p = (uint32_t *)buf;  		len = len >> 2;  		for (i = 0; i < len; i++) -			p[i] = readl(chip->IO_ADDR_R); +			p[i] = readl_relaxed(chip->IO_ADDR_R);  	} else {  		for (i = 0; i < len; i++) -			buf[i] = readb(chip->IO_ADDR_R); +			buf[i] = readb_relaxed(chip->IO_ADDR_R);  	}  } @@ -783,7 +787,7 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,  	uint32_t num_err, i;  	uint32_t ecc1, ecc2, ecc3, ecc4; -	num_err = (readl(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF; +	num_err = (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF;  	/* no bit flipping */  	if (likely(num_err == 0)) @@ -826,10 +830,10 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,  	 * uint64_t array and error offset indexes are populated in err_idx  	 * array  	 */ -	ecc1 = readl(FSMC_NAND_REG(regs, bank, ECC1)); -	ecc2 = readl(FSMC_NAND_REG(regs, bank, ECC2)); -	ecc3 = readl(FSMC_NAND_REG(regs, bank, ECC3)); -	ecc4 = readl(FSMC_NAND_REG(regs, bank, STS)); +	ecc1 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1)); +	ecc2 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2)); +	ecc3 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3)); +	ecc4 = readl_relaxed(FSMC_NAND_REG(regs, bank, STS));  	err_idx[0] = (ecc1 >> 0) & 0x1FFF;  	err_idx[1] = (ecc1 >> 13) & 0x1FFF; @@ -860,7 +864,7 @@ static bool filter(struct dma_chan *chan, void *slave)  }  #ifdef CONFIG_OF -static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev, +static int fsmc_nand_probe_config_dt(struct platform_device *pdev,  					       struct device_node *np)  {  	struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); @@ -876,15 +880,13 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,  			return -EINVAL;  		}  	} -	of_property_read_u32(np, "st,ale-off", &pdata->ale_off); -	of_property_read_u32(np, "st,cle-off", &pdata->cle_off);  	if (of_get_property(np, "nand-skip-bbtscan", NULL))  		pdata->options = NAND_SKIP_BBTSCAN;  	return 0;  }  #else -static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev, +static int fsmc_nand_probe_config_dt(struct platform_device *pdev,  					       struct device_node *np)  {  	return -ENOSYS; @@ -935,41 +937,28 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)  	if (!res)  		return -EINVAL; -	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), -				pdev->name)) { -		dev_err(&pdev->dev, "Failed to get memory data resourse\n"); -		return -ENOENT; -	} - -	host->data_pa = (dma_addr_t)res->start; -	host->data_va = devm_ioremap(&pdev->dev, res->start, -			resource_size(res)); +	host->data_va = devm_request_and_ioremap(&pdev->dev, res);  	if (!host->data_va) {  		dev_err(&pdev->dev, "data ioremap failed\n");  		return -ENOMEM;  	} +	host->data_pa = (dma_addr_t)res->start; -	if (!devm_request_mem_region(&pdev->dev, res->start + pdata->ale_off, -			resource_size(res), pdev->name)) { -		dev_err(&pdev->dev, "Failed to get memory ale resourse\n"); -		return -ENOENT; -	} +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_addr"); +	if (!res) +		return -EINVAL; -	host->addr_va = devm_ioremap(&pdev->dev, res->start + pdata->ale_off, -			resource_size(res)); +	host->addr_va = devm_request_and_ioremap(&pdev->dev, res);  	if (!host->addr_va) {  		dev_err(&pdev->dev, "ale ioremap failed\n");  		return -ENOMEM;  	} -	if (!devm_request_mem_region(&pdev->dev, res->start + pdata->cle_off, -			resource_size(res), pdev->name)) { -		dev_err(&pdev->dev, "Failed to get memory cle resourse\n"); -		return -ENOENT; -	} +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd"); +	if (!res) +		return -EINVAL; -	host->cmd_va = devm_ioremap(&pdev->dev, res->start + pdata->cle_off, -			resource_size(res)); +	host->cmd_va = devm_request_and_ioremap(&pdev->dev, res);  	if (!host->cmd_va) {  		dev_err(&pdev->dev, "ale ioremap failed\n");  		return -ENOMEM; @@ -979,14 +968,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)  	if (!res)  		return -EINVAL; -	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), -			pdev->name)) { -		dev_err(&pdev->dev, "Failed to get memory regs resourse\n"); -		return -ENOENT; -	} - -	host->regs_va = devm_ioremap(&pdev->dev, res->start, -			resource_size(res)); +	host->regs_va = devm_request_and_ioremap(&pdev->dev, res);  	if (!host->regs_va) {  		dev_err(&pdev->dev, "regs ioremap failed\n");  		return -ENOMEM; diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index bc73bc5f271..e789e3f5171 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c @@ -90,14 +90,14 @@ static void gpio_nand_writebuf(struct mtd_info *mtd, const u_char *buf, int len)  {  	struct nand_chip *this = mtd->priv; -	writesb(this->IO_ADDR_W, buf, len); +	iowrite8_rep(this->IO_ADDR_W, buf, len);  }  static void gpio_nand_readbuf(struct mtd_info *mtd, u_char *buf, int len)  {  	struct nand_chip *this = mtd->priv; -	readsb(this->IO_ADDR_R, buf, len); +	ioread8_rep(this->IO_ADDR_R, buf, len);  }  static void gpio_nand_writebuf16(struct mtd_info *mtd, const u_char *buf, @@ -106,7 +106,7 @@ static void gpio_nand_writebuf16(struct mtd_info *mtd, const u_char *buf,  	struct nand_chip *this = mtd->priv;  	if (IS_ALIGNED((unsigned long)buf, 2)) { -		writesw(this->IO_ADDR_W, buf, len>>1); +		iowrite16_rep(this->IO_ADDR_W, buf, len>>1);  	} else {  		int i;  		unsigned short *ptr = (unsigned short *)buf; @@ -121,7 +121,7 @@ static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len)  	struct nand_chip *this = mtd->priv;  	if (IS_ALIGNED((unsigned long)buf, 2)) { -		readsw(this->IO_ADDR_R, buf, len>>1); +		ioread16_rep(this->IO_ADDR_R, buf, len>>1);  	} else {  		int i;  		unsigned short *ptr = (unsigned short *)buf; @@ -134,7 +134,11 @@ static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len)  static int gpio_nand_devready(struct mtd_info *mtd)  {  	struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd); -	return gpio_get_value(gpiomtd->plat.gpio_rdy); + +	if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) +		return gpio_get_value(gpiomtd->plat.gpio_rdy); + +	return 1;  }  #ifdef CONFIG_OF @@ -227,7 +231,7 @@ gpio_nand_get_io_sync(struct platform_device *pdev)  	return platform_get_resource(pdev, IORESOURCE_MEM, 1);  } -static int __devexit gpio_nand_remove(struct platform_device *dev) +static int gpio_nand_remove(struct platform_device *dev)  {  	struct gpiomtd *gpiomtd = platform_get_drvdata(dev);  	struct resource *res; @@ -252,7 +256,8 @@ static int __devexit gpio_nand_remove(struct platform_device *dev)  	gpio_free(gpiomtd->plat.gpio_nce);  	if (gpio_is_valid(gpiomtd->plat.gpio_nwp))  		gpio_free(gpiomtd->plat.gpio_nwp); -	gpio_free(gpiomtd->plat.gpio_rdy); +	if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) +		gpio_free(gpiomtd->plat.gpio_rdy);  	kfree(gpiomtd); @@ -277,7 +282,7 @@ static void __iomem *request_and_remap(struct resource *res, size_t size,  	return ptr;  } -static int __devinit gpio_nand_probe(struct platform_device *dev) +static int gpio_nand_probe(struct platform_device *dev)  {  	struct gpiomtd *gpiomtd;  	struct nand_chip *this; @@ -336,10 +341,12 @@ static int __devinit gpio_nand_probe(struct platform_device *dev)  	if (ret)  		goto err_cle;  	gpio_direction_output(gpiomtd->plat.gpio_cle, 0); -	ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY"); -	if (ret) -		goto err_rdy; -	gpio_direction_input(gpiomtd->plat.gpio_rdy); +	if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) { +		ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY"); +		if (ret) +			goto err_rdy; +		gpio_direction_input(gpiomtd->plat.gpio_rdy); +	}  	this->IO_ADDR_W  = this->IO_ADDR_R; @@ -386,7 +393,8 @@ static int __devinit gpio_nand_probe(struct platform_device *dev)  err_wp:  	if (gpio_is_valid(gpiomtd->plat.gpio_nwp))  		gpio_set_value(gpiomtd->plat.gpio_nwp, 0); -	gpio_free(gpiomtd->plat.gpio_rdy); +	if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) +		gpio_free(gpiomtd->plat.gpio_rdy);  err_rdy:  	gpio_free(gpiomtd->plat.gpio_cle);  err_cle: diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index 3502accd4bc..d84699c7968 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c @@ -18,7 +18,6 @@   * with this program; if not, write to the Free Software Foundation, Inc.,   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.   */ -#include <linux/mtd/gpmi-nand.h>  #include <linux/delay.h>  #include <linux/clk.h> @@ -166,6 +165,15 @@ int gpmi_init(struct gpmi_nand_data *this)  	if (ret)  		goto err_out; +	/* +	 * Reset BCH here, too. We got failures otherwise :( +	 * See later BCH reset for explanation of MX23 handling +	 */ +	ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this)); +	if (ret) +		goto err_out; + +  	/* Choose NAND mode. */  	writel(BM_GPMI_CTRL1_GPMI_MODE, r->gpmi_regs + HW_GPMI_CTRL1_CLR); diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index d79696b2f19..5cd141f7bfc 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -25,7 +25,6 @@  #include <linux/slab.h>  #include <linux/interrupt.h>  #include <linux/module.h> -#include <linux/mtd/gpmi-nand.h>  #include <linux/mtd/partitions.h>  #include <linux/pinctrl/consumer.h>  #include <linux/of.h> @@ -33,6 +32,12 @@  #include <linux/of_mtd.h>  #include "gpmi-nand.h" +/* Resource names for the GPMI NAND driver. */ +#define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME  "gpmi-nand" +#define GPMI_NAND_BCH_REGS_ADDR_RES_NAME   "bch" +#define GPMI_NAND_BCH_INTERRUPT_RES_NAME   "bch" +#define GPMI_NAND_DMA_INTERRUPT_RES_NAME   "gpmi-dma" +  /* add our owner bbt descriptor */  static uint8_t scan_ff_pattern[] = { 0xff };  static struct nand_bbt_descr gpmi_bbt_descr = { @@ -222,7 +227,7 @@ void prepare_data_dma(struct gpmi_nand_data *this, enum dma_data_direction dr)  		ret = dma_map_sg(this->dev, sgl, 1, dr);  		if (ret == 0) -			pr_err("map failed.\n"); +			pr_err("DMA mapping failed.\n");  		this->direct_dma_map_ok = false;  	} @@ -314,7 +319,7 @@ int start_dma_with_bch_irq(struct gpmi_nand_data *this,  	return 0;  } -static int __devinit +static int  acquire_register_block(struct gpmi_nand_data *this, const char *res_name)  {  	struct platform_device *pdev = this->pdev; @@ -355,7 +360,7 @@ static void release_register_block(struct gpmi_nand_data *this)  	res->bch_regs = NULL;  } -static int __devinit +static int  acquire_bch_irq(struct gpmi_nand_data *this, irq_handler_t irq_h)  {  	struct platform_device *pdev = this->pdev; @@ -422,7 +427,7 @@ static void release_dma_channels(struct gpmi_nand_data *this)  		}  } -static int __devinit acquire_dma_channels(struct gpmi_nand_data *this) +static int acquire_dma_channels(struct gpmi_nand_data *this)  {  	struct platform_device *pdev = this->pdev;  	struct resource *r_dma; @@ -456,7 +461,7 @@ static int __devinit acquire_dma_channels(struct gpmi_nand_data *this)  	dma_chan = dma_request_channel(mask, gpmi_dma_filter, this);  	if (!dma_chan) { -		pr_err("dma_request_channel failed.\n"); +		pr_err("Failed to request DMA channel.\n");  		goto acquire_err;  	} @@ -487,7 +492,7 @@ static char *extra_clks_for_mx6q[GPMI_CLK_MAX] = {  	"gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch",  }; -static int __devinit gpmi_get_clks(struct gpmi_nand_data *this) +static int gpmi_get_clks(struct gpmi_nand_data *this)  {  	struct resources *r = &this->resources;  	char **extra_clks = NULL; @@ -533,7 +538,7 @@ err_clock:  	return -ENOMEM;  } -static int __devinit acquire_resources(struct gpmi_nand_data *this) +static int acquire_resources(struct gpmi_nand_data *this)  {  	struct pinctrl *pinctrl;  	int ret; @@ -583,7 +588,7 @@ static void release_resources(struct gpmi_nand_data *this)  	release_dma_channels(this);  } -static int __devinit init_hardware(struct gpmi_nand_data *this) +static int init_hardware(struct gpmi_nand_data *this)  {  	int ret; @@ -625,7 +630,8 @@ static int read_page_prepare(struct gpmi_nand_data *this,  						length, DMA_FROM_DEVICE);  		if (dma_mapping_error(dev, dest_phys)) {  			if (alt_size < length) { -				pr_err("Alternate buffer is too small\n"); +				pr_err("%s, Alternate buffer is too small\n", +					__func__);  				return -ENOMEM;  			}  			goto map_failed; @@ -675,7 +681,8 @@ static int send_page_prepare(struct gpmi_nand_data *this,  						DMA_TO_DEVICE);  		if (dma_mapping_error(dev, source_phys)) {  			if (alt_size < length) { -				pr_err("Alternate buffer is too small\n"); +				pr_err("%s, Alternate buffer is too small\n", +					__func__);  				return -ENOMEM;  			}  			goto map_failed; @@ -763,7 +770,7 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this)  error_alloc:  	gpmi_free_dma_buffer(this); -	pr_err("allocate DMA buffer ret!!\n"); +	pr_err("Error allocating DMA buffers!\n");  	return -ENOMEM;  } @@ -1474,7 +1481,7 @@ static int gpmi_set_geometry(struct gpmi_nand_data *this)  	/* Set up the NFC geometry which is used by BCH. */  	ret = bch_set_geometry(this);  	if (ret) { -		pr_err("set geometry ret : %d\n", ret); +		pr_err("Error setting BCH geometry : %d\n", ret);  		return ret;  	} @@ -1535,7 +1542,7 @@ static void gpmi_nfc_exit(struct gpmi_nand_data *this)  	gpmi_free_dma_buffer(this);  } -static int __devinit gpmi_nfc_init(struct gpmi_nand_data *this) +static int gpmi_nfc_init(struct gpmi_nand_data *this)  {  	struct mtd_info  *mtd = &this->mtd;  	struct nand_chip *chip = &this->nand; @@ -1618,7 +1625,7 @@ static const struct of_device_id gpmi_nand_id_table[] = {  };  MODULE_DEVICE_TABLE(of, gpmi_nand_id_table); -static int __devinit gpmi_nand_probe(struct platform_device *pdev) +static int gpmi_nand_probe(struct platform_device *pdev)  {  	struct gpmi_nand_data *this;  	const struct of_device_id *of_id; @@ -1668,7 +1675,7 @@ exit_acquire_resources:  	return ret;  } -static int __devexit gpmi_nand_remove(struct platform_device *pdev) +static int gpmi_nand_remove(struct platform_device *pdev)  {  	struct gpmi_nand_data *this = platform_get_drvdata(pdev); @@ -1685,7 +1692,7 @@ static struct platform_driver gpmi_nand_driver = {  		.of_match_table = gpmi_nand_id_table,  	},  	.probe   = gpmi_nand_probe, -	.remove  = __devexit_p(gpmi_nand_remove), +	.remove  = gpmi_nand_remove,  	.id_table = gpmi_ids,  };  module_platform_driver(gpmi_nand_driver); diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h index 7ac25c1e58f..3d93a5e3909 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h @@ -130,7 +130,6 @@ struct gpmi_nand_data {  	/* System Interface */  	struct device		*dev;  	struct platform_device	*pdev; -	struct gpmi_nand_platform_data	*pdata;  	/* Resources */  	struct resources	resources; diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index 100b6775e17..8d415f014e1 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -316,13 +316,17 @@ err:  	return ret;  } -static inline void jz_nand_iounmap_resource(struct resource *res, void __iomem *base) +static inline void jz_nand_iounmap_resource(struct resource *res, +					    void __iomem *base)  {  	iounmap(base);  	release_mem_region(res->start, resource_size(res));  } -static int __devinit jz_nand_detect_bank(struct platform_device *pdev, struct jz_nand *nand, unsigned char bank, size_t chipnr, uint8_t *nand_maf_id, uint8_t *nand_dev_id) { +static int jz_nand_detect_bank(struct platform_device *pdev, +			       struct jz_nand *nand, unsigned char bank, +			       size_t chipnr, uint8_t *nand_maf_id, +			       uint8_t *nand_dev_id) {  	int ret;  	int gpio;  	char gpio_name[9]; @@ -400,7 +404,7 @@ notfound_gpio:  	return ret;  } -static int __devinit jz_nand_probe(struct platform_device *pdev) +static int jz_nand_probe(struct platform_device *pdev)  {  	int ret;  	struct jz_nand *nand; @@ -541,7 +545,7 @@ err_free:  	return ret;  } -static int __devexit jz_nand_remove(struct platform_device *pdev) +static int jz_nand_remove(struct platform_device *pdev)  {  	struct jz_nand *nand = platform_get_drvdata(pdev);  	struct jz_nand_platform_data *pdata = pdev->dev.platform_data; @@ -573,7 +577,7 @@ static int __devexit jz_nand_remove(struct platform_device *pdev)  static struct platform_driver jz_nand_driver = {  	.probe = jz_nand_probe, -	.remove = __devexit_p(jz_nand_remove), +	.remove = jz_nand_remove,  	.driver = {  		.name = "jz4740-nand",  		.owner = THIS_MODULE, diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index c29b7ac1f6a..f182befa736 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c @@ -655,7 +655,7 @@ static struct lpc32xx_nand_cfg_mlc *lpc32xx_parse_dt(struct device *dev)  /*   * Probe for NAND controller   */ -static int __devinit lpc32xx_nand_probe(struct platform_device *pdev) +static int lpc32xx_nand_probe(struct platform_device *pdev)  {  	struct lpc32xx_nand_host *host;  	struct mtd_info *mtd; @@ -845,7 +845,7 @@ err_exit1:  /*   * Remove NAND device   */ -static int __devexit lpc32xx_nand_remove(struct platform_device *pdev) +static int lpc32xx_nand_remove(struct platform_device *pdev)  {  	struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);  	struct mtd_info *mtd = &host->mtd; @@ -907,7 +907,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_nand_match);  static struct platform_driver lpc32xx_nand_driver = {  	.probe		= lpc32xx_nand_probe, -	.remove		= __devexit_p(lpc32xx_nand_remove), +	.remove		= lpc32xx_nand_remove,  	.resume		= lpc32xx_nand_resume,  	.suspend	= lpc32xx_nand_suspend,  	.driver		= { diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c index 32409c45d47..030b78c6289 100644 --- a/drivers/mtd/nand/lpc32xx_slc.c +++ b/drivers/mtd/nand/lpc32xx_slc.c @@ -755,7 +755,7 @@ static struct lpc32xx_nand_cfg_slc *lpc32xx_parse_dt(struct device *dev)  /*   * Probe for NAND controller   */ -static int __devinit lpc32xx_nand_probe(struct platform_device *pdev) +static int lpc32xx_nand_probe(struct platform_device *pdev)  {  	struct lpc32xx_nand_host *host;  	struct mtd_info *mtd; @@ -949,7 +949,7 @@ err_exit1:  /*   * Remove NAND device.   */ -static int __devexit lpc32xx_nand_remove(struct platform_device *pdev) +static int lpc32xx_nand_remove(struct platform_device *pdev)  {  	uint32_t tmp;  	struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); @@ -1021,7 +1021,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_nand_match);  static struct platform_driver lpc32xx_nand_driver = {  	.probe		= lpc32xx_nand_probe, -	.remove		= __devexit_p(lpc32xx_nand_remove), +	.remove		= lpc32xx_nand_remove,  	.resume		= lpc32xx_nand_resume,  	.suspend	= lpc32xx_nand_suspend,  	.driver		= { diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index f776c8577b8..3c9cdcbc4cb 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c @@ -626,7 +626,7 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd)  		iounmap(prv->csreg);  } -static int __devinit mpc5121_nfc_probe(struct platform_device *op) +static int mpc5121_nfc_probe(struct platform_device *op)  {  	struct device_node *rootnode, *dn = op->dev.of_node;  	struct device *dev = &op->dev; @@ -827,7 +827,7 @@ error:  	return retval;  } -static int __devexit mpc5121_nfc_remove(struct platform_device *op) +static int mpc5121_nfc_remove(struct platform_device *op)  {  	struct device *dev = &op->dev;  	struct mtd_info *mtd = dev_get_drvdata(dev); @@ -841,14 +841,14 @@ static int __devexit mpc5121_nfc_remove(struct platform_device *op)  	return 0;  } -static struct of_device_id mpc5121_nfc_match[] __devinitdata = { +static struct of_device_id mpc5121_nfc_match[] = {  	{ .compatible = "fsl,mpc5121-nfc", },  	{},  };  static struct platform_driver mpc5121_nfc_driver = {  	.probe		= mpc5121_nfc_probe, -	.remove		= __devexit_p(mpc5121_nfc_remove), +	.remove		= mpc5121_nfc_remove,  	.driver		= {  		.name = DRV_NAME,  		.owner = THIS_MODULE, diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 022dcdc256f..45204e41a02 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -266,7 +266,8 @@ static struct nand_ecclayout nandv2_hw_eccoob_4k = {  	}  }; -static const char *part_probes[] = { "RedBoot", "cmdlinepart", "ofpart", NULL }; +static const char const *part_probes[] = { +	"cmdlinepart", "RedBoot", "ofpart", NULL };  static void memcpy32_fromio(void *trg, const void __iomem  *src, size_t size)  { @@ -1378,7 +1379,7 @@ static int __init mxcnd_probe_dt(struct mxc_nand_host *host)  }  #endif -static int __devinit mxcnd_probe(struct platform_device *pdev) +static int mxcnd_probe(struct platform_device *pdev)  {  	struct nand_chip *this;  	struct mtd_info *mtd; @@ -1556,12 +1557,13 @@ static int __devinit mxcnd_probe(struct platform_device *pdev)  	return 0;  escan: -	clk_disable_unprepare(host->clk); +	if (host->clk_act) +		clk_disable_unprepare(host->clk);  	return err;  } -static int __devexit mxcnd_remove(struct platform_device *pdev) +static int mxcnd_remove(struct platform_device *pdev)  {  	struct mxc_nand_host *host = platform_get_drvdata(pdev); @@ -1580,7 +1582,7 @@ static struct platform_driver mxcnd_driver = {  	},  	.id_table = mxcnd_devtype,  	.probe = mxcnd_probe, -	.remove = __devexit_p(mxcnd_remove), +	.remove = mxcnd_remove,  };  module_platform_driver(mxcnd_driver); diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 1a03b7f673c..8323ac991ad 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -93,8 +93,7 @@ static struct nand_ecclayout nand_oob_128 = {  		 .length = 78} }  }; -static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, -			   int new_state); +static int nand_get_device(struct mtd_info *mtd, int new_state);  static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,  			     struct mtd_oob_ops *ops); @@ -130,15 +129,12 @@ static int check_offs_len(struct mtd_info *mtd,   * nand_release_device - [GENERIC] release chip   * @mtd: MTD device structure   * - * Deselect, release chip lock and wake up anyone waiting on the device. + * Release chip lock and wake up anyone waiting on the device.   */  static void nand_release_device(struct mtd_info *mtd)  {  	struct nand_chip *chip = mtd->priv; -	/* De-select the NAND device */ -	chip->select_chip(mtd, -1); -  	/* Release the controller and the chip */  	spin_lock(&chip->controller->lock);  	chip->controller->active = NULL; @@ -160,7 +156,7 @@ static uint8_t nand_read_byte(struct mtd_info *mtd)  }  /** - * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip + * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip   * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip   * @mtd: MTD device structure   * @@ -303,7 +299,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)  	if (getchip) {  		chipnr = (int)(ofs >> chip->chip_shift); -		nand_get_device(chip, mtd, FL_READING); +		nand_get_device(mtd, FL_READING);  		/* Select the NAND device */  		chip->select_chip(mtd, chipnr); @@ -333,8 +329,10 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)  		i++;  	} while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE)); -	if (getchip) +	if (getchip) { +		chip->select_chip(mtd, -1);  		nand_release_device(mtd); +	}  	return res;  } @@ -383,7 +381,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)  		struct mtd_oob_ops ops;  		loff_t wr_ofs = ofs; -		nand_get_device(chip, mtd, FL_WRITING); +		nand_get_device(mtd, FL_WRITING);  		ops.datbuf = NULL;  		ops.oobbuf = buf; @@ -492,7 +490,7 @@ static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo)  void nand_wait_ready(struct mtd_info *mtd)  {  	struct nand_chip *chip = mtd->priv; -	unsigned long timeo = jiffies + 2; +	unsigned long timeo = jiffies + msecs_to_jiffies(20);  	/* 400ms timeout */  	if (in_interrupt() || oops_in_progress) @@ -750,15 +748,15 @@ static void panic_nand_get_device(struct nand_chip *chip,  /**   * nand_get_device - [GENERIC] Get chip for selected access - * @chip: the nand chip descriptor   * @mtd: MTD device structure   * @new_state: the state which is requested   *   * Get the device and lock it for exclusive access   */  static int -nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) +nand_get_device(struct mtd_info *mtd, int new_state)  { +	struct nand_chip *chip = mtd->priv;  	spinlock_t *lock = &chip->controller->lock;  	wait_queue_head_t *wq = &chip->controller->wq;  	DECLARE_WAITQUEUE(wait, current); @@ -865,6 +863,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)  	led_trigger_event(nand_led_trigger, LED_OFF);  	status = (int)chip->read_byte(mtd); +	/* This can happen if in case of timeout or buggy dev_ready */ +	WARN_ON(!(status & NAND_STATUS_READY));  	return status;  } @@ -899,7 +899,7 @@ static int __nand_unlock(struct mtd_info *mtd, loff_t ofs,  	/* Call wait ready function */  	status = chip->waitfunc(mtd, chip);  	/* See if device thinks it succeeded */ -	if (status & 0x01) { +	if (status & NAND_STATUS_FAIL) {  		pr_debug("%s: error status = 0x%08x\n",  					__func__, status);  		ret = -EIO; @@ -932,7 +932,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)  	if (ofs + len == mtd->size)  		len -= mtd->erasesize; -	nand_get_device(chip, mtd, FL_UNLOCKING); +	nand_get_device(mtd, FL_UNLOCKING);  	/* Shift to get chip number */  	chipnr = ofs >> chip->chip_shift; @@ -950,6 +950,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)  	ret = __nand_unlock(mtd, ofs, len, 0);  out: +	chip->select_chip(mtd, -1);  	nand_release_device(mtd);  	return ret; @@ -981,7 +982,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)  	if (check_offs_len(mtd, ofs, len))  		ret = -EINVAL; -	nand_get_device(chip, mtd, FL_LOCKING); +	nand_get_device(mtd, FL_LOCKING);  	/* Shift to get chip number */  	chipnr = ofs >> chip->chip_shift; @@ -1004,7 +1005,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)  	/* Call wait ready function */  	status = chip->waitfunc(mtd, chip);  	/* See if device thinks it succeeded */ -	if (status & 0x01) { +	if (status & NAND_STATUS_FAIL) {  		pr_debug("%s: error status = 0x%08x\n",  					__func__, status);  		ret = -EIO; @@ -1014,6 +1015,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)  	ret = __nand_unlock(mtd, ofs, len, 0x1);  out: +	chip->select_chip(mtd, -1);  	nand_release_device(mtd);  	return ret; @@ -1550,6 +1552,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,  			chip->select_chip(mtd, chipnr);  		}  	} +	chip->select_chip(mtd, -1);  	ops->retlen = ops->len - (size_t) readlen;  	if (oob) @@ -1577,11 +1580,10 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,  static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,  		     size_t *retlen, uint8_t *buf)  { -	struct nand_chip *chip = mtd->priv;  	struct mtd_oob_ops ops;  	int ret; -	nand_get_device(chip, mtd, FL_READING); +	nand_get_device(mtd, FL_READING);  	ops.len = len;  	ops.datbuf = buf;  	ops.oobbuf = NULL; @@ -1804,6 +1806,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,  			chip->select_chip(mtd, chipnr);  		}  	} +	chip->select_chip(mtd, -1);  	ops->oobretlen = ops->ooblen - readlen; @@ -1827,7 +1830,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,  static int nand_read_oob(struct mtd_info *mtd, loff_t from,  			 struct mtd_oob_ops *ops)  { -	struct nand_chip *chip = mtd->priv;  	int ret = -ENOTSUPP;  	ops->retlen = 0; @@ -1839,7 +1841,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,  		return -EINVAL;  	} -	nand_get_device(chip, mtd, FL_READING); +	nand_get_device(mtd, FL_READING);  	switch (ops->mode) {  	case MTD_OPS_PLACE_OOB: @@ -2186,8 +2188,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,  	chip->select_chip(mtd, chipnr);  	/* Check, if it is write protected */ -	if (nand_check_wp(mtd)) -		return -EIO; +	if (nand_check_wp(mtd)) { +		ret = -EIO; +		goto err_out; +	}  	realpage = (int)(to >> chip->page_shift);  	page = realpage & chip->pagemask; @@ -2199,8 +2203,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,  		chip->pagebuf = -1;  	/* Don't allow multipage oob writes with offset */ -	if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) -		return -EINVAL; +	if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) { +		ret = -EINVAL; +		goto err_out; +	}  	while (1) {  		int bytes = mtd->writesize; @@ -2251,6 +2257,9 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,  	ops->retlen = ops->len - writelen;  	if (unlikely(oob))  		ops->oobretlen = ops->ooblen; + +err_out: +	chip->select_chip(mtd, -1);  	return ret;  } @@ -2302,11 +2311,10 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,  static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,  			  size_t *retlen, const uint8_t *buf)  { -	struct nand_chip *chip = mtd->priv;  	struct mtd_oob_ops ops;  	int ret; -	nand_get_device(chip, mtd, FL_WRITING); +	nand_get_device(mtd, FL_WRITING);  	ops.len = len;  	ops.datbuf = (uint8_t *)buf;  	ops.oobbuf = NULL; @@ -2377,8 +2385,10 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,  	chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);  	/* Check, if it is write protected */ -	if (nand_check_wp(mtd)) +	if (nand_check_wp(mtd)) { +		chip->select_chip(mtd, -1);  		return -EROFS; +	}  	/* Invalidate the page cache, if we write to the cached page */  	if (page == chip->pagebuf) @@ -2391,6 +2401,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,  	else  		status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); +	chip->select_chip(mtd, -1); +  	if (status)  		return status; @@ -2408,7 +2420,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,  static int nand_write_oob(struct mtd_info *mtd, loff_t to,  			  struct mtd_oob_ops *ops)  { -	struct nand_chip *chip = mtd->priv;  	int ret = -ENOTSUPP;  	ops->retlen = 0; @@ -2420,7 +2431,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,  		return -EINVAL;  	} -	nand_get_device(chip, mtd, FL_WRITING); +	nand_get_device(mtd, FL_WRITING);  	switch (ops->mode) {  	case MTD_OPS_PLACE_OOB: @@ -2513,7 +2524,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,  		return -EINVAL;  	/* Grab the lock and see if the device is available */ -	nand_get_device(chip, mtd, FL_ERASING); +	nand_get_device(mtd, FL_ERASING);  	/* Shift to get first page */  	page = (int)(instr->addr >> chip->page_shift); @@ -2623,6 +2634,7 @@ erase_exit:  	ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;  	/* Deselect and wake up anyone waiting on the device */ +	chip->select_chip(mtd, -1);  	nand_release_device(mtd);  	/* Do call back function */ @@ -2658,12 +2670,10 @@ erase_exit:   */  static void nand_sync(struct mtd_info *mtd)  { -	struct nand_chip *chip = mtd->priv; -  	pr_debug("%s: called\n", __func__);  	/* Grab the lock and see if the device is available */ -	nand_get_device(chip, mtd, FL_SYNCING); +	nand_get_device(mtd, FL_SYNCING);  	/* Release it and go back */  	nand_release_device(mtd);  } @@ -2749,9 +2759,7 @@ static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,   */  static int nand_suspend(struct mtd_info *mtd)  { -	struct nand_chip *chip = mtd->priv; - -	return nand_get_device(chip, mtd, FL_PM_SUSPENDED); +	return nand_get_device(mtd, FL_PM_SUSPENDED);  }  /** @@ -2849,6 +2857,8 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,  	int i;  	int val; +	/* ONFI need to be probed in 8 bits mode */ +	WARN_ON(chip->options & NAND_BUSWIDTH_16);  	/* Try ONFI for unknown chip or LP */  	chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);  	if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' || @@ -2913,7 +2923,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,   *   * Check if an ID string is repeated within a given sequence of bytes at   * specific repetition interval period (e.g., {0x20,0x01,0x7F,0x20} has a - * period of 2). This is a helper function for nand_id_len(). Returns non-zero + * period of 3). This is a helper function for nand_id_len(). Returns non-zero   * if the repetition has a period of @period; otherwise, returns zero.   */  static int nand_id_has_period(u8 *id_data, int arrlen, int period) @@ -3242,11 +3252,15 @@ ident_done:  			break;  	} -	/* -	 * Check, if buswidth is correct. Hardware drivers should set -	 * chip correct! -	 */ -	if (busw != (chip->options & NAND_BUSWIDTH_16)) { +	if (chip->options & NAND_BUSWIDTH_AUTO) { +		WARN_ON(chip->options & NAND_BUSWIDTH_16); +		chip->options |= busw; +		nand_set_defaults(chip, busw); +	} else if (busw != (chip->options & NAND_BUSWIDTH_16)) { +		/* +		 * Check, if buswidth is correct. Hardware drivers should set +		 * chip correct! +		 */  		pr_info("NAND device: Manufacturer ID:"  			" 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,  			*dev_id, nand_manuf_ids[maf_idx].name, mtd->name); @@ -3285,10 +3299,10 @@ ident_done:  		chip->cmdfunc = nand_command_lp;  	pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s)," -		" page size: %d, OOB size: %d\n", +		" %dMiB, page size: %d, OOB size: %d\n",  		*maf_id, *dev_id, nand_manuf_ids[maf_idx].name,  		chip->onfi_version ? chip->onfi_params.model : type->name, -		mtd->writesize, mtd->oobsize); +		(int)(chip->chipsize >> 20), mtd->writesize, mtd->oobsize);  	return type;  } @@ -3327,6 +3341,8 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,  		return PTR_ERR(type);  	} +	chip->select_chip(mtd, -1); +  	/* Check for a chip array */  	for (i = 1; i < maxchips; i++) {  		chip->select_chip(mtd, i); @@ -3336,8 +3352,11 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,  		chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);  		/* Read manufacturer and device IDs */  		if (nand_maf_id != chip->read_byte(mtd) || -		    nand_dev_id != chip->read_byte(mtd)) +		    nand_dev_id != chip->read_byte(mtd)) { +			chip->select_chip(mtd, -1);  			break; +		} +		chip->select_chip(mtd, -1);  	}  	if (i > 1)  		pr_info("%d NAND chips detected\n", i); @@ -3596,9 +3615,6 @@ int nand_scan_tail(struct mtd_info *mtd)  	/* Initialize state */  	chip->state = FL_READY; -	/* De-select the device */ -	chip->select_chip(mtd, -1); -  	/* Invalidate the pagebuffer reference */  	chip->pagebuf = -1; diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index c3c13e64a2f..818b65c85d1 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -42,6 +42,8 @@  #include <linux/sched.h>  #include <linux/fs.h>  #include <linux/pagemap.h> +#include <linux/seq_file.h> +#include <linux/debugfs.h>  /* Default simulator parameters values */  #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE)  || \ @@ -105,7 +107,6 @@ static char *weakblocks = NULL;  static char *weakpages = NULL;  static unsigned int bitflips = 0;  static char *gravepages = NULL; -static unsigned int rptwear = 0;  static unsigned int overridesize = 0;  static char *cache_file = NULL;  static unsigned int bbt; @@ -130,7 +131,6 @@ module_param(weakblocks,     charp, 0400);  module_param(weakpages,      charp, 0400);  module_param(bitflips,       uint, 0400);  module_param(gravepages,     charp, 0400); -module_param(rptwear,        uint, 0400);  module_param(overridesize,   uint, 0400);  module_param(cache_file,     charp, 0400);  module_param(bbt,	     uint, 0400); @@ -162,7 +162,6 @@ MODULE_PARM_DESC(bitflips,       "Maximum number of random bit flips per page (z  MODULE_PARM_DESC(gravepages,     "Pages that lose data [: maximum reads (defaults to 3)]"  				 " separated by commas e.g. 1401:2 means page 1401"  				 " can be read only twice before failing"); -MODULE_PARM_DESC(rptwear,        "Number of erases between reporting wear, if not zero");  MODULE_PARM_DESC(overridesize,   "Specifies the NAND Flash size overriding the ID bytes. "  				 "The size is specified in erase blocks and as the exponent of a power of two"  				 " e.g. 5 means a size of 32 erase blocks"); @@ -286,6 +285,11 @@ MODULE_PARM_DESC(bch,		 "Enable BCH ecc and set how many bits should "  /* Maximum page cache pages needed to read or write a NAND page to the cache_file */  #define NS_MAX_HELD_PAGES 16 +struct nandsim_debug_info { +	struct dentry *dfs_root; +	struct dentry *dfs_wear_report; +}; +  /*   * A union to represent flash memory contents and flash buffer.   */ @@ -365,6 +369,8 @@ struct nandsim {  	void *file_buf;  	struct page *held_pages[NS_MAX_HELD_PAGES];  	int held_cnt; + +	struct nandsim_debug_info dbg;  };  /* @@ -442,11 +448,123 @@ static LIST_HEAD(grave_pages);  static unsigned long *erase_block_wear = NULL;  static unsigned int wear_eb_count = 0;  static unsigned long total_wear = 0; -static unsigned int rptwear_cnt = 0;  /* MTD structure for NAND controller */  static struct mtd_info *nsmtd; +static int nandsim_debugfs_show(struct seq_file *m, void *private) +{ +	unsigned long wmin = -1, wmax = 0, avg; +	unsigned long deciles[10], decile_max[10], tot = 0; +	unsigned int i; + +	/* Calc wear stats */ +	for (i = 0; i < wear_eb_count; ++i) { +		unsigned long wear = erase_block_wear[i]; +		if (wear < wmin) +			wmin = wear; +		if (wear > wmax) +			wmax = wear; +		tot += wear; +	} + +	for (i = 0; i < 9; ++i) { +		deciles[i] = 0; +		decile_max[i] = (wmax * (i + 1) + 5) / 10; +	} +	deciles[9] = 0; +	decile_max[9] = wmax; +	for (i = 0; i < wear_eb_count; ++i) { +		int d; +		unsigned long wear = erase_block_wear[i]; +		for (d = 0; d < 10; ++d) +			if (wear <= decile_max[d]) { +				deciles[d] += 1; +				break; +			} +	} +	avg = tot / wear_eb_count; + +	/* Output wear report */ +	seq_printf(m, "Total numbers of erases:  %lu\n", tot); +	seq_printf(m, "Number of erase blocks:   %u\n", wear_eb_count); +	seq_printf(m, "Average number of erases: %lu\n", avg); +	seq_printf(m, "Maximum number of erases: %lu\n", wmax); +	seq_printf(m, "Minimum number of erases: %lu\n", wmin); +	for (i = 0; i < 10; ++i) { +		unsigned long from = (i ? decile_max[i - 1] + 1 : 0); +		if (from > decile_max[i]) +			continue; +		seq_printf(m, "Number of ebs with erase counts from %lu to %lu : %lu\n", +			from, +			decile_max[i], +			deciles[i]); +	} + +	return 0; +} + +static int nandsim_debugfs_open(struct inode *inode, struct file *file) +{ +	return single_open(file, nandsim_debugfs_show, inode->i_private); +} + +static const struct file_operations dfs_fops = { +	.open		= nandsim_debugfs_open, +	.read		= seq_read, +	.llseek		= seq_lseek, +	.release	= single_release, +}; + +/** + * nandsim_debugfs_create - initialize debugfs + * @dev: nandsim device description object + * + * This function creates all debugfs files for UBI device @ubi. Returns zero in + * case of success and a negative error code in case of failure. + */ +static int nandsim_debugfs_create(struct nandsim *dev) +{ +	struct nandsim_debug_info *dbg = &dev->dbg; +	struct dentry *dent; +	int err; + +	if (!IS_ENABLED(CONFIG_DEBUG_FS)) +		return 0; + +	dent = debugfs_create_dir("nandsim", NULL); +	if (IS_ERR_OR_NULL(dent)) { +		int err = dent ? -ENODEV : PTR_ERR(dent); + +		NS_ERR("cannot create \"nandsim\" debugfs directory, err %d\n", +			err); +		return err; +	} +	dbg->dfs_root = dent; + +	dent = debugfs_create_file("wear_report", S_IRUSR, +				   dbg->dfs_root, dev, &dfs_fops); +	if (IS_ERR_OR_NULL(dent)) +		goto out_remove; +	dbg->dfs_wear_report = dent; + +	return 0; + +out_remove: +	debugfs_remove_recursive(dbg->dfs_root); +	err = dent ? PTR_ERR(dent) : -ENODEV; +	return err; +} + +/** + * nandsim_debugfs_remove - destroy all debugfs files + */ +static void nandsim_debugfs_remove(struct nandsim *ns) +{ +	if (IS_ENABLED(CONFIG_DEBUG_FS)) +		debugfs_remove_recursive(ns->dbg.dfs_root); +} +  /*   * Allocate array of page pointers, create slab allocation for an array   * and initialize the array by NULL pointers. @@ -911,8 +1029,6 @@ static int setup_wear_reporting(struct mtd_info *mtd)  {  	size_t mem; -	if (!rptwear) -		return 0;  	wear_eb_count = div_u64(mtd->size, mtd->erasesize);  	mem = wear_eb_count * sizeof(unsigned long);  	if (mem / sizeof(unsigned long) != wear_eb_count) { @@ -929,64 +1045,18 @@ static int setup_wear_reporting(struct mtd_info *mtd)  static void update_wear(unsigned int erase_block_no)  { -	unsigned long wmin = -1, wmax = 0, avg; -	unsigned long deciles[10], decile_max[10], tot = 0; -	unsigned int i; -  	if (!erase_block_wear)  		return;  	total_wear += 1; +	/* +	 * TODO: Notify this through a debugfs entry, +	 * instead of showing an error message. +	 */  	if (total_wear == 0)  		NS_ERR("Erase counter total overflow\n");  	erase_block_wear[erase_block_no] += 1;  	if (erase_block_wear[erase_block_no] == 0)  		NS_ERR("Erase counter overflow for erase block %u\n", erase_block_no); -	rptwear_cnt += 1; -	if (rptwear_cnt < rptwear) -		return; -	rptwear_cnt = 0; -	/* Calc wear stats */ -	for (i = 0; i < wear_eb_count; ++i) { -		unsigned long wear = erase_block_wear[i]; -		if (wear < wmin) -			wmin = wear; -		if (wear > wmax) -			wmax = wear; -		tot += wear; -	} -	for (i = 0; i < 9; ++i) { -		deciles[i] = 0; -		decile_max[i] = (wmax * (i + 1) + 5) / 10; -	} -	deciles[9] = 0; -	decile_max[9] = wmax; -	for (i = 0; i < wear_eb_count; ++i) { -		int d; -		unsigned long wear = erase_block_wear[i]; -		for (d = 0; d < 10; ++d) -			if (wear <= decile_max[d]) { -				deciles[d] += 1; -				break; -			} -	} -	avg = tot / wear_eb_count; -	/* Output wear report */ -	NS_INFO("*** Wear Report ***\n"); -	NS_INFO("Total numbers of erases:  %lu\n", tot); -	NS_INFO("Number of erase blocks:   %u\n", wear_eb_count); -	NS_INFO("Average number of erases: %lu\n", avg); -	NS_INFO("Maximum number of erases: %lu\n", wmax); -	NS_INFO("Minimum number of erases: %lu\n", wmin); -	for (i = 0; i < 10; ++i) { -		unsigned long from = (i ? decile_max[i - 1] + 1 : 0); -		if (from > decile_max[i]) -			continue; -		NS_INFO("Number of ebs with erase counts from %lu to %lu : %lu\n", -			from, -			decile_max[i], -			deciles[i]); -	} -	NS_INFO("*** End of Wear Report ***\n");  }  /* @@ -2327,6 +2397,9 @@ static int __init ns_init_module(void)  	if ((retval = setup_wear_reporting(nsmtd)) != 0)  		goto err_exit; +	if ((retval = nandsim_debugfs_create(nand)) != 0) +		goto err_exit; +  	if ((retval = init_nandsim(nsmtd)) != 0)  		goto err_exit; @@ -2366,6 +2439,7 @@ static void __exit ns_cleanup_module(void)  	struct nandsim *ns = ((struct nand_chip *)nsmtd->priv)->priv;  	int i; +	nandsim_debugfs_remove(ns);  	free_nandsim(ns);    /* Free nandsim private resources */  	nand_release(nsmtd); /* Unregister driver */  	for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i) diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 5fd3f010e3a..8e148f1478f 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -197,7 +197,7 @@ err:  	return ret;  } -static int __devinit ndfc_probe(struct platform_device *ofdev) +static int ndfc_probe(struct platform_device *ofdev)  {  	struct ndfc_controller *ndfc;  	const __be32 *reg; @@ -256,7 +256,7 @@ static int __devinit ndfc_probe(struct platform_device *ofdev)  	return 0;  } -static int __devexit ndfc_remove(struct platform_device *ofdev) +static int ndfc_remove(struct platform_device *ofdev)  {  	struct ndfc_controller *ndfc = dev_get_drvdata(&ofdev->dev); @@ -279,7 +279,7 @@ static struct platform_driver ndfc_driver = {  		.of_match_table = ndfc_match,  	},  	.probe = ndfc_probe, -	.remove = __devexit_p(ndfc_remove), +	.remove = ndfc_remove,  };  module_platform_driver(ndfc_driver); diff --git a/drivers/mtd/nand/nomadik_nand.c b/drivers/mtd/nand/nomadik_nand.c deleted file mode 100644 index 9ee0c4edfac..00000000000 --- a/drivers/mtd/nand/nomadik_nand.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - *  drivers/mtd/nand/nomadik_nand.c - * - *  Overview: - *  	Driver for on-board NAND flash on Nomadik Platforms - * - * Copyright © 2007 STMicroelectronics Pvt. Ltd. - * Author: Sachin Verma <sachin.verma@st.com> - * - * Copyright © 2009 Alessandro Rubini - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/nand.h> -#include <linux/mtd/nand_ecc.h> -#include <linux/platform_device.h> -#include <linux/mtd/partitions.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <linux/platform_data/mtd-nomadik-nand.h> -#include <mach/fsmc.h> - -#include <mtd/mtd-abi.h> - -struct nomadik_nand_host { -	struct mtd_info		mtd; -	struct nand_chip	nand; -	void __iomem *data_va; -	void __iomem *cmd_va; -	void __iomem *addr_va; -	struct nand_bbt_descr *bbt_desc; -}; - -static struct nand_ecclayout nomadik_ecc_layout = { -	.eccbytes = 3 * 4, -	.eccpos = { /* each subpage has 16 bytes: pos 2,3,4 hosts ECC */ -		0x02, 0x03, 0x04, -		0x12, 0x13, 0x14, -		0x22, 0x23, 0x24, -		0x32, 0x33, 0x34}, -	/* let's keep bytes 5,6,7 for us, just in case we change ECC algo */ -	.oobfree = { {0x08, 0x08}, {0x18, 0x08}, {0x28, 0x08}, {0x38, 0x08} }, -}; - -static void nomadik_ecc_control(struct mtd_info *mtd, int mode) -{ -	/* No need to enable hw ecc, it's on by default */ -} - -static void nomadik_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) -{ -	struct nand_chip *nand = mtd->priv; -	struct nomadik_nand_host *host = nand->priv; - -	if (cmd == NAND_CMD_NONE) -		return; - -	if (ctrl & NAND_CLE) -		writeb(cmd, host->cmd_va); -	else -		writeb(cmd, host->addr_va); -} - -static int nomadik_nand_probe(struct platform_device *pdev) -{ -	struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data; -	struct nomadik_nand_host *host; -	struct mtd_info *mtd; -	struct nand_chip *nand; -	struct resource *res; -	int ret = 0; - -	/* Allocate memory for the device structure (and zero it) */ -	host = kzalloc(sizeof(struct nomadik_nand_host), GFP_KERNEL); -	if (!host) { -		dev_err(&pdev->dev, "Failed to allocate device structure.\n"); -		return -ENOMEM; -	} - -	/* Call the client's init function, if any */ -	if (pdata->init) -		ret = pdata->init(); -	if (ret < 0) { -		dev_err(&pdev->dev, "Init function failed\n"); -		goto err; -	} - -	/* ioremap three regions */ -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_addr"); -	if (!res) { -		ret = -EIO; -		goto err_unmap; -	} -	host->addr_va = ioremap(res->start, resource_size(res)); - -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data"); -	if (!res) { -		ret = -EIO; -		goto err_unmap; -	} -	host->data_va = ioremap(res->start, resource_size(res)); - -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd"); -	if (!res) { -		ret = -EIO; -		goto err_unmap; -	} -	host->cmd_va = ioremap(res->start, resource_size(res)); - -	if (!host->addr_va || !host->data_va || !host->cmd_va) { -		ret = -ENOMEM; -		goto err_unmap; -	} - -	/* Link all private pointers */ -	mtd = &host->mtd; -	nand = &host->nand; -	mtd->priv = nand; -	nand->priv = host; - -	host->mtd.owner = THIS_MODULE; -	nand->IO_ADDR_R = host->data_va; -	nand->IO_ADDR_W = host->data_va; -	nand->cmd_ctrl = nomadik_cmd_ctrl; - -	/* -	 * This stanza declares ECC_HW but uses soft routines. It's because -	 * HW claims to make the calculation but not the correction. However, -	 * I haven't managed to get the desired data out of it until now. -	 */ -	nand->ecc.mode = NAND_ECC_SOFT; -	nand->ecc.layout = &nomadik_ecc_layout; -	nand->ecc.hwctl = nomadik_ecc_control; -	nand->ecc.size = 512; -	nand->ecc.bytes = 3; - -	nand->options = pdata->options; - -	/* -	 * Scan to find existence of the device -	 */ -	if (nand_scan(&host->mtd, 1)) { -		ret = -ENXIO; -		goto err_unmap; -	} - -	mtd_device_register(&host->mtd, pdata->parts, pdata->nparts); - -	platform_set_drvdata(pdev, host); -	return 0; - - err_unmap: -	if (host->cmd_va) -		iounmap(host->cmd_va); -	if (host->data_va) -		iounmap(host->data_va); -	if (host->addr_va) -		iounmap(host->addr_va); - err: -	kfree(host); -	return ret; -} - -/* - * Clean up routine - */ -static int nomadik_nand_remove(struct platform_device *pdev) -{ -	struct nomadik_nand_host *host = platform_get_drvdata(pdev); -	struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data; - -	if (pdata->exit) -		pdata->exit(); - -	if (host) { -		nand_release(&host->mtd); -		iounmap(host->cmd_va); -		iounmap(host->data_va); -		iounmap(host->addr_va); -		kfree(host); -	} -	return 0; -} - -static int nomadik_nand_suspend(struct device *dev) -{ -	struct nomadik_nand_host *host = dev_get_drvdata(dev); -	int ret = 0; -	if (host) -		ret = mtd_suspend(&host->mtd); -	return ret; -} - -static int nomadik_nand_resume(struct device *dev) -{ -	struct nomadik_nand_host *host = dev_get_drvdata(dev); -	if (host) -		mtd_resume(&host->mtd); -	return 0; -} - -static const struct dev_pm_ops nomadik_nand_pm_ops = { -	.suspend = nomadik_nand_suspend, -	.resume = nomadik_nand_resume, -}; - -static struct platform_driver nomadik_nand_driver = { -	.probe = nomadik_nand_probe, -	.remove = nomadik_nand_remove, -	.driver = { -		.owner = THIS_MODULE, -		.name = "nomadik_nand", -		.pm = &nomadik_nand_pm_ops, -	}, -}; - -module_platform_driver(nomadik_nand_driver); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)"); -MODULE_DESCRIPTION("NAND driver for Nomadik Platform"); diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index 94dc46bc118..a6191198d25 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c @@ -246,7 +246,7 @@ static void nuc900_nand_enable(struct nuc900_nand *nand)  	spin_unlock(&nand->lock);  } -static int __devinit nuc900_nand_probe(struct platform_device *pdev) +static int nuc900_nand_probe(struct platform_device *pdev)  {  	struct nuc900_nand *nuc900_nand;  	struct nand_chip *chip; @@ -317,7 +317,7 @@ fail1:	kfree(nuc900_nand);  	return retval;  } -static int __devexit nuc900_nand_remove(struct platform_device *pdev) +static int nuc900_nand_remove(struct platform_device *pdev)  {  	struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev);  	struct resource *res; @@ -340,7 +340,7 @@ static int __devexit nuc900_nand_remove(struct platform_device *pdev)  static struct platform_driver nuc900_nand_driver = {  	.probe		= nuc900_nand_probe, -	.remove		= __devexit_p(nuc900_nand_remove), +	.remove		= nuc900_nand_remove,  	.driver		= {  		.name	= "nuc900-fmi",  		.owner	= THIS_MODULE, diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 1f34ba104ef..0002d5e94f0 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -1323,7 +1323,7 @@ static void omap3_free_bch(struct mtd_info *mtd)  }  #endif /* CONFIG_MTD_NAND_OMAP_BCH */ -static int __devinit omap_nand_probe(struct platform_device *pdev) +static int omap_nand_probe(struct platform_device *pdev)  {  	struct omap_nand_info		*info;  	struct omap_nand_platform_data	*pdata; diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index aefaf8cd31e..cd72b9299f6 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -194,7 +194,7 @@ no_res:  	return ret;  } -static int __devexit orion_nand_remove(struct platform_device *pdev) +static int orion_nand_remove(struct platform_device *pdev)  {  	struct mtd_info *mtd = platform_get_drvdata(pdev);  	struct nand_chip *nc = mtd->priv; @@ -223,7 +223,7 @@ static struct of_device_id orion_nand_of_match_table[] = {  #endif  static struct platform_driver orion_nand_driver = { -	.remove		= __devexit_p(orion_nand_remove), +	.remove		= orion_nand_remove,  	.driver		= {  		.name	= "orion_nand",  		.owner	= THIS_MODULE, diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 1440e51cedc..5a67082c07e 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -89,7 +89,7 @@ int pasemi_device_ready(struct mtd_info *mtd)  	return !!(inl(lpcctl) & LBICTRL_LPCCTL_NR);  } -static int __devinit pasemi_nand_probe(struct platform_device *ofdev) +static int pasemi_nand_probe(struct platform_device *ofdev)  {  	struct pci_dev *pdev;  	struct device_node *np = ofdev->dev.of_node; @@ -184,7 +184,7 @@ static int __devinit pasemi_nand_probe(struct platform_device *ofdev)  	return err;  } -static int __devexit pasemi_nand_remove(struct platform_device *ofdev) +static int pasemi_nand_remove(struct platform_device *ofdev)  {  	struct nand_chip *chip; diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index a47ee68a0cf..c004566a9ad 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c @@ -28,7 +28,7 @@ static const char *part_probe_types[] = { "cmdlinepart", NULL };  /*   * Probe for the NAND device.   */ -static int __devinit plat_nand_probe(struct platform_device *pdev) +static int plat_nand_probe(struct platform_device *pdev)  {  	struct platform_nand_data *pdata = pdev->dev.platform_data;  	struct mtd_part_parser_data ppdata; @@ -134,7 +134,7 @@ out_free:  /*   * Remove a NAND device.   */ -static int __devexit plat_nand_remove(struct platform_device *pdev) +static int plat_nand_remove(struct platform_device *pdev)  {  	struct plat_nand_data *data = platform_get_drvdata(pdev);  	struct platform_nand_data *pdata = pdev->dev.platform_data; @@ -160,7 +160,7 @@ MODULE_DEVICE_TABLE(of, plat_nand_match);  static struct platform_driver plat_nand_driver = {  	.probe	= plat_nand_probe, -	.remove	= __devexit_p(plat_nand_remove), +	.remove	= plat_nand_remove,  	.driver	= {  		.name		= "gen_nand",  		.owner		= THIS_MODULE, diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 79ded48e742..df954b4dcba 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -730,11 +730,14 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,  				      struct s3c2410_nand_mtd *mtd,  				      struct s3c2410_nand_set *set)  { -	if (set) +	if (set) {  		mtd->mtd.name = set->name; -	return mtd_device_parse_register(&mtd->mtd, NULL, NULL, +		return mtd_device_parse_register(&mtd->mtd, NULL, NULL,  					 set->partitions, set->nr_partitions); +	} + +	return -ENODEV;  }  /** diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index f48ac5d80bb..57b3971c9c0 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c @@ -23,11 +23,18 @@  #include <linux/module.h>  #include <linux/kernel.h> +#include <linux/completion.h>  #include <linux/delay.h> +#include <linux/dmaengine.h> +#include <linux/dma-mapping.h>  #include <linux/interrupt.h>  #include <linux/io.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_mtd.h>  #include <linux/platform_device.h>  #include <linux/pm_runtime.h> +#include <linux/sh_dma.h>  #include <linux/slab.h>  #include <linux/string.h> @@ -106,6 +113,84 @@ static void wait_completion(struct sh_flctl *flctl)  	writeb(0x0, FLTRCR(flctl));  } +static void flctl_dma_complete(void *param) +{ +	struct sh_flctl *flctl = param; + +	complete(&flctl->dma_complete); +} + +static void flctl_release_dma(struct sh_flctl *flctl) +{ +	if (flctl->chan_fifo0_rx) { +		dma_release_channel(flctl->chan_fifo0_rx); +		flctl->chan_fifo0_rx = NULL; +	} +	if (flctl->chan_fifo0_tx) { +		dma_release_channel(flctl->chan_fifo0_tx); +		flctl->chan_fifo0_tx = NULL; +	} +} + +static void flctl_setup_dma(struct sh_flctl *flctl) +{ +	dma_cap_mask_t mask; +	struct dma_slave_config cfg; +	struct platform_device *pdev = flctl->pdev; +	struct sh_flctl_platform_data *pdata = pdev->dev.platform_data; +	int ret; + +	if (!pdata) +		return; + +	if (pdata->slave_id_fifo0_tx <= 0 || pdata->slave_id_fifo0_rx <= 0) +		return; + +	/* We can only either use DMA for both Tx and Rx or not use it at all */ +	dma_cap_zero(mask); +	dma_cap_set(DMA_SLAVE, mask); + +	flctl->chan_fifo0_tx = dma_request_channel(mask, shdma_chan_filter, +					    (void *)pdata->slave_id_fifo0_tx); +	dev_dbg(&pdev->dev, "%s: TX: got channel %p\n", __func__, +		flctl->chan_fifo0_tx); + +	if (!flctl->chan_fifo0_tx) +		return; + +	memset(&cfg, 0, sizeof(cfg)); +	cfg.slave_id = pdata->slave_id_fifo0_tx; +	cfg.direction = DMA_MEM_TO_DEV; +	cfg.dst_addr = (dma_addr_t)FLDTFIFO(flctl); +	cfg.src_addr = 0; +	ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg); +	if (ret < 0) +		goto err; + +	flctl->chan_fifo0_rx = dma_request_channel(mask, shdma_chan_filter, +					    (void *)pdata->slave_id_fifo0_rx); +	dev_dbg(&pdev->dev, "%s: RX: got channel %p\n", __func__, +		flctl->chan_fifo0_rx); + +	if (!flctl->chan_fifo0_rx) +		goto err; + +	cfg.slave_id = pdata->slave_id_fifo0_rx; +	cfg.direction = DMA_DEV_TO_MEM; +	cfg.dst_addr = 0; +	cfg.src_addr = (dma_addr_t)FLDTFIFO(flctl); +	ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg); +	if (ret < 0) +		goto err; + +	init_completion(&flctl->dma_complete); + +	return; + +err: +	flctl_release_dma(flctl); +} +  static void set_addr(struct mtd_info *mtd, int column, int page_addr)  {  	struct sh_flctl *flctl = mtd_to_flctl(mtd); @@ -225,7 +310,7 @@ static enum flctl_ecc_res_t wait_recfifo_ready  		for (i = 0; i < 3; i++) {  			uint8_t org; -			int index; +			unsigned int index;  			data = readl(ecc_reg[i]); @@ -261,6 +346,70 @@ static void wait_wecfifo_ready(struct sh_flctl *flctl)  	timeout_error(flctl, __func__);  } +static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf, +					int len, enum dma_data_direction dir) +{ +	struct dma_async_tx_descriptor *desc = NULL; +	struct dma_chan *chan; +	enum dma_transfer_direction tr_dir; +	dma_addr_t dma_addr; +	dma_cookie_t cookie = -EINVAL; +	uint32_t reg; +	int ret; + +	if (dir == DMA_FROM_DEVICE) { +		chan = flctl->chan_fifo0_rx; +		tr_dir = DMA_DEV_TO_MEM; +	} else { +		chan = flctl->chan_fifo0_tx; +		tr_dir = DMA_MEM_TO_DEV; +	} + +	dma_addr = dma_map_single(chan->device->dev, buf, len, dir); + +	if (dma_addr) +		desc = dmaengine_prep_slave_single(chan, dma_addr, len, +			tr_dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + +	if (desc) { +		reg = readl(FLINTDMACR(flctl)); +		reg |= DREQ0EN; +		writel(reg, FLINTDMACR(flctl)); + +		desc->callback = flctl_dma_complete; +		desc->callback_param = flctl; +		cookie = dmaengine_submit(desc); + +		dma_async_issue_pending(chan); +	} else { +		/* DMA failed, fall back to PIO */ +		flctl_release_dma(flctl); +		dev_warn(&flctl->pdev->dev, +			 "DMA failed, falling back to PIO\n"); +		ret = -EIO; +		goto out; +	} + +	ret = +	wait_for_completion_timeout(&flctl->dma_complete, +				msecs_to_jiffies(3000)); + +	if (ret <= 0) { +		chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); +		dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n"); +	} + +out: +	reg = readl(FLINTDMACR(flctl)); +	reg &= ~DREQ0EN; +	writel(reg, FLINTDMACR(flctl)); + +	dma_unmap_single(chan->device->dev, dma_addr, len, dir); + +	/* ret > 0 is success */ +	return ret; +} +  static void read_datareg(struct sh_flctl *flctl, int offset)  {  	unsigned long data; @@ -279,11 +428,20 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)  	len_4align = (rlen + 3) / 4; +	/* initiate DMA transfer */ +	if (flctl->chan_fifo0_rx && rlen >= 32 && +		flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_DEV_TO_MEM) > 0) +			goto convert;	/* DMA success */ + +	/* do polling transfer */  	for (i = 0; i < len_4align; i++) {  		wait_rfifo_ready(flctl);  		buf[i] = readl(FLDTFIFO(flctl)); -		buf[i] = be32_to_cpu(buf[i]);  	} + +convert: +	for (i = 0; i < len_4align; i++) +		buf[i] = be32_to_cpu(buf[i]);  }  static enum flctl_ecc_res_t read_ecfiforeg @@ -305,28 +463,39 @@ static enum flctl_ecc_res_t read_ecfiforeg  	return res;  } -static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset) +static void write_fiforeg(struct sh_flctl *flctl, int rlen, +						unsigned int offset)  {  	int i, len_4align; -	unsigned long *data = (unsigned long *)&flctl->done_buff[offset]; -	void *fifo_addr = (void *)FLDTFIFO(flctl); +	unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];  	len_4align = (rlen + 3) / 4;  	for (i = 0; i < len_4align; i++) {  		wait_wfifo_ready(flctl); -		writel(cpu_to_be32(data[i]), fifo_addr); +		writel(cpu_to_be32(buf[i]), FLDTFIFO(flctl));  	}  } -static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, int offset) +static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, +						unsigned int offset)  {  	int i, len_4align; -	unsigned long *data = (unsigned long *)&flctl->done_buff[offset]; +	unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];  	len_4align = (rlen + 3) / 4; + +	for (i = 0; i < len_4align; i++) +		buf[i] = cpu_to_be32(buf[i]); + +	/* initiate DMA transfer */ +	if (flctl->chan_fifo0_tx && rlen >= 32 && +		flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_MEM_TO_DEV) > 0) +			return;	/* DMA success */ + +	/* do polling transfer */  	for (i = 0; i < len_4align; i++) {  		wait_wecfifo_ready(flctl); -		writel(cpu_to_be32(data[i]), FLECFIFO(flctl)); +		writel(buf[i], FLECFIFO(flctl));  	}  } @@ -750,41 +919,35 @@ static void flctl_select_chip(struct mtd_info *mtd, int chipnr)  static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)  {  	struct sh_flctl *flctl = mtd_to_flctl(mtd); -	int index = flctl->index; -	memcpy(&flctl->done_buff[index], buf, len); +	memcpy(&flctl->done_buff[flctl->index], buf, len);  	flctl->index += len;  }  static uint8_t flctl_read_byte(struct mtd_info *mtd)  {  	struct sh_flctl *flctl = mtd_to_flctl(mtd); -	int index = flctl->index;  	uint8_t data; -	data = flctl->done_buff[index]; +	data = flctl->done_buff[flctl->index];  	flctl->index++;  	return data;  }  static uint16_t flctl_read_word(struct mtd_info *mtd)  { -       struct sh_flctl *flctl = mtd_to_flctl(mtd); -       int index = flctl->index; -       uint16_t data; -       uint16_t *buf = (uint16_t *)&flctl->done_buff[index]; +	struct sh_flctl *flctl = mtd_to_flctl(mtd); +	uint16_t *buf = (uint16_t *)&flctl->done_buff[flctl->index]; -       data = *buf; -       flctl->index += 2; -       return data; +	flctl->index += 2; +	return *buf;  }  static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)  {  	struct sh_flctl *flctl = mtd_to_flctl(mtd); -	int index = flctl->index; -	memcpy(buf, &flctl->done_buff[index], len); +	memcpy(buf, &flctl->done_buff[flctl->index], len);  	flctl->index += len;  } @@ -858,7 +1021,74 @@ static irqreturn_t flctl_handle_flste(int irq, void *dev_id)  	return IRQ_HANDLED;  } -static int __devinit flctl_probe(struct platform_device *pdev) +#ifdef CONFIG_OF +struct flctl_soc_config { +	unsigned long flcmncr_val; +	unsigned has_hwecc:1; +	unsigned use_holden:1; +}; + +static struct flctl_soc_config flctl_sh7372_config = { +	.flcmncr_val = CLK_16B_12L_4H | TYPESEL_SET | SHBUSSEL, +	.has_hwecc = 1, +	.use_holden = 1, +}; + +static const struct of_device_id of_flctl_match[] = { +	{ .compatible = "renesas,shmobile-flctl-sh7372", +				.data = &flctl_sh7372_config }, +	{}, +}; +MODULE_DEVICE_TABLE(of, of_flctl_match); + +static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) +{ +	const struct of_device_id *match; +	struct flctl_soc_config *config; +	struct sh_flctl_platform_data *pdata; +	struct device_node *dn = dev->of_node; +	int ret; + +	match = of_match_device(of_flctl_match, dev); +	if (match) +		config = (struct flctl_soc_config *)match->data; +	else { +		dev_err(dev, "%s: no OF configuration attached\n", __func__); +		return NULL; +	} + +	pdata = devm_kzalloc(dev, sizeof(struct sh_flctl_platform_data), +								GFP_KERNEL); +	if (!pdata) { +		dev_err(dev, "%s: failed to allocate config data\n", __func__); +		return NULL; +	} + +	/* set SoC specific options */ +	pdata->flcmncr_val = config->flcmncr_val; +	pdata->has_hwecc = config->has_hwecc; +	pdata->use_holden = config->use_holden; + +	/* parse user defined options */ +	ret = of_get_nand_bus_width(dn); +	if (ret == 16) +		pdata->flcmncr_val |= SEL_16BIT; +	else if (ret != 8) { +		dev_err(dev, "%s: invalid bus width\n", __func__); +		return NULL; +	} + +	return pdata; +} +#else /* CONFIG_OF */ +#define of_flctl_match NULL +static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) +{ +	return NULL; +} +#endif /* CONFIG_OF */ + +static int flctl_probe(struct platform_device *pdev)  {  	struct resource *res;  	struct sh_flctl *flctl; @@ -867,12 +1097,7 @@ static int __devinit flctl_probe(struct platform_device *pdev)  	struct sh_flctl_platform_data *pdata;  	int ret = -ENXIO;  	int irq; - -	pdata = pdev->dev.platform_data; -	if (pdata == NULL) { -		dev_err(&pdev->dev, "no platform data defined\n"); -		return -EINVAL; -	} +	struct mtd_part_parser_data ppdata = {};  	flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);  	if (!flctl) { @@ -904,6 +1129,17 @@ static int __devinit flctl_probe(struct platform_device *pdev)  		goto err_flste;  	} +	if (pdev->dev.of_node) +		pdata = flctl_parse_dt(&pdev->dev); +	else +		pdata = pdev->dev.platform_data; + +	if (!pdata) { +		dev_err(&pdev->dev, "no setup data defined\n"); +		ret = -EINVAL; +		goto err_pdata; +	} +  	platform_set_drvdata(pdev, flctl);  	flctl_mtd = &flctl->mtd;  	nand = &flctl->chip; @@ -932,6 +1168,8 @@ static int __devinit flctl_probe(struct platform_device *pdev)  	pm_runtime_enable(&pdev->dev);  	pm_runtime_resume(&pdev->dev); +	flctl_setup_dma(flctl); +  	ret = nand_scan_ident(flctl_mtd, 1, NULL);  	if (ret)  		goto err_chip; @@ -944,12 +1182,16 @@ static int __devinit flctl_probe(struct platform_device *pdev)  	if (ret)  		goto err_chip; -	mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts); +	ppdata.of_node = pdev->dev.of_node; +	ret = mtd_device_parse_register(flctl_mtd, NULL, &ppdata, pdata->parts, +			pdata->nr_parts);  	return 0;  err_chip: +	flctl_release_dma(flctl);  	pm_runtime_disable(&pdev->dev); +err_pdata:  	free_irq(irq, flctl);  err_flste:  	iounmap(flctl->reg); @@ -958,10 +1200,11 @@ err_iomap:  	return ret;  } -static int __devexit flctl_remove(struct platform_device *pdev) +static int flctl_remove(struct platform_device *pdev)  {  	struct sh_flctl *flctl = platform_get_drvdata(pdev); +	flctl_release_dma(flctl);  	nand_release(&flctl->mtd);  	pm_runtime_disable(&pdev->dev);  	free_irq(platform_get_irq(pdev, 0), flctl); @@ -976,6 +1219,7 @@ static struct platform_driver flctl_driver = {  	.driver = {  		.name	= "sh_flctl",  		.owner	= THIS_MODULE, +		.of_match_table = of_flctl_match,  	},  }; diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 3421e3762a5..127bc427182 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c @@ -106,7 +106,7 @@ static int sharpsl_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat,  /*   * Main initialization routine   */ -static int __devinit sharpsl_nand_probe(struct platform_device *pdev) +static int sharpsl_nand_probe(struct platform_device *pdev)  {  	struct nand_chip *this;  	struct resource *r; @@ -205,7 +205,7 @@ err_get_res:  /*   * Clean up routine   */ -static int __devexit sharpsl_nand_remove(struct platform_device *pdev) +static int sharpsl_nand_remove(struct platform_device *pdev)  {  	struct sharpsl_nand *sharpsl = platform_get_drvdata(pdev); @@ -228,7 +228,7 @@ static struct platform_driver sharpsl_nand_driver = {  		.owner	= THIS_MODULE,  	},  	.probe		= sharpsl_nand_probe, -	.remove		= __devexit_p(sharpsl_nand_remove), +	.remove		= sharpsl_nand_remove,  };  module_platform_driver(sharpsl_nand_driver); diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index f3f28fafbf7..09dde7d2717 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c @@ -140,7 +140,7 @@ static int socrates_nand_device_ready(struct mtd_info *mtd)  /*   * Probe for the NAND device.   */ -static int __devinit socrates_nand_probe(struct platform_device *ofdev) +static int socrates_nand_probe(struct platform_device *ofdev)  {  	struct socrates_nand_host *host;  	struct mtd_info *mtd; @@ -220,7 +220,7 @@ out:  /*   * Remove a NAND device.   */ -static int __devexit socrates_nand_remove(struct platform_device *ofdev) +static int socrates_nand_remove(struct platform_device *ofdev)  {  	struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev);  	struct mtd_info *mtd = &host->mtd; @@ -251,7 +251,7 @@ static struct platform_driver socrates_nand_driver = {  		.of_match_table = socrates_nand_match,  	},  	.probe		= socrates_nand_probe, -	.remove		= __devexit_p(socrates_nand_remove), +	.remove		= socrates_nand_remove,  };  module_platform_driver(socrates_nand_driver); diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index d9127e2ed80..dbd3aa574ea 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c @@ -71,7 +71,10 @@ static int parse_ofpart_partitions(struct mtd_info *master,  		(*pparts)[i].name = (char *)partname;  		if (of_get_property(pp, "read-only", &len)) -			(*pparts)[i].mask_flags = MTD_WRITEABLE; +			(*pparts)[i].mask_flags |= MTD_WRITEABLE; + +		if (of_get_property(pp, "lock", &len)) +			(*pparts)[i].mask_flags |= MTD_POWERUP_LOCK;  		i++;  	} diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c index 1c4f97c63e6..9f11562f849 100644 --- a/drivers/mtd/onenand/generic.c +++ b/drivers/mtd/onenand/generic.c @@ -35,7 +35,7 @@ struct onenand_info {  	struct onenand_chip	onenand;  }; -static int __devinit generic_onenand_probe(struct platform_device *pdev) +static int generic_onenand_probe(struct platform_device *pdev)  {  	struct onenand_info *info;  	struct onenand_platform_data *pdata = pdev->dev.platform_data; @@ -88,7 +88,7 @@ out_free_info:  	return err;  } -static int __devexit generic_onenand_remove(struct platform_device *pdev) +static int generic_onenand_remove(struct platform_device *pdev)  {  	struct onenand_info *info = platform_get_drvdata(pdev);  	struct resource *res = pdev->resource; @@ -112,7 +112,7 @@ static struct platform_driver generic_onenand_driver = {  		.owner		= THIS_MODULE,  	},  	.probe		= generic_onenand_probe, -	.remove		= __devexit_p(generic_onenand_remove), +	.remove		= generic_onenand_remove,  };  module_platform_driver(generic_onenand_driver); diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 00cd3da2943..065f3fe02a2 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -630,7 +630,7 @@ static int omap2_onenand_disable(struct mtd_info *mtd)  	return ret;  } -static int __devinit omap2_onenand_probe(struct platform_device *pdev) +static int omap2_onenand_probe(struct platform_device *pdev)  {  	struct omap_onenand_platform_data *pdata;  	struct omap2_onenand *c; @@ -799,7 +799,7 @@ err_kfree:  	return r;  } -static int __devexit omap2_onenand_remove(struct platform_device *pdev) +static int omap2_onenand_remove(struct platform_device *pdev)  {  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); @@ -822,7 +822,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)  static struct platform_driver omap2_onenand_driver = {  	.probe		= omap2_onenand_probe, -	.remove		= __devexit_p(omap2_onenand_remove), +	.remove		= omap2_onenand_remove,  	.shutdown	= omap2_onenand_shutdown,  	.driver		= {  		.name	= DRIVER_NAME, diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c index 8e4b3f2742b..33f2a8fb8df 100644 --- a/drivers/mtd/onenand/samsung.c +++ b/drivers/mtd/onenand/samsung.c @@ -1053,7 +1053,7 @@ onenand_fail:  	return err;  } -static int __devexit s3c_onenand_remove(struct platform_device *pdev) +static int s3c_onenand_remove(struct platform_device *pdev)  {  	struct mtd_info *mtd = platform_get_drvdata(pdev); @@ -1130,7 +1130,7 @@ static struct platform_driver s3c_onenand_driver = {  	},  	.id_table	= s3c_onenand_driver_ids,  	.probe          = s3c_onenand_probe, -	.remove         = __devexit_p(s3c_onenand_remove), +	.remove         = s3c_onenand_remove,  };  module_platform_driver(s3c_onenand_driver); diff --git a/drivers/mtd/tests/mtd_nandbiterrs.c b/drivers/mtd/tests/mtd_nandbiterrs.c index cc8d62cb280..207bf9a9972 100644 --- a/drivers/mtd/tests/mtd_nandbiterrs.c +++ b/drivers/mtd/tests/mtd_nandbiterrs.c @@ -39,6 +39,9 @@   * this program; see the file COPYING. If not, write to the Free Software   * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   */ + +#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt +  #include <linux/init.h>  #include <linux/module.h>  #include <linux/moduleparam.h> @@ -47,8 +50,6 @@  #include <linux/mtd/nand.h>  #include <linux/slab.h> -#define msg(FMT, VA...) pr_info("mtd_nandbiterrs: "FMT, ##VA) -  static int dev;  module_param(dev, int, S_IRUGO);  MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -103,7 +104,7 @@ static int erase_block(void)  	struct erase_info ei;  	loff_t addr = eraseblock * mtd->erasesize; -	msg("erase_block\n"); +	pr_info("erase_block\n");  	memset(&ei, 0, sizeof(struct erase_info));  	ei.mtd  = mtd; @@ -112,7 +113,7 @@ static int erase_block(void)  	err = mtd_erase(mtd, &ei);  	if (err || ei.state == MTD_ERASE_FAILED) { -		msg("error %d while erasing\n", err); +		pr_err("error %d while erasing\n", err);  		if (!err)  			err = -EIO;  		return err; @@ -128,11 +129,11 @@ static int write_page(int log)  	size_t written;  	if (log) -		msg("write_page\n"); +		pr_info("write_page\n");  	err = mtd_write(mtd, offset, mtd->writesize, &written, wbuffer);  	if (err || written != mtd->writesize) { -		msg("error: write failed at %#llx\n", (long long)offset); +		pr_err("error: write failed at %#llx\n", (long long)offset);  		if (!err)  			err = -EIO;  	} @@ -147,7 +148,7 @@ static int rewrite_page(int log)  	struct mtd_oob_ops ops;  	if (log) -		msg("rewrite page\n"); +		pr_info("rewrite page\n");  	ops.mode      = MTD_OPS_RAW; /* No ECC */  	ops.len       = mtd->writesize; @@ -160,7 +161,7 @@ static int rewrite_page(int log)  	err = mtd_write_oob(mtd, offset, &ops);  	if (err || ops.retlen != mtd->writesize) { -		msg("error: write_oob failed (%d)\n", err); +		pr_err("error: write_oob failed (%d)\n", err);  		if (!err)  			err = -EIO;  	} @@ -177,7 +178,7 @@ static int read_page(int log)  	struct mtd_ecc_stats oldstats;  	if (log) -		msg("read_page\n"); +		pr_info("read_page\n");  	/* Saving last mtd stats */  	memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats)); @@ -187,7 +188,7 @@ static int read_page(int log)  		err = mtd->ecc_stats.corrected - oldstats.corrected;  	if (err < 0 || read != mtd->writesize) { -		msg("error: read failed at %#llx\n", (long long)offset); +		pr_err("error: read failed at %#llx\n", (long long)offset);  		if (err >= 0)  			err = -EIO;  	} @@ -201,11 +202,11 @@ static int verify_page(int log)  	unsigned i, errs = 0;  	if (log) -		msg("verify_page\n"); +		pr_info("verify_page\n");  	for (i = 0; i < mtd->writesize; i++) {  		if (rbuffer[i] != hash(i+seed)) { -			msg("Error: page offset %u, expected %02x, got %02x\n", +			pr_err("Error: page offset %u, expected %02x, got %02x\n",  				i, hash(i+seed), rbuffer[i]);  			errs++;  		} @@ -230,13 +231,13 @@ static int insert_biterror(unsigned byte)  		for (bit = 7; bit >= 0; bit--) {  			if (CBIT(wbuffer[byte], bit)) {  				BCLR(wbuffer[byte], bit); -				msg("Inserted biterror @ %u/%u\n", byte, bit); +				pr_info("Inserted biterror @ %u/%u\n", byte, bit);  				return 0;  			}  		}  		byte++;  	} -	msg("biterror: Failed to find a '1' bit\n"); +	pr_err("biterror: Failed to find a '1' bit\n");  	return -EIO;  } @@ -248,7 +249,7 @@ static int incremental_errors_test(void)  	unsigned i;  	unsigned errs_per_subpage = 0; -	msg("incremental biterrors test\n"); +	pr_info("incremental biterrors test\n");  	for (i = 0; i < mtd->writesize; i++)  		wbuffer[i] = hash(i+seed); @@ -265,9 +266,9 @@ static int incremental_errors_test(void)  		err = read_page(1);  		if (err > 0) -			msg("Read reported %d corrected bit errors\n", err); +			pr_info("Read reported %d corrected bit errors\n", err);  		if (err < 0) { -			msg("After %d biterrors per subpage, read reported error %d\n", +			pr_err("After %d biterrors per subpage, read reported error %d\n",  				errs_per_subpage, err);  			err = 0;  			goto exit; @@ -275,11 +276,11 @@ static int incremental_errors_test(void)  		err = verify_page(1);  		if (err) { -			msg("ECC failure, read data is incorrect despite read success\n"); +			pr_err("ECC failure, read data is incorrect despite read success\n");  			goto exit;  		} -		msg("Successfully corrected %d bit errors per subpage\n", +		pr_info("Successfully corrected %d bit errors per subpage\n",  			errs_per_subpage);  		for (i = 0; i < subcount; i++) { @@ -311,7 +312,7 @@ static int overwrite_test(void)  	memset(bitstats, 0, sizeof(bitstats)); -	msg("overwrite biterrors test\n"); +	pr_info("overwrite biterrors test\n");  	for (i = 0; i < mtd->writesize; i++)  		wbuffer[i] = hash(i+seed); @@ -329,18 +330,18 @@ static int overwrite_test(void)  		err = read_page(0);  		if (err >= 0) {  			if (err >= MAXBITS) { -				msg("Implausible number of bit errors corrected\n"); +				pr_info("Implausible number of bit errors corrected\n");  				err = -EIO;  				break;  			}  			bitstats[err]++;  			if (err > max_corrected) {  				max_corrected = err; -				msg("Read reported %d corrected bit errors\n", +				pr_info("Read reported %d corrected bit errors\n",  					err);  			}  		} else { /* err < 0 */ -			msg("Read reported error %d\n", err); +			pr_info("Read reported error %d\n", err);  			err = 0;  			break;  		} @@ -348,7 +349,7 @@ static int overwrite_test(void)  		err = verify_page(0);  		if (err) {  			bitstats[max_corrected] = opno; -			msg("ECC failure, read data is incorrect despite read success\n"); +			pr_info("ECC failure, read data is incorrect despite read success\n");  			break;  		} @@ -357,9 +358,9 @@ static int overwrite_test(void)  	/* At this point bitstats[0] contains the number of ops with no bit  	 * errors, bitstats[1] the number of ops with 1 bit error, etc. */ -	msg("Bit error histogram (%d operations total):\n", opno); +	pr_info("Bit error histogram (%d operations total):\n", opno);  	for (i = 0; i < max_corrected; i++) -		msg("Page reads with %3d corrected bit errors: %d\n", +		pr_info("Page reads with %3d corrected bit errors: %d\n",  			i, bitstats[i]);  exit: @@ -370,36 +371,36 @@ static int __init mtd_nandbiterrs_init(void)  {  	int err = 0; -	msg("\n"); -	msg("==================================================\n"); -	msg("MTD device: %d\n", dev); +	printk("\n"); +	printk(KERN_INFO "==================================================\n"); +	pr_info("MTD device: %d\n", dev);  	mtd = get_mtd_device(NULL, dev);  	if (IS_ERR(mtd)) {  		err = PTR_ERR(mtd); -		msg("error: cannot get MTD device\n"); +		pr_err("error: cannot get MTD device\n");  		goto exit_mtddev;  	}  	if (mtd->type != MTD_NANDFLASH) { -		msg("this test requires NAND flash\n"); +		pr_info("this test requires NAND flash\n");  		err = -ENODEV;  		goto exit_nand;  	} -	msg("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n", +	pr_info("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n",  		(unsigned long long)mtd->size, mtd->erasesize,  		mtd->writesize, mtd->oobsize);  	subsize  = mtd->writesize >> mtd->subpage_sft;  	subcount = mtd->writesize / subsize; -	msg("Device uses %d subpages of %d bytes\n", subcount, subsize); +	pr_info("Device uses %d subpages of %d bytes\n", subcount, subsize);  	offset     = page_offset * mtd->writesize;  	eraseblock = mtd_div_by_eb(offset, mtd); -	msg("Using page=%u, offset=%llu, eraseblock=%u\n", +	pr_info("Using page=%u, offset=%llu, eraseblock=%u\n",  		page_offset, offset, eraseblock);  	wbuffer = kmalloc(mtd->writesize, GFP_KERNEL); @@ -432,8 +433,8 @@ static int __init mtd_nandbiterrs_init(void)  		goto exit_error;  	err = -EIO; -	msg("finished successfully.\n"); -	msg("==================================================\n"); +	pr_info("finished successfully.\n"); +	printk(KERN_INFO "==================================================\n");  exit_error:  	kfree(rbuffer); diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c index b437fa42507..1eee264509a 100644 --- a/drivers/mtd/tests/mtd_nandecctest.c +++ b/drivers/mtd/tests/mtd_nandecctest.c @@ -1,3 +1,5 @@ +#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt +  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/list.h> @@ -264,13 +266,13 @@ static int nand_ecc_test_run(const size_t size)  						correct_data, size);  		if (err) { -			pr_err("mtd_nandecctest: not ok - %s-%zd\n", +			pr_err("not ok - %s-%zd\n",  				nand_ecc_test[i].name, size);  			dump_data_ecc(error_data, error_ecc,  				correct_data, correct_ecc, size);  			break;  		} -		pr_info("mtd_nandecctest: ok - %s-%zd\n", +		pr_info("ok - %s-%zd\n",  			nand_ecc_test[i].name, size);  	}  error: diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c index ed9b62827f1..e827fa8cd84 100644 --- a/drivers/mtd/tests/mtd_oobtest.c +++ b/drivers/mtd/tests/mtd_oobtest.c @@ -19,6 +19,8 @@   * Author: Adrian Hunter <ext-adrian.hunter@nokia.com>   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <asm/div64.h>  #include <linux/init.h>  #include <linux/module.h> @@ -28,8 +30,6 @@  #include <linux/slab.h>  #include <linux/sched.h> -#define PRINT_PREF KERN_INFO "mtd_oobtest: " -  static int dev = -EINVAL;  module_param(dev, int, S_IRUGO);  MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -80,13 +80,12 @@ static int erase_eraseblock(int ebnum)  	err = mtd_erase(mtd, &ei);  	if (err) { -		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); +		pr_err("error %d while erasing EB %d\n", err, ebnum);  		return err;  	}  	if (ei.state == MTD_ERASE_FAILED) { -		printk(PRINT_PREF "some erase error occurred at EB %d\n", -		       ebnum); +		pr_err("some erase error occurred at EB %d\n", ebnum);  		return -EIO;  	} @@ -98,7 +97,7 @@ static int erase_whole_device(void)  	int err;  	unsigned int i; -	printk(PRINT_PREF "erasing whole device\n"); +	pr_info("erasing whole device\n");  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i])  			continue; @@ -107,7 +106,7 @@ static int erase_whole_device(void)  			return err;  		cond_resched();  	} -	printk(PRINT_PREF "erased %u eraseblocks\n", i); +	pr_info("erased %u eraseblocks\n", i);  	return 0;  } @@ -141,9 +140,9 @@ static int write_eraseblock(int ebnum)  		ops.oobbuf    = writebuf;  		err = mtd_write_oob(mtd, addr, &ops);  		if (err || ops.oobretlen != use_len) { -			printk(PRINT_PREF "error: writeoob failed at %#llx\n", +			pr_err("error: writeoob failed at %#llx\n",  			       (long long)addr); -			printk(PRINT_PREF "error: use_len %d, use_offset %d\n", +			pr_err("error: use_len %d, use_offset %d\n",  			       use_len, use_offset);  			errcnt += 1;  			return err ? err : -1; @@ -160,7 +159,7 @@ static int write_whole_device(void)  	int err;  	unsigned int i; -	printk(PRINT_PREF "writing OOBs of whole device\n"); +	pr_info("writing OOBs of whole device\n");  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i])  			continue; @@ -168,10 +167,10 @@ static int write_whole_device(void)  		if (err)  			return err;  		if (i % 256 == 0) -			printk(PRINT_PREF "written up to eraseblock %u\n", i); +			pr_info("written up to eraseblock %u\n", i);  		cond_resched();  	} -	printk(PRINT_PREF "written %u eraseblocks\n", i); +	pr_info("written %u eraseblocks\n", i);  	return 0;  } @@ -194,17 +193,17 @@ static int verify_eraseblock(int ebnum)  		ops.oobbuf    = readbuf;  		err = mtd_read_oob(mtd, addr, &ops);  		if (err || ops.oobretlen != use_len) { -			printk(PRINT_PREF "error: readoob failed at %#llx\n", +			pr_err("error: readoob failed at %#llx\n",  			       (long long)addr);  			errcnt += 1;  			return err ? err : -1;  		}  		if (memcmp(readbuf, writebuf, use_len)) { -			printk(PRINT_PREF "error: verify failed at %#llx\n", +			pr_err("error: verify failed at %#llx\n",  			       (long long)addr);  			errcnt += 1;  			if (errcnt > 1000) { -				printk(PRINT_PREF "error: too many errors\n"); +				pr_err("error: too many errors\n");  				return -1;  			}  		} @@ -221,29 +220,28 @@ static int verify_eraseblock(int ebnum)  			ops.oobbuf    = readbuf;  			err = mtd_read_oob(mtd, addr, &ops);  			if (err || ops.oobretlen != mtd->ecclayout->oobavail) { -				printk(PRINT_PREF "error: readoob failed at " -				       "%#llx\n", (long long)addr); +				pr_err("error: readoob failed at %#llx\n", +						(long long)addr);  				errcnt += 1;  				return err ? err : -1;  			}  			if (memcmp(readbuf + use_offset, writebuf, use_len)) { -				printk(PRINT_PREF "error: verify failed at " -				       "%#llx\n", (long long)addr); +				pr_err("error: verify failed at %#llx\n", +						(long long)addr);  				errcnt += 1;  				if (errcnt > 1000) { -					printk(PRINT_PREF "error: too many " -					       "errors\n"); +					pr_err("error: too many errors\n");  					return -1;  				}  			}  			for (k = 0; k < use_offset; ++k)  				if (readbuf[k] != 0xff) { -					printk(PRINT_PREF "error: verify 0xff " +					pr_err("error: verify 0xff "  					       "failed at %#llx\n",  					       (long long)addr);  					errcnt += 1;  					if (errcnt > 1000) { -						printk(PRINT_PREF "error: too " +						pr_err("error: too "  						       "many errors\n");  						return -1;  					} @@ -251,12 +249,12 @@ static int verify_eraseblock(int ebnum)  			for (k = use_offset + use_len;  			     k < mtd->ecclayout->oobavail; ++k)  				if (readbuf[k] != 0xff) { -					printk(PRINT_PREF "error: verify 0xff " +					pr_err("error: verify 0xff "  					       "failed at %#llx\n",  					       (long long)addr);  					errcnt += 1;  					if (errcnt > 1000) { -						printk(PRINT_PREF "error: too " +						pr_err("error: too "  						       "many errors\n");  						return -1;  					} @@ -286,17 +284,17 @@ static int verify_eraseblock_in_one_go(int ebnum)  	ops.oobbuf    = readbuf;  	err = mtd_read_oob(mtd, addr, &ops);  	if (err || ops.oobretlen != len) { -		printk(PRINT_PREF "error: readoob failed at %#llx\n", +		pr_err("error: readoob failed at %#llx\n",  		       (long long)addr);  		errcnt += 1;  		return err ? err : -1;  	}  	if (memcmp(readbuf, writebuf, len)) { -		printk(PRINT_PREF "error: verify failed at %#llx\n", +		pr_err("error: verify failed at %#llx\n",  		       (long long)addr);  		errcnt += 1;  		if (errcnt > 1000) { -			printk(PRINT_PREF "error: too many errors\n"); +			pr_err("error: too many errors\n");  			return -1;  		}  	} @@ -309,7 +307,7 @@ static int verify_all_eraseblocks(void)  	int err;  	unsigned int i; -	printk(PRINT_PREF "verifying all eraseblocks\n"); +	pr_info("verifying all eraseblocks\n");  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i])  			continue; @@ -317,10 +315,10 @@ static int verify_all_eraseblocks(void)  		if (err)  			return err;  		if (i % 256 == 0) -			printk(PRINT_PREF "verified up to eraseblock %u\n", i); +			pr_info("verified up to eraseblock %u\n", i);  		cond_resched();  	} -	printk(PRINT_PREF "verified %u eraseblocks\n", i); +	pr_info("verified %u eraseblocks\n", i);  	return 0;  } @@ -331,7 +329,7 @@ static int is_block_bad(int ebnum)  	ret = mtd_block_isbad(mtd, addr);  	if (ret) -		printk(PRINT_PREF "block %d is bad\n", ebnum); +		pr_info("block %d is bad\n", ebnum);  	return ret;  } @@ -341,18 +339,18 @@ static int scan_for_bad_eraseblocks(void)  	bbt = kmalloc(ebcnt, GFP_KERNEL);  	if (!bbt) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		return -ENOMEM;  	} -	printk(PRINT_PREF "scanning for bad eraseblocks\n"); +	pr_info("scanning for bad eraseblocks\n");  	for (i = 0; i < ebcnt; ++i) {  		bbt[i] = is_block_bad(i) ? 1 : 0;  		if (bbt[i])  			bad += 1;  		cond_resched();  	} -	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); +	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);  	return 0;  } @@ -368,22 +366,22 @@ static int __init mtd_oobtest_init(void)  	printk(KERN_INFO "=================================================\n");  	if (dev < 0) { -		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); -		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); +		pr_info("Please specify a valid mtd-device via module parameter\n"); +		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");  		return -EINVAL;  	} -	printk(PRINT_PREF "MTD device: %d\n", dev); +	pr_info("MTD device: %d\n", dev);  	mtd = get_mtd_device(NULL, dev);  	if (IS_ERR(mtd)) {  		err = PTR_ERR(mtd); -		printk(PRINT_PREF "error: cannot get MTD device\n"); +		pr_err("error: cannot get MTD device\n");  		return err;  	}  	if (mtd->type != MTD_NANDFLASH) { -		printk(PRINT_PREF "this test requires NAND flash\n"); +		pr_info("this test requires NAND flash\n");  		goto out;  	} @@ -392,7 +390,7 @@ static int __init mtd_oobtest_init(void)  	ebcnt = tmp;  	pgcnt = mtd->erasesize / mtd->writesize; -	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " +	pr_info("MTD device size %llu, eraseblock size %u, "  	       "page size %u, count of eraseblocks %u, pages per "  	       "eraseblock %u, OOB size %u\n",  	       (unsigned long long)mtd->size, mtd->erasesize, @@ -401,12 +399,12 @@ static int __init mtd_oobtest_init(void)  	err = -ENOMEM;  	readbuf = kmalloc(mtd->erasesize, GFP_KERNEL);  	if (!readbuf) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		goto out;  	}  	writebuf = kmalloc(mtd->erasesize, GFP_KERNEL);  	if (!writebuf) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		goto out;  	} @@ -420,7 +418,7 @@ static int __init mtd_oobtest_init(void)  	vary_offset = 0;  	/* First test: write all OOB, read it back and verify */ -	printk(PRINT_PREF "test 1 of 5\n"); +	pr_info("test 1 of 5\n");  	err = erase_whole_device();  	if (err) @@ -440,7 +438,7 @@ static int __init mtd_oobtest_init(void)  	 * Second test: write all OOB, a block at a time, read it back and  	 * verify.  	 */ -	printk(PRINT_PREF "test 2 of 5\n"); +	pr_info("test 2 of 5\n");  	err = erase_whole_device();  	if (err) @@ -453,7 +451,7 @@ static int __init mtd_oobtest_init(void)  	/* Check all eraseblocks */  	simple_srand(3); -	printk(PRINT_PREF "verifying all eraseblocks\n"); +	pr_info("verifying all eraseblocks\n");  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i])  			continue; @@ -461,16 +459,16 @@ static int __init mtd_oobtest_init(void)  		if (err)  			goto out;  		if (i % 256 == 0) -			printk(PRINT_PREF "verified up to eraseblock %u\n", i); +			pr_info("verified up to eraseblock %u\n", i);  		cond_resched();  	} -	printk(PRINT_PREF "verified %u eraseblocks\n", i); +	pr_info("verified %u eraseblocks\n", i);  	/*  	 * Third test: write OOB at varying offsets and lengths, read it back  	 * and verify.  	 */ -	printk(PRINT_PREF "test 3 of 5\n"); +	pr_info("test 3 of 5\n");  	err = erase_whole_device();  	if (err) @@ -503,7 +501,7 @@ static int __init mtd_oobtest_init(void)  	vary_offset = 0;  	/* Fourth test: try to write off end of device */ -	printk(PRINT_PREF "test 4 of 5\n"); +	pr_info("test 4 of 5\n");  	err = erase_whole_device();  	if (err) @@ -522,14 +520,14 @@ static int __init mtd_oobtest_init(void)  	ops.ooboffs   = mtd->ecclayout->oobavail;  	ops.datbuf    = NULL;  	ops.oobbuf    = writebuf; -	printk(PRINT_PREF "attempting to start write past end of OOB\n"); -	printk(PRINT_PREF "an error is expected...\n"); +	pr_info("attempting to start write past end of OOB\n"); +	pr_info("an error is expected...\n");  	err = mtd_write_oob(mtd, addr0, &ops);  	if (err) { -		printk(PRINT_PREF "error occurred as expected\n"); +		pr_info("error occurred as expected\n");  		err = 0;  	} else { -		printk(PRINT_PREF "error: can write past end of OOB\n"); +		pr_err("error: can write past end of OOB\n");  		errcnt += 1;  	} @@ -542,19 +540,19 @@ static int __init mtd_oobtest_init(void)  	ops.ooboffs   = mtd->ecclayout->oobavail;  	ops.datbuf    = NULL;  	ops.oobbuf    = readbuf; -	printk(PRINT_PREF "attempting to start read past end of OOB\n"); -	printk(PRINT_PREF "an error is expected...\n"); +	pr_info("attempting to start read past end of OOB\n"); +	pr_info("an error is expected...\n");  	err = mtd_read_oob(mtd, addr0, &ops);  	if (err) { -		printk(PRINT_PREF "error occurred as expected\n"); +		pr_info("error occurred as expected\n");  		err = 0;  	} else { -		printk(PRINT_PREF "error: can read past end of OOB\n"); +		pr_err("error: can read past end of OOB\n");  		errcnt += 1;  	}  	if (bbt[ebcnt - 1]) -		printk(PRINT_PREF "skipping end of device tests because last " +		pr_info("skipping end of device tests because last "  		       "block is bad\n");  	else {  		/* Attempt to write off end of device */ @@ -566,14 +564,14 @@ static int __init mtd_oobtest_init(void)  		ops.ooboffs   = 0;  		ops.datbuf    = NULL;  		ops.oobbuf    = writebuf; -		printk(PRINT_PREF "attempting to write past end of device\n"); -		printk(PRINT_PREF "an error is expected...\n"); +		pr_info("attempting to write past end of device\n"); +		pr_info("an error is expected...\n");  		err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops);  		if (err) { -			printk(PRINT_PREF "error occurred as expected\n"); +			pr_info("error occurred as expected\n");  			err = 0;  		} else { -			printk(PRINT_PREF "error: wrote past end of device\n"); +			pr_err("error: wrote past end of device\n");  			errcnt += 1;  		} @@ -586,14 +584,14 @@ static int __init mtd_oobtest_init(void)  		ops.ooboffs   = 0;  		ops.datbuf    = NULL;  		ops.oobbuf    = readbuf; -		printk(PRINT_PREF "attempting to read past end of device\n"); -		printk(PRINT_PREF "an error is expected...\n"); +		pr_info("attempting to read past end of device\n"); +		pr_info("an error is expected...\n");  		err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);  		if (err) { -			printk(PRINT_PREF "error occurred as expected\n"); +			pr_info("error occurred as expected\n");  			err = 0;  		} else { -			printk(PRINT_PREF "error: read past end of device\n"); +			pr_err("error: read past end of device\n");  			errcnt += 1;  		} @@ -610,14 +608,14 @@ static int __init mtd_oobtest_init(void)  		ops.ooboffs   = 1;  		ops.datbuf    = NULL;  		ops.oobbuf    = writebuf; -		printk(PRINT_PREF "attempting to write past end of device\n"); -		printk(PRINT_PREF "an error is expected...\n"); +		pr_info("attempting to write past end of device\n"); +		pr_info("an error is expected...\n");  		err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops);  		if (err) { -			printk(PRINT_PREF "error occurred as expected\n"); +			pr_info("error occurred as expected\n");  			err = 0;  		} else { -			printk(PRINT_PREF "error: wrote past end of device\n"); +			pr_err("error: wrote past end of device\n");  			errcnt += 1;  		} @@ -630,20 +628,20 @@ static int __init mtd_oobtest_init(void)  		ops.ooboffs   = 1;  		ops.datbuf    = NULL;  		ops.oobbuf    = readbuf; -		printk(PRINT_PREF "attempting to read past end of device\n"); -		printk(PRINT_PREF "an error is expected...\n"); +		pr_info("attempting to read past end of device\n"); +		pr_info("an error is expected...\n");  		err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);  		if (err) { -			printk(PRINT_PREF "error occurred as expected\n"); +			pr_info("error occurred as expected\n");  			err = 0;  		} else { -			printk(PRINT_PREF "error: read past end of device\n"); +			pr_err("error: read past end of device\n");  			errcnt += 1;  		}  	}  	/* Fifth test: write / read across block boundaries */ -	printk(PRINT_PREF "test 5 of 5\n"); +	pr_info("test 5 of 5\n");  	/* Erase all eraseblocks */  	err = erase_whole_device(); @@ -652,7 +650,7 @@ static int __init mtd_oobtest_init(void)  	/* Write all eraseblocks */  	simple_srand(11); -	printk(PRINT_PREF "writing OOBs of whole device\n"); +	pr_info("writing OOBs of whole device\n");  	for (i = 0; i < ebcnt - 1; ++i) {  		int cnt = 2;  		int pg; @@ -674,17 +672,16 @@ static int __init mtd_oobtest_init(void)  			if (err)  				goto out;  			if (i % 256 == 0) -				printk(PRINT_PREF "written up to eraseblock " -				       "%u\n", i); +				pr_info("written up to eraseblock %u\n", i);  			cond_resched();  			addr += mtd->writesize;  		}  	} -	printk(PRINT_PREF "written %u eraseblocks\n", i); +	pr_info("written %u eraseblocks\n", i);  	/* Check all eraseblocks */  	simple_srand(11); -	printk(PRINT_PREF "verifying all eraseblocks\n"); +	pr_info("verifying all eraseblocks\n");  	for (i = 0; i < ebcnt - 1; ++i) {  		if (bbt[i] || bbt[i + 1])  			continue; @@ -702,28 +699,28 @@ static int __init mtd_oobtest_init(void)  		if (err)  			goto out;  		if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) { -			printk(PRINT_PREF "error: verify failed at %#llx\n", +			pr_err("error: verify failed at %#llx\n",  			       (long long)addr);  			errcnt += 1;  			if (errcnt > 1000) { -				printk(PRINT_PREF "error: too many errors\n"); +				pr_err("error: too many errors\n");  				goto out;  			}  		}  		if (i % 256 == 0) -			printk(PRINT_PREF "verified up to eraseblock %u\n", i); +			pr_info("verified up to eraseblock %u\n", i);  		cond_resched();  	} -	printk(PRINT_PREF "verified %u eraseblocks\n", i); +	pr_info("verified %u eraseblocks\n", i); -	printk(PRINT_PREF "finished with %d errors\n", errcnt); +	pr_info("finished with %d errors\n", errcnt);  out:  	kfree(bbt);  	kfree(writebuf);  	kfree(readbuf);  	put_mtd_device(mtd);  	if (err) -		printk(PRINT_PREF "error %d occurred\n", err); +		pr_info("error %d occurred\n", err);  	printk(KERN_INFO "=================================================\n");  	return err;  } diff --git a/drivers/mtd/tests/mtd_pagetest.c b/drivers/mtd/tests/mtd_pagetest.c index 252ddb092fb..f93a76f8811 100644 --- a/drivers/mtd/tests/mtd_pagetest.c +++ b/drivers/mtd/tests/mtd_pagetest.c @@ -19,6 +19,8 @@   * Author: Adrian Hunter <ext-adrian.hunter@nokia.com>   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <asm/div64.h>  #include <linux/init.h>  #include <linux/module.h> @@ -28,8 +30,6 @@  #include <linux/slab.h>  #include <linux/sched.h> -#define PRINT_PREF KERN_INFO "mtd_pagetest: " -  static int dev = -EINVAL;  module_param(dev, int, S_IRUGO);  MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -79,12 +79,12 @@ static int erase_eraseblock(int ebnum)  	err = mtd_erase(mtd, &ei);  	if (err) { -		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); +		pr_err("error %d while erasing EB %d\n", err, ebnum);  		return err;  	}  	if (ei.state == MTD_ERASE_FAILED) { -		printk(PRINT_PREF "some erase error occurred at EB %d\n", +		pr_err("some erase error occurred at EB %d\n",  		       ebnum);  		return -EIO;  	} @@ -102,7 +102,7 @@ static int write_eraseblock(int ebnum)  	cond_resched();  	err = mtd_write(mtd, addr, mtd->erasesize, &written, writebuf);  	if (err || written != mtd->erasesize) -		printk(PRINT_PREF "error: write failed at %#llx\n", +		pr_err("error: write failed at %#llx\n",  		       (long long)addr);  	return err; @@ -131,7 +131,7 @@ static int verify_eraseblock(int ebnum)  		if (mtd_is_bitflip(err))  			err = 0;  		if (err || read != bufsize) { -			printk(PRINT_PREF "error: read failed at %#llx\n", +			pr_err("error: read failed at %#llx\n",  			       (long long)addr0);  			return err;  		} @@ -139,7 +139,7 @@ static int verify_eraseblock(int ebnum)  		if (mtd_is_bitflip(err))  			err = 0;  		if (err || read != bufsize) { -			printk(PRINT_PREF "error: read failed at %#llx\n", +			pr_err("error: read failed at %#llx\n",  			       (long long)(addrn - bufsize));  			return err;  		} @@ -148,12 +148,12 @@ static int verify_eraseblock(int ebnum)  		if (mtd_is_bitflip(err))  			err = 0;  		if (err || read != bufsize) { -			printk(PRINT_PREF "error: read failed at %#llx\n", +			pr_err("error: read failed at %#llx\n",  			       (long long)addr);  			break;  		}  		if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) { -			printk(PRINT_PREF "error: verify failed at %#llx\n", +			pr_err("error: verify failed at %#llx\n",  			       (long long)addr);  			errcnt += 1;  		} @@ -166,7 +166,7 @@ static int verify_eraseblock(int ebnum)  		if (mtd_is_bitflip(err))  			err = 0;  		if (err || read != bufsize) { -			printk(PRINT_PREF "error: read failed at %#llx\n", +			pr_err("error: read failed at %#llx\n",  			       (long long)addr0);  			return err;  		} @@ -174,7 +174,7 @@ static int verify_eraseblock(int ebnum)  		if (mtd_is_bitflip(err))  			err = 0;  		if (err || read != bufsize) { -			printk(PRINT_PREF "error: read failed at %#llx\n", +			pr_err("error: read failed at %#llx\n",  			       (long long)(addrn - bufsize));  			return err;  		} @@ -183,14 +183,14 @@ static int verify_eraseblock(int ebnum)  		if (mtd_is_bitflip(err))  			err = 0;  		if (err || read != bufsize) { -			printk(PRINT_PREF "error: read failed at %#llx\n", +			pr_err("error: read failed at %#llx\n",  			       (long long)addr);  			return err;  		}  		memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize);  		set_random_data(boundary + pgsize, pgsize);  		if (memcmp(twopages, boundary, bufsize)) { -			printk(PRINT_PREF "error: verify failed at %#llx\n", +			pr_err("error: verify failed at %#llx\n",  			       (long long)addr);  			errcnt += 1;  		} @@ -206,10 +206,10 @@ static int crosstest(void)  	loff_t addr, addr0, addrn;  	unsigned char *pp1, *pp2, *pp3, *pp4; -	printk(PRINT_PREF "crosstest\n"); +	pr_info("crosstest\n");  	pp1 = kmalloc(pgsize * 4, GFP_KERNEL);  	if (!pp1) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		return -ENOMEM;  	}  	pp2 = pp1 + pgsize; @@ -231,7 +231,7 @@ static int crosstest(void)  	if (mtd_is_bitflip(err))  		err = 0;  	if (err || read != pgsize) { -		printk(PRINT_PREF "error: read failed at %#llx\n", +		pr_err("error: read failed at %#llx\n",  		       (long long)addr);  		kfree(pp1);  		return err; @@ -243,7 +243,7 @@ static int crosstest(void)  	if (mtd_is_bitflip(err))  		err = 0;  	if (err || read != pgsize) { -		printk(PRINT_PREF "error: read failed at %#llx\n", +		pr_err("error: read failed at %#llx\n",  		       (long long)addr);  		kfree(pp1);  		return err; @@ -251,12 +251,12 @@ static int crosstest(void)  	/* Read first page to pp2 */  	addr = addr0; -	printk(PRINT_PREF "reading page at %#llx\n", (long long)addr); +	pr_info("reading page at %#llx\n", (long long)addr);  	err = mtd_read(mtd, addr, pgsize, &read, pp2);  	if (mtd_is_bitflip(err))  		err = 0;  	if (err || read != pgsize) { -		printk(PRINT_PREF "error: read failed at %#llx\n", +		pr_err("error: read failed at %#llx\n",  		       (long long)addr);  		kfree(pp1);  		return err; @@ -264,12 +264,12 @@ static int crosstest(void)  	/* Read last page to pp3 */  	addr = addrn - pgsize; -	printk(PRINT_PREF "reading page at %#llx\n", (long long)addr); +	pr_info("reading page at %#llx\n", (long long)addr);  	err = mtd_read(mtd, addr, pgsize, &read, pp3);  	if (mtd_is_bitflip(err))  		err = 0;  	if (err || read != pgsize) { -		printk(PRINT_PREF "error: read failed at %#llx\n", +		pr_err("error: read failed at %#llx\n",  		       (long long)addr);  		kfree(pp1);  		return err; @@ -277,25 +277,25 @@ static int crosstest(void)  	/* Read first page again to pp4 */  	addr = addr0; -	printk(PRINT_PREF "reading page at %#llx\n", (long long)addr); +	pr_info("reading page at %#llx\n", (long long)addr);  	err = mtd_read(mtd, addr, pgsize, &read, pp4);  	if (mtd_is_bitflip(err))  		err = 0;  	if (err || read != pgsize) { -		printk(PRINT_PREF "error: read failed at %#llx\n", +		pr_err("error: read failed at %#llx\n",  		       (long long)addr);  		kfree(pp1);  		return err;  	}  	/* pp2 and pp4 should be the same */ -	printk(PRINT_PREF "verifying pages read at %#llx match\n", +	pr_info("verifying pages read at %#llx match\n",  	       (long long)addr0);  	if (memcmp(pp2, pp4, pgsize)) { -		printk(PRINT_PREF "verify failed!\n"); +		pr_err("verify failed!\n");  		errcnt += 1;  	} else if (!err) -		printk(PRINT_PREF "crosstest ok\n"); +		pr_info("crosstest ok\n");  	kfree(pp1);  	return err;  } @@ -307,7 +307,7 @@ static int erasecrosstest(void)  	loff_t addr0;  	char *readbuf = twopages; -	printk(PRINT_PREF "erasecrosstest\n"); +	pr_info("erasecrosstest\n");  	ebnum = 0;  	addr0 = 0; @@ -320,79 +320,79 @@ static int erasecrosstest(void)  	while (ebnum2 && bbt[ebnum2])  		ebnum2 -= 1; -	printk(PRINT_PREF "erasing block %d\n", ebnum); +	pr_info("erasing block %d\n", ebnum);  	err = erase_eraseblock(ebnum);  	if (err)  		return err; -	printk(PRINT_PREF "writing 1st page of block %d\n", ebnum); +	pr_info("writing 1st page of block %d\n", ebnum);  	set_random_data(writebuf, pgsize);  	strcpy(writebuf, "There is no data like this!");  	err = mtd_write(mtd, addr0, pgsize, &written, writebuf);  	if (err || written != pgsize) { -		printk(PRINT_PREF "error: write failed at %#llx\n", +		pr_info("error: write failed at %#llx\n",  		       (long long)addr0);  		return err ? err : -1;  	} -	printk(PRINT_PREF "reading 1st page of block %d\n", ebnum); +	pr_info("reading 1st page of block %d\n", ebnum);  	memset(readbuf, 0, pgsize);  	err = mtd_read(mtd, addr0, pgsize, &read, readbuf);  	if (mtd_is_bitflip(err))  		err = 0;  	if (err || read != pgsize) { -		printk(PRINT_PREF "error: read failed at %#llx\n", +		pr_err("error: read failed at %#llx\n",  		       (long long)addr0);  		return err ? err : -1;  	} -	printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum); +	pr_info("verifying 1st page of block %d\n", ebnum);  	if (memcmp(writebuf, readbuf, pgsize)) { -		printk(PRINT_PREF "verify failed!\n"); +		pr_err("verify failed!\n");  		errcnt += 1;  		return -1;  	} -	printk(PRINT_PREF "erasing block %d\n", ebnum); +	pr_info("erasing block %d\n", ebnum);  	err = erase_eraseblock(ebnum);  	if (err)  		return err; -	printk(PRINT_PREF "writing 1st page of block %d\n", ebnum); +	pr_info("writing 1st page of block %d\n", ebnum);  	set_random_data(writebuf, pgsize);  	strcpy(writebuf, "There is no data like this!");  	err = mtd_write(mtd, addr0, pgsize, &written, writebuf);  	if (err || written != pgsize) { -		printk(PRINT_PREF "error: write failed at %#llx\n", +		pr_err("error: write failed at %#llx\n",  		       (long long)addr0);  		return err ? err : -1;  	} -	printk(PRINT_PREF "erasing block %d\n", ebnum2); +	pr_info("erasing block %d\n", ebnum2);  	err = erase_eraseblock(ebnum2);  	if (err)  		return err; -	printk(PRINT_PREF "reading 1st page of block %d\n", ebnum); +	pr_info("reading 1st page of block %d\n", ebnum);  	memset(readbuf, 0, pgsize);  	err = mtd_read(mtd, addr0, pgsize, &read, readbuf);  	if (mtd_is_bitflip(err))  		err = 0;  	if (err || read != pgsize) { -		printk(PRINT_PREF "error: read failed at %#llx\n", +		pr_err("error: read failed at %#llx\n",  		       (long long)addr0);  		return err ? err : -1;  	} -	printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum); +	pr_info("verifying 1st page of block %d\n", ebnum);  	if (memcmp(writebuf, readbuf, pgsize)) { -		printk(PRINT_PREF "verify failed!\n"); +		pr_err("verify failed!\n");  		errcnt += 1;  		return -1;  	}  	if (!err) -		printk(PRINT_PREF "erasecrosstest ok\n"); +		pr_info("erasecrosstest ok\n");  	return err;  } @@ -402,7 +402,7 @@ static int erasetest(void)  	int err = 0, i, ebnum, ok = 1;  	loff_t addr0; -	printk(PRINT_PREF "erasetest\n"); +	pr_info("erasetest\n");  	ebnum = 0;  	addr0 = 0; @@ -411,40 +411,40 @@ static int erasetest(void)  		ebnum += 1;  	} -	printk(PRINT_PREF "erasing block %d\n", ebnum); +	pr_info("erasing block %d\n", ebnum);  	err = erase_eraseblock(ebnum);  	if (err)  		return err; -	printk(PRINT_PREF "writing 1st page of block %d\n", ebnum); +	pr_info("writing 1st page of block %d\n", ebnum);  	set_random_data(writebuf, pgsize);  	err = mtd_write(mtd, addr0, pgsize, &written, writebuf);  	if (err || written != pgsize) { -		printk(PRINT_PREF "error: write failed at %#llx\n", +		pr_err("error: write failed at %#llx\n",  		       (long long)addr0);  		return err ? err : -1;  	} -	printk(PRINT_PREF "erasing block %d\n", ebnum); +	pr_info("erasing block %d\n", ebnum);  	err = erase_eraseblock(ebnum);  	if (err)  		return err; -	printk(PRINT_PREF "reading 1st page of block %d\n", ebnum); +	pr_info("reading 1st page of block %d\n", ebnum);  	err = mtd_read(mtd, addr0, pgsize, &read, twopages);  	if (mtd_is_bitflip(err))  		err = 0;  	if (err || read != pgsize) { -		printk(PRINT_PREF "error: read failed at %#llx\n", +		pr_err("error: read failed at %#llx\n",  		       (long long)addr0);  		return err ? err : -1;  	} -	printk(PRINT_PREF "verifying 1st page of block %d is all 0xff\n", +	pr_info("verifying 1st page of block %d is all 0xff\n",  	       ebnum);  	for (i = 0; i < pgsize; ++i)  		if (twopages[i] != 0xff) { -			printk(PRINT_PREF "verifying all 0xff failed at %d\n", +			pr_err("verifying all 0xff failed at %d\n",  			       i);  			errcnt += 1;  			ok = 0; @@ -452,7 +452,7 @@ static int erasetest(void)  		}  	if (ok && !err) -		printk(PRINT_PREF "erasetest ok\n"); +		pr_info("erasetest ok\n");  	return err;  } @@ -464,7 +464,7 @@ static int is_block_bad(int ebnum)  	ret = mtd_block_isbad(mtd, addr);  	if (ret) -		printk(PRINT_PREF "block %d is bad\n", ebnum); +		pr_info("block %d is bad\n", ebnum);  	return ret;  } @@ -474,18 +474,18 @@ static int scan_for_bad_eraseblocks(void)  	bbt = kzalloc(ebcnt, GFP_KERNEL);  	if (!bbt) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		return -ENOMEM;  	} -	printk(PRINT_PREF "scanning for bad eraseblocks\n"); +	pr_info("scanning for bad eraseblocks\n");  	for (i = 0; i < ebcnt; ++i) {  		bbt[i] = is_block_bad(i) ? 1 : 0;  		if (bbt[i])  			bad += 1;  		cond_resched();  	} -	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); +	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);  	return 0;  } @@ -499,22 +499,22 @@ static int __init mtd_pagetest_init(void)  	printk(KERN_INFO "=================================================\n");  	if (dev < 0) { -		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); -		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); +		pr_info("Please specify a valid mtd-device via module parameter\n"); +		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");  		return -EINVAL;  	} -	printk(PRINT_PREF "MTD device: %d\n", dev); +	pr_info("MTD device: %d\n", dev);  	mtd = get_mtd_device(NULL, dev);  	if (IS_ERR(mtd)) {  		err = PTR_ERR(mtd); -		printk(PRINT_PREF "error: cannot get MTD device\n"); +		pr_err("error: cannot get MTD device\n");  		return err;  	}  	if (mtd->type != MTD_NANDFLASH) { -		printk(PRINT_PREF "this test requires NAND flash\n"); +		pr_info("this test requires NAND flash\n");  		goto out;  	} @@ -524,7 +524,7 @@ static int __init mtd_pagetest_init(void)  	pgcnt = mtd->erasesize / mtd->writesize;  	pgsize = mtd->writesize; -	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " +	pr_info("MTD device size %llu, eraseblock size %u, "  	       "page size %u, count of eraseblocks %u, pages per "  	       "eraseblock %u, OOB size %u\n",  	       (unsigned long long)mtd->size, mtd->erasesize, @@ -534,17 +534,17 @@ static int __init mtd_pagetest_init(void)  	bufsize = pgsize * 2;  	writebuf = kmalloc(mtd->erasesize, GFP_KERNEL);  	if (!writebuf) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		goto out;  	}  	twopages = kmalloc(bufsize, GFP_KERNEL);  	if (!twopages) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		goto out;  	}  	boundary = kmalloc(bufsize, GFP_KERNEL);  	if (!boundary) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		goto out;  	} @@ -553,7 +553,7 @@ static int __init mtd_pagetest_init(void)  		goto out;  	/* Erase all eraseblocks */ -	printk(PRINT_PREF "erasing whole device\n"); +	pr_info("erasing whole device\n");  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i])  			continue; @@ -562,11 +562,11 @@ static int __init mtd_pagetest_init(void)  			goto out;  		cond_resched();  	} -	printk(PRINT_PREF "erased %u eraseblocks\n", i); +	pr_info("erased %u eraseblocks\n", i);  	/* Write all eraseblocks */  	simple_srand(1); -	printk(PRINT_PREF "writing whole device\n"); +	pr_info("writing whole device\n");  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i])  			continue; @@ -574,14 +574,14 @@ static int __init mtd_pagetest_init(void)  		if (err)  			goto out;  		if (i % 256 == 0) -			printk(PRINT_PREF "written up to eraseblock %u\n", i); +			pr_info("written up to eraseblock %u\n", i);  		cond_resched();  	} -	printk(PRINT_PREF "written %u eraseblocks\n", i); +	pr_info("written %u eraseblocks\n", i);  	/* Check all eraseblocks */  	simple_srand(1); -	printk(PRINT_PREF "verifying all eraseblocks\n"); +	pr_info("verifying all eraseblocks\n");  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i])  			continue; @@ -589,10 +589,10 @@ static int __init mtd_pagetest_init(void)  		if (err)  			goto out;  		if (i % 256 == 0) -			printk(PRINT_PREF "verified up to eraseblock %u\n", i); +			pr_info("verified up to eraseblock %u\n", i);  		cond_resched();  	} -	printk(PRINT_PREF "verified %u eraseblocks\n", i); +	pr_info("verified %u eraseblocks\n", i);  	err = crosstest();  	if (err) @@ -606,7 +606,7 @@ static int __init mtd_pagetest_init(void)  	if (err)  		goto out; -	printk(PRINT_PREF "finished with %d errors\n", errcnt); +	pr_info("finished with %d errors\n", errcnt);  out:  	kfree(bbt); @@ -615,7 +615,7 @@ out:  	kfree(writebuf);  	put_mtd_device(mtd);  	if (err) -		printk(PRINT_PREF "error %d occurred\n", err); +		pr_info("error %d occurred\n", err);  	printk(KERN_INFO "=================================================\n");  	return err;  } diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c index 121aba189ce..266de04b6d2 100644 --- a/drivers/mtd/tests/mtd_readtest.c +++ b/drivers/mtd/tests/mtd_readtest.c @@ -19,6 +19,8 @@   * Author: Adrian Hunter <ext-adrian.hunter@nokia.com>   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/init.h>  #include <linux/module.h>  #include <linux/moduleparam.h> @@ -27,8 +29,6 @@  #include <linux/slab.h>  #include <linux/sched.h> -#define PRINT_PREF KERN_INFO "mtd_readtest: " -  static int dev = -EINVAL;  module_param(dev, int, S_IRUGO);  MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -51,12 +51,12 @@ static int read_eraseblock_by_page(int ebnum)  	void *oobbuf = iobuf1;  	for (i = 0; i < pgcnt; i++) { -		memset(buf, 0 , pgcnt); +		memset(buf, 0 , pgsize);  		ret = mtd_read(mtd, addr, pgsize, &read, buf);  		if (ret == -EUCLEAN)  			ret = 0;  		if (ret || read != pgsize) { -			printk(PRINT_PREF "error: read failed at %#llx\n", +			pr_err("error: read failed at %#llx\n",  			       (long long)addr);  			if (!err)  				err = ret; @@ -77,7 +77,7 @@ static int read_eraseblock_by_page(int ebnum)  			ret = mtd_read_oob(mtd, addr, &ops);  			if ((ret && !mtd_is_bitflip(ret)) ||  					ops.oobretlen != mtd->oobsize) { -				printk(PRINT_PREF "error: read oob failed at " +				pr_err("error: read oob failed at "  						  "%#llx\n", (long long)addr);  				if (!err)  					err = ret; @@ -99,7 +99,7 @@ static void dump_eraseblock(int ebnum)  	char line[128];  	int pg, oob; -	printk(PRINT_PREF "dumping eraseblock %d\n", ebnum); +	pr_info("dumping eraseblock %d\n", ebnum);  	n = mtd->erasesize;  	for (i = 0; i < n;) {  		char *p = line; @@ -112,7 +112,7 @@ static void dump_eraseblock(int ebnum)  	}  	if (!mtd->oobsize)  		return; -	printk(PRINT_PREF "dumping oob from eraseblock %d\n", ebnum); +	pr_info("dumping oob from eraseblock %d\n", ebnum);  	n = mtd->oobsize;  	for (pg = 0, i = 0; pg < pgcnt; pg++)  		for (oob = 0; oob < n;) { @@ -134,7 +134,7 @@ static int is_block_bad(int ebnum)  	ret = mtd_block_isbad(mtd, addr);  	if (ret) -		printk(PRINT_PREF "block %d is bad\n", ebnum); +		pr_info("block %d is bad\n", ebnum);  	return ret;  } @@ -144,21 +144,21 @@ static int scan_for_bad_eraseblocks(void)  	bbt = kzalloc(ebcnt, GFP_KERNEL);  	if (!bbt) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		return -ENOMEM;  	}  	if (!mtd_can_have_bb(mtd))  		return 0; -	printk(PRINT_PREF "scanning for bad eraseblocks\n"); +	pr_info("scanning for bad eraseblocks\n");  	for (i = 0; i < ebcnt; ++i) {  		bbt[i] = is_block_bad(i) ? 1 : 0;  		if (bbt[i])  			bad += 1;  		cond_resched();  	} -	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); +	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);  	return 0;  } @@ -171,21 +171,21 @@ static int __init mtd_readtest_init(void)  	printk(KERN_INFO "=================================================\n");  	if (dev < 0) { -		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); +		pr_info("Please specify a valid mtd-device via module parameter\n");  		return -EINVAL;  	} -	printk(PRINT_PREF "MTD device: %d\n", dev); +	pr_info("MTD device: %d\n", dev);  	mtd = get_mtd_device(NULL, dev);  	if (IS_ERR(mtd)) {  		err = PTR_ERR(mtd); -		printk(PRINT_PREF "error: Cannot get MTD device\n"); +		pr_err("error: Cannot get MTD device\n");  		return err;  	}  	if (mtd->writesize == 1) { -		printk(PRINT_PREF "not NAND flash, assume page size is 512 " +		pr_info("not NAND flash, assume page size is 512 "  		       "bytes.\n");  		pgsize = 512;  	} else @@ -196,7 +196,7 @@ static int __init mtd_readtest_init(void)  	ebcnt = tmp;  	pgcnt = mtd->erasesize / pgsize; -	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " +	pr_info("MTD device size %llu, eraseblock size %u, "  	       "page size %u, count of eraseblocks %u, pages per "  	       "eraseblock %u, OOB size %u\n",  	       (unsigned long long)mtd->size, mtd->erasesize, @@ -205,12 +205,12 @@ static int __init mtd_readtest_init(void)  	err = -ENOMEM;  	iobuf = kmalloc(mtd->erasesize, GFP_KERNEL);  	if (!iobuf) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		goto out;  	}  	iobuf1 = kmalloc(mtd->erasesize, GFP_KERNEL);  	if (!iobuf1) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		goto out;  	} @@ -219,7 +219,7 @@ static int __init mtd_readtest_init(void)  		goto out;  	/* Read all eraseblocks 1 page at a time */ -	printk(PRINT_PREF "testing page read\n"); +	pr_info("testing page read\n");  	for (i = 0; i < ebcnt; ++i) {  		int ret; @@ -235,9 +235,9 @@ static int __init mtd_readtest_init(void)  	}  	if (err) -		printk(PRINT_PREF "finished with errors\n"); +		pr_info("finished with errors\n");  	else -		printk(PRINT_PREF "finished\n"); +		pr_info("finished\n");  out: @@ -246,7 +246,7 @@ out:  	kfree(bbt);  	put_mtd_device(mtd);  	if (err) -		printk(PRINT_PREF "error %d occurred\n", err); +		pr_info("error %d occurred\n", err);  	printk(KERN_INFO "=================================================\n");  	return err;  } diff --git a/drivers/mtd/tests/mtd_speedtest.c b/drivers/mtd/tests/mtd_speedtest.c index 42b0f7456fc..596cbea8df4 100644 --- a/drivers/mtd/tests/mtd_speedtest.c +++ b/drivers/mtd/tests/mtd_speedtest.c @@ -19,6 +19,8 @@   * Author: Adrian Hunter <adrian.hunter@nokia.com>   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/init.h>  #include <linux/module.h>  #include <linux/moduleparam.h> @@ -28,8 +30,6 @@  #include <linux/sched.h>  #include <linux/random.h> -#define PRINT_PREF KERN_INFO "mtd_speedtest: " -  static int dev = -EINVAL;  module_param(dev, int, S_IRUGO);  MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -70,12 +70,12 @@ static int erase_eraseblock(int ebnum)  	err = mtd_erase(mtd, &ei);  	if (err) { -		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); +		pr_err("error %d while erasing EB %d\n", err, ebnum);  		return err;  	}  	if (ei.state == MTD_ERASE_FAILED) { -		printk(PRINT_PREF "some erase error occurred at EB %d\n", +		pr_err("some erase error occurred at EB %d\n",  		       ebnum);  		return -EIO;  	} @@ -96,13 +96,13 @@ static int multiblock_erase(int ebnum, int blocks)  	err = mtd_erase(mtd, &ei);  	if (err) { -		printk(PRINT_PREF "error %d while erasing EB %d, blocks %d\n", +		pr_err("error %d while erasing EB %d, blocks %d\n",  		       err, ebnum, blocks);  		return err;  	}  	if (ei.state == MTD_ERASE_FAILED) { -		printk(PRINT_PREF "some erase error occurred at EB %d," +		pr_err("some erase error occurred at EB %d,"  		       "blocks %d\n", ebnum, blocks);  		return -EIO;  	} @@ -134,7 +134,7 @@ static int write_eraseblock(int ebnum)  	err = mtd_write(mtd, addr, mtd->erasesize, &written, iobuf);  	if (err || written != mtd->erasesize) { -		printk(PRINT_PREF "error: write failed at %#llx\n", addr); +		pr_err("error: write failed at %#llx\n", addr);  		if (!err)  			err = -EINVAL;  	} @@ -152,7 +152,7 @@ static int write_eraseblock_by_page(int ebnum)  	for (i = 0; i < pgcnt; i++) {  		err = mtd_write(mtd, addr, pgsize, &written, buf);  		if (err || written != pgsize) { -			printk(PRINT_PREF "error: write failed at %#llx\n", +			pr_err("error: write failed at %#llx\n",  			       addr);  			if (!err)  				err = -EINVAL; @@ -175,7 +175,7 @@ static int write_eraseblock_by_2pages(int ebnum)  	for (i = 0; i < n; i++) {  		err = mtd_write(mtd, addr, sz, &written, buf);  		if (err || written != sz) { -			printk(PRINT_PREF "error: write failed at %#llx\n", +			pr_err("error: write failed at %#llx\n",  			       addr);  			if (!err)  				err = -EINVAL; @@ -187,7 +187,7 @@ static int write_eraseblock_by_2pages(int ebnum)  	if (pgcnt % 2) {  		err = mtd_write(mtd, addr, pgsize, &written, buf);  		if (err || written != pgsize) { -			printk(PRINT_PREF "error: write failed at %#llx\n", +			pr_err("error: write failed at %#llx\n",  			       addr);  			if (!err)  				err = -EINVAL; @@ -208,7 +208,7 @@ static int read_eraseblock(int ebnum)  	if (mtd_is_bitflip(err))  		err = 0;  	if (err || read != mtd->erasesize) { -		printk(PRINT_PREF "error: read failed at %#llx\n", addr); +		pr_err("error: read failed at %#llx\n", addr);  		if (!err)  			err = -EINVAL;  	} @@ -229,7 +229,7 @@ static int read_eraseblock_by_page(int ebnum)  		if (mtd_is_bitflip(err))  			err = 0;  		if (err || read != pgsize) { -			printk(PRINT_PREF "error: read failed at %#llx\n", +			pr_err("error: read failed at %#llx\n",  			       addr);  			if (!err)  				err = -EINVAL; @@ -255,7 +255,7 @@ static int read_eraseblock_by_2pages(int ebnum)  		if (mtd_is_bitflip(err))  			err = 0;  		if (err || read != sz) { -			printk(PRINT_PREF "error: read failed at %#llx\n", +			pr_err("error: read failed at %#llx\n",  			       addr);  			if (!err)  				err = -EINVAL; @@ -270,7 +270,7 @@ static int read_eraseblock_by_2pages(int ebnum)  		if (mtd_is_bitflip(err))  			err = 0;  		if (err || read != pgsize) { -			printk(PRINT_PREF "error: read failed at %#llx\n", +			pr_err("error: read failed at %#llx\n",  			       addr);  			if (!err)  				err = -EINVAL; @@ -287,7 +287,7 @@ static int is_block_bad(int ebnum)  	ret = mtd_block_isbad(mtd, addr);  	if (ret) -		printk(PRINT_PREF "block %d is bad\n", ebnum); +		pr_info("block %d is bad\n", ebnum);  	return ret;  } @@ -321,21 +321,21 @@ static int scan_for_bad_eraseblocks(void)  	bbt = kzalloc(ebcnt, GFP_KERNEL);  	if (!bbt) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		return -ENOMEM;  	}  	if (!mtd_can_have_bb(mtd))  		goto out; -	printk(PRINT_PREF "scanning for bad eraseblocks\n"); +	pr_info("scanning for bad eraseblocks\n");  	for (i = 0; i < ebcnt; ++i) {  		bbt[i] = is_block_bad(i) ? 1 : 0;  		if (bbt[i])  			bad += 1;  		cond_resched();  	} -	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); +	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);  out:  	goodebcnt = ebcnt - bad;  	return 0; @@ -351,25 +351,25 @@ static int __init mtd_speedtest_init(void)  	printk(KERN_INFO "=================================================\n");  	if (dev < 0) { -		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); -		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); +		pr_info("Please specify a valid mtd-device via module parameter\n"); +		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");  		return -EINVAL;  	}  	if (count) -		printk(PRINT_PREF "MTD device: %d    count: %d\n", dev, count); +		pr_info("MTD device: %d    count: %d\n", dev, count);  	else -		printk(PRINT_PREF "MTD device: %d\n", dev); +		pr_info("MTD device: %d\n", dev);  	mtd = get_mtd_device(NULL, dev);  	if (IS_ERR(mtd)) {  		err = PTR_ERR(mtd); -		printk(PRINT_PREF "error: cannot get MTD device\n"); +		pr_err("error: cannot get MTD device\n");  		return err;  	}  	if (mtd->writesize == 1) { -		printk(PRINT_PREF "not NAND flash, assume page size is 512 " +		pr_info("not NAND flash, assume page size is 512 "  		       "bytes.\n");  		pgsize = 512;  	} else @@ -380,7 +380,7 @@ static int __init mtd_speedtest_init(void)  	ebcnt = tmp;  	pgcnt = mtd->erasesize / pgsize; -	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " +	pr_info("MTD device size %llu, eraseblock size %u, "  	       "page size %u, count of eraseblocks %u, pages per "  	       "eraseblock %u, OOB size %u\n",  	       (unsigned long long)mtd->size, mtd->erasesize, @@ -392,7 +392,7 @@ static int __init mtd_speedtest_init(void)  	err = -ENOMEM;  	iobuf = kmalloc(mtd->erasesize, GFP_KERNEL);  	if (!iobuf) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		goto out;  	} @@ -407,7 +407,7 @@ static int __init mtd_speedtest_init(void)  		goto out;  	/* Write all eraseblocks, 1 eraseblock at a time */ -	printk(PRINT_PREF "testing eraseblock write speed\n"); +	pr_info("testing eraseblock write speed\n");  	start_timing();  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i]) @@ -419,10 +419,10 @@ static int __init mtd_speedtest_init(void)  	}  	stop_timing();  	speed = calc_speed(); -	printk(PRINT_PREF "eraseblock write speed is %ld KiB/s\n", speed); +	pr_info("eraseblock write speed is %ld KiB/s\n", speed);  	/* Read all eraseblocks, 1 eraseblock at a time */ -	printk(PRINT_PREF "testing eraseblock read speed\n"); +	pr_info("testing eraseblock read speed\n");  	start_timing();  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i]) @@ -434,14 +434,14 @@ static int __init mtd_speedtest_init(void)  	}  	stop_timing();  	speed = calc_speed(); -	printk(PRINT_PREF "eraseblock read speed is %ld KiB/s\n", speed); +	pr_info("eraseblock read speed is %ld KiB/s\n", speed);  	err = erase_whole_device();  	if (err)  		goto out;  	/* Write all eraseblocks, 1 page at a time */ -	printk(PRINT_PREF "testing page write speed\n"); +	pr_info("testing page write speed\n");  	start_timing();  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i]) @@ -453,10 +453,10 @@ static int __init mtd_speedtest_init(void)  	}  	stop_timing();  	speed = calc_speed(); -	printk(PRINT_PREF "page write speed is %ld KiB/s\n", speed); +	pr_info("page write speed is %ld KiB/s\n", speed);  	/* Read all eraseblocks, 1 page at a time */ -	printk(PRINT_PREF "testing page read speed\n"); +	pr_info("testing page read speed\n");  	start_timing();  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i]) @@ -468,14 +468,14 @@ static int __init mtd_speedtest_init(void)  	}  	stop_timing();  	speed = calc_speed(); -	printk(PRINT_PREF "page read speed is %ld KiB/s\n", speed); +	pr_info("page read speed is %ld KiB/s\n", speed);  	err = erase_whole_device();  	if (err)  		goto out;  	/* Write all eraseblocks, 2 pages at a time */ -	printk(PRINT_PREF "testing 2 page write speed\n"); +	pr_info("testing 2 page write speed\n");  	start_timing();  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i]) @@ -487,10 +487,10 @@ static int __init mtd_speedtest_init(void)  	}  	stop_timing();  	speed = calc_speed(); -	printk(PRINT_PREF "2 page write speed is %ld KiB/s\n", speed); +	pr_info("2 page write speed is %ld KiB/s\n", speed);  	/* Read all eraseblocks, 2 pages at a time */ -	printk(PRINT_PREF "testing 2 page read speed\n"); +	pr_info("testing 2 page read speed\n");  	start_timing();  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i]) @@ -502,10 +502,10 @@ static int __init mtd_speedtest_init(void)  	}  	stop_timing();  	speed = calc_speed(); -	printk(PRINT_PREF "2 page read speed is %ld KiB/s\n", speed); +	pr_info("2 page read speed is %ld KiB/s\n", speed);  	/* Erase all eraseblocks */ -	printk(PRINT_PREF "Testing erase speed\n"); +	pr_info("Testing erase speed\n");  	start_timing();  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i]) @@ -517,12 +517,12 @@ static int __init mtd_speedtest_init(void)  	}  	stop_timing();  	speed = calc_speed(); -	printk(PRINT_PREF "erase speed is %ld KiB/s\n", speed); +	pr_info("erase speed is %ld KiB/s\n", speed);  	/* Multi-block erase all eraseblocks */  	for (k = 1; k < 7; k++) {  		blocks = 1 << k; -		printk(PRINT_PREF "Testing %dx multi-block erase speed\n", +		pr_info("Testing %dx multi-block erase speed\n",  		       blocks);  		start_timing();  		for (i = 0; i < ebcnt; ) { @@ -541,16 +541,16 @@ static int __init mtd_speedtest_init(void)  		}  		stop_timing();  		speed = calc_speed(); -		printk(PRINT_PREF "%dx multi-block erase speed is %ld KiB/s\n", +		pr_info("%dx multi-block erase speed is %ld KiB/s\n",  		       blocks, speed);  	} -	printk(PRINT_PREF "finished\n"); +	pr_info("finished\n");  out:  	kfree(iobuf);  	kfree(bbt);  	put_mtd_device(mtd);  	if (err) -		printk(PRINT_PREF "error %d occurred\n", err); +		pr_info("error %d occurred\n", err);  	printk(KERN_INFO "=================================================\n");  	return err;  } diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c index cb268cebf01..3729f679ae5 100644 --- a/drivers/mtd/tests/mtd_stresstest.c +++ b/drivers/mtd/tests/mtd_stresstest.c @@ -19,6 +19,8 @@   * Author: Adrian Hunter <ext-adrian.hunter@nokia.com>   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/init.h>  #include <linux/module.h>  #include <linux/moduleparam.h> @@ -29,8 +31,6 @@  #include <linux/vmalloc.h>  #include <linux/random.h> -#define PRINT_PREF KERN_INFO "mtd_stresstest: " -  static int dev = -EINVAL;  module_param(dev, int, S_IRUGO);  MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -94,12 +94,12 @@ static int erase_eraseblock(int ebnum)  	err = mtd_erase(mtd, &ei);  	if (unlikely(err)) { -		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); +		pr_err("error %d while erasing EB %d\n", err, ebnum);  		return err;  	}  	if (unlikely(ei.state == MTD_ERASE_FAILED)) { -		printk(PRINT_PREF "some erase error occurred at EB %d\n", +		pr_err("some erase error occurred at EB %d\n",  		       ebnum);  		return -EIO;  	} @@ -114,7 +114,7 @@ static int is_block_bad(int ebnum)  	ret = mtd_block_isbad(mtd, addr);  	if (ret) -		printk(PRINT_PREF "block %d is bad\n", ebnum); +		pr_info("block %d is bad\n", ebnum);  	return ret;  } @@ -137,7 +137,7 @@ static int do_read(void)  	if (mtd_is_bitflip(err))  		err = 0;  	if (unlikely(err || read != len)) { -		printk(PRINT_PREF "error: read failed at 0x%llx\n", +		pr_err("error: read failed at 0x%llx\n",  		       (long long)addr);  		if (!err)  			err = -EINVAL; @@ -174,7 +174,7 @@ static int do_write(void)  	addr = eb * mtd->erasesize + offs;  	err = mtd_write(mtd, addr, len, &written, writebuf);  	if (unlikely(err || written != len)) { -		printk(PRINT_PREF "error: write failed at 0x%llx\n", +		pr_err("error: write failed at 0x%llx\n",  		       (long long)addr);  		if (!err)  			err = -EINVAL; @@ -203,21 +203,21 @@ static int scan_for_bad_eraseblocks(void)  	bbt = kzalloc(ebcnt, GFP_KERNEL);  	if (!bbt) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		return -ENOMEM;  	}  	if (!mtd_can_have_bb(mtd))  		return 0; -	printk(PRINT_PREF "scanning for bad eraseblocks\n"); +	pr_info("scanning for bad eraseblocks\n");  	for (i = 0; i < ebcnt; ++i) {  		bbt[i] = is_block_bad(i) ? 1 : 0;  		if (bbt[i])  			bad += 1;  		cond_resched();  	} -	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); +	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);  	return 0;  } @@ -231,22 +231,22 @@ static int __init mtd_stresstest_init(void)  	printk(KERN_INFO "=================================================\n");  	if (dev < 0) { -		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); -		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); +		pr_info("Please specify a valid mtd-device via module parameter\n"); +		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");  		return -EINVAL;  	} -	printk(PRINT_PREF "MTD device: %d\n", dev); +	pr_info("MTD device: %d\n", dev);  	mtd = get_mtd_device(NULL, dev);  	if (IS_ERR(mtd)) {  		err = PTR_ERR(mtd); -		printk(PRINT_PREF "error: cannot get MTD device\n"); +		pr_err("error: cannot get MTD device\n");  		return err;  	}  	if (mtd->writesize == 1) { -		printk(PRINT_PREF "not NAND flash, assume page size is 512 " +		pr_info("not NAND flash, assume page size is 512 "  		       "bytes.\n");  		pgsize = 512;  	} else @@ -257,14 +257,14 @@ static int __init mtd_stresstest_init(void)  	ebcnt = tmp;  	pgcnt = mtd->erasesize / pgsize; -	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " +	pr_info("MTD device size %llu, eraseblock size %u, "  	       "page size %u, count of eraseblocks %u, pages per "  	       "eraseblock %u, OOB size %u\n",  	       (unsigned long long)mtd->size, mtd->erasesize,  	       pgsize, ebcnt, pgcnt, mtd->oobsize);  	if (ebcnt < 2) { -		printk(PRINT_PREF "error: need at least 2 eraseblocks\n"); +		pr_err("error: need at least 2 eraseblocks\n");  		err = -ENOSPC;  		goto out_put_mtd;  	} @@ -277,7 +277,7 @@ static int __init mtd_stresstest_init(void)  	writebuf = vmalloc(bufsize);  	offsets = kmalloc(ebcnt * sizeof(int), GFP_KERNEL);  	if (!readbuf || !writebuf || !offsets) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		goto out;  	}  	for (i = 0; i < ebcnt; i++) @@ -290,16 +290,16 @@ static int __init mtd_stresstest_init(void)  		goto out;  	/* Do operations */ -	printk(PRINT_PREF "doing operations\n"); +	pr_info("doing operations\n");  	for (op = 0; op < count; op++) {  		if ((op & 1023) == 0) -			printk(PRINT_PREF "%d operations done\n", op); +			pr_info("%d operations done\n", op);  		err = do_operation();  		if (err)  			goto out;  		cond_resched();  	} -	printk(PRINT_PREF "finished, %d operations done\n", op); +	pr_info("finished, %d operations done\n", op);  out:  	kfree(offsets); @@ -309,7 +309,7 @@ out:  out_put_mtd:  	put_mtd_device(mtd);  	if (err) -		printk(PRINT_PREF "error %d occurred\n", err); +		pr_info("error %d occurred\n", err);  	printk(KERN_INFO "=================================================\n");  	return err;  } diff --git a/drivers/mtd/tests/mtd_subpagetest.c b/drivers/mtd/tests/mtd_subpagetest.c index 9667bf53528..c880c2229c5 100644 --- a/drivers/mtd/tests/mtd_subpagetest.c +++ b/drivers/mtd/tests/mtd_subpagetest.c @@ -19,6 +19,8 @@   *   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/init.h>  #include <linux/module.h>  #include <linux/moduleparam.h> @@ -27,8 +29,6 @@  #include <linux/slab.h>  #include <linux/sched.h> -#define PRINT_PREF KERN_INFO "mtd_subpagetest: " -  static int dev = -EINVAL;  module_param(dev, int, S_IRUGO);  MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -82,12 +82,12 @@ static int erase_eraseblock(int ebnum)  	err = mtd_erase(mtd, &ei);  	if (err) { -		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); +		pr_err("error %d while erasing EB %d\n", err, ebnum);  		return err;  	}  	if (ei.state == MTD_ERASE_FAILED) { -		printk(PRINT_PREF "some erase error occurred at EB %d\n", +		pr_err("some erase error occurred at EB %d\n",  		       ebnum);  		return -EIO;  	} @@ -100,7 +100,7 @@ static int erase_whole_device(void)  	int err;  	unsigned int i; -	printk(PRINT_PREF "erasing whole device\n"); +	pr_info("erasing whole device\n");  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i])  			continue; @@ -109,7 +109,7 @@ static int erase_whole_device(void)  			return err;  		cond_resched();  	} -	printk(PRINT_PREF "erased %u eraseblocks\n", i); +	pr_info("erased %u eraseblocks\n", i);  	return 0;  } @@ -122,11 +122,11 @@ static int write_eraseblock(int ebnum)  	set_random_data(writebuf, subpgsize);  	err = mtd_write(mtd, addr, subpgsize, &written, writebuf);  	if (unlikely(err || written != subpgsize)) { -		printk(PRINT_PREF "error: write failed at %#llx\n", +		pr_err("error: write failed at %#llx\n",  		       (long long)addr);  		if (written != subpgsize) { -			printk(PRINT_PREF "  write size: %#x\n", subpgsize); -			printk(PRINT_PREF "  written: %#zx\n", written); +			pr_err("  write size: %#x\n", subpgsize); +			pr_err("  written: %#zx\n", written);  		}  		return err ? err : -1;  	} @@ -136,11 +136,11 @@ static int write_eraseblock(int ebnum)  	set_random_data(writebuf, subpgsize);  	err = mtd_write(mtd, addr, subpgsize, &written, writebuf);  	if (unlikely(err || written != subpgsize)) { -		printk(PRINT_PREF "error: write failed at %#llx\n", +		pr_err("error: write failed at %#llx\n",  		       (long long)addr);  		if (written != subpgsize) { -			printk(PRINT_PREF "  write size: %#x\n", subpgsize); -			printk(PRINT_PREF "  written: %#zx\n", written); +			pr_err("  write size: %#x\n", subpgsize); +			pr_err("  written: %#zx\n", written);  		}  		return err ? err : -1;  	} @@ -160,12 +160,12 @@ static int write_eraseblock2(int ebnum)  		set_random_data(writebuf, subpgsize * k);  		err = mtd_write(mtd, addr, subpgsize * k, &written, writebuf);  		if (unlikely(err || written != subpgsize * k)) { -			printk(PRINT_PREF "error: write failed at %#llx\n", +			pr_err("error: write failed at %#llx\n",  			       (long long)addr);  			if (written != subpgsize) { -				printk(PRINT_PREF "  write size: %#x\n", +				pr_err("  write size: %#x\n",  				       subpgsize * k); -				printk(PRINT_PREF "  written: %#08zx\n", +				pr_err("  written: %#08zx\n",  				       written);  			}  			return err ? err : -1; @@ -198,23 +198,23 @@ static int verify_eraseblock(int ebnum)  	err = mtd_read(mtd, addr, subpgsize, &read, readbuf);  	if (unlikely(err || read != subpgsize)) {  		if (mtd_is_bitflip(err) && read == subpgsize) { -			printk(PRINT_PREF "ECC correction at %#llx\n", +			pr_info("ECC correction at %#llx\n",  			       (long long)addr);  			err = 0;  		} else { -			printk(PRINT_PREF "error: read failed at %#llx\n", +			pr_err("error: read failed at %#llx\n",  			       (long long)addr);  			return err ? err : -1;  		}  	}  	if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { -		printk(PRINT_PREF "error: verify failed at %#llx\n", +		pr_err("error: verify failed at %#llx\n",  		       (long long)addr); -		printk(PRINT_PREF "------------- written----------------\n"); +		pr_info("------------- written----------------\n");  		print_subpage(writebuf); -		printk(PRINT_PREF "------------- read ------------------\n"); +		pr_info("------------- read ------------------\n");  		print_subpage(readbuf); -		printk(PRINT_PREF "-------------------------------------\n"); +		pr_info("-------------------------------------\n");  		errcnt += 1;  	} @@ -225,23 +225,23 @@ static int verify_eraseblock(int ebnum)  	err = mtd_read(mtd, addr, subpgsize, &read, readbuf);  	if (unlikely(err || read != subpgsize)) {  		if (mtd_is_bitflip(err) && read == subpgsize) { -			printk(PRINT_PREF "ECC correction at %#llx\n", +			pr_info("ECC correction at %#llx\n",  			       (long long)addr);  			err = 0;  		} else { -			printk(PRINT_PREF "error: read failed at %#llx\n", +			pr_err("error: read failed at %#llx\n",  			       (long long)addr);  			return err ? err : -1;  		}  	}  	if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { -		printk(PRINT_PREF "error: verify failed at %#llx\n", +		pr_info("error: verify failed at %#llx\n",  		       (long long)addr); -		printk(PRINT_PREF "------------- written----------------\n"); +		pr_info("------------- written----------------\n");  		print_subpage(writebuf); -		printk(PRINT_PREF "------------- read ------------------\n"); +		pr_info("------------- read ------------------\n");  		print_subpage(readbuf); -		printk(PRINT_PREF "-------------------------------------\n"); +		pr_info("-------------------------------------\n");  		errcnt += 1;  	} @@ -262,17 +262,17 @@ static int verify_eraseblock2(int ebnum)  		err = mtd_read(mtd, addr, subpgsize * k, &read, readbuf);  		if (unlikely(err || read != subpgsize * k)) {  			if (mtd_is_bitflip(err) && read == subpgsize * k) { -				printk(PRINT_PREF "ECC correction at %#llx\n", +				pr_info("ECC correction at %#llx\n",  				       (long long)addr);  				err = 0;  			} else { -				printk(PRINT_PREF "error: read failed at " +				pr_err("error: read failed at "  				       "%#llx\n", (long long)addr);  				return err ? err : -1;  			}  		}  		if (unlikely(memcmp(readbuf, writebuf, subpgsize * k))) { -			printk(PRINT_PREF "error: verify failed at %#llx\n", +			pr_err("error: verify failed at %#llx\n",  			       (long long)addr);  			errcnt += 1;  		} @@ -295,17 +295,17 @@ static int verify_eraseblock_ff(int ebnum)  		err = mtd_read(mtd, addr, subpgsize, &read, readbuf);  		if (unlikely(err || read != subpgsize)) {  			if (mtd_is_bitflip(err) && read == subpgsize) { -				printk(PRINT_PREF "ECC correction at %#llx\n", +				pr_info("ECC correction at %#llx\n",  				       (long long)addr);  				err = 0;  			} else { -				printk(PRINT_PREF "error: read failed at " +				pr_err("error: read failed at "  				       "%#llx\n", (long long)addr);  				return err ? err : -1;  			}  		}  		if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { -			printk(PRINT_PREF "error: verify 0xff failed at " +			pr_err("error: verify 0xff failed at "  			       "%#llx\n", (long long)addr);  			errcnt += 1;  		} @@ -320,7 +320,7 @@ static int verify_all_eraseblocks_ff(void)  	int err;  	unsigned int i; -	printk(PRINT_PREF "verifying all eraseblocks for 0xff\n"); +	pr_info("verifying all eraseblocks for 0xff\n");  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i])  			continue; @@ -328,10 +328,10 @@ static int verify_all_eraseblocks_ff(void)  		if (err)  			return err;  		if (i % 256 == 0) -			printk(PRINT_PREF "verified up to eraseblock %u\n", i); +			pr_info("verified up to eraseblock %u\n", i);  		cond_resched();  	} -	printk(PRINT_PREF "verified %u eraseblocks\n", i); +	pr_info("verified %u eraseblocks\n", i);  	return 0;  } @@ -342,7 +342,7 @@ static int is_block_bad(int ebnum)  	ret = mtd_block_isbad(mtd, addr);  	if (ret) -		printk(PRINT_PREF "block %d is bad\n", ebnum); +		pr_info("block %d is bad\n", ebnum);  	return ret;  } @@ -352,18 +352,18 @@ static int scan_for_bad_eraseblocks(void)  	bbt = kzalloc(ebcnt, GFP_KERNEL);  	if (!bbt) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		return -ENOMEM;  	} -	printk(PRINT_PREF "scanning for bad eraseblocks\n"); +	pr_info("scanning for bad eraseblocks\n");  	for (i = 0; i < ebcnt; ++i) {  		bbt[i] = is_block_bad(i) ? 1 : 0;  		if (bbt[i])  			bad += 1;  		cond_resched();  	} -	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); +	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);  	return 0;  } @@ -377,22 +377,22 @@ static int __init mtd_subpagetest_init(void)  	printk(KERN_INFO "=================================================\n");  	if (dev < 0) { -		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); -		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); +		pr_info("Please specify a valid mtd-device via module parameter\n"); +		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");  		return -EINVAL;  	} -	printk(PRINT_PREF "MTD device: %d\n", dev); +	pr_info("MTD device: %d\n", dev);  	mtd = get_mtd_device(NULL, dev);  	if (IS_ERR(mtd)) {  		err = PTR_ERR(mtd); -		printk(PRINT_PREF "error: cannot get MTD device\n"); +		pr_err("error: cannot get MTD device\n");  		return err;  	}  	if (mtd->type != MTD_NANDFLASH) { -		printk(PRINT_PREF "this test requires NAND flash\n"); +		pr_info("this test requires NAND flash\n");  		goto out;  	} @@ -402,7 +402,7 @@ static int __init mtd_subpagetest_init(void)  	ebcnt = tmp;  	pgcnt = mtd->erasesize / mtd->writesize; -	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " +	pr_info("MTD device size %llu, eraseblock size %u, "  	       "page size %u, subpage size %u, count of eraseblocks %u, "  	       "pages per eraseblock %u, OOB size %u\n",  	       (unsigned long long)mtd->size, mtd->erasesize, @@ -412,12 +412,12 @@ static int __init mtd_subpagetest_init(void)  	bufsize = subpgsize * 32;  	writebuf = kmalloc(bufsize, GFP_KERNEL);  	if (!writebuf) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_info("error: cannot allocate memory\n");  		goto out;  	}  	readbuf = kmalloc(bufsize, GFP_KERNEL);  	if (!readbuf) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_info("error: cannot allocate memory\n");  		goto out;  	} @@ -429,7 +429,7 @@ static int __init mtd_subpagetest_init(void)  	if (err)  		goto out; -	printk(PRINT_PREF "writing whole device\n"); +	pr_info("writing whole device\n");  	simple_srand(1);  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i]) @@ -438,13 +438,13 @@ static int __init mtd_subpagetest_init(void)  		if (unlikely(err))  			goto out;  		if (i % 256 == 0) -			printk(PRINT_PREF "written up to eraseblock %u\n", i); +			pr_info("written up to eraseblock %u\n", i);  		cond_resched();  	} -	printk(PRINT_PREF "written %u eraseblocks\n", i); +	pr_info("written %u eraseblocks\n", i);  	simple_srand(1); -	printk(PRINT_PREF "verifying all eraseblocks\n"); +	pr_info("verifying all eraseblocks\n");  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i])  			continue; @@ -452,10 +452,10 @@ static int __init mtd_subpagetest_init(void)  		if (unlikely(err))  			goto out;  		if (i % 256 == 0) -			printk(PRINT_PREF "verified up to eraseblock %u\n", i); +			pr_info("verified up to eraseblock %u\n", i);  		cond_resched();  	} -	printk(PRINT_PREF "verified %u eraseblocks\n", i); +	pr_info("verified %u eraseblocks\n", i);  	err = erase_whole_device();  	if (err) @@ -467,7 +467,7 @@ static int __init mtd_subpagetest_init(void)  	/* Write all eraseblocks */  	simple_srand(3); -	printk(PRINT_PREF "writing whole device\n"); +	pr_info("writing whole device\n");  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i])  			continue; @@ -475,14 +475,14 @@ static int __init mtd_subpagetest_init(void)  		if (unlikely(err))  			goto out;  		if (i % 256 == 0) -			printk(PRINT_PREF "written up to eraseblock %u\n", i); +			pr_info("written up to eraseblock %u\n", i);  		cond_resched();  	} -	printk(PRINT_PREF "written %u eraseblocks\n", i); +	pr_info("written %u eraseblocks\n", i);  	/* Check all eraseblocks */  	simple_srand(3); -	printk(PRINT_PREF "verifying all eraseblocks\n"); +	pr_info("verifying all eraseblocks\n");  	for (i = 0; i < ebcnt; ++i) {  		if (bbt[i])  			continue; @@ -490,10 +490,10 @@ static int __init mtd_subpagetest_init(void)  		if (unlikely(err))  			goto out;  		if (i % 256 == 0) -			printk(PRINT_PREF "verified up to eraseblock %u\n", i); +			pr_info("verified up to eraseblock %u\n", i);  		cond_resched();  	} -	printk(PRINT_PREF "verified %u eraseblocks\n", i); +	pr_info("verified %u eraseblocks\n", i);  	err = erase_whole_device();  	if (err) @@ -503,7 +503,7 @@ static int __init mtd_subpagetest_init(void)  	if (err)  		goto out; -	printk(PRINT_PREF "finished with %d errors\n", errcnt); +	pr_info("finished with %d errors\n", errcnt);  out:  	kfree(bbt); @@ -511,7 +511,7 @@ out:  	kfree(writebuf);  	put_mtd_device(mtd);  	if (err) -		printk(PRINT_PREF "error %d occurred\n", err); +		pr_info("error %d occurred\n", err);  	printk(KERN_INFO "=================================================\n");  	return err;  } diff --git a/drivers/mtd/tests/mtd_torturetest.c b/drivers/mtd/tests/mtd_torturetest.c index b65861bc7b8..c4cde1e9edd 100644 --- a/drivers/mtd/tests/mtd_torturetest.c +++ b/drivers/mtd/tests/mtd_torturetest.c @@ -23,6 +23,8 @@   * damage caused by this program.   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/init.h>  #include <linux/module.h>  #include <linux/moduleparam.h> @@ -31,7 +33,6 @@  #include <linux/slab.h>  #include <linux/sched.h> -#define PRINT_PREF KERN_INFO "mtd_torturetest: "  #define RETRIES 3  static int eb = 8; @@ -107,12 +108,12 @@ static inline int erase_eraseblock(int ebnum)  	err = mtd_erase(mtd, &ei);  	if (err) { -		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); +		pr_err("error %d while erasing EB %d\n", err, ebnum);  		return err;  	}  	if (ei.state == MTD_ERASE_FAILED) { -		printk(PRINT_PREF "some erase error occurred at EB %d\n", +		pr_err("some erase error occurred at EB %d\n",  		       ebnum);  		return -EIO;  	} @@ -139,40 +140,40 @@ static inline int check_eraseblock(int ebnum, unsigned char *buf)  retry:  	err = mtd_read(mtd, addr, len, &read, check_buf);  	if (mtd_is_bitflip(err)) -		printk(PRINT_PREF "single bit flip occurred at EB %d " +		pr_err("single bit flip occurred at EB %d "  		       "MTD reported that it was fixed.\n", ebnum);  	else if (err) { -		printk(PRINT_PREF "error %d while reading EB %d, " +		pr_err("error %d while reading EB %d, "  		       "read %zd\n", err, ebnum, read);  		return err;  	}  	if (read != len) { -		printk(PRINT_PREF "failed to read %zd bytes from EB %d, " +		pr_err("failed to read %zd bytes from EB %d, "  		       "read only %zd, but no error reported\n",  		       len, ebnum, read);  		return -EIO;  	}  	if (memcmp(buf, check_buf, len)) { -		printk(PRINT_PREF "read wrong data from EB %d\n", ebnum); +		pr_err("read wrong data from EB %d\n", ebnum);  		report_corrupt(check_buf, buf);  		if (retries++ < RETRIES) {  			/* Try read again */  			yield(); -			printk(PRINT_PREF "re-try reading data from EB %d\n", +			pr_info("re-try reading data from EB %d\n",  			       ebnum);  			goto retry;  		} else { -			printk(PRINT_PREF "retried %d times, still errors, " +			pr_info("retried %d times, still errors, "  			       "give-up\n", RETRIES);  			return -EINVAL;  		}  	}  	if (retries != 0) -		printk(PRINT_PREF "only attempt number %d was OK (!!!)\n", +		pr_info("only attempt number %d was OK (!!!)\n",  		       retries);  	return 0; @@ -191,12 +192,12 @@ static inline int write_pattern(int ebnum, void *buf)  	}  	err = mtd_write(mtd, addr, len, &written, buf);  	if (err) { -		printk(PRINT_PREF "error %d while writing EB %d, written %zd" +		pr_err("error %d while writing EB %d, written %zd"  		      " bytes\n", err, ebnum, written);  		return err;  	}  	if (written != len) { -		printk(PRINT_PREF "written only %zd bytes of %zd, but no error" +		pr_info("written only %zd bytes of %zd, but no error"  		       " reported\n", written, len);  		return -EIO;  	} @@ -211,64 +212,64 @@ static int __init tort_init(void)  	printk(KERN_INFO "\n");  	printk(KERN_INFO "=================================================\n"); -	printk(PRINT_PREF "Warning: this program is trying to wear out your " +	pr_info("Warning: this program is trying to wear out your "  	       "flash, stop it if this is not wanted.\n");  	if (dev < 0) { -		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); -		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); +		pr_info("Please specify a valid mtd-device via module parameter\n"); +		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");  		return -EINVAL;  	} -	printk(PRINT_PREF "MTD device: %d\n", dev); -	printk(PRINT_PREF "torture %d eraseblocks (%d-%d) of mtd%d\n", +	pr_info("MTD device: %d\n", dev); +	pr_info("torture %d eraseblocks (%d-%d) of mtd%d\n",  	       ebcnt, eb, eb + ebcnt - 1, dev);  	if (pgcnt) -		printk(PRINT_PREF "torturing just %d pages per eraseblock\n", +		pr_info("torturing just %d pages per eraseblock\n",  			pgcnt); -	printk(PRINT_PREF "write verify %s\n", check ? "enabled" : "disabled"); +	pr_info("write verify %s\n", check ? "enabled" : "disabled");  	mtd = get_mtd_device(NULL, dev);  	if (IS_ERR(mtd)) {  		err = PTR_ERR(mtd); -		printk(PRINT_PREF "error: cannot get MTD device\n"); +		pr_err("error: cannot get MTD device\n");  		return err;  	}  	if (mtd->writesize == 1) { -		printk(PRINT_PREF "not NAND flash, assume page size is 512 " +		pr_info("not NAND flash, assume page size is 512 "  		       "bytes.\n");  		pgsize = 512;  	} else  		pgsize = mtd->writesize;  	if (pgcnt && (pgcnt > mtd->erasesize / pgsize || pgcnt < 0)) { -		printk(PRINT_PREF "error: invalid pgcnt value %d\n", pgcnt); +		pr_err("error: invalid pgcnt value %d\n", pgcnt);  		goto out_mtd;  	}  	err = -ENOMEM;  	patt_5A5 = kmalloc(mtd->erasesize, GFP_KERNEL);  	if (!patt_5A5) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		goto out_mtd;  	}  	patt_A5A = kmalloc(mtd->erasesize, GFP_KERNEL);  	if (!patt_A5A) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		goto out_patt_5A5;  	}  	patt_FF = kmalloc(mtd->erasesize, GFP_KERNEL);  	if (!patt_FF) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		goto out_patt_A5A;  	}  	check_buf = kmalloc(mtd->erasesize, GFP_KERNEL);  	if (!check_buf) { -		printk(PRINT_PREF "error: cannot allocate memory\n"); +		pr_err("error: cannot allocate memory\n");  		goto out_patt_FF;  	} @@ -295,13 +296,13 @@ static int __init tort_init(void)  			err = mtd_block_isbad(mtd, (loff_t)i * mtd->erasesize);  			if (err < 0) { -				printk(PRINT_PREF "block_isbad() returned %d " +				pr_info("block_isbad() returned %d "  				       "for EB %d\n", err, i);  				goto out;  			}  			if (err) { -				printk("EB %d is bad. Skip it.\n", i); +				pr_err("EB %d is bad. Skip it.\n", i);  				bad_ebs[i - eb] = 1;  			}  		} @@ -329,7 +330,7 @@ static int __init tort_init(void)  					continue;  				err = check_eraseblock(i, patt_FF);  				if (err) { -					printk(PRINT_PREF "verify failed" +					pr_info("verify failed"  					       " for 0xFF... pattern\n");  					goto out;  				} @@ -362,7 +363,7 @@ static int __init tort_init(void)  					patt = patt_A5A;  				err = check_eraseblock(i, patt);  				if (err) { -					printk(PRINT_PREF "verify failed for %s" +					pr_info("verify failed for %s"  					       " pattern\n",  					       ((eb + erase_cycles) & 1) ?  					       "0x55AA55..." : "0xAA55AA..."); @@ -380,7 +381,7 @@ static int __init tort_init(void)  			stop_timing();  			ms = (finish.tv_sec - start.tv_sec) * 1000 +  			     (finish.tv_usec - start.tv_usec) / 1000; -			printk(PRINT_PREF "%08u erase cycles done, took %lu " +			pr_info("%08u erase cycles done, took %lu "  			       "milliseconds (%lu seconds)\n",  			       erase_cycles, ms, ms / 1000);  			start_timing(); @@ -391,7 +392,7 @@ static int __init tort_init(void)  	}  out: -	printk(PRINT_PREF "finished after %u erase cycles\n", +	pr_info("finished after %u erase cycles\n",  	       erase_cycles);  	kfree(check_buf);  out_patt_FF: @@ -403,7 +404,7 @@ out_patt_5A5:  out_mtd:  	put_mtd_device(mtd);  	if (err) -		printk(PRINT_PREF "error %d occurred during torturing\n", err); +		pr_info("error %d occurred during torturing\n", err);  	printk(KERN_INFO "=================================================\n");  	return err;  } @@ -441,9 +442,9 @@ static void report_corrupt(unsigned char *read, unsigned char *written)  			       &bits) >= 0)  			pages++; -	printk(PRINT_PREF "verify fails on %d pages, %d bytes/%d bits\n", +	pr_info("verify fails on %d pages, %d bytes/%d bits\n",  	       pages, bytes, bits); -	printk(PRINT_PREF "The following is a list of all differences between" +	pr_info("The following is a list of all differences between"  	       " what was read from flash and what was expected\n");  	for (i = 0; i < check_len; i += pgsize) { @@ -457,7 +458,7 @@ static void report_corrupt(unsigned char *read, unsigned char *written)  		printk("-------------------------------------------------------"  		       "----------------------------------\n"); -		printk(PRINT_PREF "Page %zd has %d bytes/%d bits failing verify," +		pr_info("Page %zd has %d bytes/%d bits failing verify,"  		       " starting at offset 0x%x\n",  		       (mtd->erasesize - check_len + i) / pgsize,  		       bytes, bits, first);  |