/*
 * 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;

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

	*f_pos += count;
	return count;
}

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;

	switch (origin) {
	case SEEK_SET: /* seek relative to the beginning of the file */
		newpos = offset;
		break;
	case SEEK_CUR: /* seek relative to current position in the file */
		newpos = filp->f_pos + offset;
		break;
	case SEEK_END: /* seek relative to the end of the file */
		newpos = priv->fw_size - offset;
		break;
	default:
		return -EINVAL;
	}

	/* check for sanity */
	if (newpos > priv->fw_size)
		return -EINVAL;

	filp->f_pos = newpos;
	return newpos;
}

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);
