162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Driver for Cirrus Logic EP93xx SPI controller.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2010-2011 Mika Westerberg
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Explicit FIFO handling code was inspired by amba-pl022 driver.
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * Chip select support using other than built-in GPIOs by H. Hartley Sweeten.
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci * For more information about the SPI controller see documentation on Cirrus
1262306a36Sopenharmony_ci * Logic web site:
1362306a36Sopenharmony_ci *     https://www.cirrus.com/en/pubs/manual/EP93xx_Users_Guide_UM1.pdf
1462306a36Sopenharmony_ci */
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include <linux/io.h>
1762306a36Sopenharmony_ci#include <linux/clk.h>
1862306a36Sopenharmony_ci#include <linux/err.h>
1962306a36Sopenharmony_ci#include <linux/delay.h>
2062306a36Sopenharmony_ci#include <linux/device.h>
2162306a36Sopenharmony_ci#include <linux/dmaengine.h>
2262306a36Sopenharmony_ci#include <linux/bitops.h>
2362306a36Sopenharmony_ci#include <linux/interrupt.h>
2462306a36Sopenharmony_ci#include <linux/module.h>
2562306a36Sopenharmony_ci#include <linux/platform_device.h>
2662306a36Sopenharmony_ci#include <linux/sched.h>
2762306a36Sopenharmony_ci#include <linux/scatterlist.h>
2862306a36Sopenharmony_ci#include <linux/spi/spi.h>
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#include <linux/platform_data/dma-ep93xx.h>
3162306a36Sopenharmony_ci#include <linux/platform_data/spi-ep93xx.h>
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define SSPCR0			0x0000
3462306a36Sopenharmony_ci#define SSPCR0_SPO		BIT(6)
3562306a36Sopenharmony_ci#define SSPCR0_SPH		BIT(7)
3662306a36Sopenharmony_ci#define SSPCR0_SCR_SHIFT	8
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define SSPCR1			0x0004
3962306a36Sopenharmony_ci#define SSPCR1_RIE		BIT(0)
4062306a36Sopenharmony_ci#define SSPCR1_TIE		BIT(1)
4162306a36Sopenharmony_ci#define SSPCR1_RORIE		BIT(2)
4262306a36Sopenharmony_ci#define SSPCR1_LBM		BIT(3)
4362306a36Sopenharmony_ci#define SSPCR1_SSE		BIT(4)
4462306a36Sopenharmony_ci#define SSPCR1_MS		BIT(5)
4562306a36Sopenharmony_ci#define SSPCR1_SOD		BIT(6)
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci#define SSPDR			0x0008
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci#define SSPSR			0x000c
5062306a36Sopenharmony_ci#define SSPSR_TFE		BIT(0)
5162306a36Sopenharmony_ci#define SSPSR_TNF		BIT(1)
5262306a36Sopenharmony_ci#define SSPSR_RNE		BIT(2)
5362306a36Sopenharmony_ci#define SSPSR_RFF		BIT(3)
5462306a36Sopenharmony_ci#define SSPSR_BSY		BIT(4)
5562306a36Sopenharmony_ci#define SSPCPSR			0x0010
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci#define SSPIIR			0x0014
5862306a36Sopenharmony_ci#define SSPIIR_RIS		BIT(0)
5962306a36Sopenharmony_ci#define SSPIIR_TIS		BIT(1)
6062306a36Sopenharmony_ci#define SSPIIR_RORIS		BIT(2)
6162306a36Sopenharmony_ci#define SSPICR			SSPIIR
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci/* timeout in milliseconds */
6462306a36Sopenharmony_ci#define SPI_TIMEOUT		5
6562306a36Sopenharmony_ci/* maximum depth of RX/TX FIFO */
6662306a36Sopenharmony_ci#define SPI_FIFO_SIZE		8
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci/**
6962306a36Sopenharmony_ci * struct ep93xx_spi - EP93xx SPI controller structure
7062306a36Sopenharmony_ci * @clk: clock for the controller
7162306a36Sopenharmony_ci * @mmio: pointer to ioremap()'d registers
7262306a36Sopenharmony_ci * @sspdr_phys: physical address of the SSPDR register
7362306a36Sopenharmony_ci * @tx: current byte in transfer to transmit
7462306a36Sopenharmony_ci * @rx: current byte in transfer to receive
7562306a36Sopenharmony_ci * @fifo_level: how full is FIFO (%0..%SPI_FIFO_SIZE - %1). Receiving one
7662306a36Sopenharmony_ci *              frame decreases this level and sending one frame increases it.
7762306a36Sopenharmony_ci * @dma_rx: RX DMA channel
7862306a36Sopenharmony_ci * @dma_tx: TX DMA channel
7962306a36Sopenharmony_ci * @dma_rx_data: RX parameters passed to the DMA engine
8062306a36Sopenharmony_ci * @dma_tx_data: TX parameters passed to the DMA engine
8162306a36Sopenharmony_ci * @rx_sgt: sg table for RX transfers
8262306a36Sopenharmony_ci * @tx_sgt: sg table for TX transfers
8362306a36Sopenharmony_ci * @zeropage: dummy page used as RX buffer when only TX buffer is passed in by
8462306a36Sopenharmony_ci *            the client
8562306a36Sopenharmony_ci */
8662306a36Sopenharmony_cistruct ep93xx_spi {
8762306a36Sopenharmony_ci	struct clk			*clk;
8862306a36Sopenharmony_ci	void __iomem			*mmio;
8962306a36Sopenharmony_ci	unsigned long			sspdr_phys;
9062306a36Sopenharmony_ci	size_t				tx;
9162306a36Sopenharmony_ci	size_t				rx;
9262306a36Sopenharmony_ci	size_t				fifo_level;
9362306a36Sopenharmony_ci	struct dma_chan			*dma_rx;
9462306a36Sopenharmony_ci	struct dma_chan			*dma_tx;
9562306a36Sopenharmony_ci	struct ep93xx_dma_data		dma_rx_data;
9662306a36Sopenharmony_ci	struct ep93xx_dma_data		dma_tx_data;
9762306a36Sopenharmony_ci	struct sg_table			rx_sgt;
9862306a36Sopenharmony_ci	struct sg_table			tx_sgt;
9962306a36Sopenharmony_ci	void				*zeropage;
10062306a36Sopenharmony_ci};
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci/* converts bits per word to CR0.DSS value */
10362306a36Sopenharmony_ci#define bits_per_word_to_dss(bpw)	((bpw) - 1)
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci/**
10662306a36Sopenharmony_ci * ep93xx_spi_calc_divisors() - calculates SPI clock divisors
10762306a36Sopenharmony_ci * @host: SPI host
10862306a36Sopenharmony_ci * @rate: desired SPI output clock rate
10962306a36Sopenharmony_ci * @div_cpsr: pointer to return the cpsr (pre-scaler) divider
11062306a36Sopenharmony_ci * @div_scr: pointer to return the scr divider
11162306a36Sopenharmony_ci */
11262306a36Sopenharmony_cistatic int ep93xx_spi_calc_divisors(struct spi_controller *host,
11362306a36Sopenharmony_ci				    u32 rate, u8 *div_cpsr, u8 *div_scr)
11462306a36Sopenharmony_ci{
11562306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
11662306a36Sopenharmony_ci	unsigned long spi_clk_rate = clk_get_rate(espi->clk);
11762306a36Sopenharmony_ci	int cpsr, scr;
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci	/*
12062306a36Sopenharmony_ci	 * Make sure that max value is between values supported by the
12162306a36Sopenharmony_ci	 * controller.
12262306a36Sopenharmony_ci	 */
12362306a36Sopenharmony_ci	rate = clamp(rate, host->min_speed_hz, host->max_speed_hz);
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	/*
12662306a36Sopenharmony_ci	 * Calculate divisors so that we can get speed according the
12762306a36Sopenharmony_ci	 * following formula:
12862306a36Sopenharmony_ci	 *	rate = spi_clock_rate / (cpsr * (1 + scr))
12962306a36Sopenharmony_ci	 *
13062306a36Sopenharmony_ci	 * cpsr must be even number and starts from 2, scr can be any number
13162306a36Sopenharmony_ci	 * between 0 and 255.
13262306a36Sopenharmony_ci	 */
13362306a36Sopenharmony_ci	for (cpsr = 2; cpsr <= 254; cpsr += 2) {
13462306a36Sopenharmony_ci		for (scr = 0; scr <= 255; scr++) {
13562306a36Sopenharmony_ci			if ((spi_clk_rate / (cpsr * (scr + 1))) <= rate) {
13662306a36Sopenharmony_ci				*div_scr = (u8)scr;
13762306a36Sopenharmony_ci				*div_cpsr = (u8)cpsr;
13862306a36Sopenharmony_ci				return 0;
13962306a36Sopenharmony_ci			}
14062306a36Sopenharmony_ci		}
14162306a36Sopenharmony_ci	}
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	return -EINVAL;
14462306a36Sopenharmony_ci}
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_cistatic int ep93xx_spi_chip_setup(struct spi_controller *host,
14762306a36Sopenharmony_ci				 struct spi_device *spi,
14862306a36Sopenharmony_ci				 struct spi_transfer *xfer)
14962306a36Sopenharmony_ci{
15062306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
15162306a36Sopenharmony_ci	u8 dss = bits_per_word_to_dss(xfer->bits_per_word);
15262306a36Sopenharmony_ci	u8 div_cpsr = 0;
15362306a36Sopenharmony_ci	u8 div_scr = 0;
15462306a36Sopenharmony_ci	u16 cr0;
15562306a36Sopenharmony_ci	int err;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	err = ep93xx_spi_calc_divisors(host, xfer->speed_hz,
15862306a36Sopenharmony_ci				       &div_cpsr, &div_scr);
15962306a36Sopenharmony_ci	if (err)
16062306a36Sopenharmony_ci		return err;
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci	cr0 = div_scr << SSPCR0_SCR_SHIFT;
16362306a36Sopenharmony_ci	if (spi->mode & SPI_CPOL)
16462306a36Sopenharmony_ci		cr0 |= SSPCR0_SPO;
16562306a36Sopenharmony_ci	if (spi->mode & SPI_CPHA)
16662306a36Sopenharmony_ci		cr0 |= SSPCR0_SPH;
16762306a36Sopenharmony_ci	cr0 |= dss;
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	dev_dbg(&host->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n",
17062306a36Sopenharmony_ci		spi->mode, div_cpsr, div_scr, dss);
17162306a36Sopenharmony_ci	dev_dbg(&host->dev, "setup: cr0 %#x\n", cr0);
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	writel(div_cpsr, espi->mmio + SSPCPSR);
17462306a36Sopenharmony_ci	writel(cr0, espi->mmio + SSPCR0);
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	return 0;
17762306a36Sopenharmony_ci}
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_cistatic void ep93xx_do_write(struct spi_controller *host)
18062306a36Sopenharmony_ci{
18162306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
18262306a36Sopenharmony_ci	struct spi_transfer *xfer = host->cur_msg->state;
18362306a36Sopenharmony_ci	u32 val = 0;
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	if (xfer->bits_per_word > 8) {
18662306a36Sopenharmony_ci		if (xfer->tx_buf)
18762306a36Sopenharmony_ci			val = ((u16 *)xfer->tx_buf)[espi->tx];
18862306a36Sopenharmony_ci		espi->tx += 2;
18962306a36Sopenharmony_ci	} else {
19062306a36Sopenharmony_ci		if (xfer->tx_buf)
19162306a36Sopenharmony_ci			val = ((u8 *)xfer->tx_buf)[espi->tx];
19262306a36Sopenharmony_ci		espi->tx += 1;
19362306a36Sopenharmony_ci	}
19462306a36Sopenharmony_ci	writel(val, espi->mmio + SSPDR);
19562306a36Sopenharmony_ci}
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_cistatic void ep93xx_do_read(struct spi_controller *host)
19862306a36Sopenharmony_ci{
19962306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
20062306a36Sopenharmony_ci	struct spi_transfer *xfer = host->cur_msg->state;
20162306a36Sopenharmony_ci	u32 val;
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci	val = readl(espi->mmio + SSPDR);
20462306a36Sopenharmony_ci	if (xfer->bits_per_word > 8) {
20562306a36Sopenharmony_ci		if (xfer->rx_buf)
20662306a36Sopenharmony_ci			((u16 *)xfer->rx_buf)[espi->rx] = val;
20762306a36Sopenharmony_ci		espi->rx += 2;
20862306a36Sopenharmony_ci	} else {
20962306a36Sopenharmony_ci		if (xfer->rx_buf)
21062306a36Sopenharmony_ci			((u8 *)xfer->rx_buf)[espi->rx] = val;
21162306a36Sopenharmony_ci		espi->rx += 1;
21262306a36Sopenharmony_ci	}
21362306a36Sopenharmony_ci}
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci/**
21662306a36Sopenharmony_ci * ep93xx_spi_read_write() - perform next RX/TX transfer
21762306a36Sopenharmony_ci * @host: SPI host
21862306a36Sopenharmony_ci *
21962306a36Sopenharmony_ci * This function transfers next bytes (or half-words) to/from RX/TX FIFOs. If
22062306a36Sopenharmony_ci * called several times, the whole transfer will be completed. Returns
22162306a36Sopenharmony_ci * %-EINPROGRESS when current transfer was not yet completed otherwise %0.
22262306a36Sopenharmony_ci *
22362306a36Sopenharmony_ci * When this function is finished, RX FIFO should be empty and TX FIFO should be
22462306a36Sopenharmony_ci * full.
22562306a36Sopenharmony_ci */
22662306a36Sopenharmony_cistatic int ep93xx_spi_read_write(struct spi_controller *host)
22762306a36Sopenharmony_ci{
22862306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
22962306a36Sopenharmony_ci	struct spi_transfer *xfer = host->cur_msg->state;
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci	/* read as long as RX FIFO has frames in it */
23262306a36Sopenharmony_ci	while ((readl(espi->mmio + SSPSR) & SSPSR_RNE)) {
23362306a36Sopenharmony_ci		ep93xx_do_read(host);
23462306a36Sopenharmony_ci		espi->fifo_level--;
23562306a36Sopenharmony_ci	}
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	/* write as long as TX FIFO has room */
23862306a36Sopenharmony_ci	while (espi->fifo_level < SPI_FIFO_SIZE && espi->tx < xfer->len) {
23962306a36Sopenharmony_ci		ep93xx_do_write(host);
24062306a36Sopenharmony_ci		espi->fifo_level++;
24162306a36Sopenharmony_ci	}
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci	if (espi->rx == xfer->len)
24462306a36Sopenharmony_ci		return 0;
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci	return -EINPROGRESS;
24762306a36Sopenharmony_ci}
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_cistatic enum dma_transfer_direction
25062306a36Sopenharmony_ciep93xx_dma_data_to_trans_dir(enum dma_data_direction dir)
25162306a36Sopenharmony_ci{
25262306a36Sopenharmony_ci	switch (dir) {
25362306a36Sopenharmony_ci	case DMA_TO_DEVICE:
25462306a36Sopenharmony_ci		return DMA_MEM_TO_DEV;
25562306a36Sopenharmony_ci	case DMA_FROM_DEVICE:
25662306a36Sopenharmony_ci		return DMA_DEV_TO_MEM;
25762306a36Sopenharmony_ci	default:
25862306a36Sopenharmony_ci		return DMA_TRANS_NONE;
25962306a36Sopenharmony_ci	}
26062306a36Sopenharmony_ci}
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci/**
26362306a36Sopenharmony_ci * ep93xx_spi_dma_prepare() - prepares a DMA transfer
26462306a36Sopenharmony_ci * @host: SPI host
26562306a36Sopenharmony_ci * @dir: DMA transfer direction
26662306a36Sopenharmony_ci *
26762306a36Sopenharmony_ci * Function configures the DMA, maps the buffer and prepares the DMA
26862306a36Sopenharmony_ci * descriptor. Returns a valid DMA descriptor in case of success and ERR_PTR
26962306a36Sopenharmony_ci * in case of failure.
27062306a36Sopenharmony_ci */
27162306a36Sopenharmony_cistatic struct dma_async_tx_descriptor *
27262306a36Sopenharmony_ciep93xx_spi_dma_prepare(struct spi_controller *host,
27362306a36Sopenharmony_ci		       enum dma_data_direction dir)
27462306a36Sopenharmony_ci{
27562306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
27662306a36Sopenharmony_ci	struct spi_transfer *xfer = host->cur_msg->state;
27762306a36Sopenharmony_ci	struct dma_async_tx_descriptor *txd;
27862306a36Sopenharmony_ci	enum dma_slave_buswidth buswidth;
27962306a36Sopenharmony_ci	struct dma_slave_config conf;
28062306a36Sopenharmony_ci	struct scatterlist *sg;
28162306a36Sopenharmony_ci	struct sg_table *sgt;
28262306a36Sopenharmony_ci	struct dma_chan *chan;
28362306a36Sopenharmony_ci	const void *buf, *pbuf;
28462306a36Sopenharmony_ci	size_t len = xfer->len;
28562306a36Sopenharmony_ci	int i, ret, nents;
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci	if (xfer->bits_per_word > 8)
28862306a36Sopenharmony_ci		buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
28962306a36Sopenharmony_ci	else
29062306a36Sopenharmony_ci		buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci	memset(&conf, 0, sizeof(conf));
29362306a36Sopenharmony_ci	conf.direction = ep93xx_dma_data_to_trans_dir(dir);
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	if (dir == DMA_FROM_DEVICE) {
29662306a36Sopenharmony_ci		chan = espi->dma_rx;
29762306a36Sopenharmony_ci		buf = xfer->rx_buf;
29862306a36Sopenharmony_ci		sgt = &espi->rx_sgt;
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci		conf.src_addr = espi->sspdr_phys;
30162306a36Sopenharmony_ci		conf.src_addr_width = buswidth;
30262306a36Sopenharmony_ci	} else {
30362306a36Sopenharmony_ci		chan = espi->dma_tx;
30462306a36Sopenharmony_ci		buf = xfer->tx_buf;
30562306a36Sopenharmony_ci		sgt = &espi->tx_sgt;
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci		conf.dst_addr = espi->sspdr_phys;
30862306a36Sopenharmony_ci		conf.dst_addr_width = buswidth;
30962306a36Sopenharmony_ci	}
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci	ret = dmaengine_slave_config(chan, &conf);
31262306a36Sopenharmony_ci	if (ret)
31362306a36Sopenharmony_ci		return ERR_PTR(ret);
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	/*
31662306a36Sopenharmony_ci	 * We need to split the transfer into PAGE_SIZE'd chunks. This is
31762306a36Sopenharmony_ci	 * because we are using @espi->zeropage to provide a zero RX buffer
31862306a36Sopenharmony_ci	 * for the TX transfers and we have only allocated one page for that.
31962306a36Sopenharmony_ci	 *
32062306a36Sopenharmony_ci	 * For performance reasons we allocate a new sg_table only when
32162306a36Sopenharmony_ci	 * needed. Otherwise we will re-use the current one. Eventually the
32262306a36Sopenharmony_ci	 * last sg_table is released in ep93xx_spi_release_dma().
32362306a36Sopenharmony_ci	 */
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	nents = DIV_ROUND_UP(len, PAGE_SIZE);
32662306a36Sopenharmony_ci	if (nents != sgt->nents) {
32762306a36Sopenharmony_ci		sg_free_table(sgt);
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci		ret = sg_alloc_table(sgt, nents, GFP_KERNEL);
33062306a36Sopenharmony_ci		if (ret)
33162306a36Sopenharmony_ci			return ERR_PTR(ret);
33262306a36Sopenharmony_ci	}
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	pbuf = buf;
33562306a36Sopenharmony_ci	for_each_sg(sgt->sgl, sg, sgt->nents, i) {
33662306a36Sopenharmony_ci		size_t bytes = min_t(size_t, len, PAGE_SIZE);
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci		if (buf) {
33962306a36Sopenharmony_ci			sg_set_page(sg, virt_to_page(pbuf), bytes,
34062306a36Sopenharmony_ci				    offset_in_page(pbuf));
34162306a36Sopenharmony_ci		} else {
34262306a36Sopenharmony_ci			sg_set_page(sg, virt_to_page(espi->zeropage),
34362306a36Sopenharmony_ci				    bytes, 0);
34462306a36Sopenharmony_ci		}
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci		pbuf += bytes;
34762306a36Sopenharmony_ci		len -= bytes;
34862306a36Sopenharmony_ci	}
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci	if (WARN_ON(len)) {
35162306a36Sopenharmony_ci		dev_warn(&host->dev, "len = %zu expected 0!\n", len);
35262306a36Sopenharmony_ci		return ERR_PTR(-EINVAL);
35362306a36Sopenharmony_ci	}
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	nents = dma_map_sg(chan->device->dev, sgt->sgl, sgt->nents, dir);
35662306a36Sopenharmony_ci	if (!nents)
35762306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	txd = dmaengine_prep_slave_sg(chan, sgt->sgl, nents, conf.direction,
36062306a36Sopenharmony_ci				      DMA_CTRL_ACK);
36162306a36Sopenharmony_ci	if (!txd) {
36262306a36Sopenharmony_ci		dma_unmap_sg(chan->device->dev, sgt->sgl, sgt->nents, dir);
36362306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
36462306a36Sopenharmony_ci	}
36562306a36Sopenharmony_ci	return txd;
36662306a36Sopenharmony_ci}
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci/**
36962306a36Sopenharmony_ci * ep93xx_spi_dma_finish() - finishes with a DMA transfer
37062306a36Sopenharmony_ci * @host: SPI host
37162306a36Sopenharmony_ci * @dir: DMA transfer direction
37262306a36Sopenharmony_ci *
37362306a36Sopenharmony_ci * Function finishes with the DMA transfer. After this, the DMA buffer is
37462306a36Sopenharmony_ci * unmapped.
37562306a36Sopenharmony_ci */
37662306a36Sopenharmony_cistatic void ep93xx_spi_dma_finish(struct spi_controller *host,
37762306a36Sopenharmony_ci				  enum dma_data_direction dir)
37862306a36Sopenharmony_ci{
37962306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
38062306a36Sopenharmony_ci	struct dma_chan *chan;
38162306a36Sopenharmony_ci	struct sg_table *sgt;
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci	if (dir == DMA_FROM_DEVICE) {
38462306a36Sopenharmony_ci		chan = espi->dma_rx;
38562306a36Sopenharmony_ci		sgt = &espi->rx_sgt;
38662306a36Sopenharmony_ci	} else {
38762306a36Sopenharmony_ci		chan = espi->dma_tx;
38862306a36Sopenharmony_ci		sgt = &espi->tx_sgt;
38962306a36Sopenharmony_ci	}
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	dma_unmap_sg(chan->device->dev, sgt->sgl, sgt->nents, dir);
39262306a36Sopenharmony_ci}
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_cistatic void ep93xx_spi_dma_callback(void *callback_param)
39562306a36Sopenharmony_ci{
39662306a36Sopenharmony_ci	struct spi_controller *host = callback_param;
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	ep93xx_spi_dma_finish(host, DMA_TO_DEVICE);
39962306a36Sopenharmony_ci	ep93xx_spi_dma_finish(host, DMA_FROM_DEVICE);
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci	spi_finalize_current_transfer(host);
40262306a36Sopenharmony_ci}
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_cistatic int ep93xx_spi_dma_transfer(struct spi_controller *host)
40562306a36Sopenharmony_ci{
40662306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
40762306a36Sopenharmony_ci	struct dma_async_tx_descriptor *rxd, *txd;
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci	rxd = ep93xx_spi_dma_prepare(host, DMA_FROM_DEVICE);
41062306a36Sopenharmony_ci	if (IS_ERR(rxd)) {
41162306a36Sopenharmony_ci		dev_err(&host->dev, "DMA RX failed: %ld\n", PTR_ERR(rxd));
41262306a36Sopenharmony_ci		return PTR_ERR(rxd);
41362306a36Sopenharmony_ci	}
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	txd = ep93xx_spi_dma_prepare(host, DMA_TO_DEVICE);
41662306a36Sopenharmony_ci	if (IS_ERR(txd)) {
41762306a36Sopenharmony_ci		ep93xx_spi_dma_finish(host, DMA_FROM_DEVICE);
41862306a36Sopenharmony_ci		dev_err(&host->dev, "DMA TX failed: %ld\n", PTR_ERR(txd));
41962306a36Sopenharmony_ci		return PTR_ERR(txd);
42062306a36Sopenharmony_ci	}
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	/* We are ready when RX is done */
42362306a36Sopenharmony_ci	rxd->callback = ep93xx_spi_dma_callback;
42462306a36Sopenharmony_ci	rxd->callback_param = host;
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci	/* Now submit both descriptors and start DMA */
42762306a36Sopenharmony_ci	dmaengine_submit(rxd);
42862306a36Sopenharmony_ci	dmaengine_submit(txd);
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci	dma_async_issue_pending(espi->dma_rx);
43162306a36Sopenharmony_ci	dma_async_issue_pending(espi->dma_tx);
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci	/* signal that we need to wait for completion */
43462306a36Sopenharmony_ci	return 1;
43562306a36Sopenharmony_ci}
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_cistatic irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id)
43862306a36Sopenharmony_ci{
43962306a36Sopenharmony_ci	struct spi_controller *host = dev_id;
44062306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
44162306a36Sopenharmony_ci	u32 val;
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci	/*
44462306a36Sopenharmony_ci	 * If we got ROR (receive overrun) interrupt we know that something is
44562306a36Sopenharmony_ci	 * wrong. Just abort the message.
44662306a36Sopenharmony_ci	 */
44762306a36Sopenharmony_ci	if (readl(espi->mmio + SSPIIR) & SSPIIR_RORIS) {
44862306a36Sopenharmony_ci		/* clear the overrun interrupt */
44962306a36Sopenharmony_ci		writel(0, espi->mmio + SSPICR);
45062306a36Sopenharmony_ci		dev_warn(&host->dev,
45162306a36Sopenharmony_ci			 "receive overrun, aborting the message\n");
45262306a36Sopenharmony_ci		host->cur_msg->status = -EIO;
45362306a36Sopenharmony_ci	} else {
45462306a36Sopenharmony_ci		/*
45562306a36Sopenharmony_ci		 * Interrupt is either RX (RIS) or TX (TIS). For both cases we
45662306a36Sopenharmony_ci		 * simply execute next data transfer.
45762306a36Sopenharmony_ci		 */
45862306a36Sopenharmony_ci		if (ep93xx_spi_read_write(host)) {
45962306a36Sopenharmony_ci			/*
46062306a36Sopenharmony_ci			 * In normal case, there still is some processing left
46162306a36Sopenharmony_ci			 * for current transfer. Let's wait for the next
46262306a36Sopenharmony_ci			 * interrupt then.
46362306a36Sopenharmony_ci			 */
46462306a36Sopenharmony_ci			return IRQ_HANDLED;
46562306a36Sopenharmony_ci		}
46662306a36Sopenharmony_ci	}
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ci	/*
46962306a36Sopenharmony_ci	 * Current transfer is finished, either with error or with success. In
47062306a36Sopenharmony_ci	 * any case we disable interrupts and notify the worker to handle
47162306a36Sopenharmony_ci	 * any post-processing of the message.
47262306a36Sopenharmony_ci	 */
47362306a36Sopenharmony_ci	val = readl(espi->mmio + SSPCR1);
47462306a36Sopenharmony_ci	val &= ~(SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE);
47562306a36Sopenharmony_ci	writel(val, espi->mmio + SSPCR1);
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci	spi_finalize_current_transfer(host);
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci	return IRQ_HANDLED;
48062306a36Sopenharmony_ci}
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_cistatic int ep93xx_spi_transfer_one(struct spi_controller *host,
48362306a36Sopenharmony_ci				   struct spi_device *spi,
48462306a36Sopenharmony_ci				   struct spi_transfer *xfer)
48562306a36Sopenharmony_ci{
48662306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
48762306a36Sopenharmony_ci	u32 val;
48862306a36Sopenharmony_ci	int ret;
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci	ret = ep93xx_spi_chip_setup(host, spi, xfer);
49162306a36Sopenharmony_ci	if (ret) {
49262306a36Sopenharmony_ci		dev_err(&host->dev, "failed to setup chip for transfer\n");
49362306a36Sopenharmony_ci		return ret;
49462306a36Sopenharmony_ci	}
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci	host->cur_msg->state = xfer;
49762306a36Sopenharmony_ci	espi->rx = 0;
49862306a36Sopenharmony_ci	espi->tx = 0;
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci	/*
50162306a36Sopenharmony_ci	 * There is no point of setting up DMA for the transfers which will
50262306a36Sopenharmony_ci	 * fit into the FIFO and can be transferred with a single interrupt.
50362306a36Sopenharmony_ci	 * So in these cases we will be using PIO and don't bother for DMA.
50462306a36Sopenharmony_ci	 */
50562306a36Sopenharmony_ci	if (espi->dma_rx && xfer->len > SPI_FIFO_SIZE)
50662306a36Sopenharmony_ci		return ep93xx_spi_dma_transfer(host);
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci	/* Using PIO so prime the TX FIFO and enable interrupts */
50962306a36Sopenharmony_ci	ep93xx_spi_read_write(host);
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci	val = readl(espi->mmio + SSPCR1);
51262306a36Sopenharmony_ci	val |= (SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE);
51362306a36Sopenharmony_ci	writel(val, espi->mmio + SSPCR1);
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci	/* signal that we need to wait for completion */
51662306a36Sopenharmony_ci	return 1;
51762306a36Sopenharmony_ci}
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_cistatic int ep93xx_spi_prepare_message(struct spi_controller *host,
52062306a36Sopenharmony_ci				      struct spi_message *msg)
52162306a36Sopenharmony_ci{
52262306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
52362306a36Sopenharmony_ci	unsigned long timeout;
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci	/*
52662306a36Sopenharmony_ci	 * Just to be sure: flush any data from RX FIFO.
52762306a36Sopenharmony_ci	 */
52862306a36Sopenharmony_ci	timeout = jiffies + msecs_to_jiffies(SPI_TIMEOUT);
52962306a36Sopenharmony_ci	while (readl(espi->mmio + SSPSR) & SSPSR_RNE) {
53062306a36Sopenharmony_ci		if (time_after(jiffies, timeout)) {
53162306a36Sopenharmony_ci			dev_warn(&host->dev,
53262306a36Sopenharmony_ci				 "timeout while flushing RX FIFO\n");
53362306a36Sopenharmony_ci			return -ETIMEDOUT;
53462306a36Sopenharmony_ci		}
53562306a36Sopenharmony_ci		readl(espi->mmio + SSPDR);
53662306a36Sopenharmony_ci	}
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci	/*
53962306a36Sopenharmony_ci	 * We explicitly handle FIFO level. This way we don't have to check TX
54062306a36Sopenharmony_ci	 * FIFO status using %SSPSR_TNF bit which may cause RX FIFO overruns.
54162306a36Sopenharmony_ci	 */
54262306a36Sopenharmony_ci	espi->fifo_level = 0;
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_ci	return 0;
54562306a36Sopenharmony_ci}
54662306a36Sopenharmony_ci
54762306a36Sopenharmony_cistatic int ep93xx_spi_prepare_hardware(struct spi_controller *host)
54862306a36Sopenharmony_ci{
54962306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
55062306a36Sopenharmony_ci	u32 val;
55162306a36Sopenharmony_ci	int ret;
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci	ret = clk_prepare_enable(espi->clk);
55462306a36Sopenharmony_ci	if (ret)
55562306a36Sopenharmony_ci		return ret;
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci	val = readl(espi->mmio + SSPCR1);
55862306a36Sopenharmony_ci	val |= SSPCR1_SSE;
55962306a36Sopenharmony_ci	writel(val, espi->mmio + SSPCR1);
56062306a36Sopenharmony_ci
56162306a36Sopenharmony_ci	return 0;
56262306a36Sopenharmony_ci}
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_cistatic int ep93xx_spi_unprepare_hardware(struct spi_controller *host)
56562306a36Sopenharmony_ci{
56662306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
56762306a36Sopenharmony_ci	u32 val;
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci	val = readl(espi->mmio + SSPCR1);
57062306a36Sopenharmony_ci	val &= ~SSPCR1_SSE;
57162306a36Sopenharmony_ci	writel(val, espi->mmio + SSPCR1);
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci	clk_disable_unprepare(espi->clk);
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci	return 0;
57662306a36Sopenharmony_ci}
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_cistatic bool ep93xx_spi_dma_filter(struct dma_chan *chan, void *filter_param)
57962306a36Sopenharmony_ci{
58062306a36Sopenharmony_ci	if (ep93xx_dma_chan_is_m2p(chan))
58162306a36Sopenharmony_ci		return false;
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci	chan->private = filter_param;
58462306a36Sopenharmony_ci	return true;
58562306a36Sopenharmony_ci}
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_cistatic int ep93xx_spi_setup_dma(struct ep93xx_spi *espi)
58862306a36Sopenharmony_ci{
58962306a36Sopenharmony_ci	dma_cap_mask_t mask;
59062306a36Sopenharmony_ci	int ret;
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	espi->zeropage = (void *)get_zeroed_page(GFP_KERNEL);
59362306a36Sopenharmony_ci	if (!espi->zeropage)
59462306a36Sopenharmony_ci		return -ENOMEM;
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci	dma_cap_zero(mask);
59762306a36Sopenharmony_ci	dma_cap_set(DMA_SLAVE, mask);
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ci	espi->dma_rx_data.port = EP93XX_DMA_SSP;
60062306a36Sopenharmony_ci	espi->dma_rx_data.direction = DMA_DEV_TO_MEM;
60162306a36Sopenharmony_ci	espi->dma_rx_data.name = "ep93xx-spi-rx";
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci	espi->dma_rx = dma_request_channel(mask, ep93xx_spi_dma_filter,
60462306a36Sopenharmony_ci					   &espi->dma_rx_data);
60562306a36Sopenharmony_ci	if (!espi->dma_rx) {
60662306a36Sopenharmony_ci		ret = -ENODEV;
60762306a36Sopenharmony_ci		goto fail_free_page;
60862306a36Sopenharmony_ci	}
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	espi->dma_tx_data.port = EP93XX_DMA_SSP;
61162306a36Sopenharmony_ci	espi->dma_tx_data.direction = DMA_MEM_TO_DEV;
61262306a36Sopenharmony_ci	espi->dma_tx_data.name = "ep93xx-spi-tx";
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci	espi->dma_tx = dma_request_channel(mask, ep93xx_spi_dma_filter,
61562306a36Sopenharmony_ci					   &espi->dma_tx_data);
61662306a36Sopenharmony_ci	if (!espi->dma_tx) {
61762306a36Sopenharmony_ci		ret = -ENODEV;
61862306a36Sopenharmony_ci		goto fail_release_rx;
61962306a36Sopenharmony_ci	}
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ci	return 0;
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_cifail_release_rx:
62462306a36Sopenharmony_ci	dma_release_channel(espi->dma_rx);
62562306a36Sopenharmony_ci	espi->dma_rx = NULL;
62662306a36Sopenharmony_cifail_free_page:
62762306a36Sopenharmony_ci	free_page((unsigned long)espi->zeropage);
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci	return ret;
63062306a36Sopenharmony_ci}
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_cistatic void ep93xx_spi_release_dma(struct ep93xx_spi *espi)
63362306a36Sopenharmony_ci{
63462306a36Sopenharmony_ci	if (espi->dma_rx) {
63562306a36Sopenharmony_ci		dma_release_channel(espi->dma_rx);
63662306a36Sopenharmony_ci		sg_free_table(&espi->rx_sgt);
63762306a36Sopenharmony_ci	}
63862306a36Sopenharmony_ci	if (espi->dma_tx) {
63962306a36Sopenharmony_ci		dma_release_channel(espi->dma_tx);
64062306a36Sopenharmony_ci		sg_free_table(&espi->tx_sgt);
64162306a36Sopenharmony_ci	}
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci	if (espi->zeropage)
64462306a36Sopenharmony_ci		free_page((unsigned long)espi->zeropage);
64562306a36Sopenharmony_ci}
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_cistatic int ep93xx_spi_probe(struct platform_device *pdev)
64862306a36Sopenharmony_ci{
64962306a36Sopenharmony_ci	struct spi_controller *host;
65062306a36Sopenharmony_ci	struct ep93xx_spi_info *info;
65162306a36Sopenharmony_ci	struct ep93xx_spi *espi;
65262306a36Sopenharmony_ci	struct resource *res;
65362306a36Sopenharmony_ci	int irq;
65462306a36Sopenharmony_ci	int error;
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_ci	info = dev_get_platdata(&pdev->dev);
65762306a36Sopenharmony_ci	if (!info) {
65862306a36Sopenharmony_ci		dev_err(&pdev->dev, "missing platform data\n");
65962306a36Sopenharmony_ci		return -EINVAL;
66062306a36Sopenharmony_ci	}
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ci	irq = platform_get_irq(pdev, 0);
66362306a36Sopenharmony_ci	if (irq < 0)
66462306a36Sopenharmony_ci		return irq;
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_ci	host = spi_alloc_host(&pdev->dev, sizeof(*espi));
66762306a36Sopenharmony_ci	if (!host)
66862306a36Sopenharmony_ci		return -ENOMEM;
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ci	host->use_gpio_descriptors = true;
67162306a36Sopenharmony_ci	host->prepare_transfer_hardware = ep93xx_spi_prepare_hardware;
67262306a36Sopenharmony_ci	host->unprepare_transfer_hardware = ep93xx_spi_unprepare_hardware;
67362306a36Sopenharmony_ci	host->prepare_message = ep93xx_spi_prepare_message;
67462306a36Sopenharmony_ci	host->transfer_one = ep93xx_spi_transfer_one;
67562306a36Sopenharmony_ci	host->bus_num = pdev->id;
67662306a36Sopenharmony_ci	host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
67762306a36Sopenharmony_ci	host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
67862306a36Sopenharmony_ci	/*
67962306a36Sopenharmony_ci	 * The SPI core will count the number of GPIO descriptors to figure
68062306a36Sopenharmony_ci	 * out the number of chip selects available on the platform.
68162306a36Sopenharmony_ci	 */
68262306a36Sopenharmony_ci	host->num_chipselect = 0;
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	platform_set_drvdata(pdev, host);
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci	espi = spi_controller_get_devdata(host);
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci	espi->clk = devm_clk_get(&pdev->dev, NULL);
68962306a36Sopenharmony_ci	if (IS_ERR(espi->clk)) {
69062306a36Sopenharmony_ci		dev_err(&pdev->dev, "unable to get spi clock\n");
69162306a36Sopenharmony_ci		error = PTR_ERR(espi->clk);
69262306a36Sopenharmony_ci		goto fail_release_host;
69362306a36Sopenharmony_ci	}
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_ci	/*
69662306a36Sopenharmony_ci	 * Calculate maximum and minimum supported clock rates
69762306a36Sopenharmony_ci	 * for the controller.
69862306a36Sopenharmony_ci	 */
69962306a36Sopenharmony_ci	host->max_speed_hz = clk_get_rate(espi->clk) / 2;
70062306a36Sopenharmony_ci	host->min_speed_hz = clk_get_rate(espi->clk) / (254 * 256);
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ci	espi->mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
70362306a36Sopenharmony_ci	if (IS_ERR(espi->mmio)) {
70462306a36Sopenharmony_ci		error = PTR_ERR(espi->mmio);
70562306a36Sopenharmony_ci		goto fail_release_host;
70662306a36Sopenharmony_ci	}
70762306a36Sopenharmony_ci	espi->sspdr_phys = res->start + SSPDR;
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ci	error = devm_request_irq(&pdev->dev, irq, ep93xx_spi_interrupt,
71062306a36Sopenharmony_ci				0, "ep93xx-spi", host);
71162306a36Sopenharmony_ci	if (error) {
71262306a36Sopenharmony_ci		dev_err(&pdev->dev, "failed to request irq\n");
71362306a36Sopenharmony_ci		goto fail_release_host;
71462306a36Sopenharmony_ci	}
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci	if (info->use_dma && ep93xx_spi_setup_dma(espi))
71762306a36Sopenharmony_ci		dev_warn(&pdev->dev, "DMA setup failed. Falling back to PIO\n");
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci	/* make sure that the hardware is disabled */
72062306a36Sopenharmony_ci	writel(0, espi->mmio + SSPCR1);
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_ci	error = devm_spi_register_controller(&pdev->dev, host);
72362306a36Sopenharmony_ci	if (error) {
72462306a36Sopenharmony_ci		dev_err(&pdev->dev, "failed to register SPI host\n");
72562306a36Sopenharmony_ci		goto fail_free_dma;
72662306a36Sopenharmony_ci	}
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci	dev_info(&pdev->dev, "EP93xx SPI Controller at 0x%08lx irq %d\n",
72962306a36Sopenharmony_ci		 (unsigned long)res->start, irq);
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci	return 0;
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_cifail_free_dma:
73462306a36Sopenharmony_ci	ep93xx_spi_release_dma(espi);
73562306a36Sopenharmony_cifail_release_host:
73662306a36Sopenharmony_ci	spi_controller_put(host);
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_ci	return error;
73962306a36Sopenharmony_ci}
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_cistatic void ep93xx_spi_remove(struct platform_device *pdev)
74262306a36Sopenharmony_ci{
74362306a36Sopenharmony_ci	struct spi_controller *host = platform_get_drvdata(pdev);
74462306a36Sopenharmony_ci	struct ep93xx_spi *espi = spi_controller_get_devdata(host);
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci	ep93xx_spi_release_dma(espi);
74762306a36Sopenharmony_ci}
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_cistatic struct platform_driver ep93xx_spi_driver = {
75062306a36Sopenharmony_ci	.driver		= {
75162306a36Sopenharmony_ci		.name	= "ep93xx-spi",
75262306a36Sopenharmony_ci	},
75362306a36Sopenharmony_ci	.probe		= ep93xx_spi_probe,
75462306a36Sopenharmony_ci	.remove_new	= ep93xx_spi_remove,
75562306a36Sopenharmony_ci};
75662306a36Sopenharmony_cimodule_platform_driver(ep93xx_spi_driver);
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ciMODULE_DESCRIPTION("EP93xx SPI Controller driver");
75962306a36Sopenharmony_ciMODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
76062306a36Sopenharmony_ciMODULE_LICENSE("GPL");
76162306a36Sopenharmony_ciMODULE_ALIAS("platform:ep93xx-spi");
762