From patchwork Mon Jun 17 10:51:20 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Wu X-Patchwork-Id: 251811 X-Patchwork-Delegate: andreas.biessmann@googlemail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id A9BDF2C0299 for ; Mon, 17 Jun 2013 20:54:05 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 311EC4A1B0; Mon, 17 Jun 2013 12:54:03 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ABJNxfj16pLK; Mon, 17 Jun 2013 12:54:02 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 5752B4A181; Mon, 17 Jun 2013 12:54:01 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 858254A18C for ; Mon, 17 Jun 2013 12:53:59 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id RWx2l7XYYQUc for ; Mon, 17 Jun 2013 12:53:58 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from DVREDG02.corp.atmel.com (nasmtp01.atmel.com [192.199.1.246]) by theia.denx.de (Postfix) with ESMTPS id DC6FE4A10C for ; Mon, 17 Jun 2013 12:53:55 +0200 (CEST) Received: from apsmtp01.atmel.com (10.168.254.30) by DVREDG02.corp.atmel.com (10.42.103.31) with Microsoft SMTP Server (TLS) id 14.2.342.3; Mon, 17 Jun 2013 04:53:52 -0600 Received: from shaarm01.corp.atmel.com (10.168.254.13) by apsmtp01.corp.atmel.com (10.168.254.30) with Microsoft SMTP Server id 14.2.342.3; Mon, 17 Jun 2013 18:54:30 +0800 From: Josh Wu To: Date: Mon, 17 Jun 2013 18:51:20 +0800 Message-ID: <1371466281-31922-5-git-send-email-josh.wu@atmel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1371466281-31922-1-git-send-email-josh.wu@atmel.com> References: <1371466281-31922-1-git-send-email-josh.wu@atmel.com> MIME-Version: 1.0 Cc: scottwood@freescale.com, u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 4/5] mtd: atmel_nand: alloc memory instead of use static array for pmecc data X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de In this way, the pmecc corraction capbility can change in run time. Signed-off-by: Josh Wu --- v1 --> v2: replace printk with dev_err. fix coding style. free memory before return ENOMEM. drivers/mtd/nand/atmel_nand.c | 63 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 139a479..3cd403f 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -66,13 +67,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; @@ -125,6 +126,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; @@ -710,6 +753,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(NULL, "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;