/*
 * 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)
{
	u16 div = (speed_hz) ? dwspi->ssi_clk/speed_hz : 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 : spi->bits_per_word;
	hz = (t) ? t->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 (--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;

			/* can't change speed or bits in the middle of a
			 * message. must disable the controller for this.
			 */
			if (dwspi->tx_t->speed_hz
					|| dwspi->tx_t->bits_per_word) {
				dwspi->status = -ENOPROTOOPT;
				break;
			}

			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, NULL);
			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");
