/*
 * designware_spi.c
 *
 * Synopsys DesignWare AMBA SPI controller driver (master mode only)
 *
 * Author: Baruch Siach, Tk Open Systems
 *	baruch-NswTu9S1W3P6gbPvEgmw2w@...org
 *
 * Base on the Xilinx SPI controller driver by MontaVista
 *
 * 2002-2007 (c) MontaVista Software, Inc.  This file is licensed under the
 * terms of the GNU General Public License version 2.  This program is licensed
 * "as is" without any warranty of any kind, whether express or implied.
 *
 * 2008, 2009 (c) Provigent Ltd.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <linux/spi/designware.h>

#include <linux/clk.h>
#include <linux/err.h>
#include <mach/reset.h>

#define DESIGNWARE_SPI_NAME "comcerto_spi"

/* Register definitions as per "DesignWare DW_apb_ssi Databook", Capture 6. */

#define DWSPI_CTRLR0        0x00
#define DWSPI_CTRLR1        0x04
#define DWSPI_SSIENR        0x08
#define DWSPI_MWCR          0x0C
#define DWSPI_SER           0x10
#define DWSPI_BAUDR         0x14
#define DWSPI_TXFTLR        0x18
#define DWSPI_RXFTLR        0x1C
#define DWSPI_TXFLR         0x20
#define DWSPI_RXFLR         0x24
#define DWSPI_SR            0x28
#define DWSPI_IMR           0x2C
#define DWSPI_ISR           0x30
#define DWSPI_RISR          0x34
#define DWSPI_TXOICR        0x38
#define DWSPI_RXOICR        0x3C
#define DWSPI_RXUICR        0x40
#define DWSPI_ICR           0x44
#define DWSPI_DMACR         0x4C
#define DWSPI_DMATDLR       0x50
#define DWSPI_DMARDLR       0x54
#define DWSPI_IDR           0x58
#define DWSPI_SSI_COMP_VERSION 0x5C
#define DWSPI_DR            0x60

#define DWSPI_CTRLR0_DFS_MASK	0x000f
#define DWSPI_CTRLR0_SCPOL	0x0080
#define DWSPI_CTRLR0_SCPH	0x0040
#define DWSPI_CTRLR0_TMOD_MASK	0x0300

#define DWSPI_SR_BUSY_MASK	0x01
#define DWSPI_SR_TFNF_MASK	0x02
#define DWSPI_SR_TFE_MASK	0x04
#define DWSPI_SR_RFNE_MASK	0x08
#define DWSPI_SR_RFF_MASK	0x10

#define DWSPI_ISR_TXEIS_MASK	0x01
#define DWSPI_ISR_RXFIS_MASK	0x10

#define DWSPI_IMR_TXEIM_MASK	0x01
#define DWSPI_IMR_RXFIM_MASK	0x10

struct designware_spi {
	struct device *dev;
	struct workqueue_struct *workqueue;
	struct work_struct   work;

	struct tasklet_struct pump_transfers;

	struct mutex         lock; /* lock this struct except from queue */
	struct list_head     queue; /* spi_message queue */
	spinlock_t           qlock; /* lock the queue */

	void __iomem	*regs;	/* virt. address of the control registers */
	unsigned int ssi_clk;	/* clock in Hz */
	unsigned int tx_fifo_depth; /* bytes in TX FIFO */
	unsigned int rx_fifo_depth; /* bytes in RX FIFO */

	u32		irq;

	u8 bits_per_word;	/* current data frame size */
	struct spi_transfer *tx_t; /* current tx transfer */
	struct spi_transfer *rx_t; /* current rx transfer */
	const u8 *tx_ptr;       /* current tx buffer */
	u8 *rx_ptr;             /* current rx buffer */
	int remaining_tx_bytes;	/* bytes left to tx in the current transfer */
	int remaining_rx_bytes;	/* bytes left to rx in the current transfer */
	int status;             /* status of the current spi_transfer */

	struct completion done; /* signal the end of tx for current sequence */

	struct spi_device *spi; /* current spi slave device */
	struct clk	*clk_spi;
	struct list_head *transfers_list; /* head of the current sequence */
	unsigned int tx_count, rx_count; /* bytes in the current sequence */
};

