// SPDX-License-Identifier: GPL-2.0-only
/* 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 <linux/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;

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 = { SBUS_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 (!of_node_name_eq(parent, "sbus") &&
	    !of_node_name_eq(parent, "sbi") &&
	    !of_node_name_eq(parent, "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 "%pOF: OBP Flash, RD %lx[%lx] WR %lx[%lx]\n",
	       op->dev.of_node,
	       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");
