diff options
Diffstat (limited to 'drivers/mtd/nand/denali.c')
| -rw-r--r-- | drivers/mtd/nand/denali.c | 490 | 
1 files changed, 185 insertions, 305 deletions
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 8c8d3c86c0e..9f2012a3e76 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -16,13 +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> @@ -44,16 +43,16 @@ MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting."  /* We define a macro here that combines all interrupts this driver uses into   * a single constant value, for convenience. */ -#define DENALI_IRQ_ALL	(INTR_STATUS0__DMA_CMD_COMP | \ -			INTR_STATUS0__ECC_TRANSACTION_DONE | \ -			INTR_STATUS0__ECC_ERR | \ -			INTR_STATUS0__PROGRAM_FAIL | \ -			INTR_STATUS0__LOAD_COMP | \ -			INTR_STATUS0__PROGRAM_COMP | \ -			INTR_STATUS0__TIME_OUT | \ -			INTR_STATUS0__ERASE_FAIL | \ -			INTR_STATUS0__RST_COMP | \ -			INTR_STATUS0__ERASE_COMP) +#define DENALI_IRQ_ALL	(INTR_STATUS__DMA_CMD_COMP | \ +			INTR_STATUS__ECC_TRANSACTION_DONE | \ +			INTR_STATUS__ECC_ERR | \ +			INTR_STATUS__PROGRAM_FAIL | \ +			INTR_STATUS__LOAD_COMP | \ +			INTR_STATUS__PROGRAM_COMP | \ +			INTR_STATUS__TIME_OUT | \ +			INTR_STATUS__ERASE_FAIL | \ +			INTR_STATUS__RST_COMP | \ +			INTR_STATUS__ERASE_COMP)  /* indicates whether or not the internal value for the flash bank is   * valid or not */ @@ -88,37 +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 */ } -}; - - -/* these are static lookup tables that give us easy access to - * registers in the NAND controller. - */ -static const uint32_t intr_status_addresses[4] = {INTR_STATUS0, -						  INTR_STATUS1, -						  INTR_STATUS2, -						  INTR_STATUS3}; - -static const uint32_t device_reset_banks[4] = {DEVICE_RESET__BANK0, -							DEVICE_RESET__BANK1, -							DEVICE_RESET__BANK2, -							DEVICE_RESET__BANK3}; - -static const uint32_t operation_timeout[4] = {INTR_STATUS0__TIME_OUT, -							INTR_STATUS1__TIME_OUT, -							INTR_STATUS2__TIME_OUT, -							INTR_STATUS3__TIME_OUT}; - -static const uint32_t reset_complete[4] = {INTR_STATUS0__RST_COMP, -							INTR_STATUS1__RST_COMP, -							INTR_STATUS2__RST_COMP, -							INTR_STATUS3__RST_COMP}; -  /* forward declarations */  static void clear_interrupts(struct denali_nand_info *denali);  static uint32_t wait_for_irq(struct denali_nand_info *denali, @@ -157,7 +125,6 @@ static void reset_buf(struct denali_nand_info *denali)  static void write_byte_to_buf(struct denali_nand_info *denali, uint8_t byte)  { -	BUG_ON(denali->buf.tail >= sizeof(denali->buf.buf));  	denali->buf.buf[denali->buf.tail++] = byte;  } @@ -180,19 +147,17 @@ static void read_status(struct denali_nand_info *denali)  static void reset_bank(struct denali_nand_info *denali)  {  	uint32_t irq_status = 0; -	uint32_t irq_mask = reset_complete[denali->flash_bank] | -			    operation_timeout[denali->flash_bank]; -	int bank = 0; +	uint32_t irq_mask = INTR_STATUS__RST_COMP | +			    INTR_STATUS__TIME_OUT;  	clear_interrupts(denali); -	bank = device_reset_banks[denali->flash_bank]; -	iowrite32(bank, denali->flash_reg + DEVICE_RESET); +	iowrite32(1 << denali->flash_bank, denali->flash_reg + DEVICE_RESET);  	irq_status = wait_for_irq(denali, irq_mask); -	if (irq_status & operation_timeout[denali->flash_bank]) -		dev_err(&denali->dev->dev, "reset bank failed.\n"); +	if (irq_status & INTR_STATUS__TIME_OUT) +		dev_err(denali->dev, "reset bank failed.\n");  }  /* Reset the flash controller */ @@ -200,29 +165,28 @@ static uint16_t denali_nand_reset(struct denali_nand_info *denali)  {  	uint32_t i; -	dev_dbg(&denali->dev->dev, "%s, Line %d, Function: %s\n", +	dev_dbg(denali->dev, "%s, Line %d, Function: %s\n",  		       __FILE__, __LINE__, __func__); -	for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++) -		iowrite32(reset_complete[i] | operation_timeout[i], -		denali->flash_reg + intr_status_addresses[i]); +	for (i = 0 ; i < denali->max_banks; i++) +		iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT, +		denali->flash_reg + INTR_STATUS(i)); -	for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++) { -		iowrite32(device_reset_banks[i], -				denali->flash_reg + DEVICE_RESET); +	for (i = 0 ; i < denali->max_banks; i++) { +		iowrite32(1 << i, denali->flash_reg + DEVICE_RESET);  		while (!(ioread32(denali->flash_reg + -				intr_status_addresses[i]) & -			(reset_complete[i] | operation_timeout[i]))) +				INTR_STATUS(i)) & +			(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT)))  			cpu_relax(); -		if (ioread32(denali->flash_reg + intr_status_addresses[i]) & -			operation_timeout[i]) -			dev_dbg(&denali->dev->dev, +		if (ioread32(denali->flash_reg + INTR_STATUS(i)) & +			INTR_STATUS__TIME_OUT) +			dev_dbg(denali->dev,  			"NAND Reset operation timed out on bank %d\n", i);  	} -	for (i = 0; i < LLD_MAX_FLASH_BANKS; i++) -		iowrite32(reset_complete[i] | operation_timeout[i], -			denali->flash_reg + intr_status_addresses[i]); +	for (i = 0; i < denali->max_banks; i++) +		iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT, +			denali->flash_reg + INTR_STATUS(i));  	return PASS;  } @@ -254,7 +218,7 @@ static void nand_onfi_timing_set(struct denali_nand_info *denali,  	uint16_t acc_clks;  	uint16_t addr_2_data, re_2_we, re_2_re, we_2_re, cs_cnt; -	dev_dbg(&denali->dev->dev, "%s, Line %d, Function: %s\n", +	dev_dbg(denali->dev, "%s, Line %d, Function: %s\n",  		       __FILE__, __LINE__, __func__);  	en_lo = CEIL_DIV(Trp[mode], CLK_X); @@ -291,7 +255,7 @@ static void nand_onfi_timing_set(struct denali_nand_info *denali,  		acc_clks++;  	if ((data_invalid - acc_clks * CLK_X) < 2) -		dev_warn(&denali->dev->dev, "%s, Line %d: Warning!\n", +		dev_warn(denali->dev, "%s, Line %d: Warning!\n",  			__FILE__, __LINE__);  	addr_2_data = CEIL_DIV(Tadl[mode], CLK_X); @@ -419,7 +383,7 @@ static void get_hynix_nand_para(struct denali_nand_info *denali,  #endif  		break;  	default: -		dev_warn(&denali->dev->dev, +		dev_warn(denali->dev,  			"Spectra: Unknown Hynix NAND (Device ID: 0x%x)."  			"Will use default parameter values instead.\n",  			device_id); @@ -431,17 +395,17 @@ static void get_hynix_nand_para(struct denali_nand_info *denali,   */  static void find_valid_banks(struct denali_nand_info *denali)  { -	uint32_t id[LLD_MAX_FLASH_BANKS]; +	uint32_t id[denali->max_banks];  	int i;  	denali->total_used_banks = 1; -	for (i = 0; i < LLD_MAX_FLASH_BANKS; i++) { +	for (i = 0; i < denali->max_banks; i++) {  		index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 0), 0x90);  		index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 1), 0);  		index_addr_read_data(denali,  				(uint32_t)(MODE_11 | (i << 24) | 2), &id[i]); -		dev_dbg(&denali->dev->dev, +		dev_dbg(denali->dev,  			"Return 1st ID for bank[%d]: %x\n", i, id[i]);  		if (i == 0) { @@ -461,16 +425,27 @@ static void find_valid_banks(struct denali_nand_info *denali)  		 * Multichip support is not enabled.  		 */  		if (denali->total_used_banks != 1) { -			dev_err(&denali->dev->dev, +			dev_err(denali->dev,  					"Sorry, Intel CE4100 only supports "  					"a single NAND device.\n");  			BUG();  		}  	} -	dev_dbg(&denali->dev->dev, +	dev_dbg(denali->dev,  		"denali->total_used_banks: %d\n", denali->total_used_banks);  } +/* + * Use the configuration feature register to determine the maximum number of + * banks that the hardware supports. + */ +static void detect_max_banks(struct denali_nand_info *denali) +{ +	uint32_t features = ioread32(denali->flash_reg + FEATURES); + +	denali->max_banks = 2 << (features & FEATURES__N_BANKS); +} +  static void detect_partition_feature(struct denali_nand_info *denali)  {  	/* For MRST platform, denali->fwblks represent the @@ -480,15 +455,15 @@ static void detect_partition_feature(struct denali_nand_info *denali)  	 * blocks it can't touch.  	 * */  	if (ioread32(denali->flash_reg + FEATURES) & FEATURES__PARTITION) { -		if ((ioread32(denali->flash_reg + PERM_SRC_ID_1) & -			PERM_SRC_ID_1__SRCID) == SPECTRA_PARTITION_ID) { +		if ((ioread32(denali->flash_reg + PERM_SRC_ID(1)) & +			PERM_SRC_ID__SRCID) == SPECTRA_PARTITION_ID) {  			denali->fwblks = -			    ((ioread32(denali->flash_reg + MIN_MAX_BANK_1) & -			      MIN_MAX_BANK_1__MIN_VALUE) * +			    ((ioread32(denali->flash_reg + MIN_MAX_BANK(1)) & +			      MIN_MAX_BANK__MIN_VALUE) *  			     denali->blksperchip)  			    + -			    (ioread32(denali->flash_reg + MIN_BLK_ADDR_1) & -			    MIN_BLK_ADDR_1__VALUE); +			    (ioread32(denali->flash_reg + MIN_BLK_ADDR(1)) & +			    MIN_BLK_ADDR__VALUE);  		} else  			denali->fwblks = SPECTRA_START_BLOCK;  	} else @@ -501,7 +476,7 @@ static uint16_t denali_nand_timing_set(struct denali_nand_info *denali)  	uint32_t id_bytes[5], addr;  	uint8_t i, maf_id, device_id; -	dev_dbg(&denali->dev->dev, +	dev_dbg(denali->dev,  			"%s, Line %d, Function: %s\n",  			__FILE__, __LINE__, __func__); @@ -530,7 +505,7 @@ static uint16_t denali_nand_timing_set(struct denali_nand_info *denali)  		get_hynix_nand_para(denali, device_id);  	} -	dev_info(&denali->dev->dev, +	dev_info(denali->dev,  			"Dump timing register values:"  			"acc_clks: %d, re_2_we: %d, re_2_re: %d\n"  			"we_2_re: %d, addr_2_data: %d, rdwr_en_lo_cnt: %d\n" @@ -560,7 +535,7 @@ static uint16_t denali_nand_timing_set(struct denali_nand_info *denali)  static void denali_set_intr_modes(struct denali_nand_info *denali,  					uint16_t INT_ENABLE)  { -	dev_dbg(&denali->dev->dev, "%s, Line %d, Function: %s\n", +	dev_dbg(denali->dev, "%s, Line %d, Function: %s\n",  		       __FILE__, __LINE__, __func__);  	if (INT_ENABLE) @@ -580,6 +555,7 @@ static inline bool is_flash_bank_valid(int flash_bank)  static void denali_irq_init(struct denali_nand_info *denali)  {  	uint32_t int_mask = 0; +	int i;  	/* Disable global interrupts */  	denali_set_intr_modes(denali, false); @@ -587,10 +563,8 @@ static void denali_irq_init(struct denali_nand_info *denali)  	int_mask = DENALI_IRQ_ALL;  	/* Clear all status bits */ -	iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS0); -	iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS1); -	iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS2); -	iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS3); +	for (i = 0; i < denali->max_banks; ++i) +		iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS(i));  	denali_irq_enable(denali, int_mask);  } @@ -604,10 +578,10 @@ static void denali_irq_cleanup(int irqnum, struct denali_nand_info *denali)  static void denali_irq_enable(struct denali_nand_info *denali,  							uint32_t int_mask)  { -	iowrite32(int_mask, denali->flash_reg + INTR_EN0); -	iowrite32(int_mask, denali->flash_reg + INTR_EN1); -	iowrite32(int_mask, denali->flash_reg + INTR_EN2); -	iowrite32(int_mask, denali->flash_reg + INTR_EN3); +	int i; + +	for (i = 0; i < denali->max_banks; ++i) +		iowrite32(int_mask, denali->flash_reg + INTR_EN(i));  }  /* This function only returns when an interrupt that this driver cares about @@ -624,7 +598,7 @@ static inline void clear_interrupt(struct denali_nand_info *denali,  {  	uint32_t intr_status_reg = 0; -	intr_status_reg = intr_status_addresses[denali->flash_bank]; +	intr_status_reg = INTR_STATUS(denali->flash_bank);  	iowrite32(irq_mask, denali->flash_reg + intr_status_reg);  } @@ -645,7 +619,7 @@ static uint32_t read_interrupt_status(struct denali_nand_info *denali)  {  	uint32_t intr_status_reg = 0; -	intr_status_reg = intr_status_addresses[denali->flash_bank]; +	intr_status_reg = INTR_STATUS(denali->flash_bank);  	return ioread32(denali->flash_reg + intr_status_reg);  } @@ -715,7 +689,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; @@ -724,7 +698,7 @@ static uint32_t wait_for_irq(struct denali_nand_info *denali, uint32_t irq_mask)  }  /* This helper function setups the registers for ECC and whether or not - * the spare area will be transfered. */ + * the spare area will be transferred. */  static void setup_ecc_for_xfer(struct denali_nand_info *denali, bool ecc_en,  				bool transfer_spare)  { @@ -754,7 +728,7 @@ static int denali_send_pipeline_cmd(struct denali_nand_info *denali,  		 irq_mask = 0;  	if (op == DENALI_READ) -		irq_mask = INTR_STATUS0__LOAD_COMP; +		irq_mask = INTR_STATUS__LOAD_COMP;  	else if (op == DENALI_WRITE)  		irq_mask = 0;  	else @@ -800,7 +774,7 @@ static int denali_send_pipeline_cmd(struct denali_nand_info *denali,  			irq_status = wait_for_irq(denali, irq_mask);  			if (irq_status == 0) { -				dev_err(&denali->dev->dev, +				dev_err(denali->dev,  						"cmd, page, addr on timeout "  						"(0x%x, 0x%x, 0x%x)\n",  						cmd, denali->page, addr); @@ -861,8 +835,8 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t *buf, int page)  {  	struct denali_nand_info *denali = mtd_to_denali(mtd);  	uint32_t irq_status = 0; -	uint32_t irq_mask = INTR_STATUS0__PROGRAM_COMP | -						INTR_STATUS0__PROGRAM_FAIL; +	uint32_t irq_mask = INTR_STATUS__PROGRAM_COMP | +						INTR_STATUS__PROGRAM_FAIL;  	int status = 0;  	denali->page = page; @@ -875,11 +849,11 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t *buf, int page)  		irq_status = wait_for_irq(denali, irq_mask);  		if (irq_status == 0) { -			dev_err(&denali->dev->dev, "OOB write failed\n"); +			dev_err(denali->dev, "OOB write failed\n");  			status = -EIO;  		}  	} else { -		dev_err(&denali->dev->dev, "unable to send pipeline command\n"); +		dev_err(denali->dev, "unable to send pipeline command\n");  		status = -EIO;  	}  	return status; @@ -889,7 +863,7 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t *buf, int page)  static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page)  {  	struct denali_nand_info *denali = mtd_to_denali(mtd); -	uint32_t irq_mask = INTR_STATUS0__LOAD_COMP, +	uint32_t irq_mask = INTR_STATUS__LOAD_COMP,  			 irq_status = 0, addr = 0x0, cmd = 0x0;  	denali->page = page; @@ -904,7 +878,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page)  		irq_status = wait_for_irq(denali, irq_mask);  		if (irq_status == 0) -			dev_err(&denali->dev->dev, "page on OOB timeout %d\n", +			dev_err(denali->dev, "page on OOB timeout %d\n",  					denali->page);  		/* We set the device back to MAIN_ACCESS here as I observed @@ -922,7 +896,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page)  /* this function examines buffers to see if they contain data that   * indicate that the buffer is part of an erased region of flash.   */ -bool is_erased(uint8_t *buf, int len) +static bool is_erased(uint8_t *buf, int len)  {  	int i = 0;  	for (i = 0; i < len; i++) @@ -940,11 +914,12 @@ bool is_erased(uint8_t *buf, int len)  #define ECC_LAST_ERR(x)		((x) & ERR_CORRECTION_INFO__LAST_ERR_INFO)  static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, -					uint32_t irq_status) +		       uint32_t irq_status, unsigned int *max_bitflips)  {  	bool check_erased_page = false; +	unsigned int bitflips = 0; -	if (irq_status & INTR_STATUS0__ECC_ERR) { +	if (irq_status & INTR_STATUS__ECC_ERR) {  		/* read the ECC errors. we'll ignore them for now */  		uint32_t err_address = 0, err_correction_info = 0;  		uint32_t err_byte = 0, err_sector = 0, err_device = 0; @@ -965,7 +940,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,  			if (ECC_ERROR_CORRECTABLE(err_correction_info)) {  				/* If err_byte is larger than ECC_SECTOR_SIZE, -				 * means error happend in OOB, so we ignore +				 * means error happened in OOB, so we ignore  				 * it. It's no need for us to correct it  				 * err_device is represented the NAND error  				 * bits are happened in if there are more @@ -981,6 +956,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,  					/* correct the ECC error */  					buf[offset] ^= err_correction_value;  					denali->mtd.ecc_stats.corrected++; +					bitflips++;  				}  			} else {  				/* if the error is not correctable, need to @@ -995,11 +971,12 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,  		 * for a while for this interrupt  		 * */  		while (!(read_interrupt_status(denali) & -				INTR_STATUS0__ECC_TRANSACTION_DONE)) +				INTR_STATUS__ECC_TRANSACTION_DONE))  			cpu_relax();  		clear_interrupts(denali);  		denali_set_intr_modes(denali, true);  	} +	*max_bitflips = bitflips;  	return check_erased_page;  } @@ -1041,18 +1018,17 @@ static void denali_setup_dma(struct denali_nand_info *denali, int op)  /* writes a page. user specifies type, and this function handles the   * configuration details. */ -static void write_page(struct mtd_info *mtd, struct nand_chip *chip, +static int write_page(struct mtd_info *mtd, struct nand_chip *chip,  			const uint8_t *buf, bool raw_xfer)  {  	struct denali_nand_info *denali = mtd_to_denali(mtd); -	struct pci_dev *pci_dev = denali->dev;  	dma_addr_t addr = denali->buf.dma_buf;  	size_t size = denali->mtd.writesize + denali->mtd.oobsize;  	uint32_t irq_status = 0; -	uint32_t irq_mask = INTR_STATUS0__DMA_CMD_COMP | -						INTR_STATUS0__PROGRAM_FAIL; +	uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP | +						INTR_STATUS__PROGRAM_FAIL;  	/* if it is a raw xfer, we want to disable ecc, and send  	 * the spare area. @@ -1071,7 +1047,7 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip,  			mtd->oobsize);  	} -	pci_dma_sync_single_for_device(pci_dev, addr, size, PCI_DMA_TODEVICE); +	dma_sync_single_for_device(denali->dev, addr, size, DMA_TO_DEVICE);  	clear_interrupts(denali);  	denali_enable_dma(denali, true); @@ -1082,16 +1058,18 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip,  	irq_status = wait_for_irq(denali, irq_mask);  	if (irq_status == 0) { -		dev_err(&denali->dev->dev, +		dev_err(denali->dev,  				"timeout on write_page (type = %d)\n",  				raw_xfer);  		denali->status = -			(irq_status & INTR_STATUS0__PROGRAM_FAIL) ? +			(irq_status & INTR_STATUS__PROGRAM_FAIL) ?  			NAND_STATUS_FAIL : PASS;  	}  	denali_enable_dma(denali, false); -	pci_dma_sync_single_for_cpu(pci_dev, addr, size, PCI_DMA_TODEVICE); +	dma_sync_single_for_cpu(denali->dev, addr, size, DMA_TO_DEVICE); + +	return 0;  }  /* NAND core entry points */ @@ -1100,24 +1078,24 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip,   * writing a page with ECC or without is similar, all the work is done   * by write_page above.   * */ -static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip, -				const uint8_t *buf) +static int denali_write_page(struct mtd_info *mtd, struct nand_chip *chip, +				const uint8_t *buf, int oob_required)  {  	/* for regular page writes, we let HW handle all the ECC  	 * data written to the device. */ -	write_page(mtd, chip, buf, false); +	return write_page(mtd, chip, buf, false);  }  /* This is the callback that the NAND core calls to write a page without ECC. - * raw access is similiar to ECC page writes, so all the work is done in the + * raw access is similar to ECC page writes, so all the work is done in the   * write_page() function above.   */ -static void denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, -					const uint8_t *buf) +static int denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, +					const uint8_t *buf, int oob_required)  {  	/* for raw page writes, we want to disable ECC and simply write  	   whatever data is in the buffer. */ -	write_page(mtd, chip, buf, true); +	return write_page(mtd, chip, buf, true);  }  static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip, @@ -1127,30 +1105,29 @@ static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip,  }  static int denali_read_oob(struct mtd_info *mtd, struct nand_chip *chip, -			   int page, int sndcmd) +			   int page)  {  	read_oob_data(mtd, chip->oob_poi, page); -	return 0; /* notify NAND core to send command to -			   NAND device. */ +	return 0;  }  static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, -			    uint8_t *buf, int page) +			    uint8_t *buf, int oob_required, int page)  { +	unsigned int max_bitflips;  	struct denali_nand_info *denali = mtd_to_denali(mtd); -	struct pci_dev *pci_dev = denali->dev;  	dma_addr_t addr = denali->buf.dma_buf;  	size_t size = denali->mtd.writesize + denali->mtd.oobsize;  	uint32_t irq_status = 0; -	uint32_t irq_mask = INTR_STATUS0__ECC_TRANSACTION_DONE | -			    INTR_STATUS0__ECC_ERR; +	uint32_t irq_mask = INTR_STATUS__ECC_TRANSACTION_DONE | +			    INTR_STATUS__ECC_ERR;  	bool check_erased_page = false;  	if (page != denali->page) { -		dev_err(&denali->dev->dev, "IN %s: page %d is not" +		dev_err(denali->dev, "IN %s: page %d is not"  				" equal to denali->page %d, investigate!!",  				__func__, page, denali->page);  		BUG(); @@ -1159,7 +1136,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,  	setup_ecc_for_xfer(denali, true, false);  	denali_enable_dma(denali, true); -	pci_dma_sync_single_for_device(pci_dev, addr, size, PCI_DMA_FROMDEVICE); +	dma_sync_single_for_device(denali->dev, addr, size, DMA_FROM_DEVICE);  	clear_interrupts(denali);  	denali_setup_dma(denali, DENALI_READ); @@ -1167,11 +1144,11 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,  	/* wait for operation to complete */  	irq_status = wait_for_irq(denali, irq_mask); -	pci_dma_sync_single_for_cpu(pci_dev, addr, size, PCI_DMA_FROMDEVICE); +	dma_sync_single_for_cpu(denali->dev, addr, size, DMA_FROM_DEVICE);  	memcpy(buf, denali->buf.buf, mtd->writesize); -	check_erased_page = handle_ecc(denali, buf, irq_status); +	check_erased_page = handle_ecc(denali, buf, irq_status, &max_bitflips);  	denali_enable_dma(denali, false);  	if (check_erased_page) { @@ -1185,23 +1162,22 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,  				denali->mtd.ecc_stats.failed++;  		}  	} -	return 0; +	return max_bitflips;  }  static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, -				uint8_t *buf, int page) +				uint8_t *buf, int oob_required, int page)  {  	struct denali_nand_info *denali = mtd_to_denali(mtd); -	struct pci_dev *pci_dev = denali->dev;  	dma_addr_t addr = denali->buf.dma_buf;  	size_t size = denali->mtd.writesize + denali->mtd.oobsize;  	uint32_t irq_status = 0; -	uint32_t irq_mask = INTR_STATUS0__DMA_CMD_COMP; +	uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP;  	if (page != denali->page) { -		dev_err(&denali->dev->dev, "IN %s: page %d is not" +		dev_err(denali->dev, "IN %s: page %d is not"  				" equal to denali->page %d, investigate!!",  				__func__, page, denali->page);  		BUG(); @@ -1210,7 +1186,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,  	setup_ecc_for_xfer(denali, false, true);  	denali_enable_dma(denali, true); -	pci_dma_sync_single_for_device(pci_dev, addr, size, PCI_DMA_FROMDEVICE); +	dma_sync_single_for_device(denali->dev, addr, size, DMA_FROM_DEVICE);  	clear_interrupts(denali);  	denali_setup_dma(denali, DENALI_READ); @@ -1218,7 +1194,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,  	/* wait for operation to complete */  	irq_status = wait_for_irq(denali, irq_mask); -	pci_dma_sync_single_for_cpu(pci_dev, addr, size, PCI_DMA_FROMDEVICE); +	dma_sync_single_for_cpu(denali->dev, addr, size, DMA_FROM_DEVICE);  	denali_enable_dma(denali, false); @@ -1257,7 +1233,7 @@ static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)  	return status;  } -static void denali_erase(struct mtd_info *mtd, int page) +static int denali_erase(struct mtd_info *mtd, int page)  {  	struct denali_nand_info *denali = mtd_to_denali(mtd); @@ -1271,11 +1247,10 @@ static void denali_erase(struct mtd_info *mtd, int page)  	index_addr(denali, (uint32_t)cmd, 0x1);  	/* wait for erase to complete or failure to occur */ -	irq_status = wait_for_irq(denali, INTR_STATUS0__ERASE_COMP | -					INTR_STATUS0__ERASE_FAIL); +	irq_status = wait_for_irq(denali, INTR_STATUS__ERASE_COMP | +					INTR_STATUS__ERASE_FAIL); -	denali->status = (irq_status & INTR_STATUS0__ERASE_FAIL) ? -						NAND_STATUS_FAIL : PASS; +	return (irq_status & INTR_STATUS__ERASE_FAIL) ? NAND_STATUS_FAIL : PASS;  }  static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, @@ -1319,8 +1294,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;  	}  } @@ -1330,7 +1304,7 @@ static int denali_ecc_calculate(struct mtd_info *mtd, const uint8_t *data,  				uint8_t *ecc_code)  {  	struct denali_nand_info *denali = mtd_to_denali(mtd); -	dev_err(&denali->dev->dev, +	dev_err(denali->dev,  			"denali_ecc_calculate called unexpectedly\n");  	BUG();  	return -EIO; @@ -1340,7 +1314,7 @@ static int denali_ecc_correct(struct mtd_info *mtd, uint8_t *data,  				uint8_t *read_ecc, uint8_t *calc_ecc)  {  	struct denali_nand_info *denali = mtd_to_denali(mtd); -	dev_err(&denali->dev->dev, +	dev_err(denali->dev,  			"denali_ecc_correct called unexpectedly\n");  	BUG();  	return -EIO; @@ -1349,7 +1323,7 @@ static int denali_ecc_correct(struct mtd_info *mtd, uint8_t *data,  static void denali_ecc_hwctl(struct mtd_info *mtd, int mode)  {  	struct denali_nand_info *denali = mtd_to_denali(mtd); -	dev_err(&denali->dev->dev, +	dev_err(denali->dev,  			"denali_ecc_hwctl called unexpectedly\n");  	BUG();  } @@ -1365,6 +1339,7 @@ static void denali_hw_init(struct denali_nand_info *denali)  	 * */  	denali->bbtskipbytes = ioread32(denali->flash_reg +  						SPARE_AREA_SKIP_BYTES); +	detect_max_banks(denali);  	denali_nand_reset(denali);  	iowrite32(0x0F, denali->flash_reg + RB_PIN_ENABLED);  	iowrite32(CHIP_EN_DONT_CARE__FLAG, @@ -1417,7 +1392,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {  };  /* initialize driver data structures */ -void denali_drv_init(struct denali_nand_info *denali) +static void denali_drv_init(struct denali_nand_info *denali)  {  	denali->idx = 0; @@ -1438,109 +1413,40 @@ 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; +	int ret; -	denali = kzalloc(sizeof(*denali), GFP_KERNEL); -	if (!denali) -		return -ENOMEM; - -	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; +			pr_err("Intel CE4100 only supports ONFI timing mode 1 or below\n"); +			return -EINVAL;  		} -		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; -		} -	} - -	/* Is 32-bit DMA supported? */ -	ret = pci_set_dma_mask(dev, DMA_BIT_MASK(32)); - -	if (ret) { -		printk(KERN_ERR "Spectra: no usable DMA configuration\n"); -		goto failed_enable_dev; -	} -	denali->buf.dma_buf = -		pci_map_single(dev, denali->buf.buf, -						DENALI_BUF_SIZE, -						PCI_DMA_BIDIRECTIONAL); - -	if (pci_dma_mapping_error(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; -	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; -	} +	/* allocate a temporary buffer for nand_scan_ident() */ +	denali->buf.buf = devm_kzalloc(denali->dev, PAGE_SIZE, +					GFP_DMA | GFP_KERNEL); +	if (!denali->buf.buf) +		return -ENOMEM; +	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; @@ -1554,18 +1460,34 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	/* scan for NAND devices attached to the controller  	 * this is the first stage in a two step process to register  	 * with the nand subsystem */ -	if (nand_scan_ident(&denali->mtd, LLD_MAX_FLASH_BANKS, NULL)) { +	if (nand_scan_ident(&denali->mtd, denali->max_banks, NULL)) {  		ret = -ENXIO;  		goto failed_req_irq;  	} -	/* MTD supported page sizes vary by kernel. We validate our -	 * kernel supports the device here. -	 */ -	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."); +	/* allocate the right size buffer now */ +	devm_kfree(denali->dev, denali->buf.buf); +	denali->buf.buf = devm_kzalloc(denali->dev, +			     denali->mtd.writesize + denali->mtd.oobsize, +			     GFP_KERNEL); +	if (!denali->buf.buf) { +		ret = -ENOMEM; +		goto failed_req_irq; +	} + +	/* Is 32-bit DMA supported? */ +	ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32)); +	if (ret) { +		pr_err("Spectra: no usable DMA configuration\n"); +		goto failed_req_irq; +	} + +	denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf, +			     denali->mtd.writesize + denali->mtd.oobsize, +			     DMA_BIDIRECTIONAL); +	if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) { +		dev_err(denali->dev, "Spectra: failed to map DMA buffer\n"); +		ret = -EIO;  		goto failed_req_irq;  	} @@ -1597,34 +1519,38 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	denali->nand.bbt_md = &bbt_mirror_descr;  	/* skip the scan for now until we have OOB read and write support */ -	denali->nand.options |= NAND_USE_FLASH_BBT | NAND_SKIP_BBTSCAN; +	denali->nand.bbt_options |= NAND_BBT_USE_FLASH; +	denali->nand.options |= NAND_SKIP_BBTSCAN;  	denali->nand.ecc.mode = NAND_ECC_HW_SYNDROME;  	/* Denali Controller only support 15bit and 8bit ECC in MRST,  	 * so just let controller do 15bit ECC for MLC and 8bit ECC for  	 * SLC if possible.  	 * */ -	if (denali->nand.cellinfo & 0xc && +	if (!nand_is_slc(&denali->nand) &&  			(denali->mtd.oobsize > (denali->bbtskipbytes +  			ECC_15BITS * (denali->mtd.writesize /  			ECC_SECTOR_SIZE)))) {  		/* if MLC OOB size is large enough, use 15bit ECC*/ +		denali->nand.ecc.strength = 15;  		denali->nand.ecc.layout = &nand_15bit_oob;  		denali->nand.ecc.bytes = ECC_15BITS;  		iowrite32(15, denali->flash_reg + ECC_CORRECTION);  	} 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;  		denali->nand.ecc.layout = &nand_8bit_oob;  		denali->nand.ecc.bytes = ECC_8BITS;  		iowrite32(8, denali->flash_reg + ECC_CORRECTION);  	}  	denali->nand.ecc.bytes *= denali->devnum; +	denali->nand.ecc.strength *= denali->devnum;  	denali->nand.ecc.layout->eccbytes *=  		denali->mtd.writesize / ECC_SECTOR_SIZE;  	denali->nand.ecc.layout->oobfree[0].offset = @@ -1657,80 +1583,34 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	denali->nand.ecc.write_page_raw = denali_write_page_raw;  	denali->nand.ecc.read_oob = denali_read_oob;  	denali->nand.ecc.write_oob = denali_write_oob; -	denali->nand.erase_cmd = denali_erase; +	denali->nand.erase = denali_erase;  	if (nand_scan_tail(&denali->mtd)) {  		ret = -ENXIO;  		goto failed_req_irq;  	} -	ret = add_mtd_device(&denali->mtd); +	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: -	pci_unmap_single(dev, denali->buf.dma_buf, DENALI_BUF_SIZE, -							PCI_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); -	del_mtd_device(&denali->mtd); - -	denali_irq_cleanup(dev->irq, denali); - -	iounmap(denali->flash_reg); -	iounmap(denali->flash_mem); -	pci_release_regions(dev); -	pci_disable_device(dev); -	pci_unmap_single(dev, denali->buf.dma_buf, DENALI_BUF_SIZE, -							PCI_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->mtd.writesize + denali->mtd.oobsize, +			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, -}; - -static int __devinit denali_init(void) -{ -	printk(KERN_INFO "Spectra MTD driver built on %s @ %s\n", -			__DATE__, __TIME__); -	return pci_register_driver(&denali_pci_driver); -} - -/* Free memory */ -static void __devexit denali_exit(void) -{ -	pci_unregister_driver(&denali_pci_driver); -} - -module_init(denali_init); -module_exit(denali_exit); +EXPORT_SYMBOL(denali_remove);  | 
