/*
 * Normal mappings of chips in physical memory for OF devices
 *
 * Copyright (C) 2006 MontaVista Software Inc.
 * Author: Vitaly Wool <vwool@ru.mvista.com>
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/of_device.h>
#include <asm/of_platform.h>

struct physmap_flash_info {
	struct mtd_info		*mtd;
	struct map_info		map;
	struct resource		*res;
#ifdef CONFIG_MTD_PARTITIONS
	int			nr_parts;
	struct mtd_partition	*parts;
#endif
};

static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL };
#ifdef CONFIG_MTD_PARTITIONS
static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
#endif

#ifdef CONFIG_MTD_PARTITIONS
static int parse_flash_partitions(struct device_node *node,
		struct mtd_partition **parts)
{
	int i, plen, retval = -ENOMEM;
	const  u32  *part;
	const  char *name;

	part = get_property(node, "partitions", &plen);
	if (part == NULL)
		goto err;

	retval = plen / (2 * sizeof(u32));
	*parts = kzalloc(retval * sizeof(struct mtd_partition), GFP_KERNEL);
	if (*parts == NULL) {
		printk(KERN_ERR "Can't allocate the flash partition data!\n");
		goto err;
	}

	name = get_property(node, "partition-names", &plen);

	for (i = 0; i < retval; i++) {
		(*parts)[i].offset = *part++;
		(*parts)[i].size   = *part & ~1;
		if (*part++ & 1) /* bit 0 set signifies read only partition */
			(*parts)[i].mask_flags = MTD_WRITEABLE;

		if (name != NULL && plen > 0) {
			int len = strlen(name) + 1;

			(*parts)[i].name = (char *)name;
			plen -= len;
			name += len;
		} else
			(*parts)[i].name = "unnamed";
	}
err:
	return retval;
}
#endif

static int of_physmap_remove(struct of_device *dev)
{
	struct physmap_flash_info *info;

	info = dev_get_drvdata(&dev->dev);
	if (info == NULL)
		return 0;
	dev_set_drvdata(&dev->dev, NULL);

	if (info->mtd != NULL) {
#ifdef CONFIG_MTD_PARTITIONS
		if (info->nr_parts) {
			del_mtd_partitions(info->mtd);
			kfree(info->parts);
		} else {
			del_mtd_device(info->mtd);
		}
#else
		del_mtd_device(info->mtd);
#endif
		map_destroy(info->mtd);
	}

	if (info->map.virt != NULL)
		iounmap(info->map.virt);

	if (info->res != NULL) {
		release_resource(info->res);
		kfree(info->res);
	}

	return 0;
}

static int __devinit of_physmap_probe(struct of_device *dev, const struct of_device_id *match)
{
	struct device_node *dp = dev->node;
	struct resource res;
	struct physmap_flash_info *info;
	const char **probe_type;
	const char *of_probe;
	const u32 *width;
	int err;


	if (of_address_to_resource(dp, 0, &res)) {
		dev_err(&dev->dev, "Can't get the flash mapping!\n");
		err = -EINVAL;
		goto err_out;
	}

       	dev_dbg(&dev->dev, "physmap flash device: %.8llx at %.8llx\n",
	    (unsigned long long)res.end - res.start + 1,
	    (unsigned long long)res.start);

	info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL);
	if (info == NULL) {
		err = -ENOMEM;
		goto err_out;
	}
	memset(info, 0, sizeof(*info));

	dev_set_drvdata(&dev->dev, info);

	info->res = request_mem_region(res.start, res.end - res.start + 1,
			dev->dev.bus_id);
	if (info->res == NULL) {
		dev_err(&dev->dev, "Could not reserve memory region\n");
		err = -ENOMEM;
		goto err_out;
	}

	width = get_property(dp, "bank-width", NULL);
	if (width == NULL) {
		dev_err(&dev->dev, "Can't get the flash bank width!\n");
		err = -EINVAL;
		goto err_out;
	}

	info->map.name = dev->dev.bus_id;
	info->map.phys = res.start;
	info->map.size = res.end - res.start + 1;
	info->map.bankwidth = *width;

	info->map.virt = ioremap(info->map.phys, info->map.size);
	if (info->map.virt == NULL) {
		dev_err(&dev->dev, "Failed to ioremap flash region\n");
		err = EIO;
		goto err_out;
	}

	simple_map_init(&info->map);

	of_probe = get_property(dp, "probe-type", NULL);
	if (of_probe == NULL) {
		probe_type = rom_probe_types;
		for (; info->mtd == NULL && *probe_type != NULL; probe_type++)
			info->mtd = do_map_probe(*probe_type, &info->map);
	} else if (!strcmp(of_probe, "CFI"))
		info->mtd = do_map_probe("cfi_probe", &info->map);
	else if (!strcmp(of_probe, "JEDEC"))
		info->mtd = do_map_probe("jedec_probe", &info->map);
	else {
 		if (strcmp(of_probe, "ROM"))
			dev_dbg(&dev->dev, "map_probe: don't know probe type "
			"'%s', mapping as rom\n");
		info->mtd = do_map_probe("mtd_rom", &info->map);
	}
	if (info->mtd == NULL) {
		dev_err(&dev->dev, "map_probe failed\n");
		err = -ENXIO;
		goto err_out;
	}
	info->mtd->owner = THIS_MODULE;

#ifdef CONFIG_MTD_PARTITIONS
	err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0);
	if (err > 0) {
		add_mtd_partitions(info->mtd, info->parts, err);
	} else if ((err = parse_flash_partitions(dp, &info->parts)) > 0) {
		dev_info(&dev->dev, "Using OF partition information\n");
		add_mtd_partitions(info->mtd, info->parts, err);
		info->nr_parts = err;
	} else
#endif

	add_mtd_device(info->mtd);
	return 0;

err_out:
	of_physmap_remove(dev);
	return err;

	return 0;


}

static struct of_device_id of_physmap_match[] = {
	{
		.type		= "rom",
		.compatible	= "direct-mapped"
	},
	{ },
};

MODULE_DEVICE_TABLE(of, of_physmap_match);


static struct of_platform_driver of_physmap_flash_driver = {
	.name		= "physmap-flash",
	.match_table	= of_physmap_match,
	.probe		= of_physmap_probe,
	.remove		= of_physmap_remove,
};

static int __init of_physmap_init(void)
{
	return of_register_platform_driver(&of_physmap_flash_driver);
}

static void __exit of_physmap_exit(void)
{
	of_unregister_platform_driver(&of_physmap_flash_driver);
}

module_init(of_physmap_init);
module_exit(of_physmap_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
MODULE_DESCRIPTION("Configurable MTD map driver for OF");
