From: Felipe Balbi <[EMAIL PROTECTED]>

Lot's of cleanups to davinci_nand.c:

  - convert printk() to dev_err()
  - get control base via struct resource
  - add missing static and __init
  - remove some useless ifdef
  - add some REVISIT notes for later patches
  - add locking support for register access operations

Signed-off-by: Felipe Balbi <[EMAIL PROTECTED]>
---
 drivers/mtd/nand/davinci_nand.c |  366 +++++++++++++++++++++++----------------
 1 files changed, 220 insertions(+), 146 deletions(-)

diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 97aa645..2ebdef3 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -45,6 +45,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/spinlock.h>
 
 #include <mach/hardware.h>
 #include <mach/nand.h>
@@ -52,9 +53,6 @@
 
 #include <asm/mach/flash.h>
 
-/* FIXME: this should be passed in using platform_data */
-#define DAVINCI_ASYNC_EMIF_CNTRL_BASE           (0x01E00000)
-
 #ifdef CONFIG_NAND_FLASH_HW_ECC
 #define DAVINCI_NAND_ECC_MODE NAND_ECC_HW3_512
 #else
@@ -63,13 +61,20 @@
 
 #define DRIVER_NAME "davinci_nand"
 
-static struct clk *nand_clock;
-static void __iomem *nand_vaddr;
+struct davinci_nand_info {
+       /* device lock */
+       spinlock_t              lock;
+       struct nand_chip        chip;
+       struct mtd_info         mtd;
 
-/*
- * MTD structure for DaVinici board
- */
-static struct mtd_info *nand_davinci_mtd;
+       struct device           *dev;
+       struct clk              *clk;
+
+       void __iomem            *base;
+       void __iomem            *vaddr;
+};
+
+#define to_davinci_nand(m) container_of(m, struct davinci_nand_info, mtd);
 
 #ifdef CONFIG_MTD_PARTITIONS
 const char *part_probes[] = { "cmdlinepart", NULL };
@@ -79,32 +84,38 @@ static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
 
 /* BB marker is byte 5 in OOB of page 0 */
 static struct nand_bbt_descr davinci_memorybased_small = {
-       .options = NAND_BBT_SCAN2NDPAGE,
-       .offs = 5,
-       .len = 1,
-       .pattern = scan_ff_pattern
+       .options        = NAND_BBT_SCAN2NDPAGE,
+       .offs           = 5,
+       .len            = 1,
+       .pattern        = scan_ff_pattern
 };
 
 /* BB marker is bytes 0-1 in OOB of page 0 */
 static struct nand_bbt_descr davinci_memorybased_large = {
-       .options = 0,
-       .offs = 0,
-       .len = 2,
-       .pattern = scan_ff_pattern
+       .options        = 0,
+       .offs           = 0,
+       .len            = 2,
+       .pattern        = scan_ff_pattern
 };
 
-inline unsigned int davinci_nand_readl(int offset)
+/* Caller should take care of locking */
+static inline unsigned int davinci_nand_readl(struct davinci_nand_info *info,
+               int offset)
 {
-       return davinci_readl(DAVINCI_ASYNC_EMIF_CNTRL_BASE + offset);
+       return __raw_readl(info->base + offset);
 }
 
-inline void davinci_nand_writel(unsigned long value, int offset)
+/* Caller should take care of locking */
+static inline void davinci_nand_writel(struct davinci_nand_info *info,
+               unsigned long value, int offset)
 {
-       davinci_writel(value, DAVINCI_ASYNC_EMIF_CNTRL_BASE + offset);
+       __raw_writel(value, info->base + offset);
 }
 
 /*
  * Hardware specific access to control-lines
+ *
+ * REVISIT avoid casting addresses
  */
 static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd,
                                   unsigned int ctrl)
