/*
 * CARMA Board DATA-FPGA Programmer
 *
 * Copyright (c) 2009-2011 Ira W. Snyder <iws@ovro.caltech.edu>
 *
 * 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.
 */

#include <linux/dma-mapping.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/completion.h>
#include <linux/miscdevice.h>
#include <linux/dmaengine.h>
#include <linux/interrupt.h>
#include <linux/highmem.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/leds.h>
#include <linux/slab.h>
#include <linux/kref.h>
#include <linux/fs.h>
#include <linux/io.h>

#include <media/videobuf-dma-sg.h>

/* MPC8349EMDS specific get_immrbase() */
#include <sysdev/fsl_soc.h>

static const char drv_name[] = "carma-fpga-program";

/*
 * Firmware images are always this exact size
 *
 * 12849552 bytes for a CARMA Digitizer Board (EP2S90 FPGAs)
 * 18662880 bytes for a CARMA Correlator Board (EP2S130 FPGAs)
 */
#define FW_SIZE_EP2S90		12849552
#define FW_SIZE_EP2S130		18662880

struct fpga_dev {
	struct miscdevice miscdev;

	/* Reference count */
	struct kref ref;

	/* Device Registers */
	struct device *dev;
	void __iomem *regs;
	void __iomem *immr;

	/* Freescale DMA Device */
	struct dma_chan *chan;

	/* Interrupts */
	int irq, status;
	struct completion completion;

	/* FPGA Bitfile */
	struct mutex lock;

	struct videobuf_dmabuf vb;
	bool vb_allocated;

	/* max size and written bytes */
	size_t fw_size;
	size_t bytes;
};

/*
 * FPGA Bitfile Helpers
 */

/**
 * fpga_drop_firmware_data() - drop the bitfile image from memory
 * @priv: the driver's private data structure
 *
 * LOCKING: must hold priv->lock
 */
static void fpga_drop_firmware_data(struct fpga_dev *priv)
{
	videobuf_dma_free(&priv->vb);
	priv->vb_allocated = false;
	priv->bytes = 0;
}

/*
 * Private Data Reference Count
 */

static void fpga_dev_remove(struct kref *ref)
{
	struct fpga_dev *priv = container_of(ref, struct fpga_dev, ref);

	/* free any firmware image that was not programmed */
	fpga_drop_firmware_data(priv);

	mutex_destroy(&priv->lock);
	kfree(priv);
}

/*
 * LED Trigger (could be a seperate module)
 */

/*
 * NOTE: this whole thing does have the problem that whenever the led's are
 * NOTE: first set to use the fpga trigger, they could be in the wrong state
 */

DEFINE_LED_TRIGGER(ledtrig_fpga);

static void ledtrig_fpga_programmed(bool enabled)
{
	if (enabled)
		led_trigger_event(ledtrig_fpga, LED_FULL);
	else
		led_trigger_event(ledtrig_fpga, LED_OFF);
}

/*
 * FPGA Register Helpers
 */

/* Register Definitions */
#define FPGA_CONFIG_CONTROL		0x40
#define FPGA_CONFIG_STATUS		0x44
#define FPGA_CONFIG_FIFO_SIZE		0x48
#define FPGA_CONFIG_FIFO_USED		0x4C
#define FPGA_CONFIG_TOTAL_BYTE_COUNT	0x50
#define FPGA_CONFIG_CUR_BYTE_COUNT	0x54

#define FPGA_FIFO_ADDRESS		0x3000

static int fpga_fifo_size(void __iomem *regs)
{
	return ioread32be(regs + FPGA_CONFIG_FIFO_SIZE);
}

#define CFG_STATUS_ERR_MASK	0xfffe

static int fpga_config_error(void __iomem *regs)
{
	return ioread32be(regs + FPGA_CONFIG_STATUS) & CFG_STATUS_ERR_MASK;
}

static int fpga_fifo_empty(void __iomem *regs)
{
	return ioread32be(regs + FPGA_CONFIG_FIFO_USED) == 0;
}

static void fpga_fifo_write(void __iomem *regs, u32 val)
{
	iowrite32be(val, regs + FPGA_FIFO_ADDRESS);
}

static void fpga_set_byte_count(void __iomem *regs, u32 count)
{
	iowrite32be(count, regs + FPGA_CONFIG_TOTAL_BYTE_COUNT);
}