static void dwspi_init_hw(struct designware_spi *dwspi)
{
	u16 ctrlr0;

	/* Disable the SPI master */
	writel(0, dwspi->regs + DWSPI_SSIENR);
	/* Disable all the interrupts just in case */
	writel(0, dwspi->regs + DWSPI_IMR);
	/* Set TX empty IRQ threshold */
	writew(dwspi->tx_fifo_depth / 2, dwspi->regs + DWSPI_TXFTLR);

    /* Set transmit & receive mode */
	ctrlr0 = readw(dwspi->regs + DWSPI_CTRLR0);
    ctrlr0 &= ~DWSPI_CTRLR0_TMOD_MASK;
	writew(ctrlr0, dwspi->regs + DWSPI_CTRLR0);
}

static void dwspi_baudcfg(struct designware_spi *dwspi, u32 speed_hz)
{
	/* Divisor must be an even number */
	u16 div = (speed_hz) ? DIV_ROUND_UP(dwspi->ssi_clk, speed_hz) + 1 &
		0xfffe : 0xffff;

	writew(div, dwspi->regs + DWSPI_BAUDR);
}

static void dwspi_enable(struct designware_spi *dwspi, int on)
{
	writel(on ? 1 : 0, dwspi->regs + DWSPI_SSIENR);
}

static void designware_spi_chipselect(struct spi_device *spi, int on)
{
	struct designware_spi *dwspi = spi_master_get_devdata(spi->master);
#if 0
	long gpio = (long) spi->controller_data;
	unsigned active = spi->mode & SPI_CS_HIGH;
#endif
	/*
	 * Note, the SPI controller must have been enabled at this point, i.e.
	 * SSIENR == 1
	 */

	if (on) {
	#if 0

		/* Turn the actual chip select on for GPIO chip selects */
		if (gpio >= 0)
			gpio_set_value(gpio, active);
	#endif
		/* Activate slave on the SPI controller */
		writel(1 << spi->chip_select, dwspi->regs + DWSPI_SER);
	} else {
		/* Deselect the slave on the SPI bus */
		writel(0, dwspi->regs + DWSPI_SER);
	#if 0
		if (gpio >= 0)
			gpio_set_value(gpio, !active);
	#endif
	}
}

static int designware_spi_setup_transfer(struct spi_device *spi,
		struct spi_transfer *t)
{
	u8 bits_per_word;
	u32 hz;
	struct designware_spi *dwspi = spi_master_get_devdata(spi->master);
	u16 ctrlr0 = readw(dwspi->regs + DWSPI_CTRLR0);

	bits_per_word = (t) ? (t->bits_per_word ? t->bits_per_word : spi->bits_per_word) : spi->bits_per_word;
	hz = (t) ? (t->speed_hz ? t->speed_hz : spi->max_speed_hz) : spi->max_speed_hz;

	if (bits_per_word < 4 || bits_per_word > 16) {
		dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
			__func__, bits_per_word);
		return -EINVAL;
	} else {
		ctrlr0 &= ~DWSPI_CTRLR0_DFS_MASK;
		ctrlr0 |= bits_per_word - 1;

		dwspi->bits_per_word = bits_per_word;
	}

	/* Set the SPI clock phase and polarity */
	if (spi->mode & SPI_CPHA)
		ctrlr0 |= DWSPI_CTRLR0_SCPH;
	else
		ctrlr0 &= ~DWSPI_CTRLR0_SCPH;
	if (spi->mode & SPI_CPOL)
		ctrlr0 |= DWSPI_CTRLR0_SCPOL;
	else
		ctrlr0 &= ~DWSPI_CTRLR0_SCPOL;

	writew(ctrlr0, dwspi->regs + DWSPI_CTRLR0);

	/* set speed */
	dwspi_baudcfg(dwspi, hz);

	return 0;
}

/* the spi->mode bits currently understood by this driver: */
#define MODEBITS (SPI_CPOL | SPI_CPHA)

static int designware_spi_setup(struct spi_device *spi)
{
	struct designware_spi *dwspi;
	int retval;

	dwspi = spi_master_get_devdata(spi->master);

	if (!spi->bits_per_word)
		spi->bits_per_word = 8;

	if (spi->mode & ~MODEBITS) {
		dev_err(&spi->dev, "%s, SP unsupported mode bits %x\n",
			__func__, spi->mode & ~MODEBITS);
		return -EINVAL;
	}

	if (spi->chip_select > spi->master->num_chipselect) {
		dev_err(&spi->dev,
				"setup: invalid chipselect %u (%u defined)\n",
				spi->chip_select, spi->master->num_chipselect);
		return -EINVAL;
	}

	retval = designware_spi_setup_transfer(spi, NULL);
	if (retval < 0)
		return retval;

	dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n",
		__func__, spi->mode & MODEBITS, spi->bits_per_word, 0);

	return 0;
}

