/* vmu-flash.c
 * Driver for SEGA Dreamcast Visual Memory Unit
 *
 * Copyright (c) Adrian McMenamin 2002 - 2009
 * Copyright (c) Paul Mundt 2001
 *
 * Licensed under version 2 of the
 * GNU General Public Licence
 */
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/maple.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>

struct vmu_cache {
	unsigned char *buffer;		/* Cache */
	unsigned int block;		/* Which block was cached */
	unsigned long jiffies_atc;	/* When was it cached? */
	int valid;
};

struct mdev_part {
	struct maple_device *mdev;
	int partition;
};

struct vmupart {
	u16 user_blocks;
	u16 root_block;
	u16 numblocks;
	char *name;
	struct vmu_cache *pcache;
};

struct memcard {
	u16 tempA;
	u16 tempB;
	u32 partitions;
	u32 blocklen;
	u32 writecnt;
	u32 readcnt;
	u32 removeable;
	int partition;
	int read;
	unsigned char *blockread;
	struct vmupart *parts;
	struct mtd_info *mtd;
};

struct vmu_block {
	unsigned int num; /* block number */
	unsigned int ofs; /* block offset */
};

static struct vmu_block *ofs_to_block(unsigned long src_ofs,
	struct mtd_info *mtd, int partition)
{
	struct vmu_block *vblock;
	struct maple_device *mdev;
	struct memcard *card;
	struct mdev_part *mpart;
	int num;

	mpart = mtd->priv;
	mdev = mpart->mdev;
	card = maple_get_drvdata(mdev);

	if (src_ofs >= card->parts[partition].numblocks * card->blocklen)
		goto failed;

	num = src_ofs / card->blocklen;
	if (num > card->parts[partition].numblocks)
		goto failed;

	vblock = kmalloc(sizeof(struct vmu_block), GFP_KERNEL);
	if (!vblock)
		goto failed;

	vblock->num = num;
	vblock->ofs = src_ofs % card->blocklen;
	return vblock;

failed:
	return NULL;
}

/* Maple bus callback function for reads */
static void vmu_blockread(struct mapleq *mq)
{
	struct maple_device *mdev;
	struct memcard *card;

	mdev = mq->dev;
	card = maple_get_drvdata(mdev);
	/* copy the read in data */

	if (unlikely(!card->blockread))
		return;

	memcpy(card->blockread, mq->recvbuf->buf + 12,
		card->blocklen/card->readcnt);

}

/* Interface with maple bus to read blocks
 * caching the results so that other parts
 * of the driver can access block reads */
static int maple_vmu_read_block(unsigned int num, unsigned char *buf,
	struct mtd_info *mtd)
{
	struct memcard *card;
	struct mdev_part *mpart;
	struct maple_device *mdev;
	int partition, error = 0, x, wait;
	unsigned char *blockread = NULL;
	struct vmu_cache *pcache;
	__be32 sendbuf;

	mpart = mtd->priv;
	mdev = mpart->mdev;
	partition = mpart->partition;
	card = maple_get_drvdata(mdev);
	pcache = card->parts[partition].pcache;
	pcache->valid = 0;

	/* prepare the cache for this block */
	if (!pcache->buffer) {
		pcache->buffer = kmalloc(card->blocklen, GFP_KERNEL);
		if (!pcache->buffer) {
			dev_err(&mdev->dev, "VMU at (%d, %d) - read fails due"
				" to lack of memory\n", mdev->port,
				mdev->unit);
			error = -ENOMEM;
			goto outB;
		}
	}

