/*
 * intel_mid_ssp_spi.c
 * This driver supports Bulverde SSP core used on Intel MID platforms
 * It supports SSP of Moorestown & Medfield platforms and handles clock
 * slave & master modes.
 *
 * Copyright (c) 2010, Intel Corporation.
 *  Ken Mills <ken.k.mills@intel.com>
 *  Sylvain Centelles <sylvain.centelles@intel.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

/*
 * Note:
 *
 * Supports DMA and non-interrupt polled transfers.
 *
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/highmem.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/intel_mid_dma.h>
#include <linux/pm_qos.h>
#include <linux/pm_runtime.h>
#include <linux/completion.h>
#include <asm/intel-mid.h>

#include <linux/spi/spi.h>
#include <linux/spi/intel_mid_ssp_spi.h>

#define DRIVER_NAME "intel_mid_ssp_spi_unified"

MODULE_AUTHOR("Ken Mills");
MODULE_DESCRIPTION("Bulverde SSP core SPI contoller");
MODULE_LICENSE("GPL");

static int ssp_timing_wr;

#ifdef DUMP_RX
static void dump_trailer(const struct device *dev, char *buf, int len, int sz)
{
	int tlen1 = (len < sz ? len : sz);
	int tlen2 =  ((len - sz) > sz) ? sz : (len - sz);
	unsigned char *p;
	static char msg[MAX_SPI_TRANSFER_SIZE];

	memset(msg, '\0', sizeof(msg));
	p = buf;
	while (p < buf + tlen1)
		sprintf(msg, "%s%02x", msg, (unsigned int)*p++);

	if (tlen2 > 0) {
		sprintf(msg, "%s .....", msg);
		p = (buf+len) - tlen2;
		while (p < buf + len)
			sprintf(msg, "%s%02x", msg, (unsigned int)*p++);
	}

	dev_info(dev, "DUMP: %p[0:%d ... %d:%d]:%s", buf, tlen1 - 1,
		   len-tlen2, len - 1, msg);
}
#endif

static inline u8 ssp_cfg_get_mode(u8 ssp_cfg)
{
	if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER ||
	    intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_ANNIEDALE)
		return (ssp_cfg) & 0x03;
	else
		return (ssp_cfg) & 0x07;
}

static inline u8 ssp_cfg_get_spi_bus_nb(u8 ssp_cfg)
{
	if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER ||
	    intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_ANNIEDALE)
		return ((ssp_cfg) >> 2) & 0x07;
	else
		return ((ssp_cfg) >> 3) & 0x07;
}

static inline u8 ssp_cfg_is_spi_slave(u8 ssp_cfg)
{
	if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER ||
	    intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_ANNIEDALE)
		return (ssp_cfg) & 0x20;
	else
		return (ssp_cfg) & 0x40;
}

static inline u32 is_tx_fifo_empty(struct ssp_drv_context *sspc)
{
	u32 sssr;
	sssr = read_SSSR(sspc->ioaddr);
	if ((sssr & SSSR_TFL_MASK) || (sssr & SSSR_TNF) == 0)
		return 0;
	else
		return 1;
}

static inline u32 is_rx_fifo_empty(struct ssp_drv_context *sspc)
{
	return ((read_SSSR(sspc->ioaddr) & SSSR_RNE) == 0);
}

static inline void disable_interface(struct ssp_drv_context *sspc)
{
	void *reg = sspc->ioaddr;
	write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
}

static inline void disable_triggers(struct ssp_drv_context *sspc)
{
	void *reg = sspc->ioaddr;
	write_SSCR1(read_SSCR1(reg) & ~sspc->cr1_sig, reg);
}


static void flush(struct ssp_drv_context *sspc)
{
	void *reg = sspc->ioaddr;
	u32 i = 0;

	/* If the transmit fifo is not empty, reset the interface. */
	if (!is_tx_fifo_empty(sspc)) {
		dev_err(&sspc->pdev->dev, "TX FIFO not empty. Reset of SPI IF");
		disable_interface(sspc);
		return;
	}

	dev_dbg(&sspc->pdev->dev, " SSSR=%x\r\n", read_SSSR(reg));
	while (!is_rx_fifo_empty(sspc) && (i < SPI_FIFO_SIZE + 1)) {
		read_SSDR(reg);
		i++;
	}
	WARN(i > 0, "%d words flush occured\n", i);

	return;
}

static int null_writer(struct ssp_drv_context *sspc)
{
	void *reg = sspc->ioaddr;
	u8 n_bytes = sspc->n_bytes;

	if (((read_SSSR(reg) & SSSR_TFL_MASK) == SSSR_TFL_MASK)
		|| (sspc->tx == sspc->tx_end))
		return 0;

	write_SSDR(0, reg);
	sspc->tx += n_bytes;

	return n_bytes;
}

static int null_reader(struct ssp_drv_context *sspc)
{
	void *reg = sspc->ioaddr;
	u8 n_bytes = sspc->n_bytes;
	size_t pkg_len = sspc->len;

	while ((read_SSSR(reg) & SSSR_RNE)
		&& (pkg_len > 0)) {
		read_SSDR(reg);
		sspc->rx += n_bytes;
		pkg_len -= n_bytes;
	}

	return sspc->rx == sspc->rx_end;
}

static int u8_writer(struct ssp_drv_context *sspc)
{
	void *reg = sspc->ioaddr;
	if (((read_SSSR(reg) & SSSR_TFL_MASK) == SSSR_TFL_MASK)
		|| (sspc->tx == sspc->tx_end))
		return 0;

	write_SSDR(*(u8 *)(sspc->tx), reg);
	++sspc->tx;

	return 1;
}

static int u8_reader(struct ssp_drv_context *sspc)
{
	void *reg = sspc->ioaddr;
	size_t pkg_len = sspc->len;

	while ((read_SSSR(reg) & SSSR_RNE)
		&& (pkg_len > 0)) {
		*(u8 *)(sspc->rx) = read_SSDR(reg);
		++sspc->rx;
		--pkg_len;
	}

	return sspc->rx == sspc->rx_end;
}

static int u16_writer(struct ssp_drv_context *sspc)
{
	void *reg = sspc->ioaddr;
	if (((read_SSSR(reg) & SSSR_TFL_MASK) == SSSR_TFL_MASK)
		|| (sspc->tx == sspc->tx_end))
		return 0;

	write_SSDR(*(u16 *)(sspc->tx), reg);
	sspc->tx += 2;

	return 2;
}

static int u16_reader(struct ssp_drv_context *sspc)
{
	void *reg = sspc->ioaddr;
	size_t pkg_len = sspc->len;

	while ((read_SSSR(reg) & SSSR_RNE)
		&& (pkg_len > 0)) {
		*(u16 *)(sspc->rx) = read_SSDR(reg);
		sspc->rx += 2;
		pkg_len -= 2;
	}

	return sspc->rx == sspc->rx_end;
}

static int u32_writer(struct ssp_drv_context *sspc)
{
	void *reg = sspc->ioaddr;
	if (((read_SSSR(reg) & SSSR_TFL_MASK) == SSSR_TFL_MASK)
		|| (sspc->tx == sspc->tx_end))
		return 0;

	write_SSDR(*(u32 *)(sspc->tx), reg);
	sspc->tx += 4;

	return 4;
}

static int u32_reader(struct ssp_drv_context *sspc)
{
	void *reg = sspc->ioaddr;
	size_t pkg_len = sspc->len;

	while ((read_SSSR(reg) & SSSR_RNE)
		&& (pkg_len > 0)) {
		*(u32 *)(sspc->rx) = read_SSDR(reg);
		sspc->rx += 4;
		pkg_len -= 4;
	}

	return sspc->rx == sspc->rx_end;
}

static bool chan_filter(struct dma_chan *chan, void *param)
{
	struct ssp_drv_context *sspc = param;
	bool ret = false;

	if (!sspc->dmac1)
		return ret;

	if (chan->device->dev == &sspc->dmac1->dev)
		ret = true;

	return ret;
}

/**
 * unmap_dma_buffers() - Unmap the DMA buffers used during the last transfer.
 * @sspc:	Pointer to the private driver context
 */