#define CFG_CTL_ENABLE	(1 << 0)
#define CFG_CTL_RESET	(1 << 1)
#define CFG_CTL_DMA	(1 << 2)

static void fpga_programmer_enable(struct fpga_dev *priv, bool dma)
{
	u32 val;

	val = (dma) ? (CFG_CTL_ENABLE | CFG_CTL_DMA) : CFG_CTL_ENABLE;
	iowrite32be(val, priv->regs + FPGA_CONFIG_CONTROL);
}

static void fpga_programmer_disable(struct fpga_dev *priv)
{
	iowrite32be(0x0, priv->regs + FPGA_CONFIG_CONTROL);
}

static void fpga_dump_registers(struct fpga_dev *priv)
{
	u32 control, status, size, used, total, curr;

	/* good status: do nothing */
	if (priv->status == 0)
		return;

	/* Dump all status registers */
	control = ioread32be(priv->regs + FPGA_CONFIG_CONTROL);
	status = ioread32be(priv->regs + FPGA_CONFIG_STATUS);
	size = ioread32be(priv->regs + FPGA_CONFIG_FIFO_SIZE);
	used = ioread32be(priv->regs + FPGA_CONFIG_FIFO_USED);
	total = ioread32be(priv->regs + FPGA_CONFIG_TOTAL_BYTE_COUNT);
	curr = ioread32be(priv->regs + FPGA_CONFIG_CUR_BYTE_COUNT);

	dev_err(priv->dev, "Configuration failed, dumping status registers\n");
	dev_err(priv->dev, "Control:    0x%.8x\n", control);
	dev_err(priv->dev, "Status:     0x%.8x\n", status);
	dev_err(priv->dev, "FIFO Size:  0x%.8x\n", size);
	dev_err(priv->dev, "FIFO Used:  0x%.8x\n", used);
	dev_err(priv->dev, "FIFO Total: 0x%.8x\n", total);
	dev_err(priv->dev, "FIFO Curr:  0x%.8x\n", curr);
}

/*
 * FPGA Power Supply Code
 */

#define CTL_PWR_CONTROL		0x2006
#define CTL_PWR_STATUS		0x200A
#define CTL_PWR_FAIL		0x200B

#define PWR_CONTROL_ENABLE	0x01

#define PWR_STATUS_ERROR_MASK	0x10
#define PWR_STATUS_GOOD		0x0f

/*
 * Determine if the FPGA power is good for all supplies
 */
static bool fpga_power_good(struct fpga_dev *priv)
{
	u8 val;

	val = ioread8(priv->regs + CTL_PWR_STATUS);
	if (val & PWR_STATUS_ERROR_MASK)
		return false;

	return val == PWR_STATUS_GOOD;
}

/*
 * Disable the FPGA power supplies
 */
static void fpga_disable_power_supplies(struct fpga_dev *priv)
{
	unsigned long start;
	u8 val;

	iowrite8(0x0, priv->regs + CTL_PWR_CONTROL);

	/*
	 * Wait 500ms for the power rails to discharge
	 *
	 * Without this delay, the CTL-CPLD state machine can get into a
	 * state where it is waiting for the power-goods to assert, but they
	 * never do. This only happens when enabling and disabling the
	 * power sequencer very rapidly.
	 *
	 * The loop below will also wait for the power goods to de-assert,
	 * but testing has shown that they are always disabled by the time
	 * the sleep completes. However, omitting the sleep and only waiting
	 * for the power-goods to de-assert was not sufficient to ensure
	 * that the power sequencer would not wedge itself.
	 */
	msleep(500);

	start = jiffies;
	while (time_before(jiffies, start + HZ)) {
		val = ioread8(priv->regs + CTL_PWR_STATUS);
		if (!(val & PWR_STATUS_GOOD))
			break;

		usleep_range(5000, 10000);
	}

	val = ioread8(priv->regs + CTL_PWR_STATUS);
	if (val & PWR_STATUS_GOOD) {
		dev_err(priv->dev, "power disable failed: "
				   "power goods: status 0x%.2x\n", val);
	}

	if (val & PWR_STATUS_ERROR_MASK) {
		dev_err(priv->dev, "power disable failed: "
				   "alarm bit set: status 0x%.2x\n", val);
	}
}