@@ -136,15 +147,23 @@ static void nand_davinci_select_chip(struct mtd_info 
*mtd, int chip)
 #ifdef CONFIG_NAND_FLASH_HW_ECC
 static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode)
 {
+       struct davinci_nand_info *info;
+       unsigned long flags;
        u32 retval;
 
+       info = to_davinci_nand(mtd);
+
+       spin_lock_irqsave(&info->lock, flags);
+
        /* Reset ECC hardware */
-       retval = davinci_nand_readl(NANDF1ECC_OFFSET);
+       retval = davinci_nand_readl(info, NANDF1ECC_OFFSET);
 
        /* Restart ECC hardware */
-       retval = davinci_nand_readl(NANDFCR_OFFSET);
+       retval = davinci_nand_readl(info, NANDFCR_OFFSET);
        retval |= (1 << 8);
-       davinci_nand_writel(retval, NANDFCR_OFFSET);
+       davinci_nand_writel(info, retval, NANDFCR_OFFSET);
+
+       spin_unlock_irqrestore(&info->lock, flags);
 }
 
 /*
@@ -152,8 +171,18 @@ static void nand_davinci_enable_hwecc(struct mtd_info 
*mtd, int mode)
  */
 static u32 nand_davinci_readecc(struct mtd_info *mtd)
 {
+       struct davinci_nand_info *info;
+       unsigned int offset;
+       unsigned long flags;
+
+       info = to_davinci_nand(mtd);
+
        /* Read register ECC and clear it */
-       return davinci_nand_readl(NANDF1ECC_OFFSET);
+       spin_lock_irqsave(&info->lock, flags);
+       offset = davinci_nand_readl(info, NANDF1ECC_OFFSET);
+       spin_unlock_irqrestore(&info->lock, flags);
+
+       return offset;
 }
 
 /*
@@ -164,7 +193,7 @@ static int nand_davinci_calculate_ecc(struct mtd_info *mtd,
 {
        unsigned int ecc_val = nand_davinci_readecc(mtd);
        /* squeeze 0 middle bits out so that it fits in 3 bytes */
-       unsigned int tmp = (ecc_val&0x0fff)|((ecc_val&0x0fff0000)>>4);
+       unsigned int tmp = (ecc_val & 0x0fff) | ((ecc_val & 0x0fff0000) >> 4);
        /* invert so that erased block ecc is correct */
        tmp = ~tmp;
        ecc_code[0] = (u_char)(tmp);
