@ -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 ;