	/*
	* Reads may be phased - again the hardware spec
	* supports this - though may not be any devices in
	* the wild that implement it, but we will here
	*/
	for (x = 0; x < card->readcnt; x++) {
		sendbuf = cpu_to_be32(partition << 24 | x << 16 | num);

		if (atomic_read(&mdev->busy) == 1) {
			wait_event_interruptible_timeout(mdev->maple_wait,
				atomic_read(&mdev->busy) == 0, HZ);
			if (atomic_read(&mdev->busy) == 1) {
				dev_notice(&mdev->dev, "VMU at (%d, %d)"
					" is busy\n", mdev->port, mdev->unit);
				error = -EAGAIN;
				goto outB;
			}
		}

		atomic_set(&mdev->busy, 1);
		blockread = kmalloc(card->blocklen/card->readcnt, GFP_KERNEL);
		if (!blockread) {
			error = -ENOMEM;
			atomic_set(&mdev->busy, 0);
			goto outB;
		}
		card->blockread = blockread;

		maple_getcond_callback(mdev, vmu_blockread, 0,
			MAPLE_FUNC_MEMCARD);
		error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
				MAPLE_COMMAND_BREAD, 2, &sendbuf);
		/* Very long timeouts seem to be needed when box is stressed */
		wait = wait_event_interruptible_timeout(mdev->maple_wait,
			(atomic_read(&mdev->busy) == 0 ||
			atomic_read(&mdev->busy) == 2), HZ * 3);
		/*
		* MTD layer does not handle hotplugging well
		* so have to return errors when VMU is unplugged
		* in the middle of a read (busy == 2)
		*/
		if (error || atomic_read(&mdev->busy) == 2) {
			if (atomic_read(&mdev->busy) == 2)
				error = -ENXIO;
			atomic_set(&mdev->busy, 0);
			card->blockread = NULL;
			goto outA;
		}
		if (wait == 0 || wait == -ERESTARTSYS) {
			card->blockread = NULL;
			atomic_set(&mdev->busy, 0);
			error = -EIO;
			list_del_init(&(mdev->mq->list));
			kfree(mdev->mq->sendbuf);
			mdev->mq->sendbuf = NULL;
			if (wait == -ERESTARTSYS) {
				dev_warn(&mdev->dev, "VMU read on (%d, %d)"
					" interrupted on block 0x%X\n",
					mdev->port, mdev->unit, num);
			} else
				dev_notice(&mdev->dev, "VMU read on (%d, %d)"
					" timed out on block 0x%X\n",
					mdev->port, mdev->unit, num);
			goto outA;
		}

		memcpy(buf + (card->blocklen/card->readcnt) * x, blockread,
			card->blocklen/card->readcnt);

		memcpy(pcache->buffer + (card->blocklen/card->readcnt) * x,
			card->blockread, card->blocklen/card->readcnt);
		card->blockread = NULL;
		pcache->block = num;
		pcache->jiffies_atc = jiffies;
		pcache->valid = 1;
		kfree(blockread);
	}

	return error;

outA:
	kfree(blockread);
outB:
	return error;
}

/* communicate with maple bus for phased writing */
static int maple_vmu_write_block(unsigned int num, const unsigned char *buf,
	struct mtd_info *mtd)
{
	struct memcard *card;
	struct mdev_part *mpart;
	struct maple_device *mdev;
	int partition, error, locking, x, phaselen, wait;
	__be32 *sendbuf;

	mpart = mtd->priv;
	mdev = mpart->mdev;
	partition = mpart->partition;
	card = maple_get_drvdata(mdev);

	phaselen = card->blocklen/card->writecnt;

	sendbuf = kmalloc(phaselen + 4, GFP_KERNEL);
	if (!sendbuf) {
		error = -ENOMEM;
		goto fail_nosendbuf;
	}
	for (x = 0; x < card->writecnt; x++) {
		sendbuf[0] = cpu_to_be32(partition << 24 | x << 16 | num);
		memcpy(&sendbuf[1], buf + phaselen * x, phaselen);
		/* wait until the device is not busy doing something else
		* or 1 second - which ever is longer */
		if (atomic_read(&mdev->busy) == 1) {
			wait_event_interruptible_timeout(mdev->maple_wait,
				atomic_read(&mdev->busy) == 0, HZ);
			if (atomic_read(&mdev->busy) == 1) {
				error = -EBUSY;
				dev_notice(&mdev->dev, "VMU write at (%d, %d)"
					"failed - device is busy\n",
					mdev->port, mdev->unit);
				goto fail_nolock;
			}
		}
		atomic_set(&mdev->busy, 1);

		locking = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
			MAPLE_COMMAND_BWRITE, phaselen / 4 + 2, sendbuf);
		wait = wait_event_interruptible_timeout(mdev->maple_wait,
			atomic_read(&mdev->busy) == 0, HZ/10);
		if (locking) {
			error = -EIO;
			atomic_set(&mdev->busy, 0);
			goto fail_nolock;
		}
		if (atomic_read(&mdev->busy) == 2) {
			atomic_set(&mdev->busy, 0);
		} else if (wait == 0 || wait == -ERESTARTSYS) {
			error = -EIO;
			dev_warn(&mdev->dev, "Write at (%d, %d) of block"
				" 0x%X at phase %d failed: could not"
				" communicate with VMU", mdev->port,
				mdev->unit, num, x);
			atomic_set(&mdev->busy, 0);
			kfree(mdev->mq->sendbuf);
			mdev->mq->sendbuf = NULL;
			list_del_init(&(mdev->mq->list));
			goto fail_nolock;
		}
	}
	kfree(sendbuf);

	return card->blocklen;

