/*
 * Ceiva flash memory driver.
 * Copyright (C) 2002 Rob Scott <rscott@mtrob.fdns.net>
 *
 * Note: this driver supports jedec compatible devices. Modification
 * for CFI compatible devices should be straight forward: change
 * jedec_probe to cfi_probe.
 *
 * Based on: sa1100-flash.c, which has the following copyright:
 * Flash memory access on SA11x0 based devices
 *
 * (C) 2000 Nicolas Pitre <nico@fluxnic.net>
 *
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/concat.h>

#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/io.h>
#include <asm/sizes.h>

/*
 * This isn't complete yet, so...
 */
#define CONFIG_MTD_CEIVA_STATICMAP

#ifdef CONFIG_MTD_CEIVA_STATICMAP
/*
 * See include/linux/mtd/partitions.h for definition of the mtd_partition
 * structure.
 *
 * Please note:
 *  1. The flash size given should be the largest flash size that can
 *     be accomodated.
 *
 *  2. The bus width must defined in clps_setup_flash.
 *
 * The MTD layer will detect flash chip aliasing and reduce the size of
 * the map accordingly.
 *
 */

#ifdef CONFIG_ARCH_CEIVA
/* Flash / Partition sizing */
/* For the 28F8003, we use the block mapping to calcuate the sizes */
#define MAX_SIZE_KiB                  (16 + 8 + 8 + 96 + (7*128))
#define BOOT_PARTITION_SIZE_KiB       (16)
#define PARAMS_PARTITION_SIZE_KiB     (8)
#define KERNEL_PARTITION_SIZE_KiB     (4*128)
/* Use both remaing portion of first flash, and all of second flash */
#define ROOT_PARTITION_SIZE_KiB       (3*128) + (8*128)

static struct mtd_partition ceiva_partitions[] = {
	{
		.name = "Ceiva BOOT partition",
		.size   = BOOT_PARTITION_SIZE_KiB*1024,
		.offset = 0,

	},{
		.name = "Ceiva parameters partition",
		.size   = PARAMS_PARTITION_SIZE_KiB*1024,
		.offset = (16 + 8) * 1024,
	},{
		.name = "Ceiva kernel partition",
		.size = (KERNEL_PARTITION_SIZE_KiB)*1024,
		.offset = 0x20000,

	},{
		.name = "Ceiva root filesystem partition",
		.offset = MTDPART_OFS_APPEND,
		.size = (ROOT_PARTITION_SIZE_KiB)*1024,
	}
};
#endif

static int __init clps_static_partitions(struct mtd_partition **parts)
{
	int nb_parts = 0;

#ifdef CONFIG_ARCH_CEIVA
	if (machine_is_ceiva()) {
		*parts       = ceiva_partitions;
		nb_parts     = ARRAY_SIZE(ceiva_partitions);
	}
#endif
	return nb_parts;
}
#endif

struct clps_info {
	unsigned long base;
	unsigned long size;
	int width;
	void *vbase;
	struct map_info *map;
	struct mtd_info *mtd;
	struct resource *res;
};

#define NR_SUBMTD 4

static struct clps_info info[NR_SUBMTD];

static int __init clps_setup_mtd(struct clps_info *clps, int nr, struct mtd_info **rmtd)
{
	struct mtd_info *subdev[nr];
	struct map_info *maps;
	int i, found = 0, ret = 0;

	/*
	 * Allocate the map_info structs in one go.
	 */
	maps = kzalloc(sizeof(struct map_info) * nr, GFP_KERNEL);
	if (!maps)
		return -ENOMEM;
	/*
	 * Claim and then map the memory regions.
	 */
	for (i = 0; i < nr; i++) {
		if (clps[i].base == (unsigned long)-1)
			break;

		clps[i].res = request_mem_region(clps[i].base, clps[i].size, "clps flash");
		if (!clps[i].res) {
			ret = -EBUSY;
			break;
		}

		clps[i].map = maps + i;

		clps[i].map->name = "clps flash";
		clps[i].map->phys = clps[i].base;

		clps[i].vbase = ioremap(clps[i].base, clps[i].size);
		if (!clps[i].vbase) {
			ret = -ENOMEM;
			break;
		}

		clps[i].map->virt = (void __iomem *)clps[i].vbase;
		clps[i].map->bankwidth = clps[i].width;
		clps[i].map->size = clps[i].size;

		simple_map_init(&clps[i].map);

		clps[i].mtd = do_map_probe("jedec_probe", clps[i].map);
		if (clps[i].mtd == NULL) {
			ret = -ENXIO;
			break;
		}
		clps[i].mtd->owner = THIS_MODULE;
		subdev[i] = clps[i].mtd;

		printk(KERN_INFO "clps flash: JEDEC device at 0x%08lx, %dMiB, "
			"%d-bit\n", clps[i].base, clps[i].mtd->size >> 20,
			clps[i].width * 8);
		found += 1;
	}

	/*
	 * ENXIO is special.  It means we didn't find a chip when
	 * we probed.  We need to tear down the mapping, free the
	 * resource and mark it as such.
	 */
	if (ret == -ENXIO) {
		iounmap(clps[i].vbase);
		clps[i].vbase = NULL;
		release_resource(clps[i].res);
		clps[i].res = NULL;
	}

	/*
	 * If we found one device, don't bother with concat support.
	 * If we found multiple devices, use concat if we have it
	 * available, otherwise fail.
	 */
	if (ret == 0 || ret == -ENXIO) {
		if (found == 1) {
			*rmtd = subdev[0];
			ret = 0;
		} else if (found > 1) {
			/*
			 * We detected multiple devices.  Concatenate
			 * them together.
			 */
#ifdef CONFIG_MTD_CONCAT
			*rmtd = mtd_concat_create(subdev, found,
						  "clps flash");
			if (*rmtd == NULL)
				ret = -ENXIO;
#else
			printk(KERN_ERR "clps flash: multiple devices "
			       "found but MTD concat support disabled.\n");
			ret = -ENXIO;
#endif
		}
	}

	/*
	 * If we failed, clean up.
	 */
	if (ret) {
		do {
			if (clps[i].mtd)
				map_destroy(clps[i].mtd);
			if (clps[i].vbase)
				iounmap(clps[i].vbase);
			if (clps[i].res)
				release_resource(clps[i].res);
		} while (i--);

		kfree(maps);
	}

	return ret;
}

