/*
 * 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/fsldma.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 = dmaengine_slave_config(chan, &config);
	if (ret) {
		dev_err(priv->dev, "DMA slave configuration failed\n");
		goto out_dma_unmap;
	}

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

	/* setup and submit the DMA transaction */

	tx = dmaengine_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);
