/* IBM POWER Barrier Synchronization Register Driver
 *
 * Copyright IBM Corporation 2008
 *
 * Author: Sonny Rao <sonnyrao@us.ibm.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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <asm/pgtable.h>
#include <asm/io.h>

/*
 This driver exposes a special register which can be used for fast
 synchronization across a large SMP machine.  The hardware is exposed
 as an array of bytes where each process will write to one of the bytes to
 indicate it has finished the current stage and this update is broadcast to
 all processors without having to bounce a cacheline between them. In
 POWER5 and POWER6 there is one of these registers per SMP,  but it is
 presented in two forms; first, it is given as a whole and then as a number
 of smaller registers which alias to parts of the single whole register.
 This can potentially allow multiple groups of processes to each have their
 own private synchronization device.

 Note that this hardware *must* be written to using *only* single byte writes.
 It may be read using 1, 2, 4, or 8 byte loads which must be aligned since
 this region is treated as cache-inhibited  processes should also use a
 full sync before and after writing to the BSR to ensure all stores and
 the BSR update have made it to all chips in the system
*/

/* This is arbitrary number, up to Power6 it's been 17 or fewer  */
#define BSR_MAX_DEVS (32)

struct bsr_dev {
	u64      bsr_addr;     /* Real address */
	u64      bsr_len;      /* length of mem region we can map */
	unsigned bsr_bytes;    /* size of the BSR reg itself */
	unsigned bsr_stride;   /* interval at which BSR repeats in the page */
	unsigned bsr_type;     /* maps to enum below */
	unsigned bsr_num;      /* bsr id number for its type */
	int      bsr_minor;

	struct list_head bsr_list;

	dev_t    bsr_dev;
	struct cdev bsr_cdev;
	struct device *bsr_device;
	char     bsr_name[32];

};

static unsigned total_bsr_devs;
static struct list_head bsr_devs = LIST_HEAD_INIT(bsr_devs);
static struct class *bsr_class;
static int bsr_major;

enum {
	BSR_8    = 0,
	BSR_16   = 1,
	BSR_64   = 2,
	BSR_128  = 3,
	BSR_4096 = 4,
	BSR_UNKNOWN = 5,
	BSR_MAX  = 6,
};

static unsigned bsr_types[BSR_MAX];

static ssize_t
bsr_size_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct bsr_dev *bsr_dev = dev_get_drvdata(dev);
	return sprintf(buf, "%u\n", bsr_dev->bsr_bytes);
}

static ssize_t
bsr_stride_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct bsr_dev *bsr_dev = dev_get_drvdata(dev);
	return sprintf(buf, "%u\n", bsr_dev->bsr_stride);
}

static ssize_t
bsr_len_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct bsr_dev *bsr_dev = dev_get_drvdata(dev);
	return sprintf(buf, "%llu\n", bsr_dev->bsr_len);
}

static struct device_attribute bsr_dev_attrs[] = {
	__ATTR(bsr_size, S_IRUGO, bsr_size_show, NULL),
	__ATTR(bsr_stride, S_IRUGO, bsr_stride_show, NULL),
	__ATTR(bsr_length, S_IRUGO, bsr_len_show, NULL),
	__ATTR_NULL
};

static int bsr_mmap(struct file *filp, struct vm_area_struct *vma)
{
	unsigned long size   = vma->vm_end - vma->vm_start;
	struct bsr_dev *dev = filp->private_data;
	int ret;

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

	/* check for the case of a small BSR device and map one 4k page for it*/
	if (dev->bsr_len < PAGE_SIZE && size == PAGE_SIZE)
		ret = remap_4k_pfn(vma, vma->vm_start, dev->bsr_addr >> 12,
				   vma->vm_page_prot);
	else if (size <= dev->bsr_len)
		ret = io_remap_pfn_range(vma, vma->vm_start,
					 dev->bsr_addr >> PAGE_SHIFT,
					 size, vma->vm_page_prot);
	else
		return -EINVAL;

	if (ret)
		return -EAGAIN;

	return 0;
}

static int bsr_open(struct inode * inode, struct file * filp)
{
	struct cdev *cdev = inode->i_cdev;
	struct bsr_dev *dev = container_of(cdev, struct bsr_dev, bsr_cdev);

	filp->private_data = dev;
	return 0;
}

static const struct file_operations bsr_fops = {
	.owner = THIS_MODULE,
	.mmap  = bsr_mmap,
	.open  = bsr_open,
};

static void bsr_cleanup_devs(void)
{
	struct bsr_dev *cur, *n;

	list_for_each_entry_safe(cur, n, &bsr_devs, bsr_list) {
		if (cur->bsr_device) {
			cdev_del(&cur->bsr_cdev);
			device_del(cur->bsr_device);
		}
		list_del(&cur->bsr_list);
		kfree(cur);
	}
}