/**
 * fpga_enable_power_supplies() - enable the DATA-FPGA power supplies
 * @priv: the driver's private data structure
 *
 * Enable the DATA-FPGA power supplies, waiting up to 1 second for
 * them to enable successfully.
 *
 * Returns 0 on success, -ERRNO otherwise
 */
static int fpga_enable_power_supplies(struct fpga_dev *priv)
{
	unsigned long start = jiffies;

	if (fpga_power_good(priv)) {
		dev_dbg(priv->dev, "power was already good\n");
		return 0;
	}

	iowrite8(PWR_CONTROL_ENABLE, priv->regs + CTL_PWR_CONTROL);
	while (time_before(jiffies, start + HZ)) {
		if (fpga_power_good(priv))
			return 0;

		usleep_range(5000, 10000);
	}

	return fpga_power_good(priv) ? 0 : -ETIMEDOUT;
}

/*
 * Determine if the FPGA power supplies are all enabled
 */
static bool fpga_power_enabled(struct fpga_dev *priv)
{
	u8 val;

	val = ioread8(priv->regs + CTL_PWR_CONTROL);
	if (val & PWR_CONTROL_ENABLE)
		return true;

	return false;
}

/*
 * Determine if the FPGA's are programmed and running correctly
 */
static bool fpga_running(struct fpga_dev *priv)
{
	if (!fpga_power_good(priv))
		return false;

	/* Check the config done bit */
	return ioread32be(priv->regs + FPGA_CONFIG_STATUS) & (1 << 18);
}

/*
 * FPGA Programming Code
 */

/**
 * fpga_program_block() - put a block of data into the programmer's FIFO
 * @priv: the driver's private data structure
 * @buf: the data to program
 * @count: the length of data to program (must be a multiple of 4 bytes)
 *
 * Returns 0 on success, -ERRNO otherwise
 */
static int fpga_program_block(struct fpga_dev *priv, void *buf, size_t count)
{
	u32 *data = buf;
	int size = fpga_fifo_size(priv->regs);
	int i, len;
	unsigned long timeout;

	/* enforce correct data length for the FIFO */
	BUG_ON(count % 4 != 0);

	while (count > 0) {

		/* Get the size of the block to write (maximum is FIFO_SIZE) */
		len = min_t(size_t, count, size);
		timeout = jiffies + HZ / 4;

		/* Write the block */
		for (i = 0; i < len / 4; i++)
			fpga_fifo_write(priv->regs, data[i]);

		/* Update the amounts left */
		count -= len;
		data += len / 4;

		/* Wait for the fifo to empty */
		while (true) {

			if (fpga_fifo_empty(priv->regs)) {
				break;
			} else {
				dev_dbg(priv->dev, "Fifo not empty\n");
				cpu_relax();
			}

			if (fpga_config_error(priv->regs)) {
				dev_err(priv->dev, "Error detected\n");
				return -EIO;
			}

			if (time_after(jiffies, timeout)) {
				dev_err(priv->dev, "Fifo drain timeout\n");
				return -ETIMEDOUT;
			}

			usleep_range(5000, 10000);
		}
	}

	return 0;
}

/**
 * fpga_program_cpu() - program the DATA-FPGA's using the CPU
 * @priv: the driver's private data structure
 *
 * This is useful when the DMA programming method fails. It is possible to
 * wedge the Freescale DMA controller such that the DMA programming method
 * always fails. This method has always succeeded.
 *
 * Returns 0 on success, -ERRNO otherwise
 */
static noinline int fpga_program_cpu(struct fpga_dev *priv)
{
	int ret;

	/* Disable the programmer */
	fpga_programmer_disable(priv);

	/* Set the total byte count */
	fpga_set_byte_count(priv->regs, priv->bytes);
	dev_dbg(priv->dev, "total byte count %u bytes\n", priv->bytes);

	/* Enable the controller for programming */
	fpga_programmer_enable(priv, false);
	dev_dbg(priv->dev, "enabled the controller\n");

	/* Write each chunk of the FPGA bitfile to FPGA programmer */
	ret = fpga_program_block(priv, priv->vb.vaddr, priv->bytes);
	if (ret)
		goto out_disable_controller;

	/* Wait for the interrupt handler to signal that programming finished */
	ret = wait_for_completion_timeout(&priv->completion, 2 * HZ);
	if (!ret) {
		dev_err(priv->dev, "Timed out waiting for completion\n");
		ret = -ETIMEDOUT;
		goto out_disable_controller;
	}

	/* Retrieve the status from the interrupt handler */
	ret = priv->status;

out_disable_controller:
	fpga_programmer_disable(priv);
	return ret;
}