static void unmap_dma_buffers(struct ssp_drv_context *sspc)
{
	struct device *dev = &sspc->pdev->dev;

	if (!sspc->dma_mapped)
		return;
	dma_unmap_single(dev, sspc->rx_dma, sspc->len, PCI_DMA_FROMDEVICE);
	dma_unmap_single(dev, sspc->tx_dma, sspc->len, PCI_DMA_TODEVICE);
	sspc->dma_mapped = 0;
}

/**
 * intel_mid_ssp_spi_dma_done() - End of DMA transfer callback
 * @arg:	Pointer to the data provided at callback registration
 *
 * This function is set as callback for both RX and TX DMA transfers. The
 * RX or TX 'done' flag is set acording to the direction of the ended
 * transfer. Then, if both RX and TX flags are set, it means that the
 * transfer job is completed.
 */
static void intel_mid_ssp_spi_dma_done(void *arg)
{
	struct callback_param *cb_param = (struct callback_param *)arg;
	struct ssp_drv_context *sspc = cb_param->drv_context;
	struct device *dev = &sspc->pdev->dev;
	void *reg = sspc->ioaddr;

	if (cb_param->direction == TX_DIRECTION) {
		dma_sync_single_for_cpu(dev, sspc->tx_dma,
			sspc->len, DMA_TO_DEVICE);
		sspc->txdma_done = 1;
	} else {
		sspc->rxdma_done = 1;
		dma_sync_single_for_cpu(dev, sspc->rx_dma,
			sspc->len, DMA_FROM_DEVICE);
	}

	dev_dbg(dev, "DMA callback for direction %d [RX done:%d] [TX done:%d]\n",
		cb_param->direction, sspc->rxdma_done,
		sspc->txdma_done);

	if (sspc->txdma_done && sspc->rxdma_done) {
		/* Clear Status Register */
		write_SSSR(sspc->clear_sr, reg);
		dev_dbg(dev, "DMA done\n");
		/* Disable Triggers to DMA or to CPU*/
		disable_triggers(sspc);
		unmap_dma_buffers(sspc);

		queue_work(sspc->dma_wq, &sspc->complete_work);
	}
}

/**
 * intel_mid_ssp_spi_dma_init() - Initialize DMA
 * @sspc:	Pointer to the private driver context
 *
 * This function is called at driver setup phase to allocate DMA
 * ressources.
 */
static void intel_mid_ssp_spi_dma_init(struct ssp_drv_context *sspc)
{
	struct intel_mid_dma_slave *rxs, *txs;
	struct dma_slave_config *ds;
	dma_cap_mask_t mask;
	struct device *dev = &sspc->pdev->dev;
	unsigned int device_id;

	/* Configure RX channel parameters */
	rxs = &sspc->dmas_rx;
	ds = &rxs->dma_slave;

	ds->direction = DMA_FROM_DEVICE;
	rxs->hs_mode = LNW_DMA_HW_HS;
	rxs->cfg_mode = LNW_DMA_PER_TO_MEM;
	ds->dst_addr_width = sspc->n_bytes;
	ds->src_addr_width = sspc->n_bytes;

	if (sspc->quirks & QUIRKS_PLATFORM_BYT) {
		/*These are fixed HW info from Baytrail datasheet*/
		rxs->device_instance = 1; /*DMA Req line*/
	} else if (sspc->quirks & QUIRKS_PLATFORM_MRFL)
		rxs->device_instance = sspc->master->bus_num;
	else
		rxs->device_instance = 0;

	/* Use a DMA burst according to the FIFO thresholds */
	if (sspc->rx_fifo_threshold == 8) {
		ds->src_maxburst = LNW_DMA_MSIZE_8;
		ds->dst_maxburst = LNW_DMA_MSIZE_8;
	} else if (sspc->rx_fifo_threshold == 4) {
		ds->src_maxburst = LNW_DMA_MSIZE_4;
		ds->dst_maxburst = LNW_DMA_MSIZE_4;
	} else {
		ds->src_maxburst = LNW_DMA_MSIZE_1;
		ds->dst_maxburst = LNW_DMA_MSIZE_1;
	}

	/* Configure TX channel parameters */
	txs = &sspc->dmas_tx;
	ds = &txs->dma_slave;

	ds->direction = DMA_TO_DEVICE;
	txs->hs_mode = LNW_DMA_HW_HS;
	txs->cfg_mode = LNW_DMA_MEM_TO_PER;
	ds->src_addr_width = sspc->n_bytes;
	ds->dst_addr_width = sspc->n_bytes;

	if (sspc->quirks & QUIRKS_PLATFORM_BYT) {
		/*These are fixed HW info from Baytrail datasheet*/
		txs->device_instance = 0;/*DMA Req Line*/
	} else if (sspc->quirks & QUIRKS_PLATFORM_MRFL)
		txs->device_instance = sspc->master->bus_num;
	else
		txs->device_instance = 0;

	/* Use a DMA burst according to the FIFO thresholds */
	if (sspc->rx_fifo_threshold == 8) {
		ds->src_maxburst = LNW_DMA_MSIZE_8;
		ds->dst_maxburst = LNW_DMA_MSIZE_8;
	} else if (sspc->rx_fifo_threshold == 4) {
		ds->src_maxburst = LNW_DMA_MSIZE_4;
		ds->dst_maxburst = LNW_DMA_MSIZE_4;
	} else {
		ds->src_maxburst = LNW_DMA_MSIZE_1;
		ds->dst_maxburst = LNW_DMA_MSIZE_1;
	}

	/* Nothing more to do if already initialized */
	if (sspc->dma_initialized)
		return;

	/* Use DMAC1 */
	if (sspc->quirks & QUIRKS_PLATFORM_MRST)
		device_id = PCI_MRST_DMAC1_ID;
	else if (sspc->quirks & QUIRKS_PLATFORM_BYT)
		device_id = PCI_BYT_DMAC1_ID;
	else if (sspc->quirks & QUIRKS_PLATFORM_MRFL)
		device_id = PCI_MRFL_DMAC_ID;
	else
		device_id = PCI_MDFL_DMAC1_ID;

	sspc->dmac1 = pci_get_device(PCI_VENDOR_ID_INTEL, device_id, NULL);
	if (!sspc->dmac1) {
		dev_err(dev, "Can't find DMAC1");
		return;
	}

	if (sspc->quirks & QUIRKS_SRAM_ADDITIONAL_CPY) {
		sspc->virt_addr_sram_rx = ioremap_nocache(SRAM_BASE_ADDR,
				2 * MAX_SPI_TRANSFER_SIZE);
		if (sspc->virt_addr_sram_rx)
			sspc->virt_addr_sram_tx = sspc->virt_addr_sram_rx +
							MAX_SPI_TRANSFER_SIZE;
		else
			dev_err(dev, "Virt_addr_sram_rx is null\n");
	}

	/* 1. Allocate rx channel */
	dma_cap_zero(mask);
	dma_cap_set(DMA_MEMCPY, mask);
	dma_cap_set(DMA_SLAVE, mask);

	sspc->rxchan = dma_request_channel(mask, chan_filter, sspc);
	if (!sspc->rxchan)
		goto err_exit;

	sspc->rxchan->private = rxs;

	/* 2. Allocate tx channel */
	dma_cap_set(DMA_SLAVE, mask);
	dma_cap_set(DMA_MEMCPY, mask);

	sspc->txchan = dma_request_channel(mask, chan_filter, sspc);
	if (!sspc->txchan)
		goto free_rxchan;
	else
		sspc->txchan->private = txs;

	/* set the dma done bit to 1 */
	sspc->txdma_done = 1;
	sspc->rxdma_done = 1;

	sspc->tx_param.drv_context  = sspc;
	sspc->tx_param.direction = TX_DIRECTION;
	sspc->rx_param.drv_context  = sspc;
	sspc->rx_param.direction = RX_DIRECTION;

	sspc->dma_initialized = 1;
	return;

free_rxchan:
	dma_release_channel(sspc->rxchan);
err_exit:
	dev_err(dev, "Error : DMA Channel Not available\n");

	if (sspc->quirks & QUIRKS_SRAM_ADDITIONAL_CPY)
		iounmap(sspc->virt_addr_sram_rx);

	pci_dev_put(sspc->dmac1);
	return;
}