fail_nolock:
	kfree(sendbuf);
fail_nosendbuf:
	dev_err(&mdev->dev, "VMU (%d, %d): write failed\n", mdev->port,
		mdev->unit);
	return error;
}

/* mtd function to simulate reading byte by byte */
static unsigned char vmu_flash_read_char(unsigned long ofs, int *retval,
	struct mtd_info *mtd)
{
	struct vmu_block *vblock;
	struct memcard *card;
	struct mdev_part *mpart;
	struct maple_device *mdev;
	unsigned char *buf, ret;
	int partition, error;

	mpart = mtd->priv;
	mdev = mpart->mdev;
	partition = mpart->partition;
	card = maple_get_drvdata(mdev);
	*retval =  0;

	buf = kmalloc(card->blocklen, GFP_KERNEL);
	if (!buf) {
		*retval = 1;
		ret = -ENOMEM;
		goto finish;
	}

	vblock = ofs_to_block(ofs, mtd, partition);
	if (!vblock) {
		*retval = 3;
		ret = -ENOMEM;
		goto out_buf;
	}

	error = maple_vmu_read_block(vblock->num, buf, mtd);
	if (error) {
		ret = error;
		*retval = 2;
		goto out_vblock;
	}

	ret = buf[vblock->ofs];

out_vblock:
	kfree(vblock);
out_buf:
	kfree(buf);
finish:
	return ret;
}

/* mtd higher order function to read flash */
static int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
	size_t *retlen,  u_char *buf)
{
	struct maple_device *mdev;
	struct memcard *card;
	struct mdev_part *mpart;
	struct vmu_cache *pcache;
	struct vmu_block *vblock;
	int index = 0, retval, partition, leftover, numblocks;
	unsigned char cx;

	if (len < 1)
		return -EIO;

	mpart = mtd->priv;
	mdev = mpart->mdev;
	partition = mpart->partition;
	card = maple_get_drvdata(mdev);

	numblocks = card->parts[partition].numblocks;
	if (from + len > numblocks * card->blocklen)
		len = numblocks * card->blocklen - from;
	if (len == 0)
		return -EIO;
	/* Have we cached this bit already? */
	pcache = card->parts[partition].pcache;
	do {
		vblock =  ofs_to_block(from + index, mtd, partition);
		if (!vblock)
			return -ENOMEM;
		/* Have we cached this and is the cache valid and timely? */
		if (pcache->valid &&
			time_before(jiffies, pcache->jiffies_atc + HZ) &&
			(pcache->block == vblock->num)) {
			/* we have cached it, so do necessary copying */
			leftover = card->blocklen - vblock->ofs;
			if (vblock->ofs + len - index < card->blocklen) {
				/* only a bit of this block to copy */
				memcpy(buf + index,
					pcache->buffer + vblock->ofs,
					len - index);
				index = len;
			} else {
				/* otherwise copy remainder of whole block */
				memcpy(buf + index, pcache->buffer +
					vblock->ofs, leftover);
				index += leftover;
			}
		} else {
			/*
			* Not cached so read one byte -
			* but cache the rest of the block
			*/
			cx = vmu_flash_read_char(from + index, &retval, mtd);
			if (retval) {
				*retlen = index;
				kfree(vblock);
				return cx;
			}
			memset(buf + index, cx, 1);
			index++;
		}
		kfree(vblock);
	} while (len > index);
	*retlen = index;

	return 0;
}