static void designware_spi_do_tx(struct designware_spi *dwspi)
{
	u8 sr;
	int bytes_to_tx = dwspi->remaining_tx_bytes;
	u8 valid_tx_fifo_bytes = readb(dwspi->regs + DWSPI_TXFLR);
	u8 valid_rx_fifo_bytes = readb(dwspi->regs + DWSPI_RXFLR);
	int tx_limit = min(dwspi->tx_fifo_depth - valid_tx_fifo_bytes,\
			dwspi->rx_fifo_depth - valid_rx_fifo_bytes);

	/* Fill the Tx FIFO with as many bytes as possible */
	sr = readb(dwspi->regs + DWSPI_SR);
	while ((sr & DWSPI_SR_TFNF_MASK) && dwspi->remaining_tx_bytes > 0) {
		if (dwspi->bits_per_word <= 8) {
			u8 dr = (dwspi->tx_ptr) ? *dwspi->tx_ptr++ : 0;

			writeb(dr, dwspi->regs + DWSPI_DR);
			dwspi->remaining_tx_bytes--;
		} else {
			u16 dr = (dwspi->tx_ptr) ? *(u16 *) dwspi->tx_ptr : 0;

			dwspi->tx_ptr += 2;
			writew(dr, dwspi->regs + DWSPI_DR);
			dwspi->remaining_tx_bytes -= 2;
		}

		if(dwspi->bits_per_word <= 8){
			--tx_limit;
		}else{
			tx_limit -= 2;
		}

		if (tx_limit <= 0)
			break;

		sr = readb(dwspi->regs + DWSPI_SR);
	}

	dwspi->tx_count += bytes_to_tx - dwspi->remaining_tx_bytes;
}

/* Return 1 when done, 0 otherwise */
static int designware_spi_fill_tx_fifo(struct designware_spi *dwspi)
{
	unsigned cs_change = 0;
	unsigned int ser;

	ser = readw(dwspi->regs + DWSPI_SER);

	list_for_each_entry_from(dwspi->tx_t, dwspi->transfers_list,
		transfer_list) {
		if (dwspi->remaining_tx_bytes == 0) {
			/* Initialize new spi_transfer */
			dwspi->tx_ptr = dwspi->tx_t->tx_buf;
			dwspi->remaining_tx_bytes = dwspi->tx_t->len;
			dwspi->status = 0;

			if (!dwspi->tx_t->tx_buf && !dwspi->tx_t->rx_buf
					&& dwspi->tx_t->len) {
				dwspi->status = -EINVAL;
				break;
			}

			if (cs_change)
				break;
		}

		designware_spi_do_tx(dwspi);

		/* Don't advance dwspi->tx_t, we'll get back to this
		 * spi_transfer later
		 */
		if (dwspi->remaining_tx_bytes > 0)
		{
			return 0;
		}

		cs_change = dwspi->tx_t->cs_change;
	}

	complete(&dwspi->done);

	return 1;
}

static void designware_spi_do_rx(struct designware_spi *dwspi)
{
	u8 sr;
	int bytes_to_rx = dwspi->remaining_rx_bytes;

	sr = readb(dwspi->regs + DWSPI_SR);

	if (sr & DWSPI_SR_RFF_MASK) {
	#if 0
		dev_err(dwspi->dev, "%s: RX FIFO overflow\n", __func__);
		dwspi->status = -EIO;
	#endif
	}

	/* Read as long as RX FIFO is not empty */
	while ((sr & DWSPI_SR_RFNE_MASK) != 0
			&& dwspi->remaining_rx_bytes > 0) {
		int rx_level = readl(dwspi->regs + DWSPI_RXFLR);

		while (rx_level-- && dwspi->remaining_rx_bytes > 0) {
			if (dwspi->bits_per_word <= 8) {
				u8 data;

				data = readb(dwspi->regs + DWSPI_DR);
				dwspi->remaining_rx_bytes--;
				if (dwspi->rx_ptr)
					*dwspi->rx_ptr++ = data;
			} else {
				u16 data;

				data = readw(dwspi->regs + DWSPI_DR);
				dwspi->remaining_rx_bytes -= 2;
				if (dwspi->rx_ptr) {
					*(u16 *) dwspi->rx_ptr = data;
					dwspi->rx_ptr += 2;
				}
			}
		}
		sr = readb(dwspi->regs + DWSPI_SR);
	}

	dwspi->rx_count += (bytes_to_rx - dwspi->remaining_rx_bytes);
}