/**
 * intel_mid_ssp_spi_dma_exit() - Release DMA ressources
 * @sspc:	Pointer to the private driver context
 */
static void intel_mid_ssp_spi_dma_exit(struct ssp_drv_context *sspc)
{
	dma_release_channel(sspc->txchan);
	dma_release_channel(sspc->rxchan);

	if (sspc->quirks & QUIRKS_SRAM_ADDITIONAL_CPY)
		iounmap(sspc->virt_addr_sram_rx);

	pci_dev_put(sspc->dmac1);
}

/**
 * dma_transfer() - Initiate a DMA transfer
 * @sspc:	Pointer to the private driver context
 */
static void dma_transfer(struct ssp_drv_context *sspc)
{
	dma_addr_t ssdr_addr;
	struct dma_async_tx_descriptor *txdesc = NULL, *rxdesc = NULL;
	struct dma_chan *txchan, *rxchan;
	enum dma_ctrl_flags flag;
	struct device *dev = &sspc->pdev->dev;

	/* get Data Read/Write address */
	ssdr_addr = (dma_addr_t)(sspc->paddr + 0x10);

	if (sspc->tx_dma)
		sspc->txdma_done = 0;

	if (sspc->rx_dma)
		sspc->rxdma_done = 0;

	/* 2. prepare the RX dma transfer */
	txchan = sspc->txchan;
	rxchan = sspc->rxchan;

	flag = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;

	if (likely(sspc->quirks & QUIRKS_DMA_USE_NO_TRAIL)) {
		/* Since the DMA is configured to do 32bits access */
		/* to/from the DDR, the DMA transfer size must be  */
		/* a multiple of 4 bytes                           */
		sspc->len_dma_rx = sspc->len & ~(4 - 1);
		sspc->len_dma_tx = sspc->len_dma_rx;

		/* In Rx direction, TRAIL Bytes are handled by memcpy */
		if (sspc->rx_dma &&
			(sspc->len_dma_rx >=
				sspc->rx_fifo_threshold * sspc->n_bytes))
		{
			sspc->len_dma_rx = TRUNCATE(sspc->len_dma_rx,
				sspc->rx_fifo_threshold * sspc->n_bytes);
			sspc->len_dma_tx = sspc->len_dma_rx;
		}
		else if (!sspc->rx_dma)
			dev_err(dev, "ERROR : rx_dma is null\r\n");
	} else {
		/* TRAIL Bytes are handled by DMA */
		if (sspc->rx_dma) {
			sspc->len_dma_rx = sspc->len;
			sspc->len_dma_tx = sspc->len;
		} else
			dev_err(dev, "ERROR : sspc->rx_dma is null!\n");
	}

	sspc->dmas_rx.dma_slave.src_addr = ssdr_addr;
	rxchan->device->device_control(rxchan, DMA_SLAVE_CONFIG,
		(unsigned long)&(sspc->dmas_rx.dma_slave));
	dma_sync_single_for_device(dev, sspc->rx_dma,
		sspc->len, DMA_FROM_DEVICE);

	rxdesc = rxchan->device->device_prep_dma_memcpy
		(rxchan,			/* DMA Channel */
		sspc->rx_dma,			/* DAR */
		ssdr_addr,			/* SAR */
		sspc->len_dma_rx,		/* Data Length */
		flag);					/* Flag */

	if (rxdesc) {
		rxdesc->callback = intel_mid_ssp_spi_dma_done;
		rxdesc->callback_param = &sspc->rx_param;
	} else {
		dev_dbg(dev, "rxdesc is null! (len_dma_rx:%d)\n",
			sspc->len_dma_rx);
		sspc->rxdma_done = 1;
	}

	/* 3. prepare the TX dma transfer */
	sspc->dmas_tx.dma_slave.dst_addr = ssdr_addr;
	txchan->device->device_control(txchan, DMA_SLAVE_CONFIG,
		(unsigned long)&(sspc->dmas_tx.dma_slave));
	dma_sync_single_for_device(dev, sspc->tx_dma,
		sspc->len, DMA_TO_DEVICE);

	if (sspc->tx_dma) {
		txdesc = txchan->device->device_prep_dma_memcpy
			(txchan,			/* DMA Channel */
			ssdr_addr,			/* DAR */
			sspc->tx_dma,			/* SAR */
			sspc->len_dma_tx,		/* Data Length */
			flag);				/* Flag */
		if (txdesc) {
			txdesc->callback = intel_mid_ssp_spi_dma_done;
			txdesc->callback_param = &sspc->tx_param;
		} else {
			dev_dbg(dev, "txdesc is null! (len_dma_tx:%d)\n",
				sspc->len_dma_tx);
			sspc->txdma_done = 1;
		}
	} else {
		dev_err(dev, "ERROR : sspc->tx_dma is null!\n");
		return;
	}

	dev_dbg(dev, "DMA transfer len:%d len_dma_tx:%d len_dma_rx:%d\n",
		sspc->len, sspc->len_dma_tx, sspc->len_dma_rx);

	if (rxdesc || txdesc) {
		if (rxdesc) {
			dev_dbg(dev, "Firing DMA RX channel\n");
			rxdesc->tx_submit(rxdesc);
		}
		if (txdesc) {
			dev_dbg(dev, "Firing DMA TX channel\n");
			txdesc->tx_submit(txdesc);
		}
	} else {
		struct callback_param cb_param;
		cb_param.drv_context = sspc;
		dev_dbg(dev, "Bypassing DMA transfer\n");
		intel_mid_ssp_spi_dma_done(&cb_param);
	}
}

/**
 * map_dma_buffers() - Map DMA buffer before a transfer
 * @sspc:	Pointer to the private drivzer context
 */
static int map_dma_buffers(struct ssp_drv_context *sspc)
{
	struct device *dev = &sspc->pdev->dev;

	if (unlikely(sspc->dma_mapped)) {
		dev_err(dev, "ERROR : DMA buffers already mapped\n");
		return 0;
	}
	if (unlikely(sspc->quirks & QUIRKS_SRAM_ADDITIONAL_CPY)) {
		/* Copy sspc->tx into sram_tx */
		memcpy_toio(sspc->virt_addr_sram_tx, sspc->tx, sspc->len);
#ifdef DUMP_RX
		dump_trailer(&sspc->pdev->dev, sspc->tx, sspc->len, 16);
#endif
		sspc->rx_dma = SRAM_RX_ADDR;
		sspc->tx_dma = SRAM_TX_ADDR;
	} else {
		/* no QUIRKS_SRAM_ADDITIONAL_CPY */
		if (unlikely(sspc->dma_mapped))
			return 1;

		sspc->tx_dma = dma_map_single(dev, sspc->tx, sspc->len,
						PCI_DMA_TODEVICE);
		if (unlikely(dma_mapping_error(dev, sspc->tx_dma))) {
			dev_err(dev, "ERROR : tx dma mapping failed\n");
			return 0;
		}

		sspc->rx_dma = dma_map_single(dev, sspc->rx, sspc->len,
						PCI_DMA_FROMDEVICE);
		if (unlikely(dma_mapping_error(dev, sspc->rx_dma))) {
			dma_unmap_single(dev, sspc->tx_dma,
				sspc->len, DMA_TO_DEVICE);
			dev_err(dev, "ERROR : rx dma mapping failed\n");
			return 0;
		}
	}
	return 1;
}

/**
 * drain_trail() - Handle trailing bytes of a transfer
 * @sspc:	Pointer to the private driver context
 *
 * This function handles the trailing bytes of a transfer for the case
 * they are not handled by the DMA.
 */
void drain_trail(struct ssp_drv_context *sspc)
{
	struct device *dev = &sspc->pdev->dev;
	void *reg = sspc->ioaddr;

	if (sspc->len != sspc->len_dma_rx) {
		dev_dbg(dev, "Handling trailing bytes. SSSR:%08x\n",
			read_SSSR(reg));
		sspc->rx += sspc->len_dma_rx;
		sspc->tx += sspc->len_dma_tx;
		sspc->len = sspc->len - sspc->len_dma_rx;
		sspc->cur_msg->actual_length = sspc->len_dma_rx;

		while ((sspc->tx < sspc->tx_end) ||
			(sspc->rx < sspc->rx_end)) {
			sspc->read(sspc);
			sspc->write(sspc);
		}
	}
}