static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
	size_t *retlen, const u_char *buf)
{
	struct maple_device *mdev;
	struct memcard *card;
	struct mdev_part *mpart;
	int index = 0, partition, error = 0, numblocks;
	struct vmu_cache *pcache;
	struct vmu_block *vblock;
	unsigned char *buffer;

	mpart = mtd->priv;
	mdev = mpart->mdev;
	partition = mpart->partition;
	card = maple_get_drvdata(mdev);

	/* simple sanity checks */
	if (len < 1) {
		error = -EIO;
		goto failed;
	}
	numblocks = card->parts[partition].numblocks;
	if (to + len > numblocks * card->blocklen)
		len = numblocks * card->blocklen - to;
	if (len == 0) {
		error = -EIO;
		goto failed;
	}

	vblock = ofs_to_block(to, mtd, partition);
	if (!vblock) {
		error = -ENOMEM;
		goto failed;
	}

	buffer = kmalloc(card->blocklen, GFP_KERNEL);
	if (!buffer) {
		error = -ENOMEM;
		goto fail_buffer;
	}

	do {
		/* Read in the block we are to write to */
		error = maple_vmu_read_block(vblock->num, buffer, mtd);
		if (error)
			goto fail_io;

		do {
			buffer[vblock->ofs] = buf[index];
			vblock->ofs++;
			index++;
			if (index >= len)
				break;
		} while (vblock->ofs < card->blocklen);

		/* write out new buffer */
		error = maple_vmu_write_block(vblock->num, buffer, mtd);
		/* invalidate the cache */
		pcache = card->parts[partition].pcache;
		pcache->valid = 0;

		if (error != card->blocklen)
			goto fail_io;

		vblock->num++;
		vblock->ofs = 0;
	} while (len > index);

	kfree(buffer);
	*retlen = index;
	kfree(vblock);
	return 0;

fail_io:
	kfree(buffer);
fail_buffer:
	kfree(vblock);
failed:
	dev_err(&mdev->dev, "VMU write failing with error %d\n", error);
	return error;
}

static void vmu_flash_sync(struct mtd_info *mtd)
{
	/* Do nothing here */
}

/* Maple bus callback function to recursively query hardware details */
static void vmu_queryblocks(struct mapleq *mq)
{
	struct maple_device *mdev;
	unsigned short *res;
	struct memcard *card;
	__be32 partnum;
	struct vmu_cache *pcache;
	struct mdev_part *mpart;
	struct mtd_info *mtd_cur;
	struct vmupart *part_cur;
	int error;

	mdev = mq->dev;
	card = maple_get_drvdata(mdev);
	res = (unsigned short *) (mq->recvbuf->buf);
	card->tempA = res[12];
	card->tempB = res[6];

	dev_info(&mdev->dev, "VMU device at partition %d has %d user "
		"blocks with a root block at %d\n", card->partition,
		card->tempA, card->tempB);

	part_cur = &card->parts[card->partition];
	part_cur->user_blocks = card->tempA;
	part_cur->root_block = card->tempB;
	part_cur->numblocks = card->tempB + 1;
	part_cur->name = kmalloc(12, GFP_KERNEL);
	if (!part_cur->name)
		goto fail_name;

	sprintf(part_cur->name, "vmu%d.%d.%d",
		mdev->port, mdev->unit, card->partition);
	mtd_cur = &card->mtd[card->partition];
	mtd_cur->name = part_cur->name;
	mtd_cur->type = 8;
	mtd_cur->flags = MTD_WRITEABLE|MTD_NO_ERASE;
	mtd_cur->size = part_cur->numblocks * card->blocklen;
	mtd_cur->erasesize = card->blocklen;
	mtd_cur->write = vmu_flash_write;
	mtd_cur->read = vmu_flash_read;
	mtd_cur->sync = vmu_flash_sync;
	mtd_cur->writesize = card->blocklen;

	mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL);
	if (!mpart)
		goto fail_mpart;

	mpart->mdev = mdev;
	mpart->partition = card->partition;
	mtd_cur->priv = mpart;
	mtd_cur->owner = THIS_MODULE;

	pcache = kzalloc(sizeof(struct vmu_cache), GFP_KERNEL);
	if (!pcache)
		goto fail_cache_create;
	part_cur->pcache = pcache;

	error = add_mtd_device(mtd_cur);
	if (error)
		goto fail_mtd_register;

	maple_getcond_callback(mdev, NULL, 0,
		MAPLE_FUNC_MEMCARD);

	/*
	* Set up a recursive call to the (probably theoretical)
	* second or more partition
	*/
	if (++card->partition < card->partitions) {
		partnum = cpu_to_be32(card->partition << 24);
		maple_getcond_callback(mdev, vmu_queryblocks, 0,
			MAPLE_FUNC_MEMCARD);
		maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
			MAPLE_COMMAND_GETMINFO, 2, &partnum);
	}
	return;

