diff options
| author | Wu, Josh <Josh.wu@atmel.com> | 2013-07-03 11:11:48 +0800 | 
|---|---|---|
| committer | Andreas Bießmann <andreas.devel@googlemail.com> | 2013-08-22 16:50:44 +0200 | 
| commit | ddd85974b1685f51e1f2cbf690136fb2e1a2bf16 (patch) | |
| tree | c0571740ddb7884d642b3de7d12bfb6827009e34 | |
| parent | 2f96b06be5838bcb5e2ee7cbeba4fe59edfd29b0 (diff) | |
| download | olio-uboot-2014.01-ddd85974b1685f51e1f2cbf690136fb2e1a2bf16.tar.xz olio-uboot-2014.01-ddd85974b1685f51e1f2cbf690136fb2e1a2bf16.zip | |
mtd: atmel_nand: alloc memory instead of use static array for pmecc data
In this way, the pmecc corraction capbility can change in run time.
Signed-off-by: Josh Wu <josh.wu@atmel.com>
Acked-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Andreas Bießmann <andreas.devel@googlemail.com>
| -rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 63 | 
1 files changed, 56 insertions, 7 deletions
| diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 304491bcb..15fb4fb38 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -16,6 +16,7 @@  #include <asm/arch/gpio.h>  #include <asm/arch/at91_pio.h> +#include <malloc.h>  #include <nand.h>  #include <watchdog.h> @@ -50,13 +51,13 @@ struct atmel_nand_host {  	void __iomem	*pmecc_index_of;  	/* data for pmecc computation */ -	int16_t	pmecc_smu[(CONFIG_PMECC_CAP + 2) * (2 * CONFIG_PMECC_CAP + 1)]; -	int16_t	pmecc_partial_syn[2 * CONFIG_PMECC_CAP + 1]; -	int16_t	pmecc_si[2 * CONFIG_PMECC_CAP + 1]; -	int16_t	pmecc_lmu[CONFIG_PMECC_CAP + 1]; /* polynomal order */ -	int	pmecc_mu[CONFIG_PMECC_CAP + 1]; -	int	pmecc_dmu[CONFIG_PMECC_CAP + 1]; -	int	pmecc_delta[CONFIG_PMECC_CAP + 1]; +	int16_t	*pmecc_smu; +	int16_t	*pmecc_partial_syn; +	int16_t	*pmecc_si; +	int16_t	*pmecc_lmu; /* polynomal order */ +	int	*pmecc_mu; +	int	*pmecc_dmu; +	int	*pmecc_delta;  };  static struct atmel_nand_host pmecc_host; @@ -109,6 +110,48 @@ static void __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)  			table_size * sizeof(int16_t);  } +static void pmecc_data_free(struct atmel_nand_host *host) +{ +	free(host->pmecc_partial_syn); +	free(host->pmecc_si); +	free(host->pmecc_lmu); +	free(host->pmecc_smu); +	free(host->pmecc_mu); +	free(host->pmecc_dmu); +	free(host->pmecc_delta); +} + +static int pmecc_data_alloc(struct atmel_nand_host *host) +{ +	const int cap = host->pmecc_corr_cap; +	int size; + +	size = (2 * cap + 1) * sizeof(int16_t); +	host->pmecc_partial_syn = malloc(size); +	host->pmecc_si = malloc(size); +	host->pmecc_lmu = malloc((cap + 1) * sizeof(int16_t)); +	host->pmecc_smu = malloc((cap + 2) * size); + +	size = (cap + 1) * sizeof(int); +	host->pmecc_mu = malloc(size); +	host->pmecc_dmu = malloc(size); +	host->pmecc_delta = malloc(size); + +	if (host->pmecc_partial_syn && +			host->pmecc_si && +			host->pmecc_lmu && +			host->pmecc_smu && +			host->pmecc_mu && +			host->pmecc_dmu && +			host->pmecc_delta) +		return 0; + +	/* error happened */ +	pmecc_data_free(host); +	return -ENOMEM; + +} +  static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector)  {  	struct nand_chip *nand_chip = mtd->priv; @@ -694,6 +737,12 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,  		return 0;  	} +	/* Allocate data for PMECC computation */ +	if (pmecc_data_alloc(host)) { +		dev_err(host->dev, "Cannot allocate memory for PMECC computation!\n"); +		return -ENOMEM; +	} +  	nand->ecc.read_page = atmel_nand_pmecc_read_page;  	nand->ecc.write_page = atmel_nand_pmecc_write_page;  	nand->ecc.strength = cap; |