/**
 * sram_to_ddr_cpy() - Copy data from Langwell SDRAM to DDR
 * @sspc:	Pointer to the private driver context
 */
static void sram_to_ddr_cpy(struct ssp_drv_context *sspc)
{
	u32 length = sspc->len;

	if ((sspc->quirks & QUIRKS_DMA_USE_NO_TRAIL)
		&& (sspc->len > sspc->rx_fifo_threshold * sspc->n_bytes))
		length = TRUNCATE(sspc->len,
			sspc->rx_fifo_threshold * sspc->n_bytes);

	memcpy_fromio(sspc->rx, sspc->virt_addr_sram_rx, length);
}

static void int_transfer_complete(struct ssp_drv_context *sspc)
{
	void *reg = sspc->ioaddr;
	struct spi_message *msg;
	struct device *dev = &sspc->pdev->dev;

	if (unlikely(sspc->quirks & QUIRKS_USE_PM_QOS))
		pm_qos_update_request(&sspc->pm_qos_req,
					PM_QOS_DEFAULT_VALUE);

	if (unlikely(sspc->quirks & QUIRKS_SRAM_ADDITIONAL_CPY))
		sram_to_ddr_cpy(sspc);

	if (likely(sspc->quirks & QUIRKS_DMA_USE_NO_TRAIL))
		drain_trail(sspc);
	else
		/* Stop getting Time Outs */
		write_SSTO(0, reg);

	sspc->cur_msg->status = 0;
	sspc->cur_msg->actual_length += sspc->len;

#ifdef DUMP_RX
	dump_trailer(dev, sspc->rx, sspc->len, 16);
#endif

	if (sspc->cs_control)
		sspc->cs_control(!sspc->cs_assert);

	dev_dbg(dev, "End of transfer. SSSR:%08X\n", read_SSSR(reg));
	complete(&sspc->msg_done);
}

static void int_transfer_complete_work(struct work_struct *work)
{
	struct ssp_drv_context *sspc = container_of(work,
				struct ssp_drv_context, complete_work);

	int_transfer_complete(sspc);
}

static void poll_transfer_complete(struct ssp_drv_context *sspc)
{
	/* Update total byte transfered return count actual bytes read */
	sspc->cur_msg->actual_length += sspc->len - (sspc->rx_end - sspc->rx);

	sspc->cur_msg->status = 0;
}

/**
 * ssp_int() - Interrupt handler
 * @irq
 * @dev_id
 *
 * The SSP interrupt is not used for transfer which are handled by
 * DMA or polling: only under/over run are catched to detect
 * broken transfers.
 */
static irqreturn_t ssp_int(int irq, void *dev_id)
{
	struct ssp_drv_context *sspc = dev_id;
	void *reg = sspc->ioaddr;
	struct device *dev = &sspc->pdev->dev;
	u32 status = read_SSSR(reg);

	/* It should never be our interrupt since SSP will */
	/* only trigs interrupt for under/over run.*/
	if (likely(!(status & sspc->mask_sr)))
		return IRQ_NONE;

	if (status & SSSR_ROR || status & SSSR_TUR) {
		dev_err(dev, "--- SPI ROR or TUR occurred : SSSR=%x\n",	status);
		WARN_ON(1);
		if (status & SSSR_ROR)
			dev_err(dev, "we have Overrun\n");
		if (status & SSSR_TUR)
			dev_err(dev, "we have Underrun\n");
	}

	/* We can fall here when not using DMA mode */
	if (!sspc->cur_msg) {
		disable_interface(sspc);
		disable_triggers(sspc);
	}
	/* clear status register */
	write_SSSR(sspc->clear_sr, reg);
	return IRQ_HANDLED;
}

static void poll_writer(struct work_struct *work)
{
	struct ssp_drv_context *sspc =
		container_of(work, struct ssp_drv_context, poll_write);
	struct device *dev = &sspc->pdev->dev;
	size_t pkg_len = sspc->len;
	int ret;

	while ((pkg_len > 0)) {
		ret = sspc->write(sspc);
		pkg_len -= ret;
	}
}

/*
 * Perform a single transfer.
 */
static void poll_transfer(unsigned long data)
{
	struct ssp_drv_context *sspc = (void *)data;

	while (!sspc->read(sspc))
		cpu_relax();

	poll_transfer_complete(sspc);
}

/**
 * start_bitbanging() - Clock synchronization by bit banging
 * @sspc:	Pointer to private driver context
 *
 * This clock synchronization will be removed as soon as it is
 * handled by the SCU.
 */
static void start_bitbanging(struct ssp_drv_context *sspc)
{
	u32 sssr;
	u32 count = 0;
	u32 cr0;
	void *i2c_reg = sspc->I2C_ioaddr;
	struct device *dev = &sspc->pdev->dev;
	void *reg = sspc->ioaddr;
	struct chip_data *chip = spi_get_ctldata(sspc->cur_msg->spi);
	cr0 = chip->cr0;

	dev_warn(dev, "In %s : Starting bit banging\n",
		__func__);
	if (read_SSSR(reg) & SSP_NOT_SYNC)
		dev_warn(dev, "SSP clock desynchronized.\n");
	if (!(read_SSCR0(reg) & SSCR0_SSE))
		dev_warn(dev, "in SSCR0, SSP disabled.\n");

	dev_dbg(dev, "SSP not ready, start CLK sync\n");

	write_SSCR0(cr0 & ~SSCR0_SSE, reg);
	write_SSPSP(0x02010007, reg);

	write_SSTO(chip->timeout, reg);
	write_SSCR0(cr0, reg);

	/*
	*  This routine uses the DFx block to override the SSP inputs
	*  and outputs allowing us to bit bang SSPSCLK. On Langwell,
	*  we have to generate the clock to clear busy.
	*/
	write_I2CDATA(0x3, i2c_reg);
	udelay(I2C_ACCESS_USDELAY);
	write_I2CCTRL(0x01070034, i2c_reg);
	udelay(I2C_ACCESS_USDELAY);
	write_I2CDATA(0x00000099, i2c_reg);
	udelay(I2C_ACCESS_USDELAY);
	write_I2CCTRL(0x01070038, i2c_reg);
	udelay(I2C_ACCESS_USDELAY);
	sssr = read_SSSR(reg);

	/* Bit bang the clock until CSS clears */
	while ((sssr & 0x400000) && (count < MAX_BITBANGING_LOOP)) {
		write_I2CDATA(0x2, i2c_reg);
		udelay(I2C_ACCESS_USDELAY);
		write_I2CCTRL(0x01070034, i2c_reg);
		udelay(I2C_ACCESS_USDELAY);
		write_I2CDATA(0x3, i2c_reg);
		udelay(I2C_ACCESS_USDELAY);
		write_I2CCTRL(0x01070034, i2c_reg);
		udelay(I2C_ACCESS_USDELAY);
		sssr = read_SSSR(reg);
		count++;
	}
	if (count >= MAX_BITBANGING_LOOP)
		dev_err(dev, "ERROR in %s : infinite loop on bit banging. Aborting\n",
								__func__);

	dev_dbg(dev, "---Bit bang count=%d\n", count);

	write_I2CDATA(0x0, i2c_reg);
	udelay(I2C_ACCESS_USDELAY);
	write_I2CCTRL(0x01070038, i2c_reg);
}

static unsigned int ssp_get_clk_div(struct ssp_drv_context *sspc, int speed)
{
	if (sspc->quirks & QUIRKS_PLATFORM_MRFL)
		/* The clock divider shall stay between 0 and 4095. */
		return clamp(25000000 / speed - 1, 0, 4095);
	else
		return clamp(100000000 / speed - 1, 3, 4095);
}


static int ssp_get_speed(struct ssp_drv_context *sspc, int clk_div)
{
	if (sspc->quirks & QUIRKS_PLATFORM_MRFL)
		return 25000000 / (clk_div + 1);
	else
		return 100000000 / (clk_div + 1);
}

/**
 * transfer() - Start a SPI transfer
 * @spi:	Pointer to the spi_device struct
 * @msg:	Pointer to the spi_message struct
 */
