Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd5f6346 authored by Kyungmin Park's avatar Kyungmin Park Committed by Thomas Gleixner
Browse files

[MTD] Add initial support for OneNAND flash chips



OneNAND is a new flash technology from Samsung with integrated SRAM
buffers and logic interface.

Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 4ce1f562
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
# $Id: Kconfig,v 1.9 2005/06/16 08:49:29 sean Exp $
# $Id: Kconfig,v 1.10 2005/07/11 10:39:27 gleixner Exp $

menu "Memory Technology Devices (MTD)"

@@ -259,9 +259,9 @@ config RFD_FTL
	---help---
	  This provides support for the flash translation layer known 
	  as the Resident Flash Disk (RFD), as used by the Embedded BIOS 
	  of General Software.
	  See http://www.gensw.com/pages/prod/bios/rfd.htm for further
	  information.
	  of General Software. There is a blurb at:

		http://www.gensw.com/pages/prod/bios/rfd.htm

source "drivers/mtd/chips/Kconfig"

@@ -271,5 +271,7 @@ source "drivers/mtd/devices/Kconfig"

source "drivers/mtd/nand/Kconfig"

source "drivers/mtd/onenand/Kconfig"

endmenu
+2 −2
Original line number Diff line number Diff line
#
# Makefile for the memory technology device drivers.
#
# $Id: Makefile.common,v 1.6 2005/06/16 08:49:29 sean Exp $
# $Id: Makefile.common,v 1.7 2005/07/11 10:39:27 gleixner Exp $

# Core functionality.
mtd-y				:= mtdcore.o
@@ -25,4 +25,4 @@ obj-$(CONFIG_RFD_FTL) += rfd_ftl.o mtd_blkdevs.o
nftl-objs		:= nftlcore.o nftlmount.o
inftl-objs		:= inftlcore.o inftlmount.o

obj-y		+= chips/ maps/ devices/ nand/
obj-y		+= chips/ maps/ devices/ nand/ onenand/
+32 −0
Original line number Diff line number Diff line
#
# linux/drivers/mtd/onenand/Kconfig
#

menu "OneNAND Flash Device Drivers (EXPERIMENTAL)"
	depends on MTD != n && EXPERIMENTAL

config MTD_ONENAND
	tristate "OneNAND Device Support"
	depends on MTD
	help
	  This enables support for accessing all type of OneNAND flash
	  devices. For further information see
	  <http://www.samsung.com/Products/Semiconductor/Flash/OneNAND_TM/index.htm>.

config MTD_ONENAND_VERIFY_WRITE
	bool "Verify OneNAND page writes"
	depends on MTD_ONENAND
	help
	  This adds an extra check when data is written to the flash. The
	  OneNAND flash device internally checks only bits transitioning
	  from 1 to 0. There is a rare possibility that even though the
	  device thinks the write was successful, a bit could have been
	  flipped accidentaly due to device wear or something else.

config MTD_ONENAND_OMAP
	tristate "OneNAND Flash device on OMAP board"
	depends on ARCH_OMAP && MTD_ONENAND
	help
	  Support for OneNAND flash on TI OMAP board.

endmenu
+9 −0
Original line number Diff line number Diff line
#
# Makefile for the OneNAND MTD
#

# Core functionality.
obj-$(CONFIG_MTD_ONENAND)		+= onenand_base.o

# Board specific.
obj-$(CONFIG_MTD_ONENAND_OMAP)		+= omap-onenand.o
+178 −0
Original line number Diff line number Diff line
/*
 *  linux/drivers/mtd/onenand/omap-onenand.c
 *
 *  Copyright (c) 2005 Samsung Electronics
 *  Kyungmin Park <kyungmin.park@samsung.com>
 *
 *  Derived from linux/drivers/mtd/nand/omap-nand-flash.c
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 *  Overview:
 *   This is a device driver for the OneNAND flash device for TI OMAP boards.
 */

#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
#include <linux/mtd/partitions.h>

#include <asm/io.h>
#include <asm/arch/hardware.h>
#include <asm/arch/tc.h>
#include <asm/sizes.h>

#define OMAP_ONENAND_FLASH_START1	OMAP_CS2A_PHYS
#define OMAP_ONENAND_FLASH_START2	OMAP_CS0_PHYS
/*
 * MTD structure for OMAP board
 */
