|
@@ -48,9 +48,9 @@
|
|
|
|
|
|
/* Register access macros */
|
|
|
#define ecc_readl(add, reg) \
|
|
|
- __raw_readl(add + AT91_ECC_##reg)
|
|
|
+ __raw_readl(add + ATMEL_ECC_##reg)
|
|
|
#define ecc_writel(add, reg, value) \
|
|
|
- __raw_writel((value), add + AT91_ECC_##reg)
|
|
|
+ __raw_writel((value), add + ATMEL_ECC_##reg)
|
|
|
|
|
|
#include "atmel_nand_ecc.h" /* Hardware ECC registers */
|
|
|
|
|
@@ -59,7 +59,7 @@
|
|
|
* the bytes have to be consecutives to avoid
|
|
|
* several NAND_CMD_RNDOUT during read
|
|
|
*/
|
|
|
-static struct nand_ecclayout at91_oobinfo_large = {
|
|
|
+static struct nand_ecclayout atmel_oobinfo_large = {
|
|
|
.eccbytes = 4,
|
|
|
.eccpos = {60, 61, 62, 63},
|
|
|
.oobfree = {
|
|
@@ -72,7 +72,7 @@ static struct nand_ecclayout at91_oobinfo_large = {
|
|
|
* the bytes have to be consecutives to avoid
|
|
|
* several NAND_CMD_RNDOUT during read
|
|
|
*/
|
|
|
-static struct nand_ecclayout at91_oobinfo_small = {
|
|
|
+static struct nand_ecclayout atmel_oobinfo_small = {
|
|
|
.eccbytes = 4,
|
|
|
.eccpos = {0, 1, 2, 3},
|
|
|
.oobfree = {
|
|
@@ -80,11 +80,11 @@ static struct nand_ecclayout at91_oobinfo_small = {
|
|
|
},
|
|
|
};
|
|
|
|
|
|
-struct at91_nand_host {
|
|
|
+struct atmel_nand_host {
|
|
|
struct nand_chip nand_chip;
|
|
|
struct mtd_info mtd;
|
|
|
void __iomem *io_base;
|
|
|
- struct at91_nand_data *board;
|
|
|
+ struct atmel_nand_data *board;
|
|
|
struct device *dev;
|
|
|
void __iomem *ecc;
|
|
|
};
|
|
@@ -92,7 +92,7 @@ struct at91_nand_host {
|
|
|
/*
|
|
|
* Enable NAND.
|
|
|
*/
|
|
|
-static void at91_nand_enable(struct at91_nand_host *host)
|
|
|
+static void atmel_nand_enable(struct atmel_nand_host *host)
|
|
|
{
|
|
|
if (host->board->enable_pin)
|
|
|
gpio_set_value(host->board->enable_pin, 0);
|
|
@@ -101,7 +101,7 @@ static void at91_nand_enable(struct at91_nand_host *host)
|
|
|
/*
|
|
|
* Disable NAND.
|
|
|
*/
|
|
|
-static void at91_nand_disable(struct at91_nand_host *host)
|
|
|
+static void atmel_nand_disable(struct atmel_nand_host *host)
|
|
|
{
|
|
|
if (host->board->enable_pin)
|
|
|
gpio_set_value(host->board->enable_pin, 1);
|
|
@@ -110,16 +110,16 @@ static void at91_nand_disable(struct at91_nand_host *host)
|
|
|
/*
|
|
|
* Hardware specific access to control-lines
|
|
|
*/
|
|
|
-static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
|
|
+static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
|
|
{
|
|
|
struct nand_chip *nand_chip = mtd->priv;
|
|
|
- struct at91_nand_host *host = nand_chip->priv;
|
|
|
+ struct atmel_nand_host *host = nand_chip->priv;
|
|
|
|
|
|
if (ctrl & NAND_CTRL_CHANGE) {
|
|
|
if (ctrl & NAND_NCE)
|
|
|
- at91_nand_enable(host);
|
|
|
+ atmel_nand_enable(host);
|
|
|
else
|
|
|
- at91_nand_disable(host);
|
|
|
+ atmel_nand_disable(host);
|
|
|
}
|
|
|
if (cmd == NAND_CMD_NONE)
|
|
|
return;
|
|
@@ -133,10 +133,10 @@ static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
|
|
/*
|
|
|
* Read the Device Ready pin.
|
|
|
*/
|
|
|
-static int at91_nand_device_ready(struct mtd_info *mtd)
|
|
|
+static int atmel_nand_device_ready(struct mtd_info *mtd)
|
|
|
{
|
|
|
struct nand_chip *nand_chip = mtd->priv;
|
|
|
- struct at91_nand_host *host = nand_chip->priv;
|
|
|
+ struct atmel_nand_host *host = nand_chip->priv;
|
|
|
|
|
|
return gpio_get_value(host->board->rdy_pin);
|
|
|
}
|
|
@@ -144,7 +144,7 @@ static int at91_nand_device_ready(struct mtd_info *mtd)
|
|
|
/*
|
|
|
* write oob for small pages
|
|
|
*/
|
|
|
-static int at91_nand_write_oob_512(struct mtd_info *mtd,
|
|
|
+static int atmel_nand_write_oob_512(struct mtd_info *mtd,
|
|
|
struct nand_chip *chip, int page)
|
|
|
{
|
|
|
int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
|
|
@@ -172,7 +172,7 @@ static int at91_nand_write_oob_512(struct mtd_info *mtd,
|
|
|
/*
|
|
|
* read oob for small pages
|
|
|
*/
|
|
|
-static int at91_nand_read_oob_512(struct mtd_info *mtd,
|
|
|
+static int atmel_nand_read_oob_512(struct mtd_info *mtd,
|
|
|
struct nand_chip *chip, int page, int sndcmd)
|
|
|
{
|
|
|
if (sndcmd) {
|
|
@@ -192,11 +192,11 @@ static int at91_nand_read_oob_512(struct mtd_info *mtd,
|
|
|
* dat: raw data (unused)
|
|
|
* ecc_code: buffer for ECC
|
|
|
*/
|
|
|
-static int at91_nand_calculate(struct mtd_info *mtd,
|
|
|
+static int atmel_nand_calculate(struct mtd_info *mtd,
|
|
|
const u_char *dat, unsigned char *ecc_code)
|
|
|
{
|
|
|
struct nand_chip *nand_chip = mtd->priv;
|
|
|
- struct at91_nand_host *host = nand_chip->priv;
|
|
|
+ struct atmel_nand_host *host = nand_chip->priv;
|
|
|
uint32_t *eccpos = nand_chip->ecc.layout->eccpos;
|
|
|
unsigned int ecc_value;
|
|
|
|
|
@@ -207,7 +207,7 @@ static int at91_nand_calculate(struct mtd_info *mtd,
|
|
|
ecc_code[eccpos[1]] = (ecc_value >> 8) & 0xFF;
|
|
|
|
|
|
/* get the last 2 ECC bytes */
|
|
|
- ecc_value = ecc_readl(host->ecc, NPR) & AT91_ECC_NPARITY;
|
|
|
+ ecc_value = ecc_readl(host->ecc, NPR) & ATMEL_ECC_NPARITY;
|
|
|
|
|
|
ecc_code[eccpos[2]] = ecc_value & 0xFF;
|
|
|
ecc_code[eccpos[3]] = (ecc_value >> 8) & 0xFF;
|
|
@@ -222,7 +222,7 @@ static int at91_nand_calculate(struct mtd_info *mtd,
|
|
|
* chip: nand chip info structure
|
|
|
* buf: buffer to store read data
|
|
|
*/
|
|
|
-static int at91_nand_read_page(struct mtd_info *mtd,
|
|
|
+static int atmel_nand_read_page(struct mtd_info *mtd,
|
|
|
struct nand_chip *chip, uint8_t *buf)
|
|
|
{
|
|
|
int eccsize = chip->ecc.size;
|
|
@@ -281,11 +281,11 @@ static int at91_nand_read_page(struct mtd_info *mtd,
|
|
|
*
|
|
|
* Detect and correct a 1 bit error for a page
|
|
|
*/
|
|
|
-static int at91_nand_correct(struct mtd_info *mtd, u_char *dat,
|
|
|
+static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat,
|
|
|
u_char *read_ecc, u_char *isnull)
|
|
|
{
|
|
|
struct nand_chip *nand_chip = mtd->priv;
|
|
|
- struct at91_nand_host *host = nand_chip->priv;
|
|
|
+ struct atmel_nand_host *host = nand_chip->priv;
|
|
|
unsigned int ecc_status;
|
|
|
unsigned int ecc_word, ecc_bit;
|
|
|
|
|
@@ -293,43 +293,43 @@ static int at91_nand_correct(struct mtd_info *mtd, u_char *dat,
|
|
|
ecc_status = ecc_readl(host->ecc, SR);
|
|
|
|
|
|
/* if there's no error */
|
|
|
- if (likely(!(ecc_status & AT91_ECC_RECERR)))
|
|
|
+ if (likely(!(ecc_status & ATMEL_ECC_RECERR)))
|
|
|
return 0;
|
|
|
|
|
|
/* get error bit offset (4 bits) */
|
|
|
- ecc_bit = ecc_readl(host->ecc, PR) & AT91_ECC_BITADDR;
|
|
|
+ ecc_bit = ecc_readl(host->ecc, PR) & ATMEL_ECC_BITADDR;
|
|
|
/* get word address (12 bits) */
|
|
|
- ecc_word = ecc_readl(host->ecc, PR) & AT91_ECC_WORDADDR;
|
|
|
+ ecc_word = ecc_readl(host->ecc, PR) & ATMEL_ECC_WORDADDR;
|
|
|
ecc_word >>= 4;
|
|
|
|
|
|
/* if there are multiple errors */
|
|
|
- if (ecc_status & AT91_ECC_MULERR) {
|
|
|
+ if (ecc_status & ATMEL_ECC_MULERR) {
|
|
|
/* check if it is a freshly erased block
|
|
|
* (filled with 0xff) */
|
|
|
- if ((ecc_bit == AT91_ECC_BITADDR)
|
|
|
- && (ecc_word == (AT91_ECC_WORDADDR >> 4))) {
|
|
|
+ if ((ecc_bit == ATMEL_ECC_BITADDR)
|
|
|
+ && (ecc_word == (ATMEL_ECC_WORDADDR >> 4))) {
|
|
|
/* the block has just been erased, return OK */
|
|
|
return 0;
|
|
|
}
|
|
|
/* it doesn't seems to be a freshly
|
|
|
* erased block.
|
|
|
* We can't correct so many errors */
|
|
|
- dev_dbg(host->dev, "at91_nand : multiple errors detected."
|
|
|
+ dev_dbg(host->dev, "atmel_nand : multiple errors detected."
|
|
|
" Unable to correct.\n");
|
|
|
return -EIO;
|
|
|
}
|
|
|
|
|
|
/* if there's a single bit error : we can correct it */
|
|
|
- if (ecc_status & AT91_ECC_ECCERR) {
|
|
|
+ if (ecc_status & ATMEL_ECC_ECCERR) {
|
|
|
/* there's nothing much to do here.
|
|
|
* the bit error is on the ECC itself.
|
|
|
*/
|
|
|
- dev_dbg(host->dev, "at91_nand : one bit error on ECC code."
|
|
|
+ dev_dbg(host->dev, "atmel_nand : one bit error on ECC code."
|
|
|
" Nothing to correct\n");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- dev_dbg(host->dev, "at91_nand : one bit error on data."
|
|
|
+ dev_dbg(host->dev, "atmel_nand : one bit error on data."
|
|
|
" (word offset in the page :"
|
|
|
" 0x%x bit offset : 0x%x)\n",
|
|
|
ecc_word, ecc_bit);
|
|
@@ -341,14 +341,14 @@ static int at91_nand_correct(struct mtd_info *mtd, u_char *dat,
|
|
|
/* 8 bits words */
|
|
|
dat[ecc_word] ^= (1 << ecc_bit);
|
|
|
}
|
|
|
- dev_dbg(host->dev, "at91_nand : error corrected\n");
|
|
|
+ dev_dbg(host->dev, "atmel_nand : error corrected\n");
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* Enable HW ECC : unsused
|
|
|
*/
|
|
|
-static void at91_nand_hwctl(struct mtd_info *mtd, int mode) { ; }
|
|
|
+static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) { ; }
|
|
|
|
|
|
#ifdef CONFIG_MTD_PARTITIONS
|
|
|
static const char *part_probes[] = { "cmdlinepart", NULL };
|
|
@@ -357,9 +357,9 @@ static const char *part_probes[] = { "cmdlinepart", NULL };
|
|
|
/*
|
|
|
* Probe for the NAND device.
|
|
|
*/
|
|
|
-static int __init at91_nand_probe(struct platform_device *pdev)
|
|
|
+static int __init atmel_nand_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
- struct at91_nand_host *host;
|
|
|
+ struct atmel_nand_host *host;
|
|
|
struct mtd_info *mtd;
|
|
|
struct nand_chip *nand_chip;
|
|
|
struct resource *regs;
|
|
@@ -372,21 +372,21 @@ static int __init at91_nand_probe(struct platform_device *pdev)
|
|
|
#endif
|
|
|
|
|
|
/* Allocate memory for the device structure (and zero it) */
|
|
|
- host = kzalloc(sizeof(struct at91_nand_host), GFP_KERNEL);
|
|
|
+ host = kzalloc(sizeof(struct atmel_nand_host), GFP_KERNEL);
|
|
|
if (!host) {
|
|
|
- printk(KERN_ERR "at91_nand: failed to allocate device structure.\n");
|
|
|
+ printk(KERN_ERR "atmel_nand: failed to allocate device structure.\n");
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
|
if (!mem) {
|
|
|
- printk(KERN_ERR "at91_nand: can't get I/O resource mem\n");
|
|
|
+ printk(KERN_ERR "atmel_nand: can't get I/O resource mem\n");
|
|
|
return -ENXIO;
|
|
|
}
|
|
|
|
|
|
host->io_base = ioremap(mem->start, mem->end - mem->start + 1);
|
|
|
if (host->io_base == NULL) {
|
|
|
- printk(KERN_ERR "at91_nand: ioremap failed\n");
|
|
|
+ printk(KERN_ERR "atmel_nand: ioremap failed\n");
|
|
|
kfree(host);
|
|
|
return -EIO;
|
|
|
}
|
|
@@ -403,14 +403,14 @@ static int __init at91_nand_probe(struct platform_device *pdev)
|
|
|
/* Set address of NAND IO lines */
|
|
|
nand_chip->IO_ADDR_R = host->io_base;
|
|
|
nand_chip->IO_ADDR_W = host->io_base;
|
|
|
- nand_chip->cmd_ctrl = at91_nand_cmd_ctrl;
|
|
|
+ nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl;
|
|
|
|
|
|
if (host->board->rdy_pin)
|
|
|
- nand_chip->dev_ready = at91_nand_device_ready;
|
|
|
+ nand_chip->dev_ready = atmel_nand_device_ready;
|
|
|
|
|
|
regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
|
|
if (!regs && hard_ecc) {
|
|
|
- printk(KERN_ERR "at91_nand: can't get I/O resource "
|
|
|
+ printk(KERN_ERR "atmel_nand: can't get I/O resource "
|
|
|
"regs\nFalling back on software ECC\n");
|
|
|
}
|
|
|
|
|
@@ -420,15 +420,15 @@ static int __init at91_nand_probe(struct platform_device *pdev)
|
|
|
if (hard_ecc && regs) {
|
|
|
host->ecc = ioremap(regs->start, regs->end - regs->start + 1);
|
|
|
if (host->ecc == NULL) {
|
|
|
- printk(KERN_ERR "at91_nand: ioremap failed\n");
|
|
|
+ printk(KERN_ERR "atmel_nand: ioremap failed\n");
|
|
|
res = -EIO;
|
|
|
goto err_ecc_ioremap;
|
|
|
}
|
|
|
nand_chip->ecc.mode = NAND_ECC_HW_SYNDROME;
|
|
|
- nand_chip->ecc.calculate = at91_nand_calculate;
|
|
|
- nand_chip->ecc.correct = at91_nand_correct;
|
|
|
- nand_chip->ecc.hwctl = at91_nand_hwctl;
|
|
|
- nand_chip->ecc.read_page = at91_nand_read_page;
|
|
|
+ nand_chip->ecc.calculate = atmel_nand_calculate;
|
|
|
+ nand_chip->ecc.correct = atmel_nand_correct;
|
|
|
+ nand_chip->ecc.hwctl = atmel_nand_hwctl;
|
|
|
+ nand_chip->ecc.read_page = atmel_nand_read_page;
|
|
|
nand_chip->ecc.bytes = 4;
|
|
|
nand_chip->ecc.prepad = 0;
|
|
|
nand_chip->ecc.postpad = 0;
|
|
@@ -440,7 +440,7 @@ static int __init at91_nand_probe(struct platform_device *pdev)
|
|
|
nand_chip->options |= NAND_BUSWIDTH_16;
|
|
|
|
|
|
platform_set_drvdata(pdev, host);
|
|
|
- at91_nand_enable(host);
|
|
|
+ atmel_nand_enable(host);
|
|
|
|
|
|
if (host->board->det_pin) {
|
|
|
if (gpio_get_value(host->board->det_pin)) {
|
|
@@ -463,22 +463,22 @@ static int __init at91_nand_probe(struct platform_device *pdev)
|
|
|
/* set ECC page size and oob layout */
|
|
|
switch (mtd->writesize) {
|
|
|
case 512:
|
|
|
- nand_chip->ecc.layout = &at91_oobinfo_small;
|
|
|
- nand_chip->ecc.read_oob = at91_nand_read_oob_512;
|
|
|
- nand_chip->ecc.write_oob = at91_nand_write_oob_512;
|
|
|
- ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_528);
|
|
|
+ nand_chip->ecc.layout = &atmel_oobinfo_small;
|
|
|
+ nand_chip->ecc.read_oob = atmel_nand_read_oob_512;
|
|
|
+ nand_chip->ecc.write_oob = atmel_nand_write_oob_512;
|
|
|
+ ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528);
|
|
|
break;
|
|
|
case 1024:
|
|
|
- nand_chip->ecc.layout = &at91_oobinfo_large;
|
|
|
- ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_1056);
|
|
|
+ nand_chip->ecc.layout = &atmel_oobinfo_large;
|
|
|
+ ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_1056);
|
|
|
break;
|
|
|
case 2048:
|
|
|
- nand_chip->ecc.layout = &at91_oobinfo_large;
|
|
|
- ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_2112);
|
|
|
+ nand_chip->ecc.layout = &atmel_oobinfo_large;
|
|
|
+ ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_2112);
|
|
|
break;
|
|
|
case 4096:
|
|
|
- nand_chip->ecc.layout = &at91_oobinfo_large;
|
|
|
- ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_4224);
|
|
|
+ nand_chip->ecc.layout = &atmel_oobinfo_large;
|
|
|
+ ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_4224);
|
|
|
break;
|
|
|
default:
|
|
|
/* page size not handled by HW ECC */
|
|
@@ -503,7 +503,7 @@ static int __init at91_nand_probe(struct platform_device *pdev)
|
|
|
|
|
|
#ifdef CONFIG_MTD_PARTITIONS
|
|
|
#ifdef CONFIG_MTD_CMDLINE_PARTS
|
|
|
- mtd->name = "at91_nand";
|
|
|
+ mtd->name = "atmel_nand";
|
|
|
num_partitions = parse_mtd_partitions(mtd, part_probes,
|
|
|
&partitions, 0);
|
|
|
#endif
|
|
@@ -512,7 +512,7 @@ static int __init at91_nand_probe(struct platform_device *pdev)
|
|
|
&num_partitions);
|
|
|
|
|
|
if ((!partitions) || (num_partitions == 0)) {
|
|
|
- printk(KERN_ERR "at91_nand: No parititions defined, or unsupported device.\n");
|
|
|
+ printk(KERN_ERR "atmel_nand: No parititions defined, or unsupported device.\n");
|
|
|
res = ENXIO;
|
|
|
goto release;
|
|
|
}
|
|
@@ -534,7 +534,7 @@ out:
|
|
|
iounmap(host->ecc);
|
|
|
|
|
|
err_ecc_ioremap:
|
|
|
- at91_nand_disable(host);
|
|
|
+ atmel_nand_disable(host);
|
|
|
platform_set_drvdata(pdev, NULL);
|
|
|
iounmap(host->io_base);
|
|
|
kfree(host);
|
|
@@ -544,14 +544,14 @@ err_ecc_ioremap:
|
|
|
/*
|
|
|
* Remove a NAND device.
|
|
|
*/
|
|
|
-static int __devexit at91_nand_remove(struct platform_device *pdev)
|
|
|
+static int __devexit atmel_nand_remove(struct platform_device *pdev)
|
|
|
{
|
|
|
- struct at91_nand_host *host = platform_get_drvdata(pdev);
|
|
|
+ struct atmel_nand_host *host = platform_get_drvdata(pdev);
|
|
|
struct mtd_info *mtd = &host->mtd;
|
|
|
|
|
|
nand_release(mtd);
|
|
|
|
|
|
- at91_nand_disable(host);
|
|
|
+ atmel_nand_disable(host);
|
|
|
|
|
|
iounmap(host->io_base);
|
|
|
iounmap(host->ecc);
|
|
@@ -560,31 +560,31 @@ static int __devexit at91_nand_remove(struct platform_device *pdev)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static struct platform_driver at91_nand_driver = {
|
|
|
- .probe = at91_nand_probe,
|
|
|
- .remove = at91_nand_remove,
|
|
|
+static struct platform_driver atmel_nand_driver = {
|
|
|
+ .probe = atmel_nand_probe,
|
|
|
+ .remove = atmel_nand_remove,
|
|
|
.driver = {
|
|
|
- .name = "at91_nand",
|
|
|
+ .name = "atmel_nand",
|
|
|
.owner = THIS_MODULE,
|
|
|
},
|
|
|
};
|
|
|
|
|
|
-static int __init at91_nand_init(void)
|
|
|
+static int __init atmel_nand_init(void)
|
|
|
{
|
|
|
- return platform_driver_register(&at91_nand_driver);
|
|
|
+ return platform_driver_register(&atmel_nand_driver);
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void __exit at91_nand_exit(void)
|
|
|
+static void __exit atmel_nand_exit(void)
|
|
|
{
|
|
|
- platform_driver_unregister(&at91_nand_driver);
|
|
|
+ platform_driver_unregister(&atmel_nand_driver);
|
|
|
}
|
|
|
|
|
|
|
|
|
-module_init(at91_nand_init);
|
|
|
-module_exit(at91_nand_exit);
|
|
|
+module_init(atmel_nand_init);
|
|
|
+module_exit(atmel_nand_exit);
|
|
|
|
|
|
MODULE_LICENSE("GPL");
|
|
|
MODULE_AUTHOR("Rick Bronson");
|
|
|
MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91 / AVR32");
|
|
|
-MODULE_ALIAS("platform:at91_nand");
|
|
|
+MODULE_ALIAS("platform:atmel_nand");
|