static int transfer(struct spi_device *spi, struct spi_message *msg)
{
	struct ssp_drv_context *sspc = spi_master_get_devdata(spi->master);
	unsigned long flags;

	msg->actual_length = 0;
	msg->status = -EINPROGRESS;
	spin_lock_irqsave(&sspc->lock, flags);
	list_add_tail(&msg->queue, &sspc->queue);
	if (!sspc->suspended)
		queue_work(sspc->workqueue, &sspc->pump_messages);
	spin_unlock_irqrestore(&sspc->lock, flags);

	return 0;
}

static int handle_message(struct ssp_drv_context *sspc)
{
	struct chip_data *chip = NULL;
	struct spi_transfer *transfer = NULL;
	void *reg = sspc->ioaddr;
	u32 cr0, saved_cr0, cr1, saved_cr1;
	struct device *dev = &sspc->pdev->dev;
	struct spi_message *msg = sspc->cur_msg;
	u32 clk_div, saved_speed_hz, speed_hz;
	u8 dma_enabled;
	u32 timeout;
	u8 chip_select;
	u32 mask = 0;
	int bits_per_word, saved_bits_per_word;
	unsigned long flags;

	chip = spi_get_ctldata(msg->spi);

	/* get every chip data we need to handle atomically the full message */
	spin_lock_irqsave(&sspc->lock, flags);
	saved_cr0 = chip->cr0;
	saved_cr1 = chip->cr1;
	saved_bits_per_word = msg->spi->bits_per_word;
	saved_speed_hz = chip->speed_hz;
	sspc->cs_control = chip->cs_control;
	timeout = chip->timeout;
	chip_select = chip->chip_select;
	dma_enabled = chip->dma_enabled;
	spin_unlock_irqrestore(&sspc->lock, flags);

	/* multiple transfers must be serialized and this complete() is needed in order
        to be able to process the transfers list in a generic way */
	complete(&sspc->msg_done);

	list_for_each_entry(transfer, &msg->transfers, transfer_list) {
		wait_for_completion(&sspc->msg_done);
		INIT_COMPLETION(sspc->msg_done);

		/* Check transfer length */
		if (unlikely((transfer->len > MAX_SPI_TRANSFER_SIZE) ||
					(transfer->len == 0))) {
			dev_warn(dev, "transfer length null or greater than %d\n",
					MAX_SPI_TRANSFER_SIZE);
			dev_warn(dev, "length = %d\n", transfer->len);
			msg->status = -EINVAL;

			if (msg->complete)
				msg->complete(msg->context);
			complete(&sspc->msg_done);
			return 0;
		}

		/* If the bits_per_word field in non-zero in the spi_transfer provided
		 * by the user-space, consider this value. Otherwise consider the
		 * default bits_per_word field from the spi setting. */
		if (transfer->bits_per_word) {
			bits_per_word = transfer->bits_per_word;
			cr0 = saved_cr0;
			cr0 &= ~(SSCR0_EDSS | SSCR0_DSS);
			cr0 |= SSCR0_DataSize(bits_per_word > 16 ?
					bits_per_word - 16 : bits_per_word)
				| (bits_per_word > 16 ? SSCR0_EDSS : 0);
		} else {
			/* Use default value. */
			bits_per_word = saved_bits_per_word;
			cr0 = saved_cr0;
		}

		if ((bits_per_word < MIN_BITS_PER_WORD
					|| bits_per_word > MAX_BITS_PER_WORD)) {
			dev_warn(dev, "invalid wordsize\n");
			msg->status = -EINVAL;
			if (msg->complete)
				msg->complete(msg->context);
			complete(&sspc->msg_done);
			return 0;
		}

		/* Check message length and bit per words consistency */
		if (bits_per_word <= 8)
			mask = 0;
		else if (bits_per_word <= 16)
			mask = 1;
		else if (bits_per_word <= 32)
			mask = 3;

		if (transfer->len & mask) {
			dev_warn(dev,
					"message rejected : data length %d not multiple of %d "
					"while in %d bits mode\n",
					transfer->len,
					mask + 1,
					(mask == 1) ? 16 : 32);
			msg->status = -EINVAL;
			if (msg->complete)
				msg->complete(msg->context);
			complete(&sspc->msg_done);
			return 0;
		}

		/* Flush any remaining data (in case of failed previous transfer) */
		flush(sspc);

		dev_dbg(dev, "%d bits/word, mode %d\n",
				bits_per_word, msg->spi->mode & 0x3);
		if (bits_per_word <= 8) {
			sspc->n_bytes = 1;
			sspc->read = u8_reader;
			sspc->write = u8_writer;
		} else if (bits_per_word <= 16) {
			sspc->n_bytes = 2;
			sspc->read = u16_reader;
			sspc->write = u16_writer;
		} else if (bits_per_word <= 32) {
			if (!ssp_timing_wr)
				cr0 |= SSCR0_EDSS;
			sspc->n_bytes = 4;
			sspc->read = u32_reader;
			sspc->write = u32_writer;
		}

		sspc->tx  = (void *)transfer->tx_buf;
		sspc->rx  = (void *)transfer->rx_buf;
		sspc->len = transfer->len;
		sspc->cs_control = chip->cs_control;
		sspc->cs_change = transfer->cs_change;

		if (likely(chip->dma_enabled)) {
			sspc->dma_mapped = map_dma_buffers(sspc);
			if (unlikely(!sspc->dma_mapped))
				return 0;
		}

		sspc->write = sspc->tx ? sspc->write : null_writer;
		sspc->read  = sspc->rx ? sspc->read : null_reader;

		sspc->tx_end = sspc->tx + transfer->len;
		sspc->rx_end = sspc->rx + transfer->len;

		/* [REVERT ME] Bug in status register clear for Tangier simulation */
		if ((intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER) ||
				(intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_ANNIEDALE)) {
			if ((intel_mid_identify_sim() != INTEL_MID_CPU_SIMULATION_VP &&
						(intel_mid_identify_sim() != INTEL_MID_CPU_SIMULATION_HVP)))
				write_SSSR(sspc->clear_sr, reg);
		} else /* Clear status  */
			write_SSSR(sspc->clear_sr, reg);

		/* setup the CR1 control register */
		cr1 = saved_cr1 | sspc->cr1_sig;

		if (likely(sspc->quirks & QUIRKS_DMA_USE_NO_TRAIL)) {
			/* in case of len smaller than burst size, adjust the RX     */
			/* threshold. All other cases will use the default threshold */
			/* value. The RX fifo threshold must be aligned with the DMA */
			/* RX transfer size, which may be limited to a multiple of 4 */
			/* bytes due to 32bits DDR access.                           */
			if  (sspc->len / sspc->n_bytes < sspc->rx_fifo_threshold) {
				u32 rx_fifo_threshold;

				rx_fifo_threshold = (sspc->len & ~(4 - 1)) /
					sspc->n_bytes;
				cr1 &= ~(SSCR1_RFT);
				cr1 |= SSCR1_RxTresh(rx_fifo_threshold) & SSCR1_RFT;
			} else
				write_SSTO(timeout, reg);
		}
		dev_dbg(dev, "transfer len:%d  n_bytes:%d  cr0:%x  cr1:%x",
				sspc->len, sspc->n_bytes, cr0, cr1);

		/* first set CR1 */
		write_SSCR1(cr1, reg);

		if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER)
			write_SSFS((1 << chip_select), reg);

		/* recalculate the frequency for each transfer */
		if (transfer->speed_hz)
			speed_hz = transfer->speed_hz;
		else
			speed_hz = saved_speed_hz;

		clk_div = ssp_get_clk_div(sspc, speed_hz);

		cr0 &= ~SSCR0_SCR;
		cr0 |= (clk_div & 0xFFF) << 8;

		/* Do bitbanging only if SSP not-enabled or not-synchronized */
		if (unlikely(((read_SSSR(reg) & SSP_NOT_SYNC) ||
						(!(read_SSCR0(reg) & SSCR0_SSE))) &&
					(sspc->quirks & QUIRKS_BIT_BANGING))) {
			start_bitbanging(sspc);
		} else {

			/* if speed is higher than 6.25Mhz, enable clock delay */
			if (speed_hz > 6250000)
				write_SSCR2((read_SSCR2(reg) | SSCR2_CLK_DEL_EN), reg);
			else
				write_SSCR2((read_SSCR2(reg) & ~SSCR2_CLK_DEL_EN), reg);

			/* (re)start the SSP */
			if (ssp_timing_wr) {
				dev_dbg(dev, "original cr0 before reset:%x",
						cr0);
				/*we should not disable TUM and RIM interrup*/
				write_SSCR0(0x0000000F, reg);
				cr0 &= ~(SSCR0_SSE);
				dev_dbg(dev, "reset ssp:cr0:%x", cr0);
				write_SSCR0(cr0, reg);
				cr0 |= SSCR0_SSE;
				dev_dbg(dev, "reset ssp:cr0:%x", cr0);
				write_SSCR0(cr0, reg);
			} else
				write_SSCR0(cr0, reg);
		}

		if (sspc->cs_control)
			sspc->cs_control(sspc->cs_assert);

		if (likely(dma_enabled)) {
			if (unlikely(sspc->quirks & QUIRKS_USE_PM_QOS))
				pm_qos_update_request(&sspc->pm_qos_req,
						MIN_EXIT_LATENCY);
			dma_transfer(sspc);
		} else {
			/* Do the transfer syncronously */
			queue_work(sspc->wq_poll_write, &sspc->poll_write);
			poll_transfer((unsigned long)sspc);
			unmap_dma_buffers(sspc);
			complete(&sspc->msg_done);
		}

		if (list_is_last(&transfer->transfer_list, &msg->transfers)
				|| sspc->cs_change) {
			if (sspc->cs_control)
				sspc->cs_control(!sspc->cs_assert);
		}

	} /* end of list_for_each_entry */

	wait_for_completion(&sspc->msg_done);

	/* Now we are done with this entire message */
	if (likely(msg->complete))
		msg->complete(msg->context);

	return 0;
}