#define FIFO_DMA_ADDRESS	0xf0003000
#define FIFO_MAX_LEN		4096

/**
 * fpga_program_dma() - program the DATA-FPGA's using the DMA engine
 * @priv: the driver's private data structure
 *
 * Program the DATA-FPGA's using the Freescale DMA engine. This requires that
 * the engine is programmed such that the hardware DMA request lines can
 * control the entire DMA transaction. The system controller FPGA then
 * completely offloads the programming from the CPU.
 *
 * Returns 0 on success, -ERRNO otherwise
 */
static noinline int fpga_program_dma(struct fpga_dev *priv)
{
	struct videobuf_dmabuf *vb = &priv->vb;
	struct dma_chan *chan = priv->chan;
	struct dma_async_tx_descriptor *tx;
	size_t num_pages, len, avail = 0;
	struct dma_slave_config config;
	struct scatterlist *sg;
	struct sg_table table;
	dma_cookie_t cookie;
	int ret, i;

	/* Disable the programmer */
	fpga_programmer_disable(priv);

	/* Allocate a scatterlist for the DMA destination */
	num_pages = DIV_ROUND_UP(priv->bytes, FIFO_MAX_LEN);
	ret = sg_alloc_table(&table, num_pages, GFP_KERNEL);
	if (ret) {
		dev_err(priv->dev, "Unable to allocate dst scatterlist\n");
		ret = -ENOMEM;
		goto out_return;
	}

	/*
	 * This is an ugly hack
	 *
	 * We fill in a scatterlist as if it were mapped for DMA. This is
	 * necessary because there exists no better structure for this
	 * inside the kernel code.
	 *
	 * As an added bonus, we can use the DMAEngine API for all of this,
	 * rather than inventing another extremely similar API.
	 */
	avail = priv->bytes;
	for_each_sg(table.sgl, sg, num_pages, i) {
		len = min_t(size_t, avail, FIFO_MAX_LEN);
		sg_dma_address(sg) = FIFO_DMA_ADDRESS;
		sg_dma_len(sg) = len;

		avail -= len;
	}

	/* Map the buffer for DMA */
	ret = videobuf_dma_map(priv->dev, &priv->vb);
	if (ret) {
		dev_err(priv->dev, "Unable to map buffer for DMA\n");
		goto out_free_table;
	}

	/*
	 * Configure the DMA channel to transfer FIFO_SIZE / 2 bytes per
	 * transaction, and then put it under external control
	 */
	memset(&config, 0, sizeof(config));
	config.direction = DMA_MEM_TO_DEV;
	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	config.dst_maxburst = fpga_fifo_size(priv->regs) / 2 / 4;
	ret = chan->device->device_control(chan, DMA_SLAVE_CONFIG,
					   (unsigned long)&config);
	if (ret) {
		dev_err(priv->dev, "DMA slave configuration failed\n");
		goto out_dma_unmap;
	}

	ret = chan->device->device_control(chan, FSLDMA_EXTERNAL_START, 1);
	if (ret) {
		dev_err(priv->dev, "DMA external control setup failed\n");
		goto out_dma_unmap;
	}

	/* setup and submit the DMA transaction */
	tx = chan->device->device_prep_dma_sg(chan,
					      table.sgl, num_pages,
					      vb->sglist, vb->sglen, 0);
	if (!tx) {
		dev_err(priv->dev, "Unable to prep DMA transaction\n");
		ret = -ENOMEM;
		goto out_dma_unmap;
	}

	cookie = tx->tx_submit(tx);
	if (dma_submit_error(cookie)) {
		dev_err(priv->dev, "Unable to submit DMA transaction\n");
		ret = -ENOMEM;
		goto out_dma_unmap;
	}

	dma_async_issue_pending(chan);

	/* Set the total byte count */
	fpga_set_byte_count(priv->regs, priv->bytes);
	dev_dbg(priv->dev, "total byte count %u bytes\n", priv->bytes);

	/* Enable the controller for DMA programming */
	fpga_programmer_enable(priv, true);
	dev_dbg(priv->dev, "enabled the controller\n");

	/* Wait for the interrupt handler to signal that programming finished */
	ret = wait_for_completion_timeout(&priv->completion, 2 * HZ);
	if (!ret) {
		dev_err(priv->dev, "Timed out waiting for completion\n");
		ret = -ETIMEDOUT;
		goto out_disable_controller;
	}

	/* Retrieve the status from the interrupt handler */
	ret = priv->status;

out_disable_controller:
	fpga_programmer_disable(priv);
out_dma_unmap:
	videobuf_dma_unmap(priv->dev, vb);
out_free_table:
	sg_free_table(&table);
out_return:
	return ret;
}