static void __exit clps_destroy_mtd(struct clps_info *clps, struct mtd_info *mtd)
{
	int i;

	del_mtd_partitions(mtd);

	if (mtd != clps[0].mtd)
		mtd_concat_destroy(mtd);

	for (i = NR_SUBMTD; i >= 0; i--) {
		if (clps[i].mtd)
			map_destroy(clps[i].mtd);
		if (clps[i].vbase)
			iounmap(clps[i].vbase);
		if (clps[i].res)
			release_resource(clps[i].res);
	}
	kfree(clps[0].map);
}

/*
 * We define the memory space, size, and width for the flash memory
 * space here.
 */

static int __init clps_setup_flash(void)
{
	int nr;

#ifdef CONFIG_ARCH_CEIVA
	if (machine_is_ceiva()) {
		info[0].base = CS0_PHYS_BASE;
		info[0].size = SZ_32M;
		info[0].width = CEIVA_FLASH_WIDTH;
		info[1].base = CS1_PHYS_BASE;
		info[1].size = SZ_32M;
		info[1].width = CEIVA_FLASH_WIDTH;
		nr = 2;
	}
#endif
	return nr;
}

static struct mtd_partition *parsed_parts;
static const char *probes[] = { "cmdlinepart", "RedBoot", NULL };

static void __init clps_locate_partitions(struct mtd_info *mtd)
{
	const char *part_type = NULL;
	int nr_parts = 0;
	do {
		/*
		 * Partition selection stuff.
		 */
		nr_parts = parse_mtd_partitions(mtd, probes, &parsed_parts, 0);
		if (nr_parts > 0) {
			part_type = "command line";
			break;
		}
#ifdef CONFIG_MTD_CEIVA_STATICMAP
		nr_parts = clps_static_partitions(&parsed_parts);
		if (nr_parts > 0) {
			part_type = "static";
			break;
		}
		printk("found: %d partitions\n", nr_parts);
#endif
	} while (0);

	if (nr_parts == 0) {
		printk(KERN_NOTICE "clps flash: no partition info "
			"available, registering whole flash\n");
		add_mtd_device(mtd);
	} else {
		printk(KERN_NOTICE "clps flash: using %s partition "
			"definition\n", part_type);
		add_mtd_partitions(mtd, parsed_parts, nr_parts);
	}

	/* Always succeeds. */
}

static void __exit clps_destroy_partitions(void)
{
	kfree(parsed_parts);
}

static struct mtd_info *mymtd;

static int __init clps_mtd_init(void)
{
	int ret;
	int nr;

	nr = clps_setup_flash();
	if (nr < 0)
		return nr;

	ret = clps_setup_mtd(info, nr, &mymtd);
	if (ret)
		return ret;

	clps_locate_partitions(mymtd);

	return 0;
}

static void __exit clps_mtd_cleanup(void)
{
	clps_destroy_mtd(info, mymtd);
	clps_destroy_partitions();
}

module_init(clps_mtd_init);
module_exit(clps_mtd_cleanup);

MODULE_AUTHOR("Rob Scott");
MODULE_DESCRIPTION("Cirrus Logic JEDEC map driver");
MODULE_LICENSE("GPL");
