xref: /linux/drivers/spi/spi-st-ssc4.c (revision 06d07429858317ded2db7986113a9e0129cd599b)
1f3949fd0SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
29e862375SLee Jones /*
39e862375SLee Jones  *  Copyright (c) 2008-2014 STMicroelectronics Limited
49e862375SLee Jones  *
59e862375SLee Jones  *  Author: Angus Clark <Angus.Clark@st.com>
69e862375SLee Jones  *          Patrice Chotard <patrice.chotard@st.com>
79e862375SLee Jones  *          Lee Jones <lee.jones@linaro.org>
89e862375SLee Jones  *
9*e6b7e64cSYang Yingliang  *  SPI host mode controller driver, used in STMicroelectronics devices.
109e862375SLee Jones  */
119e862375SLee Jones 
129e862375SLee Jones #include <linux/clk.h>
139e862375SLee Jones #include <linux/delay.h>
149e862375SLee Jones #include <linux/interrupt.h>
159e862375SLee Jones #include <linux/io.h>
169e862375SLee Jones #include <linux/module.h>
179e862375SLee Jones #include <linux/pinctrl/consumer.h>
189e862375SLee Jones #include <linux/platform_device.h>
199e862375SLee Jones #include <linux/of.h>
209e862375SLee Jones #include <linux/of_irq.h>
219e862375SLee Jones #include <linux/pm_runtime.h>
229e862375SLee Jones #include <linux/spi/spi.h>
239e862375SLee Jones #include <linux/spi/spi_bitbang.h>
249e862375SLee Jones 
259e862375SLee Jones /* SSC registers */
269e862375SLee Jones #define SSC_BRG				0x000
279e862375SLee Jones #define SSC_TBUF			0x004
289e862375SLee Jones #define SSC_RBUF			0x008
299e862375SLee Jones #define SSC_CTL				0x00C
309e862375SLee Jones #define SSC_IEN				0x010
319e862375SLee Jones #define SSC_I2C				0x018
329e862375SLee Jones 
339e862375SLee Jones /* SSC Control */
349e862375SLee Jones #define SSC_CTL_DATA_WIDTH_9		0x8
359e862375SLee Jones #define SSC_CTL_DATA_WIDTH_MSK		0xf
369e862375SLee Jones #define SSC_CTL_BM			0xf
379e862375SLee Jones #define SSC_CTL_HB			BIT(4)
389e862375SLee Jones #define SSC_CTL_PH			BIT(5)
399e862375SLee Jones #define SSC_CTL_PO			BIT(6)
409e862375SLee Jones #define SSC_CTL_SR			BIT(7)
419e862375SLee Jones #define SSC_CTL_MS			BIT(8)
429e862375SLee Jones #define SSC_CTL_EN			BIT(9)
439e862375SLee Jones #define SSC_CTL_LPB			BIT(10)
449e862375SLee Jones #define SSC_CTL_EN_TX_FIFO		BIT(11)
459e862375SLee Jones #define SSC_CTL_EN_RX_FIFO		BIT(12)
469e862375SLee Jones #define SSC_CTL_EN_CLST_RX		BIT(13)
479e862375SLee Jones 
489e862375SLee Jones /* SSC Interrupt Enable */
499e862375SLee Jones #define SSC_IEN_TEEN			BIT(2)
509e862375SLee Jones 
519e862375SLee Jones #define FIFO_SIZE			8
529e862375SLee Jones 
539e862375SLee Jones struct spi_st {
549e862375SLee Jones 	/* SSC SPI Controller */
559e862375SLee Jones 	void __iomem		*base;
569e862375SLee Jones 	struct clk		*clk;
579e862375SLee Jones 	struct device		*dev;
589e862375SLee Jones 
599e862375SLee Jones 	/* SSC SPI current transaction */
609e862375SLee Jones 	const u8		*tx_ptr;
619e862375SLee Jones 	u8			*rx_ptr;
629e862375SLee Jones 	u16			bytes_per_word;
639e862375SLee Jones 	unsigned int		words_remaining;
649e862375SLee Jones 	unsigned int		baud;
659e862375SLee Jones 	struct completion	done;
669e862375SLee Jones };
679e862375SLee Jones 
689e862375SLee Jones /* Load the TX FIFO */
ssc_write_tx_fifo(struct spi_st * spi_st)699e862375SLee Jones static void ssc_write_tx_fifo(struct spi_st *spi_st)
709e862375SLee Jones {
719e862375SLee Jones 	unsigned int count, i;
729e862375SLee Jones 	uint32_t word = 0;
739e862375SLee Jones 
749e862375SLee Jones 	if (spi_st->words_remaining > FIFO_SIZE)
759e862375SLee Jones 		count = FIFO_SIZE;
769e862375SLee Jones 	else
779e862375SLee Jones 		count = spi_st->words_remaining;
789e862375SLee Jones 
799e862375SLee Jones 	for (i = 0; i < count; i++) {
809e862375SLee Jones 		if (spi_st->tx_ptr) {
819e862375SLee Jones 			if (spi_st->bytes_per_word == 1) {
829e862375SLee Jones 				word = *spi_st->tx_ptr++;
839e862375SLee Jones 			} else {
849e862375SLee Jones 				word = *spi_st->tx_ptr++;
859e862375SLee Jones 				word = *spi_st->tx_ptr++ | (word << 8);
869e862375SLee Jones 			}
879e862375SLee Jones 		}
889e862375SLee Jones 		writel_relaxed(word, spi_st->base + SSC_TBUF);
899e862375SLee Jones 	}
909e862375SLee Jones }
919e862375SLee Jones 
929e862375SLee Jones /* Read the RX FIFO */
ssc_read_rx_fifo(struct spi_st * spi_st)939e862375SLee Jones static void ssc_read_rx_fifo(struct spi_st *spi_st)
949e862375SLee Jones {
959e862375SLee Jones 	unsigned int count, i;
969e862375SLee Jones 	uint32_t word = 0;
979e862375SLee Jones 
989e862375SLee Jones 	if (spi_st->words_remaining > FIFO_SIZE)
999e862375SLee Jones 		count = FIFO_SIZE;
1009e862375SLee Jones 	else
1019e862375SLee Jones 		count = spi_st->words_remaining;
1029e862375SLee Jones 
1039e862375SLee Jones 	for (i = 0; i < count; i++) {
1049e862375SLee Jones 		word = readl_relaxed(spi_st->base + SSC_RBUF);
1059e862375SLee Jones 
1069e862375SLee Jones 		if (spi_st->rx_ptr) {
1079e862375SLee Jones 			if (spi_st->bytes_per_word == 1) {
1089e862375SLee Jones 				*spi_st->rx_ptr++ = (uint8_t)word;
1099e862375SLee Jones 			} else {
1109e862375SLee Jones 				*spi_st->rx_ptr++ = (word >> 8);
1119e862375SLee Jones 				*spi_st->rx_ptr++ = word & 0xff;
1129e862375SLee Jones 			}
1139e862375SLee Jones 		}
1149e862375SLee Jones 	}
1159e862375SLee Jones 	spi_st->words_remaining -= count;
1169e862375SLee Jones }
1179e862375SLee Jones 
spi_st_transfer_one(struct spi_controller * host,struct spi_device * spi,struct spi_transfer * t)118*e6b7e64cSYang Yingliang static int spi_st_transfer_one(struct spi_controller *host,
1199e862375SLee Jones 			       struct spi_device *spi, struct spi_transfer *t)
1209e862375SLee Jones {
121*e6b7e64cSYang Yingliang 	struct spi_st *spi_st = spi_controller_get_devdata(host);
1229e862375SLee Jones 	uint32_t ctl = 0;
1239e862375SLee Jones 
1249e862375SLee Jones 	/* Setup transfer */
1259e862375SLee Jones 	spi_st->tx_ptr = t->tx_buf;
1269e862375SLee Jones 	spi_st->rx_ptr = t->rx_buf;
1279e862375SLee Jones 
1289e862375SLee Jones 	if (spi->bits_per_word > 8) {
1299e862375SLee Jones 		/*
1309e862375SLee Jones 		 * Anything greater than 8 bits-per-word requires 2
1319e862375SLee Jones 		 * bytes-per-word in the RX/TX buffers
1329e862375SLee Jones 		 */
1339e862375SLee Jones 		spi_st->bytes_per_word = 2;
1349e862375SLee Jones 		spi_st->words_remaining = t->len / 2;
1359e862375SLee Jones 
1369e862375SLee Jones 	} else if (spi->bits_per_word == 8 && !(t->len & 0x1)) {
1379e862375SLee Jones 		/*
1389e862375SLee Jones 		 * If transfer is even-length, and 8 bits-per-word, then
1399e862375SLee Jones 		 * implement as half-length 16 bits-per-word transfer
1409e862375SLee Jones 		 */
1419e862375SLee Jones 		spi_st->bytes_per_word = 2;
1429e862375SLee Jones 		spi_st->words_remaining = t->len / 2;
1439e862375SLee Jones 
1449e862375SLee Jones 		/* Set SSC_CTL to 16 bits-per-word */
1459e862375SLee Jones 		ctl = readl_relaxed(spi_st->base + SSC_CTL);
1469e862375SLee Jones 		writel_relaxed((ctl | 0xf), spi_st->base + SSC_CTL);
1479e862375SLee Jones 
1489e862375SLee Jones 		readl_relaxed(spi_st->base + SSC_RBUF);
1499e862375SLee Jones 
1509e862375SLee Jones 	} else {
1519e862375SLee Jones 		spi_st->bytes_per_word = 1;
1529e862375SLee Jones 		spi_st->words_remaining = t->len;
1539e862375SLee Jones 	}
1549e862375SLee Jones 
1559e862375SLee Jones 	reinit_completion(&spi_st->done);
1569e862375SLee Jones 
1579e862375SLee Jones 	/* Start transfer by writing to the TX FIFO */
1589e862375SLee Jones 	ssc_write_tx_fifo(spi_st);
1599e862375SLee Jones 	writel_relaxed(SSC_IEN_TEEN, spi_st->base + SSC_IEN);
1609e862375SLee Jones 
1619e862375SLee Jones 	/* Wait for transfer to complete */
1629e862375SLee Jones 	wait_for_completion(&spi_st->done);
1639e862375SLee Jones 
1649e862375SLee Jones 	/* Restore SSC_CTL if necessary */
1659e862375SLee Jones 	if (ctl)
1669e862375SLee Jones 		writel_relaxed(ctl, spi_st->base + SSC_CTL);
1679e862375SLee Jones 
168*e6b7e64cSYang Yingliang 	spi_finalize_current_transfer(spi->controller);
1699e862375SLee Jones 
1709e862375SLee Jones 	return t->len;
1719e862375SLee Jones }
1729e862375SLee Jones 
1739e862375SLee Jones /* the spi->mode bits understood by this driver: */
1749e862375SLee Jones #define MODEBITS  (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_LOOP | SPI_CS_HIGH)
spi_st_setup(struct spi_device * spi)1759e862375SLee Jones static int spi_st_setup(struct spi_device *spi)
1769e862375SLee Jones {
177*e6b7e64cSYang Yingliang 	struct spi_st *spi_st = spi_controller_get_devdata(spi->controller);
1789e862375SLee Jones 	u32 spi_st_clk, sscbrg, var;
1799e862375SLee Jones 	u32 hz = spi->max_speed_hz;
1809e862375SLee Jones 
1819e862375SLee Jones 	if (!hz)  {
1829e862375SLee Jones 		dev_err(&spi->dev, "max_speed_hz unspecified\n");
1839e862375SLee Jones 		return -EINVAL;
1849e862375SLee Jones 	}
1859e862375SLee Jones 
1869e264f3fSAmit Kumar Mahapatra via Alsa-devel 	if (!spi_get_csgpiod(spi, 0)) {
18732159969SLinus Walleij 		dev_err(&spi->dev, "no valid gpio assigned\n");
1889e862375SLee Jones 		return -EINVAL;
1899e862375SLee Jones 	}
1909e862375SLee Jones 
1919e862375SLee Jones 	spi_st_clk = clk_get_rate(spi_st->clk);
1929e862375SLee Jones 
1939e862375SLee Jones 	/* Set SSC_BRF */
1949e862375SLee Jones 	sscbrg = spi_st_clk / (2 * hz);
1959e862375SLee Jones 	if (sscbrg < 0x07 || sscbrg > BIT(16)) {
1969e862375SLee Jones 		dev_err(&spi->dev,
1979e862375SLee Jones 			"baudrate %d outside valid range %d\n", sscbrg, hz);
19832159969SLinus Walleij 		return -EINVAL;
1999e862375SLee Jones 	}
2009e862375SLee Jones 
2019e862375SLee Jones 	spi_st->baud = spi_st_clk / (2 * sscbrg);
2029e862375SLee Jones 	if (sscbrg == BIT(16)) /* 16-bit counter wraps */
2039e862375SLee Jones 		sscbrg = 0x0;
2049e862375SLee Jones 
2059e862375SLee Jones 	writel_relaxed(sscbrg, spi_st->base + SSC_BRG);
2069e862375SLee Jones 
2079e862375SLee Jones 	dev_dbg(&spi->dev,
2089e862375SLee Jones 		"setting baudrate:target= %u hz, actual= %u hz, sscbrg= %u\n",
2099e862375SLee Jones 		hz, spi_st->baud, sscbrg);
2109e862375SLee Jones 
2119e862375SLee Jones 	/* Set SSC_CTL and enable SSC */
2129e862375SLee Jones 	var = readl_relaxed(spi_st->base + SSC_CTL);
2139e862375SLee Jones 	var |= SSC_CTL_MS;
2149e862375SLee Jones 
2159e862375SLee Jones 	if (spi->mode & SPI_CPOL)
2169e862375SLee Jones 		var |= SSC_CTL_PO;
2179e862375SLee Jones 	else
2189e862375SLee Jones 		var &= ~SSC_CTL_PO;
2199e862375SLee Jones 
2209e862375SLee Jones 	if (spi->mode & SPI_CPHA)
2219e862375SLee Jones 		var |= SSC_CTL_PH;
2229e862375SLee Jones 	else
2239e862375SLee Jones 		var &= ~SSC_CTL_PH;
2249e862375SLee Jones 
2259e862375SLee Jones 	if ((spi->mode & SPI_LSB_FIRST) == 0)
2269e862375SLee Jones 		var |= SSC_CTL_HB;
2279e862375SLee Jones 	else
2289e862375SLee Jones 		var &= ~SSC_CTL_HB;
2299e862375SLee Jones 
2309e862375SLee Jones 	if (spi->mode & SPI_LOOP)
2319e862375SLee Jones 		var |= SSC_CTL_LPB;
2329e862375SLee Jones 	else
2339e862375SLee Jones 		var &= ~SSC_CTL_LPB;
2349e862375SLee Jones 
2359e862375SLee Jones 	var &= ~SSC_CTL_DATA_WIDTH_MSK;
2369e862375SLee Jones 	var |= (spi->bits_per_word - 1);
2379e862375SLee Jones 
2389e862375SLee Jones 	var |= SSC_CTL_EN_TX_FIFO | SSC_CTL_EN_RX_FIFO;
2399e862375SLee Jones 	var |= SSC_CTL_EN;
2409e862375SLee Jones 
2419e862375SLee Jones 	writel_relaxed(var, spi_st->base + SSC_CTL);
2429e862375SLee Jones 
2439e862375SLee Jones 	/* Clear the status register */
2449e862375SLee Jones 	readl_relaxed(spi_st->base + SSC_RBUF);
2459e862375SLee Jones 
2469e862375SLee Jones 	return 0;
2479e862375SLee Jones }
2489e862375SLee Jones 
2499e862375SLee Jones /* Interrupt fired when TX shift register becomes empty */
spi_st_irq(int irq,void * dev_id)2509e862375SLee Jones static irqreturn_t spi_st_irq(int irq, void *dev_id)
2519e862375SLee Jones {
2529e862375SLee Jones 	struct spi_st *spi_st = (struct spi_st *)dev_id;
2539e862375SLee Jones 
2549e862375SLee Jones 	/* Read RX FIFO */
2559e862375SLee Jones 	ssc_read_rx_fifo(spi_st);
2569e862375SLee Jones 
2579e862375SLee Jones 	/* Fill TX FIFO */
2589e862375SLee Jones 	if (spi_st->words_remaining) {
2599e862375SLee Jones 		ssc_write_tx_fifo(spi_st);
2609e862375SLee Jones 	} else {
2619e862375SLee Jones 		/* TX/RX complete */
2629e862375SLee Jones 		writel_relaxed(0x0, spi_st->base + SSC_IEN);
2639e862375SLee Jones 		/*
2649e862375SLee Jones 		 * read SSC_IEN to ensure that this bit is set
2659e862375SLee Jones 		 * before re-enabling interrupt
2669e862375SLee Jones 		 */
2679e862375SLee Jones 		readl(spi_st->base + SSC_IEN);
2689e862375SLee Jones 		complete(&spi_st->done);
2699e862375SLee Jones 	}
2709e862375SLee Jones 
2719e862375SLee Jones 	return IRQ_HANDLED;
2729e862375SLee Jones }
2739e862375SLee Jones 
spi_st_probe(struct platform_device * pdev)2749e862375SLee Jones static int spi_st_probe(struct platform_device *pdev)
2759e862375SLee Jones {
2769e862375SLee Jones 	struct device_node *np = pdev->dev.of_node;
277*e6b7e64cSYang Yingliang 	struct spi_controller *host;
2789e862375SLee Jones 	struct spi_st *spi_st;
2799e862375SLee Jones 	int irq, ret = 0;
2809e862375SLee Jones 	u32 var;
2819e862375SLee Jones 
282*e6b7e64cSYang Yingliang 	host = spi_alloc_host(&pdev->dev, sizeof(*spi_st));
283*e6b7e64cSYang Yingliang 	if (!host)
2849e862375SLee Jones 		return -ENOMEM;
2859e862375SLee Jones 
286*e6b7e64cSYang Yingliang 	host->dev.of_node		= np;
287*e6b7e64cSYang Yingliang 	host->mode_bits			= MODEBITS;
288*e6b7e64cSYang Yingliang 	host->setup			= spi_st_setup;
289*e6b7e64cSYang Yingliang 	host->transfer_one		= spi_st_transfer_one;
290*e6b7e64cSYang Yingliang 	host->bits_per_word_mask	= SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
291*e6b7e64cSYang Yingliang 	host->auto_runtime_pm		= true;
292*e6b7e64cSYang Yingliang 	host->bus_num			= pdev->id;
293*e6b7e64cSYang Yingliang 	host->use_gpio_descriptors	= true;
294*e6b7e64cSYang Yingliang 	spi_st				= spi_controller_get_devdata(host);
2959e862375SLee Jones 
2969e862375SLee Jones 	spi_st->clk = devm_clk_get(&pdev->dev, "ssc");
2979e862375SLee Jones 	if (IS_ERR(spi_st->clk)) {
2989e862375SLee Jones 		dev_err(&pdev->dev, "Unable to request clock\n");
2991051550eSAxel Lin 		ret = PTR_ERR(spi_st->clk);
300*e6b7e64cSYang Yingliang 		goto put_host;
3019e862375SLee Jones 	}
3029e862375SLee Jones 
303cf4b5cebSLee Jones 	ret = clk_prepare_enable(spi_st->clk);
3049e862375SLee Jones 	if (ret)
305*e6b7e64cSYang Yingliang 		goto put_host;
3069e862375SLee Jones 
3079e862375SLee Jones 	init_completion(&spi_st->done);
3089e862375SLee Jones 
3099e862375SLee Jones 	/* Get resources */
310338dd352SYueHaibing 	spi_st->base = devm_platform_ioremap_resource(pdev, 0);
3119e862375SLee Jones 	if (IS_ERR(spi_st->base)) {
3129e862375SLee Jones 		ret = PTR_ERR(spi_st->base);
3139e862375SLee Jones 		goto clk_disable;
3149e862375SLee Jones 	}
3159e862375SLee Jones 
3169e862375SLee Jones 	/* Disable I2C and Reset SSC */
3179e862375SLee Jones 	writel_relaxed(0x0, spi_st->base + SSC_I2C);
3189e862375SLee Jones 	var = readw_relaxed(spi_st->base + SSC_CTL);
3199e862375SLee Jones 	var |= SSC_CTL_SR;
3209e862375SLee Jones 	writel_relaxed(var, spi_st->base + SSC_CTL);
3219e862375SLee Jones 
3229e862375SLee Jones 	udelay(1);
3239e862375SLee Jones 	var = readl_relaxed(spi_st->base + SSC_CTL);
3249e862375SLee Jones 	var &= ~SSC_CTL_SR;
3259e862375SLee Jones 	writel_relaxed(var, spi_st->base + SSC_CTL);
3269e862375SLee Jones 
327*e6b7e64cSYang Yingliang 	/* Set SSC into target mode before reconfiguring PIO pins */
3289e862375SLee Jones 	var = readl_relaxed(spi_st->base + SSC_CTL);
3299e862375SLee Jones 	var &= ~SSC_CTL_MS;
3309e862375SLee Jones 	writel_relaxed(var, spi_st->base + SSC_CTL);
3319e862375SLee Jones 
3329e862375SLee Jones 	irq = irq_of_parse_and_map(np, 0);
3339e862375SLee Jones 	if (!irq) {
3349e862375SLee Jones 		dev_err(&pdev->dev, "IRQ missing or invalid\n");
3359e862375SLee Jones 		ret = -EINVAL;
3369e862375SLee Jones 		goto clk_disable;
3379e862375SLee Jones 	}
3389e862375SLee Jones 
3399e862375SLee Jones 	ret = devm_request_irq(&pdev->dev, irq, spi_st_irq, 0,
3409e862375SLee Jones 			       pdev->name, spi_st);
3419e862375SLee Jones 	if (ret) {
3429e862375SLee Jones 		dev_err(&pdev->dev, "Failed to request irq %d\n", irq);
3439e862375SLee Jones 		goto clk_disable;
3449e862375SLee Jones 	}
3459e862375SLee Jones 
3469e862375SLee Jones 	/* by default the device is on */
3479e862375SLee Jones 	pm_runtime_set_active(&pdev->dev);
3489e862375SLee Jones 	pm_runtime_enable(&pdev->dev);
3499e862375SLee Jones 
350*e6b7e64cSYang Yingliang 	platform_set_drvdata(pdev, host);
3519e862375SLee Jones 
352*e6b7e64cSYang Yingliang 	ret = devm_spi_register_controller(&pdev->dev, host);
3539e862375SLee Jones 	if (ret) {
354*e6b7e64cSYang Yingliang 		dev_err(&pdev->dev, "Failed to register host\n");
3555ef76dacSLukas Wunner 		goto rpm_disable;
3569e862375SLee Jones 	}
3579e862375SLee Jones 
3589e862375SLee Jones 	return 0;
3599e862375SLee Jones 
3605ef76dacSLukas Wunner rpm_disable:
361cd050abeSChuhong Yuan 	pm_runtime_disable(&pdev->dev);
3625ef76dacSLukas Wunner clk_disable:
363cf4b5cebSLee Jones 	clk_disable_unprepare(spi_st->clk);
364*e6b7e64cSYang Yingliang put_host:
365*e6b7e64cSYang Yingliang 	spi_controller_put(host);
3669e862375SLee Jones 	return ret;
3679e862375SLee Jones }
3689e862375SLee Jones 
spi_st_remove(struct platform_device * pdev)3692dd42da0SUwe Kleine-König static void spi_st_remove(struct platform_device *pdev)
3709e862375SLee Jones {
371*e6b7e64cSYang Yingliang 	struct spi_controller *host = platform_get_drvdata(pdev);
372*e6b7e64cSYang Yingliang 	struct spi_st *spi_st = spi_controller_get_devdata(host);
3739e862375SLee Jones 
374cd050abeSChuhong Yuan 	pm_runtime_disable(&pdev->dev);
375cd050abeSChuhong Yuan 
376cf4b5cebSLee Jones 	clk_disable_unprepare(spi_st->clk);
3779e862375SLee Jones 
3789e862375SLee Jones 	pinctrl_pm_select_sleep_state(&pdev->dev);
3799e862375SLee Jones }
3809e862375SLee Jones 
3819e862375SLee Jones #ifdef CONFIG_PM
spi_st_runtime_suspend(struct device * dev)3829e862375SLee Jones static int spi_st_runtime_suspend(struct device *dev)
3839e862375SLee Jones {
384*e6b7e64cSYang Yingliang 	struct spi_controller *host = dev_get_drvdata(dev);
385*e6b7e64cSYang Yingliang 	struct spi_st *spi_st = spi_controller_get_devdata(host);
3869e862375SLee Jones 
3879e862375SLee Jones 	writel_relaxed(0, spi_st->base + SSC_IEN);
3889e862375SLee Jones 	pinctrl_pm_select_sleep_state(dev);
3899e862375SLee Jones 
390cf4b5cebSLee Jones 	clk_disable_unprepare(spi_st->clk);
3919e862375SLee Jones 
3929e862375SLee Jones 	return 0;
3939e862375SLee Jones }
3949e862375SLee Jones 
spi_st_runtime_resume(struct device * dev)3959e862375SLee Jones static int spi_st_runtime_resume(struct device *dev)
3969e862375SLee Jones {
397*e6b7e64cSYang Yingliang 	struct spi_controller *host = dev_get_drvdata(dev);
398*e6b7e64cSYang Yingliang 	struct spi_st *spi_st = spi_controller_get_devdata(host);
3999e862375SLee Jones 	int ret;
4009e862375SLee Jones 
401cf4b5cebSLee Jones 	ret = clk_prepare_enable(spi_st->clk);
4029e862375SLee Jones 	pinctrl_pm_select_default_state(dev);
4039e862375SLee Jones 
4049e862375SLee Jones 	return ret;
4059e862375SLee Jones }
4069e862375SLee Jones #endif
4079e862375SLee Jones 
4089e862375SLee Jones #ifdef CONFIG_PM_SLEEP
spi_st_suspend(struct device * dev)4099e862375SLee Jones static int spi_st_suspend(struct device *dev)
4109e862375SLee Jones {
411*e6b7e64cSYang Yingliang 	struct spi_controller *host = dev_get_drvdata(dev);
4129e862375SLee Jones 	int ret;
4139e862375SLee Jones 
414*e6b7e64cSYang Yingliang 	ret = spi_controller_suspend(host);
4159e862375SLee Jones 	if (ret)
4169e862375SLee Jones 		return ret;
4179e862375SLee Jones 
4189e862375SLee Jones 	return pm_runtime_force_suspend(dev);
4199e862375SLee Jones }
4209e862375SLee Jones 
spi_st_resume(struct device * dev)4219e862375SLee Jones static int spi_st_resume(struct device *dev)
4229e862375SLee Jones {
423*e6b7e64cSYang Yingliang 	struct spi_controller *host = dev_get_drvdata(dev);
4249e862375SLee Jones 	int ret;
4259e862375SLee Jones 
426*e6b7e64cSYang Yingliang 	ret = spi_controller_resume(host);
4279e862375SLee Jones 	if (ret)
4289e862375SLee Jones 		return ret;
4299e862375SLee Jones 
4309e862375SLee Jones 	return pm_runtime_force_resume(dev);
4319e862375SLee Jones }
4329e862375SLee Jones #endif
4339e862375SLee Jones 
4349e862375SLee Jones static const struct dev_pm_ops spi_st_pm = {
4359e862375SLee Jones 	SET_SYSTEM_SLEEP_PM_OPS(spi_st_suspend, spi_st_resume)
4369e862375SLee Jones 	SET_RUNTIME_PM_OPS(spi_st_runtime_suspend, spi_st_runtime_resume, NULL)
4379e862375SLee Jones };
4389e862375SLee Jones 
43909355402SFabian Frederick static const struct of_device_id stm_spi_match[] = {
4409e862375SLee Jones 	{ .compatible = "st,comms-ssc4-spi", },
4419e862375SLee Jones 	{},
4429e862375SLee Jones };
4439e862375SLee Jones MODULE_DEVICE_TABLE(of, stm_spi_match);
4449e862375SLee Jones 
4459e862375SLee Jones static struct platform_driver spi_st_driver = {
4469e862375SLee Jones 	.driver = {
4479e862375SLee Jones 		.name = "spi-st",
4489e862375SLee Jones 		.pm = &spi_st_pm,
4499e862375SLee Jones 		.of_match_table = of_match_ptr(stm_spi_match),
4509e862375SLee Jones 	},
4519e862375SLee Jones 	.probe = spi_st_probe,
4522dd42da0SUwe Kleine-König 	.remove_new = spi_st_remove,
4539e862375SLee Jones };
4549e862375SLee Jones module_platform_driver(spi_st_driver);
4559e862375SLee Jones 
4569e862375SLee Jones MODULE_AUTHOR("Patrice Chotard <patrice.chotard@st.com>");
4579e862375SLee Jones MODULE_DESCRIPTION("STM SSC SPI driver");
4589e862375SLee Jones MODULE_LICENSE("GPL v2");
459