/*
 * Interrupt Handling
 */

static irqreturn_t fpga_irq(int irq, void *dev_id)
{
	struct fpga_dev *priv = dev_id;

	/* Save the status */
	priv->status = fpga_config_error(priv->regs) ? -EIO : 0;
	dev_dbg(priv->dev, "INTERRUPT status %d\n", priv->status);
	fpga_dump_registers(priv);

	/* Disabling the programmer clears the interrupt */
	fpga_programmer_disable(priv);

	/* Notify any waiters */
	complete(&priv->completion);

	return IRQ_HANDLED;
}

/*
 * SYSFS Helpers
 */

/**
 * fpga_do_stop() - deconfigure (reset) the DATA-FPGA's
 * @priv: the driver's private data structure
 *
 * LOCKING: must hold priv->lock
 */
static int fpga_do_stop(struct fpga_dev *priv)
{
	u32 val;

	/* Set the led to unprogrammed */
	ledtrig_fpga_programmed(false);

	/* Pulse the config line to reset the FPGA's */
	val = CFG_CTL_ENABLE | CFG_CTL_RESET;
	iowrite32be(val, priv->regs + FPGA_CONFIG_CONTROL);
	iowrite32be(0x0, priv->regs + FPGA_CONFIG_CONTROL);

	return 0;
}

static noinline int fpga_do_program(struct fpga_dev *priv)
{
	int ret;

	if (priv->bytes != priv->fw_size) {
		dev_err(priv->dev, "Incorrect bitfile size: got %zu bytes, "
				   "should be %zu bytes\n",
				   priv->bytes, priv->fw_size);
		return -EINVAL;
	}

	if (!fpga_power_enabled(priv)) {
		dev_err(priv->dev, "Power not enabled\n");
		return -EINVAL;
	}

	if (!fpga_power_good(priv)) {
		dev_err(priv->dev, "Power not good\n");
		return -EINVAL;
	}

	/* Set the LED to unprogrammed */
	ledtrig_fpga_programmed(false);

	/* Try to program the FPGA's using DMA */
	ret = fpga_program_dma(priv);

	/* If DMA failed or doesn't exist, try with CPU */
	if (ret) {
		dev_warn(priv->dev, "Falling back to CPU programming\n");
		ret = fpga_program_cpu(priv);
	}

	if (ret) {
		dev_err(priv->dev, "Unable to program FPGA's\n");
		return ret;
	}

	/* Drop the firmware bitfile from memory */
	fpga_drop_firmware_data(priv);

	dev_dbg(priv->dev, "FPGA programming successful\n");
	ledtrig_fpga_programmed(true);

	return 0;
}

/*
 * File Operations
 */

static int fpga_open(struct inode *inode, struct file *filp)
{
	/*
	 * The miscdevice layer puts our struct miscdevice into the
	 * filp->private_data field. We use this to find our private
	 * data and then overwrite it with our own private structure.
	 */
	struct fpga_dev *priv = container_of(filp->private_data,
					     struct fpga_dev, miscdev);
	unsigned int nr_pages;
	int ret;

	/* We only allow one process at a time */
	ret = mutex_lock_interruptible(&priv->lock);
	if (ret)
		return ret;

	filp->private_data = priv;
	kref_get(&priv->ref);

	/* Truncation: drop any existing data */
	if (filp->f_flags & O_TRUNC)
		priv->bytes = 0;

	/* Check if we have already allocated a buffer */
	if (priv->vb_allocated)
		return 0;

	/* Allocate a buffer to hold enough data for the bitfile */
	nr_pages = DIV_ROUND_UP(priv->fw_size, PAGE_SIZE);
	ret = videobuf_dma_init_kernel(&priv->vb, DMA_TO_DEVICE, nr_pages);
	if (ret) {
		dev_err(priv->dev, "unable to allocate data buffer\n");
		mutex_unlock(&priv->lock);
		kref_put(&priv->ref, fpga_dev_remove);
		return ret;
	}

	priv->vb_allocated = true;
	return 0;
}