fail_mtd_register:
	dev_err(&mdev->dev, "Could not register maple device at (%d, %d)"
		"error is 0x%X\n", mdev->port, mdev->unit, error);
	for (error = 0; error <= card->partition; error++) {
		kfree(((card->parts)[error]).pcache);
		((card->parts)[error]).pcache = NULL;
	}
fail_cache_create:
fail_mpart:
	for (error = 0; error <= card->partition; error++) {
		kfree(((card->mtd)[error]).priv);
		((card->mtd)[error]).priv = NULL;
	}
	maple_getcond_callback(mdev, NULL, 0,
		MAPLE_FUNC_MEMCARD);
	kfree(part_cur->name);
fail_name:
	return;
}

/* Handles very basic info about the flash, queries for details */
static int __devinit vmu_connect(struct maple_device *mdev)
{
	unsigned long test_flash_data, basic_flash_data;
	int c, error;
	struct memcard *card;
	u32 partnum = 0;

	test_flash_data = be32_to_cpu(mdev->devinfo.function);
	/* Need to count how many bits are set - to find out which
	 * function_data element has details of the memory card
	 */
	c = hweight_long(test_flash_data);

	basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]);

	card = kmalloc(sizeof(struct memcard), GFP_KERNEL);
	if (!card) {
		error = -ENOMEM;
		goto fail_nomem;
	}

	card->partitions = (basic_flash_data >> 24 & 0xFF) + 1;
	card->blocklen = ((basic_flash_data >> 16 & 0xFF) + 1) << 5;
	card->writecnt = basic_flash_data >> 12 & 0xF;
	card->readcnt = basic_flash_data >> 8 & 0xF;
	card->removeable = basic_flash_data >> 7 & 1;

	card->partition = 0;

	/*
	* Not sure there are actually any multi-partition devices in the
	* real world, but the hardware supports them, so, so will we
	*/
	card->parts = kmalloc(sizeof(struct vmupart) * card->partitions,
		GFP_KERNEL);
	if (!card->parts) {
		error = -ENOMEM;
		goto fail_partitions;
	}

	card->mtd = kmalloc(sizeof(struct mtd_info) * card->partitions,
		GFP_KERNEL);
	if (!card->mtd) {
		error = -ENOMEM;
		goto fail_mtd_info;
	}

	maple_set_drvdata(mdev, card);

	/*
	* We want to trap meminfo not get cond
	* so set interval to zero, but rely on maple bus
	* driver to pass back the results of the meminfo
	*/
	maple_getcond_callback(mdev, vmu_queryblocks, 0,
		MAPLE_FUNC_MEMCARD);

	/* Make sure we are clear to go */
	if (atomic_read(&mdev->busy) == 1) {
		wait_event_interruptible_timeout(mdev->maple_wait,
			atomic_read(&mdev->busy) == 0, HZ);
		if (atomic_read(&mdev->busy) == 1) {
			dev_notice(&mdev->dev, "VMU at (%d, %d) is busy\n",
				mdev->port, mdev->unit);
			error = -EAGAIN;
			goto fail_device_busy;
		}
	}

	atomic_set(&mdev->busy, 1);

	/*
	* Set up the minfo call: vmu_queryblocks will handle
	* the information passed back
	*/
	error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
		MAPLE_COMMAND_GETMINFO, 2, &partnum);
	if (error) {
		dev_err(&mdev->dev, "Could not lock VMU at (%d, %d)"
			" error is 0x%X\n", mdev->port, mdev->unit, error);
		goto fail_mtd_info;
	}
	return 0;