static struct mtd_info *omap_onenand_mtd = NULL;

/*
 * Define partitions for flash devices
 */

#ifdef CONFIG_MTD_PARTITIONS
static struct mtd_partition static_partition[] = {
	{
		.name		= "X-Loader + U-Boot",
		.offset		= 0,
		.size		= SZ_128K,
		.mask_flags	= MTD_WRITEABLE	/* force read-only */
 	},
	{
		.name		= "U-Boot Environment",
		.offset		= MTDPART_OFS_APPEND,
		.size		= SZ_128K,
		.mask_flags	= MTD_WRITEABLE	/* force read-only */
 	},
	{
		.name		= "kernel",
		.offset		= MTDPART_OFS_APPEND,
		.size		= 2 * SZ_1M
	},
	{
		.name		= "filesystem0",
		.offset		= MTDPART_OFS_APPEND,
		.size		= SZ_16M,
	},
	{
		.name		= "filesystem1",
		.offset		= MTDPART_OFS_APPEND,
		.size		= MTDPART_SIZ_FULL,
	},
};

const char *part_probes[] = { "cmdlinepart", NULL,  };

#endif

/* Scan to find existance of the device at base.
   This also allocates oob and data internal buffers */
static char onenand_name[] = "onenand";

/*
 * Main initialization routine
 */
static int __init omap_onenand_init (void)
{
	struct onenand_chip *this;
	struct mtd_partition *dynamic_partition = 0;
	int err = 0;

	/* Allocate memory for MTD device structure and private data */
	omap_onenand_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct onenand_chip),
				GFP_KERNEL);
	if (!omap_onenand_mtd) {
		printk (KERN_WARNING "Unable to allocate OneNAND MTD device structure.\n");
		err = -ENOMEM;
		goto out;
	}

	/* Get pointer to private data */
	this = (struct onenand_chip *) (&omap_onenand_mtd[1]);

	/* Initialize structures */
	memset((char *) omap_onenand_mtd, 0, sizeof(struct mtd_info) + sizeof(struct onenand_chip));

	/* Link the private data with the MTD structure */
	omap_onenand_mtd->priv = this;

        /* try the first address */
	this->base = ioremap(OMAP_ONENAND_FLASH_START1, SZ_128K);
	omap_onenand_mtd->name = onenand_name;
	if (onenand_scan(omap_onenand_mtd, 1)){
		/* try the second address */
		iounmap(this->base);
		this->base = ioremap(OMAP_ONENAND_FLASH_START2, SZ_128K);
		if (onenand_scan(omap_onenand_mtd, 1)) {
			iounmap(this->base);
                        err = -ENXIO;
                        goto out_mtd;
		}
	}

	/* Register the partitions */
	switch (omap_onenand_mtd->size) {
	case SZ_128M:
	case SZ_64M:
	case SZ_32M:
#ifdef CONFIG_MTD_PARTITIONS
		err = parse_mtd_partitions(omap_onenand_mtd, part_probes,
					&dynamic_partition, 0);
		if (err > 0)
			err = add_mtd_partitions(omap_onenand_mtd,
					dynamic_partition, err);
		else if (1)
			err = add_mtd_partitions(omap_onenand_mtd,
					static_partition,
					ARRAY_SIZE(static_partition));
		else
#endif
			err = add_mtd_device(omap_onenand_mtd);
		if (err)
			goto out_buf;
		break;

	default:
		printk(KERN_WARNING "Unsupported OneNAND device\n");
		err = -ENXIO;
		goto out_buf;
	}

	return 0;

out_buf:
	onenand_release(omap_onenand_mtd);
	iounmap(this->base);
out_mtd:
	kfree(omap_onenand_mtd);
out:
	return err;
}

/*
 * Clean up routine
 */
static void __exit omap_onenand_cleanup (void)
{
	struct onenand_chip *this = omap_onenand_mtd->priv;

	/* onenand_release frees MTD partitions, MTD structure
	   and onenand internal buffers */
	onenand_release(omap_onenand_mtd);
	iounmap(this->base);
	kfree(omap_onenand_mtd);
}

module_init(omap_onenand_init);
module_exit(omap_onenand_cleanup);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
MODULE_DESCRIPTION("Glue layer for OneNAND flash on OMAP boards");
Loading