/* 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 = mtd_device_register(mtd_cur, NULL, 0);
	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;
		mtd_device_unregister(&((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");