@@ -185,15 +214,15 @@ static int nand_davinci_correct_data(struct mtd_info 
*mtd, u_char *dat,
        u_int32_t diff = eccCalc ^ eccNand;
 
        if (diff) {
-               if ((((diff>>12)^diff) & 0xfff) == 0xfff) {
+               if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
                        /* Correctable error */
-                       if ((diff>>(12+3)) < chip->ecc.size) {
-                               dat[diff>>(12+3)] ^= (1 << ((diff>>12)&7));
+                       if ((diff >> (12 + 3)) < chip->ecc.size) {
+                               dat[diff >> (12 + 3)] ^= (1 << ((diff >> 12) & 
7));
                                return 1;
                        } else {
                                return -1;
                        }
-               } else if (!(diff & (diff-1))) {
+               } else if (!(diff & (diff - 1))) {
                        /* Single bit ECC error in the ECC itself,
                           nothing to fix */
                        return 1;
@@ -211,7 +240,7 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, 
u_char *dat,
  * Read OOB data from flash.
  */
 static int read_oob_and_check(struct mtd_info *mtd, loff_t offs, uint8_t *buf,
-                             struct nand_bbt_descr *bd)
+               struct nand_bbt_descr *bd)
 {
        int i, ret;
        int page;
@@ -241,7 +270,7 @@ static int read_oob_and_check(struct mtd_info *mtd, loff_t 
offs, uint8_t *buf,
  * Fill in the memory based Bad Block Table (BBT).
  */
 static int nand_davinci_memory_bbt(struct mtd_info *mtd,
-                                  struct nand_bbt_descr *bd)
+               struct nand_bbt_descr *bd)
 {
        int i, numblocks;
        int startblock = 0;
@@ -250,6 +279,7 @@ static int nand_davinci_memory_bbt(struct mtd_info *mtd,
        int blocksize = 1 << chip->bbt_erase_shift;
        uint8_t *buf = chip->buffers->databuf;
        int len = bd->options & NAND_BBT_SCAN2NDPAGE ? 2 : 1;
+       struct davinci_nand_info *info = to_davinci_nand(mtd);
 
        /* -numblocks- is 2 times the actual number of eraseblocks */
        numblocks = mtd->size >> (chip->bbt_erase_shift - 1);
@@ -275,7 +305,7 @@ static int nand_davinci_memory_bbt(struct mtd_info *mtd,
                                   table */
                                chip->bbt[i >> 3] |= 0x03 << (i & 0x6);
 
-                               printk(KERN_WARNING "Bad eraseblock %d at " \
+                               dev_warn(info->dev, "Bad eraseblock %d at " \
                                                    "0x%08x\n", i >> 1,
                                                     (unsigned int)from);
 
@@ -289,8 +319,8 @@ static int nand_davinci_memory_bbt(struct mtd_info *mtd,
                from += blocksize;
        }
 
-       printk(KERN_NOTICE "Bad block scan: %d out of %d blocks are bad.\n",
-                           mtd->ecc_stats.badblocks, numblocks>>1);
+       dev_notice(info->dev, "Bad block scan: %d out of %d blocks are bad.\n",
+                           mtd->ecc_stats.badblocks, numblocks >> 1);
 
        return 0;
 }
@@ -305,6 +335,7 @@ static int nand_davinci_scan_bbt(struct mtd_info *mtd)
        struct nand_chip *chip = mtd->priv;
        struct nand_bbt_descr *bd;
        int len, ret = 0;
+       struct davinci_nand_info *info = to_davinci_nand(mtd);
 
        chip->bbt_td = NULL;
        chip->bbt_md = NULL;
@@ -324,15 +355,15 @@ static int nand_davinci_scan_bbt(struct mtd_info *mtd)
           table */
        chip->bbt = kzalloc(len, GFP_KERNEL);
        if (!chip->bbt) {
-               printk(KERN_ERR "nand_davinci_scan_bbt: Out of memory\n");
+               dev_err(info->dev, "%s: out of memory\n", __func__);
                return -ENOMEM;
        }
 
        /* Now try to fill in the BBT */
        ret = nand_davinci_memory_bbt(mtd, bd);
        if (ret) {
-               printk(KERN_ERR "nand_davinci_scan_bbt: "
-                      "Can't scan flash and build the RAM-based BBT\n");
+               dev_err(info->dev, "%s: can't scan flash and build BBT\n",
+                               __func__);
 
                kfree(chip->bbt);
                chip->bbt = NULL;
@@ -362,10 +393,20 @@ static void nand_davinci_read_buf(struct mtd_info *mtd, 
uint8_t *buf, int len)
  */
 static int nand_davinci_dev_ready(struct mtd_info *mtd)
 {
-       return (davinci_nand_readl(NANDFSR_OFFSET) & NAND_BUSY_FLAG);
+       struct davinci_nand_info *info;
+       unsigned int offset;
+       unsigned long flags;
+
+       info = to_davinci_nand(mtd);
+
+       spin_lock_irqsave(&info->lock, flags);
+       offset = davinci_nand_readl(info, NANDFSR_OFFSET) & NAND_BUSY_FLAG;
+       spin_unlock_irqrestore(&info->lock, flags);
+
+       return offset;
 }
 
-static void nand_davinci_set_eccsize(struct nand_chip *chip)
+static void __init nand_davinci_set_eccsize(struct nand_chip *chip)
 {
        chip->ecc.size = 256;
 
@@ -389,7 +430,7 @@ static void nand_davinci_set_eccsize(struct nand_chip *chip)
 #endif
 }
 
-static void nand_davinci_set_eccbytes(struct nand_chip *chip)
+static void __init nand_davinci_set_eccbytes(struct nand_chip *chip)
 {
        chip->ecc.bytes = 3;
 
@@ -410,10 +451,13 @@ static void nand_davinci_set_eccbytes(struct nand_chip 
*chip)
 #endif
 }
 
-static void __devinit nand_davinci_flash_init(void)
+static void __init nand_davinci_flash_init(struct davinci_nand_info *info)
 {
+       unsigned long flags;
        u32 regval, tmp;
 
+       spin_lock_irqsave(&info->lock, flags);
+
        /* Check for correct pin mux, reconfigure if necessary */
        tmp = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + PINMUX0);
 
@@ -433,14 +477,14 @@ static void __devinit nand_davinci_flash_init(void)
 
                regval = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + PINMUX0);
 
-               printk(KERN_WARNING "Warning: MUX config for NAND: Set " \
+               dev_dbg(info->dev, "MUX config for NAND: Set " \
                       "PINMUX0 reg to 0x%08x, was 0x%08x, should be done " \
                       "by bootloader.\n", regval, tmp);
        }
 
-       regval = davinci_nand_readl(AWCCR_OFFSET);
+       regval = davinci_nand_readl(info, AWCCR_OFFSET);
        regval |= 0x10000000;
-       davinci_nand_writel(regval, AWCCR_OFFSET);
+       davinci_nand_writel(info, regval, AWCCR_OFFSET);
 
        /*------------------------------------------------------------------*
         *  NAND FLASH CHIP TIMEOUT @ 459 MHz                               *
@@ -449,6 +493,7 @@ static void __devinit nand_davinci_flash_init(void)
         *  AEMIF.CLK period = 1/76.5 MHz = 13.1 ns                         *
         *                                                                  *
         *------------------------------------------------------------------*/
+       /* REVISIT avoid magic numbers */
        regval = 0
                | (0 << 31)           /* selectStrobe */
                | (0 << 30)           /* extWait */
@@ -461,160 +506,196 @@ static void __devinit nand_davinci_flash_init(void)
                | (3 << 2)            /* turnAround      ?? ns */
                | (0 << 0)            /* asyncSize       8-bit bus */
                ;
-       tmp = davinci_nand_readl(A1CR_OFFSET);
+       tmp = davinci_nand_readl(info, A1CR_OFFSET);
        if (tmp != regval) {
-               printk(KERN_WARNING "Warning: NAND config: Set A1CR " \
+               dev_dbg(info->dev, "NAND config: Set A1CR " \
                       "reg to 0x%08x, was 0x%08x, should be done by " \
                       "bootloader.\n", regval, tmp);
-               davinci_nand_writel(regval, A1CR_OFFSET); /* 0x0434018C */
+               davinci_nand_writel(info, regval, A1CR_OFFSET); /* 0x0434018C */
        }
 
-       davinci_nand_writel(0x00000101, NANDFCR_OFFSET);
+       davinci_nand_writel(info, 0x00000101, NANDFCR_OFFSET);
+
+       spin_unlock_irqrestore(&info->lock, flags);
 }
 
-/*
- * Main initialization routine
- */
-int __devinit nand_davinci_probe(struct platform_device *pdev)
+static int __init nand_davinci_probe(struct platform_device *pdev)
 {
-       struct flash_platform_data *pdata = pdev->dev.platform_data;
-       struct resource           *res = pdev->resource;
-       struct nand_chip          *chip;
-       struct device             *dev = NULL;
-       u32                       nand_rev_code;
+       struct flash_platform_data      *pdata = pdev->dev.platform_data;
+       struct davinci_nand_info        *info;
+       struct resource                 *res1;
+       struct resource                 *res2;
+
 #ifdef CONFIG_MTD_CMDLINE_PARTS
-       char                      *master_name;
-       int                       mtd_parts_nb = 0;
-       struct mtd_partition      *mtd_parts = 0;
+       struct mtd_partition            *mtd_parts = 0;
+       char                            *master_name;
+       int                             mtd_parts_nb = 0;
 #endif
 
-       nand_clock = clk_get(dev, "AEMIFCLK");
-       if (IS_ERR(nand_clock)) {
-               printk(KERN_ERR "Error %ld getting AEMIFCLK clock?\n",
-                      PTR_ERR(nand_clock));
-               return -1;
-       }
+       void __iomem                    *vaddr;
+       void __iomem                    *base;
 
-       clk_enable(nand_clock);
+       int                             ret;
 
-       /* Allocate memory for MTD device structure and private data */
-       nand_davinci_mtd = kmalloc(sizeof(struct mtd_info) +
-                                  sizeof(struct nand_chip), GFP_KERNEL);
+       u32                             rev;
 
-       if (!nand_davinci_mtd) {
-               printk(KERN_ERR "Unable to allocate davinci NAND MTD device " \
-                      "structure.\n");
-               clk_disable(nand_clock);
-               return -ENOMEM;
+       if (!pdata) {
+               dev_err(&pdev->dev, "platform data missing\n");
+               ret = -ENODEV;
+               goto err_pdata;
        }
 
-       /* Get pointer to private data */
-       chip = (struct nand_chip *) (&nand_davinci_mtd[1]);
-
-       /* Initialize structures */
-       memset((char *)nand_davinci_mtd, 0, sizeof(struct mtd_info));
-       memset((char *)chip, 0, sizeof(struct nand_chip));
+       info = kzalloc(sizeof(*info), GFP_KERNEL);
+       if (!info) {
+               dev_err(&pdev->dev, "unable to allocate memory\n");
+               ret = -ENOMEM;
+               goto err_nomem;
+       }
 
-       /* Link the private data with the MTD structure */
-       nand_davinci_mtd->priv = chip;
+       spin_lock_init(&info->lock);
+       platform_set_drvdata(pdev, info);
 
-       nand_rev_code = davinci_nand_readl(NRCSR_OFFSET);
+       res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (!res1 || !res2) {
+               dev_err(&pdev->dev, "resource missing\n");
+               ret = -EINVAL;
+               goto err_res;
+       }
 
-       printk("DaVinci NAND Controller rev. %d.%d\n",
-              (nand_rev_code >> 8) & 0xff, nand_rev_code & 0xff);
+       vaddr = ioremap(res1->start, res1->end - res1->start);
+       base = ioremap(res2->start, res2->end - res2->start);
+       if (!vaddr || !base) {
+               dev_err(&pdev->dev, "ioremap failed\n");
+               ret = -EINVAL;
+               goto err_ioremap;
 
-       nand_vaddr = ioremap(res->start, res->end - res->start);
-       if (nand_vaddr == NULL) {
-               printk(KERN_ERR "DaVinci NAND: ioremap failed.\n");
-               clk_disable(nand_clock);
-               kfree(nand_davinci_mtd);
-               return -ENOMEM;
        }
 
-       chip->IO_ADDR_R   = (void __iomem *)nand_vaddr;
-       chip->IO_ADDR_W   = (void __iomem *)nand_vaddr;
-       chip->chip_delay  = 0;
-       chip->select_chip = nand_davinci_select_chip;
-       chip->options     = 0;
-       chip->ecc.mode    = DAVINCI_NAND_ECC_MODE;
+       info->dev               = &pdev->dev;
+       info->base              = base;
+       info->vaddr             = vaddr;
 
-       /* Set ECC size and bytes */
-       nand_davinci_set_eccsize(chip);
-       nand_davinci_set_eccbytes(chip);
+       info->mtd.priv          = &info->chip;
+       info->mtd.name          = dev_name(&pdev->dev);
+       info->mtd.owner         = THIS_MODULE;
+
+       info->chip.IO_ADDR_R    = vaddr;
+       info->chip.IO_ADDR_W    = vaddr;
+       info->chip.chip_delay   = 0;
+       info->chip.select_chip  = nand_davinci_select_chip;
+       info->chip.options      = 0;
+       info->chip.ecc.mode     = DAVINCI_NAND_ECC_MODE;
 
        /* Set address of hardware control function */
-       chip->cmd_ctrl  = nand_davinci_hwcontrol;
-       chip->dev_ready = nand_davinci_dev_ready;
+       info->chip.cmd_ctrl     = nand_davinci_hwcontrol;
+       info->chip.dev_ready    = nand_davinci_dev_ready;
+
+       /* Speed up the read buffer */
+       info->chip.read_buf      = nand_davinci_read_buf;
+
+       /* Speed up the creation of the bad block table */
+       info->chip.scan_bbt      = nand_davinci_scan_bbt;
 
 #ifdef CONFIG_NAND_FLASH_HW_ECC
-       chip->ecc.calculate = nand_davinci_calculate_ecc;
-       chip->ecc.correct   = nand_davinci_correct_data;
-       chip->ecc.hwctl     = nand_davinci_enable_hwecc;
+       /* REVISIT should be using runtime check */
+       info->chip.ecc.calculate = nand_davinci_calculate_ecc;
+       info->chip.ecc.correct   = nand_davinci_correct_data;
+       info->chip.ecc.hwctl     = nand_davinci_enable_hwecc;
 #endif
 
-       /* Speed up the read buffer */
-       chip->read_buf      = nand_davinci_read_buf;
+       info->clk = clk_get(&pdev->dev, "AEMIFCLK");
+       if (IS_ERR(info->clk)) {
+               ret = PTR_ERR(info->clk);
+               dev_dbg(&pdev->dev, "unable to get AEMIFCLK, err %d", ret);
+               goto err_clk;
+       }
 
-       /* Speed up the creation of the bad block table */
-       chip->scan_bbt      = nand_davinci_scan_bbt;
+       ret = clk_enable(info->clk);
+       if (ret < 0) {
+               dev_dbg(&pdev->dev, "unable to enable AEMIFCLK, err %d\n", ret);
+               goto err_clk_enable;
+       }
 
-       nand_davinci_flash_init();
+       /* Set ECC size and bytes */
+       nand_davinci_set_eccsize(&info->chip);
+       nand_davinci_set_eccbytes(&info->chip);
 
-       nand_davinci_mtd->owner = THIS_MODULE;
+       nand_davinci_flash_init(info);
 
        /* Scan to find existence of the device */
-       if (nand_scan(nand_davinci_mtd, 1)) {
-               printk(KERN_ERR "Chip Select is not set for NAND\n");
-               clk_disable(nand_clock);
-               kfree(nand_davinci_mtd);
-               return -ENXIO;
+       if (nand_scan(&info->mtd, 1)) {
+               dev_err(&pdev->dev, "chip select is not set for 'NAND'\n");
+               ret = -ENXIO;
+               goto err_scan;
        }
 
        /* Register the partitions */
-       add_mtd_partitions(nand_davinci_mtd, pdata->parts, pdata->nr_parts);
+       add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts);
 
 #ifdef CONFIG_MTD_CMDLINE_PARTS
-       /* Set nand_davinci_mtd->name = 0 temporarily */
-       master_name = nand_davinci_mtd->name;
-       nand_davinci_mtd->name = (char *)0;
+       /* Set info->mtd.name = 0 temporarily */
+       master_name             = info->mtd.name;
+       info->mtd.name          = (char *)0;
 
-       /* nand_davinci_mtd->name == 0, means: don't bother checking
+       /* info->mtd.name == 0, means: don't bother checking
           <mtd-id> */
-       mtd_parts_nb = parse_mtd_partitions(nand_davinci_mtd, part_probes,
+       mtd_parts_nb = parse_mtd_partitions(&info->mtd, part_probes,
                                            &mtd_parts, 0);
 
-       /* Restore nand_davinci_mtd->name */
-       nand_davinci_mtd->name = master_name;
+       /* Restore info->mtd.name */
+       info->mtd.name = master_name;
 
-       add_mtd_partitions(nand_davinci_mtd, mtd_parts, mtd_parts_nb);
+       add_mtd_partitions(&info->mtd, mtd_parts, mtd_parts_nb);
 #endif
 
+       rev = davinci_nand_readl(info, NRCSR_OFFSET);
+       dev_info(&pdev->dev, "controller rev. %d.%d\n",
+              (rev >> 8) & 0xff, rev & 0xff);
+
        return 0;
+
+err_scan:
+       clk_disable(info->clk);
+
+err_clk_enable:
+       clk_put(info->clk);
+
+err_clk:
+err_ioremap:
+       kfree(info);
+
+err_nomem:
+err_res:
+err_pdata:
+       return ret;
 }
 
-/*
- * Clean up routine
- */
-static int nand_davinci_remove(struct platform_device *pdev)
+static int __exit nand_davinci_remove(struct platform_device *pdev)
 {
-       clk_disable(nand_clock);
+       struct davinci_nand_info *info = platform_get_drvdata(pdev);
 
-       if (nand_vaddr)
-               iounmap(nand_vaddr);
+       iounmap(info->base);
+       iounmap(info->vaddr);
 
-       /* Release resources, unregister device */
-       nand_release(nand_davinci_mtd);
+       nand_release(&info->mtd);
 
-       /* Free the MTD device structure */
-       kfree(nand_davinci_mtd);
+       clk_disable(info->clk);
+       clk_put(info->clk);
+
+       kfree(info);
 
        return 0;
 }
 
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("DaVinci NAND driver");
 
 static struct platform_driver nand_davinci_driver = {
        .probe          = nand_davinci_probe,
-       .remove         = nand_davinci_remove,
+       .remove         = __exit_p(nand_davinci_remove),
        .driver         = {
                .name   = DRIVER_NAME,
        },
@@ -626,16 +707,9 @@ static int __init nand_davinci_init(void)
 }
 module_init(nand_davinci_init);
 
-#ifdef MODULE
 static void __exit nand_davinci_exit(void)
 {
        platform_driver_unregister(&nand_davinci_driver);
 }
 module_exit(nand_davinci_exit);
-#endif
 
-MODULE_ALIAS(DRIVER_NAME);
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Texas Instruments");
-MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on davinci" \
-                  "board");
-- 
1.6.0.4.617.g2baf1


_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to