static void pump_messages(struct work_struct *work)
{
	struct ssp_drv_context *sspc =
		container_of(work, struct ssp_drv_context, pump_messages);
	struct device *dev = &sspc->pdev->dev;
	unsigned long flags;
	struct spi_message *msg;

	pm_runtime_get_sync(dev);
	spin_lock_irqsave(&sspc->lock, flags);
	while (!list_empty(&sspc->queue)) {
		if (sspc->suspended)
			break;
		msg = list_entry(sspc->queue.next, struct spi_message, queue);
		list_del_init(&msg->queue);
		sspc->cur_msg = msg;
		spin_unlock_irqrestore(&sspc->lock, flags);
		handle_message(sspc);
		spin_lock_irqsave(&sspc->lock, flags);
		sspc->cur_msg = NULL;
	}
	spin_unlock_irqrestore(&sspc->lock, flags);
	pm_runtime_mark_last_busy(dev);
	pm_runtime_put_autosuspend(dev);
}

/**
 * setup() - Driver setup procedure
 * @spi:	Pointeur to the spi_device struct
 */
static int setup(struct spi_device *spi)
{
	struct intel_mid_ssp_spi_chip *chip_info = NULL;
	struct chip_data *chip, *alloc_chip = NULL;
	struct ssp_drv_context *sspc =
		spi_master_get_devdata(spi->master);
	u32 tx_fifo_threshold;
	u32 burst_size;
	u32 clk_div;
	static u32 one_time_setup = 1;
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(&sspc->lock, flags);
	if (!spi->bits_per_word)
		spi->bits_per_word = DFLT_BITS_PER_WORD;

	if ((spi->bits_per_word != 8) && (spi->bits_per_word != 16)
		&& (spi->bits_per_word != 32)) {
		spin_unlock_irqrestore(&sspc->lock, flags);
		dev_warn(&spi->dev, "invalid wordsize, system only support 8,16,32 bits per word.\n");
		return -EINVAL;
	}

	chip = spi_get_ctldata(spi);
	if (!chip) {
		spin_unlock_irqrestore(&sspc->lock, flags);
		alloc_chip = chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
		spin_lock_irqsave(&sspc->lock, flags);
		if (!chip) {
			dev_err(&spi->dev,
			"failed setup: can't allocate chip data\n");
			ret = -ENOMEM;
			goto exit_setup;
		}

		if (spi_get_ctldata(spi)) {
			dev_err(&spi->dev, "failed setup: already executed\n");
			ret = -EAGAIN;
			goto exit_setup;
		}
	}

	chip->cr0 = SSCR0_Motorola | SSCR0_DataSize(spi->bits_per_word > 16 ?
		spi->bits_per_word - 16 : spi->bits_per_word)
			| SSCR0_SSE
			| (spi->bits_per_word > 16 ? SSCR0_EDSS : 0);

	/* protocol drivers may change the chip settings, so...  */
	/* if chip_info exists, use it                           */
	chip_info = spi->controller_data;

	/* chip_info isn't always needed */
	chip->cr1 = 0;
	if (chip_info) {
		/* If user requested CS Active High need to verify that there
		 * is no transfer pending. If this is the case, kindly fail.  */
		if ((spi->mode & SPI_CS_HIGH) != sspc->cs_assert) {
			if (sspc->cur_msg) {
				dev_err(&spi->dev, "message pending... Failing\n");
				/* A message is currently in transfer. Do not toggle CS */
				ret = -EAGAIN;
				goto exit_setup;
			}
			if (!chip_info->cs_control) {
				/* unable to control cs by hand */
				dev_err(&spi->dev,
						"This CS does not support SPI_CS_HIGH flag\n");
				ret = -EINVAL;
				goto exit_setup;
			}
			sspc->cs_assert = spi->mode & SPI_CS_HIGH;
			chip_info->cs_control(!sspc->cs_assert);
		}

		burst_size = chip_info->burst_size;
		if (burst_size > IMSS_FIFO_BURST_8)
			burst_size = DFLT_FIFO_BURST_SIZE;

		chip->timeout = chip_info->timeout;

		if (chip_info->enable_loopback)
			chip->cr1 |= SSCR1_LBM;

		chip->dma_enabled = chip_info->dma_enabled;
		chip->cs_control = chip_info->cs_control;

		/* Request platform-specific gpio and pinmux here since
		 * it is not possible to get the intel_mid_ssp_spi_chip
		 * structure in probe */
		if (one_time_setup && !chip_info->dma_enabled
				&& chip_info->platform_pinmux) {
			chip_info->platform_pinmux();
			one_time_setup = 0;
		}

	} else {
		/* if no chip_info provided by protocol driver, */
		/* set default values                           */
		dev_info(&spi->dev, "setting default chip values\n");

		burst_size = DFLT_FIFO_BURST_SIZE;
		chip->dma_enabled = 1;
		if (sspc->quirks & QUIRKS_DMA_USE_NO_TRAIL)
			chip->timeout = 0;
		else
			chip->timeout = DFLT_TIMEOUT_VAL;
	}
	/* Set FIFO thresholds according to burst_size */
	if (burst_size == IMSS_FIFO_BURST_8)
		sspc->rx_fifo_threshold = 8;
	else if (burst_size == IMSS_FIFO_BURST_4)
		sspc->rx_fifo_threshold = 4;
	else
		sspc->rx_fifo_threshold = 1;
	/* FIXME: This is a workaround. */
	/* When speed is lower than 800KHz, the transfer data will be */
	/* incorrect on MRFL by DMA method*/
	if (sspc->quirks & QUIRKS_PLATFORM_MRFL && chip->dma_enabled
			&& (spi->max_speed_hz < 800000))
		sspc->rx_fifo_threshold = 1;
	tx_fifo_threshold = SPI_FIFO_SIZE - sspc->rx_fifo_threshold;
	chip->cr1 |= (SSCR1_RxTresh(sspc->rx_fifo_threshold) &
		SSCR1_RFT) | (SSCR1_TxTresh(tx_fifo_threshold) & SSCR1_TFT);

	sspc->dma_mapped = 0;

	/* setting phase and polarity. spi->mode comes from boardinfo */
	if ((spi->mode & SPI_CPHA) != 0)
		chip->cr1 |= SSCR1_SPH;
	if ((spi->mode & SPI_CPOL) != 0)
		chip->cr1 |= SSCR1_SPO;

	if (sspc->quirks & QUIRKS_SPI_SLAVE_CLOCK_MODE)
		/* set slave mode */
		chip->cr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR;
	chip->cr1 |= SSCR1_SCFR;        /* clock is not free running */

	if (spi->bits_per_word <= 8) {
		chip->n_bytes = 1;
	} else if (spi->bits_per_word <= 16) {
		chip->n_bytes = 2;
	} else if (spi->bits_per_word <= 32) {
		chip->n_bytes = 4;
	} else {
		dev_err(&spi->dev, "invalid wordsize\n");
		ret = -EINVAL;
		goto exit_setup;
	}

	if ((sspc->quirks & QUIRKS_SPI_SLAVE_CLOCK_MODE) == 0) {
		clk_div = ssp_get_clk_div(sspc, spi->max_speed_hz);
		chip->cr0 |= (clk_div & 0xFFF) << 8;
		spi->max_speed_hz = ssp_get_speed(sspc, clk_div);
		chip->speed_hz = spi->max_speed_hz;
		dev_dbg(&spi->dev, "spi->max_speed_hz:%d clk_div:%x cr0:%x",
			spi->max_speed_hz, clk_div, chip->cr0);
	}
	chip->bits_per_word = spi->bits_per_word;
	chip->chip_select = spi->chip_select;

	alloc_chip = NULL;
	spi_set_ctldata(spi, chip);

	/* setup of sspc members that will not change across transfers */

	if (chip->dma_enabled) {
		sspc->n_bytes = chip->n_bytes;
		spin_unlock_irqrestore(&sspc->lock, flags);
		intel_mid_ssp_spi_dma_init(sspc);
		spin_lock_irqsave(&sspc->lock, flags);
		sspc->cr1_sig = SSCR1_TSRE | SSCR1_RSRE;
		sspc->mask_sr = SSSR_ROR | SSSR_TUR;
		if (sspc->quirks & QUIRKS_DMA_USE_NO_TRAIL)
			sspc->cr1_sig |= SSCR1_TRAIL;
	} else {
		sspc->cr1_sig = SSCR1_TINTE;
		sspc->mask_sr = SSSR_ROR | SSSR_TUR | SSSR_TINT;
	}
	sspc->clear_sr = SSSR_TUR | SSSR_ROR | SSSR_TINT;

exit_setup:
	if (alloc_chip)
		kfree(alloc_chip);

	spin_unlock_irqrestore(&sspc->lock, flags);
	return ret;
}