/* return 1 if cs_change is true, 0 otherwise */
static int designware_spi_read_rx_fifo(struct designware_spi *dwspi)
{
	unsigned cs_change = 0;
	unsigned int ser;

	ser = readw(dwspi->regs + DWSPI_SER);

	list_for_each_entry_from(dwspi->rx_t, dwspi->transfers_list,
			transfer_list) {
		if (dwspi->remaining_rx_bytes == 0) {
			dwspi->rx_ptr = dwspi->rx_t->rx_buf;
			dwspi->remaining_rx_bytes = dwspi->rx_t->len;

			if (cs_change)
				return 1;
		}

		designware_spi_do_rx(dwspi);

		/* The rx buffer is filling up with more bytes. Don't advance
		 * dwspi->rx_t, as we have more bytes to read in this
		 * spi_transfer.
		 */
		if (dwspi->remaining_rx_bytes > 0)
			return 0;

		cs_change = dwspi->rx_t->cs_change;
	}

	return 0;
}

/* interate through the list of spi_transfer elements.
 * stop at the end of the list or when t->cs_change is true.
 */
static void designware_spi_do_transfers(struct designware_spi *dwspi)
{
	int tx_done, cs_change;

	init_completion(&dwspi->done);

	/* transfer kickoff */
	tx_done = designware_spi_fill_tx_fifo(dwspi);
	designware_spi_chipselect(dwspi->spi, 1);

	if (!tx_done) {
		/* Enable the transmit empty interrupt, which we use to
		 * determine progress on the transmission in case we're
		 * not done yet.
		 */
		writeb(DWSPI_IMR_TXEIM_MASK, dwspi->regs + DWSPI_IMR);

		/* wait for tx completion */
		wait_for_completion(&dwspi->done);
	}

	/* This delay should be good enough for 100KHz spi transfers. Slower
	 * transfers may need a longer delay.
	 */
	//udelay(10);

	/* get remaining rx bytes */
    do {
		cs_change = designware_spi_read_rx_fifo(dwspi);
	} while (readb(dwspi->regs + DWSPI_SR) &
			(DWSPI_SR_BUSY_MASK | DWSPI_SR_RFNE_MASK));

	/* transaction is done */
	designware_spi_chipselect(dwspi->spi, 0);

	if (dwspi->status < 0)
		return;

	if (!cs_change && (dwspi->remaining_rx_bytes > 0 ||
			dwspi->remaining_tx_bytes > 0)) {
	#if 0
		dev_err(dwspi->dev, "%s: remaining_rx_bytes = %d, "
				"remaining_tx_bytes = %d\n",
				__func__,  dwspi->remaining_rx_bytes,
				dwspi->remaining_tx_bytes);
	#endif
		dwspi->status = -EIO;
    }

	if (dwspi->rx_count != dwspi->tx_count) {
	#if 0
		dev_err(dwspi->dev, "%s: rx_count == %d, tx_count == %d\n",
				__func__, dwspi->rx_count, dwspi->tx_count);
	#endif
		dwspi->status = -EIO;
    }
}

static int designware_spi_transfer(struct spi_device *spi,
		struct spi_message *mesg)
{
	struct designware_spi *dwspi = spi_master_get_devdata(spi->master);

	mesg->actual_length = 0;
	mesg->status = -EINPROGRESS;

	/* we can't block here, so we use a spinlock
	 * here instead of the global mutex
	 */
	spin_lock(&dwspi->qlock);
	list_add_tail(&mesg->queue, &dwspi->queue);
	queue_work(dwspi->workqueue, &dwspi->work);
	spin_unlock(&dwspi->qlock);

	return 0;
}

static void designware_work(struct work_struct *work)
{
	struct designware_spi *dwspi = container_of(work,
			struct designware_spi, work);

	mutex_lock(&dwspi->lock);
	spin_lock(&dwspi->qlock);

	while (!list_empty(&dwspi->queue)) {
		struct spi_message *m;

		m = container_of(dwspi->queue.next, struct spi_message, queue);
		list_del_init(&m->queue);
		spin_unlock(&dwspi->qlock);

		dwspi->spi = m->spi;
		dwspi->tx_t = dwspi->rx_t =
			list_first_entry(&m->transfers, struct spi_transfer,
					transfer_list);

		/*
		 * Interate through groups of spi_transfer structs
		 * that are separated by cs_change being true
		 */
		dwspi->transfers_list = &m->transfers;
		do {
			dwspi->remaining_tx_bytes =
				dwspi->remaining_rx_bytes = 0;
			dwspi->tx_count = dwspi->rx_count = 0;
			designware_spi_setup_transfer(m->spi, dwspi->tx_t);
			dwspi_enable(dwspi, 1);
			designware_spi_do_transfers(dwspi);
			dwspi_enable(dwspi, 0);
			if (dwspi->status < 0)
				break;
			m->actual_length +=
				dwspi->tx_count; /* same as rx_count */
		} while (&dwspi->tx_t->transfer_list != &m->transfers);

		m->status = dwspi->status;
		m->complete(m->context);
		spin_lock(&dwspi->qlock);
	}
	spin_unlock(&dwspi->qlock);
	mutex_unlock(&dwspi->lock);
}