static int bsr_add_node(struct device_node *bn)
{
	int bsr_stride_len, bsr_bytes_len, num_bsr_devs;
	const u32 *bsr_stride;
	const u32 *bsr_bytes;
	unsigned i;
	int ret = -ENODEV;

	bsr_stride = of_get_property(bn, "ibm,lock-stride", &bsr_stride_len);
	bsr_bytes  = of_get_property(bn, "ibm,#lock-bytes", &bsr_bytes_len);

	if (!bsr_stride || !bsr_bytes ||
	    (bsr_stride_len != bsr_bytes_len)) {
		printk(KERN_ERR "bsr of-node has missing/incorrect property\n");
		return ret;
	}

	num_bsr_devs = bsr_bytes_len / sizeof(u32);

	for (i = 0 ; i < num_bsr_devs; i++) {
		struct bsr_dev *cur = kzalloc(sizeof(struct bsr_dev),
					      GFP_KERNEL);
		struct resource res;
		int result;

		if (!cur) {
			printk(KERN_ERR "Unable to alloc bsr dev\n");
			ret = -ENOMEM;
			goto out_err;
		}

		result = of_address_to_resource(bn, i, &res);
		if (result < 0) {
			printk(KERN_ERR "bsr of-node has invalid reg property, skipping\n");
			kfree(cur);
			continue;
		}

		cur->bsr_minor  = i + total_bsr_devs;
		cur->bsr_addr   = res.start;
		cur->bsr_len    = res.end - res.start + 1;
		cur->bsr_bytes  = bsr_bytes[i];
		cur->bsr_stride = bsr_stride[i];
		cur->bsr_dev    = MKDEV(bsr_major, i + total_bsr_devs);

		/* if we have a bsr_len of > 4k and less then PAGE_SIZE (64k pages) */
		/* we can only map 4k of it, so only advertise the 4k in sysfs */
		if (cur->bsr_len > 4096 && cur->bsr_len < PAGE_SIZE)
			cur->bsr_len = 4096;

		switch(cur->bsr_bytes) {
		case 8:
			cur->bsr_type = BSR_8;
			break;
		case 16:
			cur->bsr_type = BSR_16;
			break;
		case 64:
			cur->bsr_type = BSR_64;
			break;
		case 128:
			cur->bsr_type = BSR_128;
			break;
		case 4096:
			cur->bsr_type = BSR_4096;
			break;
		default:
			cur->bsr_type = BSR_UNKNOWN;
		}

		cur->bsr_num = bsr_types[cur->bsr_type];
		snprintf(cur->bsr_name, 32, "bsr%d_%d",
			 cur->bsr_bytes, cur->bsr_num);

		cdev_init(&cur->bsr_cdev, &bsr_fops);
		result = cdev_add(&cur->bsr_cdev, cur->bsr_dev, 1);
		if (result) {
			kfree(cur);
			goto out_err;
		}

		cur->bsr_device = device_create(bsr_class, NULL, cur->bsr_dev,
						cur, cur->bsr_name);
		if (!cur->bsr_device) {
			printk(KERN_ERR "device_create failed for %s\n",
			       cur->bsr_name);
			cdev_del(&cur->bsr_cdev);
			kfree(cur);
			goto out_err;
		}

		bsr_types[cur->bsr_type] = cur->bsr_num + 1;
		list_add_tail(&cur->bsr_list, &bsr_devs);
	}

	total_bsr_devs += num_bsr_devs;

	return 0;

 out_err:

	bsr_cleanup_devs();
	return ret;
}

static int bsr_create_devs(struct device_node *bn)
{
	int ret;

	while (bn) {
		ret = bsr_add_node(bn);
		if (ret) {
			of_node_put(bn);
			return ret;
		}
		bn = of_find_compatible_node(bn, NULL, "ibm,bsr");
	}
	return 0;
}

static int __init bsr_init(void)
{
	struct device_node *np;
	dev_t bsr_dev = MKDEV(bsr_major, 0);
	int ret = -ENODEV;
	int result;

	np = of_find_compatible_node(NULL, NULL, "ibm,bsr");
	if (!np)
		goto out_err;

	bsr_class = class_create(THIS_MODULE, "bsr");
	if (IS_ERR(bsr_class)) {
		printk(KERN_ERR "class_create() failed for bsr_class\n");
		goto out_err_1;
	}
	bsr_class->dev_attrs = bsr_dev_attrs;

	result = alloc_chrdev_region(&bsr_dev, 0, BSR_MAX_DEVS, "bsr");
	bsr_major = MAJOR(bsr_dev);
	if (result < 0) {
		printk(KERN_ERR "alloc_chrdev_region() failed for bsr\n");
		goto out_err_2;
	}

	if ((ret = bsr_create_devs(np)) < 0) {
		np = NULL;
		goto out_err_3;
	}

	return 0;

 out_err_3:
	unregister_chrdev_region(bsr_dev, BSR_MAX_DEVS);

 out_err_2:
	class_destroy(bsr_class);

 out_err_1:
	of_node_put(np);

 out_err:

	return ret;
}

static void __exit  bsr_exit(void)
{

	bsr_cleanup_devs();

	if (bsr_class)
		class_destroy(bsr_class);

	if (bsr_major)
		unregister_chrdev_region(MKDEV(bsr_major, 0), BSR_MAX_DEVS);
}

module_init(bsr_init);
module_exit(bsr_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sonny Rao <sonnyrao@us.ibm.com>");