/**
 * cleanup() - Driver cleanup procedure
 * @spi:	Pointer to the spi_device struct
 */
static void cleanup(struct spi_device *spi)
{
	struct chip_data *chip = spi_get_ctldata(spi);
	struct ssp_drv_context *sspc =
		spi_master_get_devdata(spi->master);

	if (sspc->dma_initialized)
		intel_mid_ssp_spi_dma_exit(sspc);

	/* Remove the PM_QOS request */
	if (sspc->quirks & QUIRKS_USE_PM_QOS)
		pm_qos_remove_request(&sspc->pm_qos_req);

	kfree(chip);
	spi_set_ctldata(spi, NULL);
}

/**
 * intel_mid_ssp_spi_probe() - Driver probe procedure
 * @pdev:	Pointer to the pci_dev struct
 * @ent:	Pointer to the pci_device_id struct
 */
static int intel_mid_ssp_spi_probe(struct pci_dev *pdev,
	const struct pci_device_id *ent)
{
	struct device *dev = &pdev->dev;
	struct spi_master *master;
	struct ssp_drv_context *sspc = 0;
	int status;
	u32 iolen = 0;
	u8 ssp_cfg;
	int pos;
	void __iomem *syscfg_ioaddr;
	unsigned long syscfg;

	/* Check if the SSP we are probed for has been allocated */
	/* to operate as SPI. This information is retreived from */
	/* the field adid of the Vendor-Specific PCI capability  */
	/* which is used as a configuration register.            */
	pos = pci_find_capability(pdev, PCI_CAP_ID_VNDR);
	if (pos > 0) {
		pci_read_config_byte(pdev,
			pos + VNDR_CAPABILITY_ADID_OFFSET,
			&ssp_cfg);
	} else {
		dev_info(dev, "No Vendor Specific PCI capability\n");
		goto err_abort_probe;
	}

	if (ssp_cfg_get_mode(ssp_cfg) != SSP_CFG_SPI_MODE_ID) {
		dev_info(dev, "Unsupported SSP mode (%02xh)\n", ssp_cfg);
		goto err_abort_probe;
	}

	dev_info(dev, "found PCI SSP controller (ID: %04xh:%04xh cfg: %02xh)\n",
		pdev->vendor, pdev->device, ssp_cfg);

	status = pci_enable_device(pdev);
	if (status)
		return status;

	/* Allocate Slave with space for sspc and null dma buffer */
	master = spi_alloc_master(dev, sizeof(struct ssp_drv_context));

	if (!master) {
		dev_err(dev, "cannot alloc spi_slave\n");
		status = -ENOMEM;
		goto err_free_0;
	}

	sspc = spi_master_get_devdata(master);
	sspc->master = master;

	sspc->pdev = pdev;
	sspc->quirks = ent->driver_data;

	/* Set platform & configuration quirks */
	if (sspc->quirks & QUIRKS_PLATFORM_MRST) {
		/* Apply bit banging workarround on MRST */
		sspc->quirks |= QUIRKS_BIT_BANGING;
		/* MRST slave mode workarrounds */
		if (ssp_cfg_is_spi_slave(ssp_cfg))
			sspc->quirks |= QUIRKS_USE_PM_QOS |
					QUIRKS_SRAM_ADDITIONAL_CPY;
	}
	sspc->quirks |= QUIRKS_DMA_USE_NO_TRAIL;
	if (ssp_cfg_is_spi_slave(ssp_cfg))
		sspc->quirks |= QUIRKS_SPI_SLAVE_CLOCK_MODE;

	master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;
	master->bus_num = ssp_cfg_get_spi_bus_nb(ssp_cfg);
	master->num_chipselect = 4;
	master->cleanup = cleanup;
	master->setup = setup;
	master->transfer = transfer;
	sspc->dma_wq = create_workqueue("intel_mid_ssp_spi");
	INIT_WORK(&sspc->complete_work, int_transfer_complete_work);

	sspc->dma_initialized = 0;
	sspc->suspended = 0;
	sspc->cur_msg = NULL;

	/* get basic io resource and map it */
	sspc->paddr = pci_resource_start(pdev, 0);
	iolen = pci_resource_len(pdev, 0);

	status = pci_request_region(pdev, 0, dev_name(&pdev->dev));
	if (status)
		goto err_free_1;

	sspc->ioaddr = ioremap_nocache(sspc->paddr, iolen);
	if (!sspc->ioaddr) {
		status = -ENOMEM;
		goto err_free_2;
	}
	dev_dbg(dev, "paddr = : %08lx", sspc->paddr);
	dev_dbg(dev, "ioaddr = : %p\n", sspc->ioaddr);
	dev_dbg(dev, "attaching to IRQ: %04x\n", pdev->irq);
	dev_dbg(dev, "quirks = : %08lx\n", sspc->quirks);

	if (sspc->quirks & QUIRKS_BIT_BANGING) {
		/* Bit banging on the clock is done through */
		/* DFT which is available through I2C.      */
		/* get base address of I2C_Serbus registers */
		sspc->I2C_paddr = 0xff12b000;
		sspc->I2C_ioaddr = ioremap_nocache(sspc->I2C_paddr, 0x10);
		if (!sspc->I2C_ioaddr) {
			status = -ENOMEM;
			goto err_free_3;
		}
	}

	/* Attach to IRQ */
	sspc->irq = pdev->irq;
	status = request_irq(sspc->irq, ssp_int, IRQF_SHARED,
		"intel_mid_ssp_spi", sspc);

	if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER) {
		if ((intel_mid_identify_sim() ==
				INTEL_MID_CPU_SIMULATION_SLE) ||
		    (intel_mid_identify_sim() ==
				INTEL_MID_CPU_SIMULATION_NONE)) {
			/* [REVERT ME] Tangier SLE not supported.
			 * Requires debug before removal.  Assume
			 * also required in Si. */
			disable_irq_nosync(sspc->irq);
		}
		if (intel_mid_identify_sim() == INTEL_MID_CPU_SIMULATION_NONE)
			ssp_timing_wr = 1;
	}

	if (status < 0) {
		dev_err(&pdev->dev, "can not get IRQ\n");
		goto err_free_4;
	}

	if (sspc->quirks & QUIRKS_PLATFORM_MDFL) {
		/* get base address of DMA selector. */
		syscfg = sspc->paddr - SYSCFG;
		syscfg_ioaddr = ioremap_nocache(syscfg, 0x10);
		if (!syscfg_ioaddr) {
			status = -ENOMEM;
			goto err_free_5;
		}
		iowrite32(ioread32(syscfg_ioaddr) | 2, syscfg_ioaddr);
	}

	INIT_LIST_HEAD(&sspc->queue);
	init_completion(&sspc->msg_done);
	spin_lock_init(&sspc->lock);
	INIT_WORK(&sspc->pump_messages, pump_messages);
	sspc->workqueue = create_singlethread_workqueue(dev_name(&pdev->dev));

	INIT_WORK(&sspc->poll_write, poll_writer);
	sspc->wq_poll_write = create_singlethread_workqueue("spi_poll_wr");

	/* Register with the SPI framework */
	dev_info(dev, "register with SPI framework (bus spi%d)\n",
			master->bus_num);

	status = spi_register_master(master);
	if (status) {
		dev_err(dev, "problem registering spi\n");
		goto err_free_5;
	}

	pci_set_drvdata(pdev, sspc);

	/* Create the PM_QOS request */
	if (sspc->quirks & QUIRKS_USE_PM_QOS)
		pm_qos_add_request(&sspc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
				PM_QOS_DEFAULT_VALUE);

	pm_runtime_set_autosuspend_delay(&pdev->dev, 25);
	pm_runtime_use_autosuspend(&pdev->dev);
	pm_runtime_set_active(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev))
		dev_err(&pdev->dev, "spi runtime pm not enabled!\n");
	pm_runtime_put_noidle(&pdev->dev);
	pm_runtime_allow(&pdev->dev);

	return status;