static void designware_pump_transfers(unsigned long data)
{
	struct designware_spi *dwspi = (struct designware_spi *) data;

	designware_spi_read_rx_fifo(dwspi);
	if (!designware_spi_fill_tx_fifo(dwspi))
		/* reenable the interrupt */
		writeb(DWSPI_IMR_TXEIM_MASK, dwspi->regs + DWSPI_IMR);
}

static irqreturn_t designware_spi_irq(int irq, void *dev_id)
{
	struct designware_spi *dwspi = dev_id;

	tasklet_schedule(&dwspi->pump_transfers);
	/* disable the interrupt for now */
	writeb(0, dwspi->regs + DWSPI_IMR);

	return IRQ_HANDLED;
}

static void designware_spi_cleanup(struct spi_device *spi)
{
}

static int __init designware_spi_probe(struct platform_device *dev)
{
	int ret = 0;
	struct spi_master *master;
	struct designware_spi *dwspi;
	//struct designware_platform_data *pdata;
	struct spi_controller_pdata *pdata;
	struct resource *r;
	struct clk *clk_spi;

	pdata = dev->dev.platform_data;
	if (pdata == NULL) {
		dev_err(&dev->dev, "no device data specified\n");
		return -EINVAL;
	}

        if(memcmp(pdata->clk_name, "DUS", 3))
                c2000_block_reset(COMPONENT_AXI_LEGACY_SPI, 0);
        else
                c2000_block_reset(COMPONENT_AXI_FAST_SPI, 0);

	clk_spi = clk_get(NULL,pdata->clk_name);
	if (IS_ERR(clk_spi)) {
		ret = PTR_ERR(clk_spi);
		pr_err("%s:Unable to obtain spi clock: %d\n",\
				__func__, ret);
		goto err_clk;
	}

	clk_enable(clk_spi);

	printk ("%s:Initializing SPI Controller : Using dma=%d CLK(%s)=%ld Hz\n", __func__, \
			pdata->use_dma, pdata->clk_name, clk_get_rate(clk_spi));

	/* Get resources(memory, IRQ) associated with the device */
	master = spi_alloc_master(&dev->dev, sizeof(struct designware_spi));
	if (master == NULL) {
		ret = -ENOMEM;
		goto err_nomem;
	}

	master->mode_bits = SPI_CPOL | SPI_CPHA;
	master->bus_num = pdata->bus_num;
	master->num_chipselect = pdata->num_chipselects;
	master->setup = designware_spi_setup;
	master->transfer = designware_spi_transfer;
	master->cleanup = designware_spi_cleanup;
	platform_set_drvdata(dev, master);

	r = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (r == NULL) {
		ret = -ENODEV;
		goto put_master;
	}

	dwspi = spi_master_get_devdata(master);
	dwspi->clk_spi = clk_spi;
	dwspi->ssi_clk = clk_get_rate(dwspi->clk_spi);
	//dwspi->ssi_clk = pdata->max_freq;
	dwspi->tx_fifo_depth = TX_FIFO_DEPTH;
	dwspi->rx_fifo_depth = RX_FIFO_DEPTH;
#if 0
	dwspi->tx_fifo_depth = pdata->tx_fifo_depth;
	dwspi->rx_fifo_depth = pdata->rx_fifo_depth;
#endif
	dwspi->dev = &dev->dev;
	spin_lock_init(&dwspi->qlock);
	mutex_init(&dwspi->lock);
	INIT_LIST_HEAD(&dwspi->queue);
	INIT_WORK(&dwspi->work, designware_work);
	dwspi->workqueue =
		create_singlethread_workqueue(dev_name(master->dev.parent));
	
	if (dwspi->workqueue == NULL) {
		ret = -EBUSY;
		goto put_master;
	}
	tasklet_init(&dwspi->pump_transfers, designware_pump_transfers,
			(unsigned long) dwspi);

	if (!request_mem_region(r->start,
			r->end - r->start + 1, DESIGNWARE_SPI_NAME)) {
		ret = -ENXIO;
		goto destroy_wq;
	}

	dwspi->regs = ioremap(r->start, r->end - r->start + 1);
	if (dwspi->regs == NULL) {
		ret = -ENOMEM;
		goto destroy_wq;
	}

	dwspi->irq = platform_get_irq(dev, 0);
	if (dwspi->irq < 0) {
		ret = -ENXIO;
		goto unmap_io;
	}

	/* SPI controller initializations */
	dwspi_init_hw(dwspi);

	/* Register for SPI Interrupt */
	ret = request_irq(dwspi->irq, designware_spi_irq, 0,
			DESIGNWARE_SPI_NAME, dwspi);
	if (ret != 0)
		goto unmap_io;

	ret = spi_register_master(master);
    if (ret < 0)
		goto free_irq;

	dev_info(&dev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n",
			r->start, (u32)dwspi->regs, dwspi->irq);

	return ret;

free_irq:
	free_irq(dwspi->irq, dwspi);
unmap_io:
	iounmap(dwspi->regs);
destroy_wq:
	destroy_workqueue(dwspi->workqueue);
put_master:
	spi_master_put(master);
err_nomem:
	clk_disable(clk_spi);
	clk_put(clk_spi);
err_clk:
        if(memcmp(pdata->clk_name, "DUS", 3))
                c2000_block_reset(COMPONENT_AXI_LEGACY_SPI, 1);
        else
                c2000_block_reset(COMPONENT_AXI_FAST_SPI, 1);

	return ret;
}