fail_device_busy:
	kfree(card->mtd);
fail_mtd_info:
	kfree(card->parts);
fail_partitions:
	kfree(card);
fail_nomem:
	return error;
}

static void __devexit vmu_disconnect(struct maple_device *mdev)
{
	struct memcard *card;
	struct mdev_part *mpart;
	int x;

	mdev->callback = NULL;
	card = maple_get_drvdata(mdev);
	for (x = 0; x < card->partitions; x++) {
		mpart = ((card->mtd)[x]).priv;
		mpart->mdev = NULL;
		del_mtd_device(&((card->mtd)[x]));
		kfree(((card->parts)[x]).name);
	}
	kfree(card->parts);
	kfree(card->mtd);
	kfree(card);
}

/* Callback to handle eccentricities of both mtd subsystem
 * and general flakyness of Dreamcast VMUs
 */
static int vmu_can_unload(struct maple_device *mdev)
{
	struct memcard *card;
	int x;
	struct mtd_info *mtd;

	card = maple_get_drvdata(mdev);
	for (x = 0; x < card->partitions; x++) {
		mtd = &((card->mtd)[x]);
		if (mtd->usecount > 0)
			return 0;
	}
	return 1;
}

#define ERRSTR "VMU at (%d, %d) file error -"

static void vmu_file_error(struct maple_device *mdev, void *recvbuf)
{
	enum maple_file_errors error = ((int *)recvbuf)[1];

	switch (error) {

	case MAPLE_FILEERR_INVALID_PARTITION:
		dev_notice(&mdev->dev, ERRSTR " invalid partition number\n",
			mdev->port, mdev->unit);
		break;

	case MAPLE_FILEERR_PHASE_ERROR:
		dev_notice(&mdev->dev, ERRSTR " phase error\n",
			mdev->port, mdev->unit);
		break;

	case MAPLE_FILEERR_INVALID_BLOCK:
		dev_notice(&mdev->dev, ERRSTR " invalid block number\n",
			mdev->port, mdev->unit);
		break;

	case MAPLE_FILEERR_WRITE_ERROR:
		dev_notice(&mdev->dev, ERRSTR " write error\n",
			mdev->port, mdev->unit);
		break;

	case MAPLE_FILEERR_INVALID_WRITE_LENGTH:
		dev_notice(&mdev->dev, ERRSTR " invalid write length\n",
			mdev->port, mdev->unit);
		break;

	case MAPLE_FILEERR_BAD_CRC:
		dev_notice(&mdev->dev, ERRSTR " bad CRC\n",
			mdev->port, mdev->unit);
		break;

	default:
		dev_notice(&mdev->dev, ERRSTR " 0x%X\n",
			mdev->port, mdev->unit, error);
	}
}


static int __devinit probe_maple_vmu(struct device *dev)
{
	int error;
	struct maple_device *mdev = to_maple_dev(dev);
	struct maple_driver *mdrv = to_maple_driver(dev->driver);

	mdev->can_unload = vmu_can_unload;
	mdev->fileerr_handler = vmu_file_error;
	mdev->driver = mdrv;

	error = vmu_connect(mdev);
	if (error)
		return error;

	return 0;
}

static int __devexit remove_maple_vmu(struct device *dev)
{
	struct maple_device *mdev = to_maple_dev(dev);

	vmu_disconnect(mdev);
	return 0;
}

static struct maple_driver vmu_flash_driver = {
	.function =	MAPLE_FUNC_MEMCARD,
	.drv = {
		.name =		"Dreamcast_visual_memory",
		.probe =	probe_maple_vmu,
		.remove = 	__devexit_p(remove_maple_vmu),
	},
};

static int __init vmu_flash_map_init(void)
{
	return maple_driver_register(&vmu_flash_driver);
}

static void __exit vmu_flash_map_exit(void)
{
	maple_driver_unregister(&vmu_flash_driver);
}

module_init(vmu_flash_map_init);
module_exit(vmu_flash_map_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Adrian McMenamin");
MODULE_DESCRIPTION("Flash mapping for Sega Dreamcast visual memory");