static int fpga_release(struct inode *inode, struct file *filp)
{
	struct fpga_dev *priv = filp->private_data;

	mutex_unlock(&priv->lock);
	kref_put(&priv->ref, fpga_dev_remove);
	return 0;
}

static ssize_t fpga_write(struct file *filp, const char __user *buf,
			  size_t count, loff_t *f_pos)
{
	struct fpga_dev *priv = filp->private_data;

	/* FPGA bitfiles have an exact size: disallow anything else */
	if (priv->bytes >= priv->fw_size)
		return -ENOSPC;

	count = min_t(size_t, priv->fw_size - priv->bytes, count);
	if (copy_from_user(priv->vb.vaddr + priv->bytes, buf, count))
		return -EFAULT;

	priv->bytes += count;
	return count;
}

static ssize_t fpga_read(struct file *filp, char __user *buf, size_t count,
			 loff_t *f_pos)
{
	struct fpga_dev *priv = filp->private_data;
	return simple_read_from_buffer(buf, count, ppos,
				       priv->vb.vaddr, priv->bytes);
}

static loff_t fpga_llseek(struct file *filp, loff_t offset, int origin)
{
	struct fpga_dev *priv = filp->private_data;
	loff_t newpos;

	/* only read-only opens are allowed to seek */
	if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
		return -EINVAL;

	return fixed_size_llseek(file, offset, origin, priv->fw_size);
}

static const struct file_operations fpga_fops = {
	.open		= fpga_open,
	.release	= fpga_release,
	.write		= fpga_write,
	.read		= fpga_read,
	.llseek		= fpga_llseek,
};

/*
 * Device Attributes
 */

static ssize_t pfail_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
{
	struct fpga_dev *priv = dev_get_drvdata(dev);
	u8 val;

	val = ioread8(priv->regs + CTL_PWR_FAIL);
	return snprintf(buf, PAGE_SIZE, "0x%.2x\n", val);
}

static ssize_t pgood_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
{
	struct fpga_dev *priv = dev_get_drvdata(dev);
	return snprintf(buf, PAGE_SIZE, "%d\n", fpga_power_good(priv));
}

static ssize_t penable_show(struct device *dev, struct device_attribute *attr,
			    char *buf)
{
	struct fpga_dev *priv = dev_get_drvdata(dev);
	return snprintf(buf, PAGE_SIZE, "%d\n", fpga_power_enabled(priv));
}

static ssize_t penable_store(struct device *dev, struct device_attribute *attr,
			     const char *buf, size_t count)
{
	struct fpga_dev *priv = dev_get_drvdata(dev);
	unsigned long val;
	int ret;

	ret = kstrtoul(buf, 0, &val);
	if (ret)
		return ret;

	if (val) {
		ret = fpga_enable_power_supplies(priv);
		if (ret)
			return ret;
	} else {
		fpga_do_stop(priv);
		fpga_disable_power_supplies(priv);
	}

	return count;
}

static ssize_t program_show(struct device *dev, struct device_attribute *attr,
			    char *buf)
{
	struct fpga_dev *priv = dev_get_drvdata(dev);
	return snprintf(buf, PAGE_SIZE, "%d\n", fpga_running(priv));
}

static ssize_t program_store(struct device *dev, struct device_attribute *attr,
			     const char *buf, size_t count)
{
	struct fpga_dev *priv = dev_get_drvdata(dev);
	unsigned long val;
	int ret;

	ret = kstrtoul(buf, 0, &val);
	if (ret)
		return ret;

	/* We can't have an image writer and be programming simultaneously */
	if (mutex_lock_interruptible(&priv->lock))
		return -ERESTARTSYS;

	/* Program or Reset the FPGA's */
	ret = val ? fpga_do_program(priv) : fpga_do_stop(priv);
	if (ret)
		goto out_unlock;

	/* Success */
	ret = count;

out_unlock:
	mutex_unlock(&priv->lock);
	return ret;
}

