/* flash.c: Allow mmap access to the OBP Flash, for OBP updates.
 *
 * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/fcntl.h>
#include <linux/poll.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/of.h>
#include <linux/of_device.h>

#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/upa.h>

static DEFINE_MUTEX(flash_mutex);
static DEFINE_SPINLOCK(flash_lock);
static struct {
	unsigned long read_base;	/* Physical read address */
	unsigned long write_base;	/* Physical write address */
	unsigned long read_size;	/* Size of read area */
	unsigned long write_size;	/* Size of write area */
	unsigned long busy;		/* In use? */
} flash;

#define FLASH_MINOR	152

static int
flash_mmap(struct file *file, struct vm_area_struct *vma)
{
	unsigned long addr;
	unsigned long size;

	spin_lock(&flash_lock);
	if (flash.read_base == flash.write_base) {
		addr = flash.read_base;
		size = flash.read_size;
	} else {
		if ((vma->vm_flags & VM_READ) &&
		    (vma->vm_flags & VM_WRITE)) {
			spin_unlock(&flash_lock);
			return -EINVAL;
		}
		if (vma->vm_flags & VM_READ) {
			addr = flash.read_base;
			size = flash.read_size;
		} else if (vma->vm_flags & VM_WRITE) {
			addr = flash.write_base;
			size = flash.write_size;
		} else {
			spin_unlock(&flash_lock);
			return -ENXIO;
		}
	}
	spin_unlock(&flash_lock);

	if ((vma->vm_pgoff << PAGE_SHIFT) > size)
		return -ENXIO;
	addr = vma->vm_pgoff + (addr >> PAGE_SHIFT);

	if (vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)) > size)
		size = vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT));

	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

	if (io_remap_pfn_range(vma, vma->vm_start, addr, size, vma->vm_page_prot))
		return -EAGAIN;
		
	return 0;
}

static long long
flash_llseek(struct file *file, long long offset, int origin)
{
	mutex_lock(&flash_mutex);
	switch (origin) {
		case 0:
			file->f_pos = offset;
			break;
		case 1:
			file->f_pos += offset;
			if (file->f_pos > flash.read_size)
				file->f_pos = flash.read_size;
			break;
		case 2:
			file->f_pos = flash.read_size;
			break;
		default:
			mutex_unlock(&flash_mutex);
			return -EINVAL;
	}
	mutex_unlock(&flash_mutex);
	return file->f_pos;
}

static ssize_t
flash_read(struct file * file, char __user * buf,
	   size_t count, loff_t *ppos)
{
	loff_t p = *ppos;
	int i;

	if (count > flash.read_size - p)
		count = flash.read_size - p;

	for (i = 0; i < count; i++) {
		u8 data = upa_readb(flash.read_base + p + i);
		if (put_user(data, buf))
			return -EFAULT;
		buf++;
	}

	*ppos += count;
	return count;
}

static int
flash_open(struct inode *inode, struct file *file)
{
	mutex_lock(&flash_mutex);
	if (test_and_set_bit(0, (void *)&flash.busy) != 0) {
		mutex_unlock(&flash_mutex);
		return -EBUSY;
	}

	mutex_unlock(&flash_mutex);
	return 0;
}

static int
flash_release(struct inode *inode, struct file *file)
{
	spin_lock(&flash_lock);
	flash.busy = 0;
	spin_unlock(&flash_lock);

	return 0;
}

static const struct file_operations flash_fops = {
	/* no write to the Flash, use mmap
	 * and play flash dependent tricks.
	 */
	.owner =	THIS_MODULE,
	.llseek =	flash_llseek,
	.read =		flash_read,
	.mmap =		flash_mmap,
	.open =		flash_open,
	.release =	flash_release,
};

static struct miscdevice flash_dev = { FLASH_MINOR, "flash", &flash_fops };

static int flash_probe(struct platform_device *op)
{
	struct device_node *dp = op->dev.of_node;
	struct device_node *parent;

	parent = dp->parent;

	if (strcmp(parent->name, "sbus") &&
	    strcmp(parent->name, "sbi") &&
	    strcmp(parent->name, "ebus"))
		return -ENODEV;

	flash.read_base = op->resource[0].start;
	flash.read_size = resource_size(&op->resource[0]);
	if (op->resource[1].flags) {
		flash.write_base = op->resource[1].start;
		flash.write_size = resource_size(&op->resource[1]);
	} else {
		flash.write_base = op->resource[0].start;
		flash.write_size = resource_size(&op->resource[0]);
	}
	flash.busy = 0;

	printk(KERN_INFO "%s: OBP Flash, RD %lx[%lx] WR %lx[%lx]\n",
	       op->dev.of_node->full_name,
	       flash.read_base, flash.read_size,
	       flash.write_base, flash.write_size);

	return misc_register(&flash_dev);
}

static int flash_remove(struct platform_device *op)
{
	misc_deregister(&flash_dev);

	return 0;
}

static const struct of_device_id flash_match[] = {
	{
		.name = "flashprom",
	},
	{},
};
MODULE_DEVICE_TABLE(of, flash_match);

static struct platform_driver flash_driver = {
	.driver = {
		.name = "flash",
		.of_match_table = flash_match,
	},
	.probe		= flash_probe,
	.remove		= flash_remove,
};

module_platform_driver(flash_driver);

MODULE_LICENSE("GPL");