static int __devexit designware_spi_remove(struct platform_device *dev)
{
	struct designware_spi *dwspi;
	struct spi_master *master;
	struct spi_controller_pdata *pdata;

	master = platform_get_drvdata(dev);
	dwspi = spi_master_get_devdata(master);

	free_irq(dwspi->irq, dwspi);
	iounmap(dwspi->regs);
	destroy_workqueue(dwspi->workqueue);
	tasklet_kill(&dwspi->pump_transfers);
	platform_set_drvdata(dev, 0);
	spi_master_put(master);
	clk_disable(dwspi->clk_spi);
	clk_put(dwspi->clk_spi);

        pdata = dev->dev.platform_data;
        if(!pdata)
        {
                return -EINVAL;
        }

        if(memcmp(pdata->clk_name, "DUS", 3))
                c2000_block_reset(COMPONENT_AXI_LEGACY_SPI, 1);
        else
                c2000_block_reset(COMPONENT_AXI_FAST_SPI, 1);

	return 0;
}

#if CONFIG_PM
static int designware_spi_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct designware_spi *dwspi;
	struct spi_master *master;

	master = platform_get_drvdata(pdev);
	dwspi = spi_master_get_devdata(master);

        /* Disable the SPI master */
        writel(0, dwspi->regs + DWSPI_SSIENR);

        clk_disable(dwspi->clk_spi);

        return 0;

}

static int designware_spi_resume(struct platform_device *pdev)
{
	struct designware_spi *dwspi;
	struct spi_master *master;

	master = platform_get_drvdata(pdev);
	dwspi = spi_master_get_devdata(master);

        clk_enable(dwspi->clk_spi);
	dwspi_init_hw(dwspi);

        return 0;
}
#endif

/* work with hotplug and coldplug */
MODULE_ALIAS("platform:" DESIGNWARE_SPI_NAME);

static struct platform_driver designware_spi_driver = {
	.probe  = designware_spi_probe,
	.remove	= __devexit_p(designware_spi_remove),
#if CONFIG_PM
        .suspend        = designware_spi_suspend,
        .resume         = designware_spi_resume,
#endif
	.driver = {
		.name = DESIGNWARE_SPI_NAME,
		.owner = THIS_MODULE,
	},
};

static int __init designware_spi_init(void)
{
	return platform_driver_register(&designware_spi_driver);
}
module_init(designware_spi_init);

static void __exit designware_spi_exit(void)
{
	platform_driver_unregister(&designware_spi_driver);
}
module_exit(designware_spi_exit);

MODULE_AUTHOR("Baruch Siach <baruch-NswTu9S1W3P6gbPvEgmw2w@...org>");
MODULE_DESCRIPTION("Synopsys DesignWare SPI driver");
MODULE_LICENSE("GPL");