static DEVICE_ATTR(power_fail, S_IRUGO, pfail_show, NULL);
static DEVICE_ATTR(power_good, S_IRUGO, pgood_show, NULL);
static DEVICE_ATTR(power_enable, S_IRUGO | S_IWUSR,
		   penable_show, penable_store);

static DEVICE_ATTR(program, S_IRUGO | S_IWUSR,
		   program_show, program_store);

static struct attribute *fpga_attributes[] = {
	&dev_attr_power_fail.attr,
	&dev_attr_power_good.attr,
	&dev_attr_power_enable.attr,
	&dev_attr_program.attr,
	NULL,
};

static const struct attribute_group fpga_attr_group = {
	.attrs = fpga_attributes,
};

/*
 * OpenFirmware Device Subsystem
 */

#define SYS_REG_VERSION		0x00
#define SYS_REG_GEOGRAPHIC	0x10

static bool dma_filter(struct dma_chan *chan, void *data)
{
	/*
	 * DMA Channel #0 is the only acceptable device
	 *
	 * This probably won't survive an unload/load cycle of the Freescale
	 * DMAEngine driver, but that won't be a problem
	 */
	return chan->chan_id == 0 && chan->device->dev_id == 0;
}

static int fpga_of_remove(struct platform_device *op)
{
	struct fpga_dev *priv = platform_get_drvdata(op);
	struct device *this_device = priv->miscdev.this_device;

	sysfs_remove_group(&this_device->kobj, &fpga_attr_group);
	misc_deregister(&priv->miscdev);

	free_irq(priv->irq, priv);
	irq_dispose_mapping(priv->irq);

	/* make sure the power supplies are off */
	fpga_disable_power_supplies(priv);

	/* unmap registers */
	iounmap(priv->immr);
	iounmap(priv->regs);

	dma_release_channel(priv->chan);

	/* drop our reference to the private data structure */
	kref_put(&priv->ref, fpga_dev_remove);
	return 0;
}

/* CTL-CPLD Version Register */
#define CTL_CPLD_VERSION	0x2000