err_free_5:
	free_irq(sspc->irq, sspc);
err_free_4:
	iounmap(sspc->I2C_ioaddr);
err_free_3:
	iounmap(sspc->ioaddr);
err_free_2:
	pci_release_region(pdev, 0);
err_free_1:
	spi_master_put(master);
err_free_0:
	pci_disable_device(pdev);

	return status;
err_abort_probe:
	dev_info(dev, "Abort probe for SSP %04xh:%04xh\n",
		pdev->vendor, pdev->device);
	return -ENODEV;
}

/**
 * intel_mid_ssp_spi_remove() - driver remove procedure
 * @pdev:	Pointer to the pci_dev struct
 */
static void intel_mid_ssp_spi_remove(struct pci_dev *pdev)
{
	struct ssp_drv_context *sspc = pci_get_drvdata(pdev);

	if (!sspc)
		return;

	pm_runtime_forbid(&pdev->dev);
	pm_runtime_get_noresume(&pdev->dev);

	if (sspc->dma_wq)
		destroy_workqueue(sspc->dma_wq);
	if (sspc->workqueue)
		destroy_workqueue(sspc->workqueue);

	/* Release IRQ */
	free_irq(sspc->irq, sspc);

	if (sspc->ioaddr)
		iounmap(sspc->ioaddr);
	if (sspc->quirks & QUIRKS_BIT_BANGING && sspc->I2C_ioaddr)
		iounmap(sspc->I2C_ioaddr);

	/* disconnect from the SPI framework */
	if (sspc->master)
		spi_unregister_master(sspc->master);

	pci_set_drvdata(pdev, NULL);
	pci_release_region(pdev, 0);
	pci_disable_device(pdev);

	return;
}

#ifdef CONFIG_PM
static int intel_mid_ssp_spi_suspend(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct ssp_drv_context *sspc = pci_get_drvdata(pdev);
	unsigned long flags;
	int loop = 26;

	dev_dbg(dev, "suspend\n");

	spin_lock_irqsave(&sspc->lock, flags);
	sspc->suspended = 1;
	/*
	 * If there is one msg being handled, wait 500ms at most,
	 * if still not done, return busy
	 */
	while (sspc->cur_msg && --loop) {
		spin_unlock_irqrestore(&sspc->lock, flags);
		msleep(20);
		spin_lock_irqsave(&sspc->lock, flags);
		if (!loop)
			sspc->suspended = 0;
	}
	spin_unlock_irqrestore(&sspc->lock, flags);

	if (loop)
		return 0;
	else
		return -EBUSY;
}

static int intel_mid_ssp_spi_resume(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct ssp_drv_context *sspc = pci_get_drvdata(pdev);

	dev_dbg(dev, "resume\n");
	spin_lock(&sspc->lock);
	sspc->suspended = 0;
	if (!list_empty(&sspc->queue))
		queue_work(sspc->workqueue, &sspc->pump_messages);
	spin_unlock(&sspc->lock);
	return 0;
}

static int intel_mid_ssp_spi_runtime_suspend(struct device *dev)
{
	dev_dbg(dev, "runtime suspend called\n");
	return 0;
}

static int intel_mid_ssp_spi_runtime_resume(struct device *dev)
{
	dev_dbg(dev, "runtime resume called\n");
	return 0;
}

static int intel_mid_ssp_spi_runtime_idle(struct device *dev)
{
	int err;

	dev_dbg(dev, "runtime idle called\n");
	if (system_state == SYSTEM_BOOTING)
		/* if SSP SPI UART is set as default console and earlyprintk
		 * is enabled, it cannot shutdown SSP controller during booting.
		 */
		err = pm_schedule_suspend(dev, 30000);
	else
		err = pm_schedule_suspend(dev, 500);

	return err;
}
#else
#define intel_mid_ssp_spi_suspend NULL
#define intel_mid_ssp_spi_resume NULL
#define intel_mid_ssp_spi_runtime_suspend NULL
#define intel_mid_ssp_spi_runtime_resume NULL
#define intel_mid_ssp_spi_runtime_idle NULL
#endif /* CONFIG_PM */


static DEFINE_PCI_DEVICE_TABLE(pci_ids) = {
	/* MRST SSP0 */
	{ PCI_VDEVICE(INTEL, 0x0815), QUIRKS_PLATFORM_MRST},
	/* MDFL SSP0 */
	{ PCI_VDEVICE(INTEL, 0x0832), QUIRKS_PLATFORM_MDFL},
	/* MDFL SSP1 */
	{ PCI_VDEVICE(INTEL, 0x0825), QUIRKS_PLATFORM_MDFL},
	/* MDFL SSP3 */
	{ PCI_VDEVICE(INTEL, 0x0816), QUIRKS_PLATFORM_MDFL},
	/* MRFL SSP5 */
	{ PCI_VDEVICE(INTEL, 0x1194), QUIRKS_PLATFORM_MRFL},
	/* BYT SSP3 */
	{ PCI_VDEVICE(INTEL, 0x0f0e), QUIRKS_PLATFORM_BYT},
	{},
};

static const struct dev_pm_ops intel_mid_ssp_spi_pm_ops = {
	.suspend = intel_mid_ssp_spi_suspend,
	.resume = intel_mid_ssp_spi_resume,
	.runtime_suspend = intel_mid_ssp_spi_runtime_suspend,
	.runtime_resume = intel_mid_ssp_spi_runtime_resume,
	.runtime_idle = intel_mid_ssp_spi_runtime_idle,
};

static struct pci_driver intel_mid_ssp_spi_driver = {
	.name =		DRIVER_NAME,
	.id_table =	pci_ids,
	.probe =	intel_mid_ssp_spi_probe,
	.remove =	intel_mid_ssp_spi_remove,
	.driver =	{
		.pm	= &intel_mid_ssp_spi_pm_ops,
	},
};

static int __init intel_mid_ssp_spi_init(void)
{
	return pci_register_driver(&intel_mid_ssp_spi_driver);
}

late_initcall(intel_mid_ssp_spi_init);

static void __exit intel_mid_ssp_spi_exit(void)
{
	pci_unregister_driver(&intel_mid_ssp_spi_driver);
}

module_exit(intel_mid_ssp_spi_exit);