static int fpga_of_probe(struct platform_device *op)
{
	struct device_node *of_node = op->dev.of_node;
	struct device *this_device;
	struct fpga_dev *priv;
	dma_cap_mask_t mask;
	u32 ver;
	int ret;

	/* Allocate private data */
	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		dev_err(&op->dev, "Unable to allocate private data\n");
		ret = -ENOMEM;
		goto out_return;
	}

	/* Setup the miscdevice */
	priv->miscdev.minor = MISC_DYNAMIC_MINOR;
	priv->miscdev.name = drv_name;
	priv->miscdev.fops = &fpga_fops;

	kref_init(&priv->ref);

	platform_set_drvdata(op, priv);
	priv->dev = &op->dev;
	mutex_init(&priv->lock);
	init_completion(&priv->completion);
	videobuf_dma_init(&priv->vb);

	dev_set_drvdata(priv->dev, priv);
	dma_cap_zero(mask);
	dma_cap_set(DMA_MEMCPY, mask);
	dma_cap_set(DMA_SLAVE, mask);
	dma_cap_set(DMA_SG, mask);

	/* Get control of DMA channel #0 */
	priv->chan = dma_request_channel(mask, dma_filter, NULL);
	if (!priv->chan) {
		dev_err(&op->dev, "Unable to acquire DMA channel #0\n");
		ret = -ENODEV;
		goto out_free_priv;
	}

	/* Remap the registers for use */
	priv->regs = of_iomap(of_node, 0);
	if (!priv->regs) {
		dev_err(&op->dev, "Unable to ioremap registers\n");
		ret = -ENOMEM;
		goto out_dma_release_channel;
	}

	/* Remap the IMMR for use */
	priv->immr = ioremap(get_immrbase(), 0x100000);
	if (!priv->immr) {
		dev_err(&op->dev, "Unable to ioremap IMMR\n");
		ret = -ENOMEM;
		goto out_unmap_regs;
	}

	/*
	 * Check that external DMA is configured
	 *
	 * U-Boot does this for us, but we should check it and bail out if
	 * there is a problem. Failing to have this register setup correctly
	 * will cause the DMA controller to transfer a single cacheline
	 * worth of data, then wedge itself.
	 */
	if ((ioread32be(priv->immr + 0x114) & 0xE00) != 0xE00) {
		dev_err(&op->dev, "External DMA control not configured\n");
		ret = -ENODEV;
		goto out_unmap_immr;
	}

	/*
	 * Check the CTL-CPLD version
	 *
	 * This driver uses the CTL-CPLD DATA-FPGA power sequencer, and we
	 * don't want to run on any version of the CTL-CPLD that does not use
	 * a compatible register layout.
	 *
	 * v2: changed register layout, added power sequencer
	 * v3: added glitch filter on the i2c overcurrent/overtemp outputs
	 */
	ver = ioread8(priv->regs + CTL_CPLD_VERSION);
	if (ver != 0x02 && ver != 0x03) {
		dev_err(&op->dev, "CTL-CPLD is not version 0x02 or 0x03!\n");
		ret = -ENODEV;
		goto out_unmap_immr;
	}

	/* Set the exact size that the firmware image should be */
	ver = ioread32be(priv->regs + SYS_REG_VERSION);
	priv->fw_size = (ver & (1 << 18)) ? FW_SIZE_EP2S130 : FW_SIZE_EP2S90;

	/* Find the correct IRQ number */
	priv->irq = irq_of_parse_and_map(of_node, 0);
	if (priv->irq == NO_IRQ) {
		dev_err(&op->dev, "Unable to find IRQ line\n");
		ret = -ENODEV;
		goto out_unmap_immr;
	}

	/* Request the IRQ */
	ret = request_irq(priv->irq, fpga_irq, IRQF_SHARED, drv_name, priv);
	if (ret) {
		dev_err(&op->dev, "Unable to request IRQ %d\n", priv->irq);
		ret = -ENODEV;
		goto out_irq_dispose_mapping;
	}

	/* Reset and stop the FPGA's, just in case */
	fpga_do_stop(priv);

	/* Register the miscdevice */
	ret = misc_register(&priv->miscdev);
	if (ret) {
		dev_err(&op->dev, "Unable to register miscdevice\n");
		goto out_free_irq;
	}

	/* Create the sysfs files */
	this_device = priv->miscdev.this_device;
	dev_set_drvdata(this_device, priv);
	ret = sysfs_create_group(&this_device->kobj, &fpga_attr_group);
	if (ret) {
		dev_err(&op->dev, "Unable to create sysfs files\n");
		goto out_misc_deregister;
	}

	dev_info(priv->dev, "CARMA FPGA Programmer: %s rev%s with %s FPGAs\n",
			(ver & (1 << 17)) ? "Correlator" : "Digitizer",
			(ver & (1 << 16)) ? "B" : "A",
			(ver & (1 << 18)) ? "EP2S130" : "EP2S90");

	return 0;

out_misc_deregister:
	misc_deregister(&priv->miscdev);
out_free_irq:
	free_irq(priv->irq, priv);
out_irq_dispose_mapping:
	irq_dispose_mapping(priv->irq);
out_unmap_immr:
	iounmap(priv->immr);
out_unmap_regs:
	iounmap(priv->regs);
out_dma_release_channel:
	dma_release_channel(priv->chan);
out_free_priv:
	kref_put(&priv->ref, fpga_dev_remove);
out_return:
	return ret;
}

static struct of_device_id fpga_of_match[] = {
	{ .compatible = "carma,fpga-programmer", },
	{},
};

static struct platform_driver fpga_of_driver = {
	.probe		= fpga_of_probe,
	.remove		= fpga_of_remove,
	.driver		= {
		.name		= drv_name,
		.of_match_table	= fpga_of_match,
		.owner		= THIS_MODULE,
	},
};

/*
 * Module Init / Exit
 */

static int __init fpga_init(void)
{
	led_trigger_register_simple("fpga", &ledtrig_fpga);
	return platform_driver_register(&fpga_of_driver);
}

static void __exit fpga_exit(void)
{
	platform_driver_unregister(&fpga_of_driver);
	led_trigger_unregister_simple(ledtrig_fpga);
}

MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
MODULE_DESCRIPTION("CARMA Board DATA-FPGA Programmer");
MODULE_LICENSE("GPL");

module_init(fpga_init);
module_exit(fpga_exit);
