xref: /linux/drivers/spi/spi-st-ssc4.c (revision 5ef76dac0f2c26aeae4ee79eb830280f16d5aceb)
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  *
99e862375SLee Jones  *  SPI master 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_gpio.h>
219e862375SLee Jones #include <linux/of_irq.h>
229e862375SLee Jones #include <linux/pm_runtime.h>
239e862375SLee Jones #include <linux/spi/spi.h>
249e862375SLee Jones #include <linux/spi/spi_bitbang.h>
259e862375SLee Jones 
269e862375SLee Jones /* SSC registers */
279e862375SLee Jones #define SSC_BRG				0x000
289e862375SLee Jones #define SSC_TBUF			0x004
299e862375SLee Jones #define SSC_RBUF			0x008
309e862375SLee Jones #define SSC_CTL				0x00C
319e862375SLee Jones #define SSC_IEN				0x010
329e862375SLee Jones #define SSC_I2C				0x018
339e862375SLee Jones 
349e862375SLee Jones /* SSC Control */
359e862375SLee Jones #define SSC_CTL_DATA_WIDTH_9		0x8
369e862375SLee Jones #define SSC_CTL_DATA_WIDTH_MSK		0xf
379e862375SLee Jones #define SSC_CTL_BM			0xf
389e862375SLee Jones #define SSC_CTL_HB			BIT(4)
399e862375SLee Jones #define SSC_CTL_PH			BIT(5)
409e862375SLee Jones #define SSC_CTL_PO			BIT(6)
419e862375SLee Jones #define SSC_CTL_SR			BIT(7)
429e862375SLee Jones #define SSC_CTL_MS			BIT(8)
439e862375SLee Jones #define SSC_CTL_EN			BIT(9)
449e862375SLee Jones #define SSC_CTL_LPB			BIT(10)
459e862375SLee Jones #define SSC_CTL_EN_TX_FIFO		BIT(11)
469e862375SLee Jones #define SSC_CTL_EN_RX_FIFO		BIT(12)
479e862375SLee Jones #define SSC_CTL_EN_CLST_RX		BIT(13)
489e862375SLee Jones 
499e862375SLee Jones /* SSC Interrupt Enable */
509e862375SLee Jones #define SSC_IEN_TEEN			BIT(2)
519e862375SLee Jones 
529e862375SLee Jones #define FIFO_SIZE			8
539e862375SLee Jones 
549e862375SLee Jones struct spi_st {
559e862375SLee Jones 	/* SSC SPI Controller */
569e862375SLee Jones 	void __iomem		*base;
579e862375SLee Jones 	struct clk		*clk;
589e862375SLee Jones 	struct device		*dev;
599e862375SLee Jones 
609e862375SLee Jones 	/* SSC SPI current transaction */
619e862375SLee Jones 	const u8		*tx_ptr;
629e862375SLee Jones 	u8			*rx_ptr;
639e862375SLee Jones 	u16			bytes_per_word;
649e862375SLee Jones 	unsigned int		words_remaining;
659e862375SLee Jones 	unsigned int		baud;
669e862375SLee Jones 	struct completion	done;
679e862375SLee Jones };
689e862375SLee Jones 
699e862375SLee Jones /* Load the TX FIFO */
709e862375SLee Jones static void ssc_write_tx_fifo(struct spi_st *spi_st)
719e862375SLee Jones {
729e862375SLee Jones 	unsigned int count, i;
739e862375SLee Jones 	uint32_t word = 0;
749e862375SLee Jones 
759e862375SLee Jones 	if (spi_st->words_remaining > FIFO_SIZE)
769e862375SLee Jones 		count = FIFO_SIZE;
779e862375SLee Jones 	else
789e862375SLee Jones 		count = spi_st->words_remaining;
799e862375SLee Jones 
809e862375SLee Jones 	for (i = 0; i < count; i++) {
819e862375SLee Jones 		if (spi_st->tx_ptr) {
829e862375SLee Jones 			if (spi_st->bytes_per_word == 1) {
839e862375SLee Jones 				word = *spi_st->tx_ptr++;
849e862375SLee Jones 			} else {
859e862375SLee Jones 				word = *spi_st->tx_ptr++;
869e862375SLee Jones 				word = *spi_st->tx_ptr++ | (word << 8);
879e862375SLee Jones 			}
889e862375SLee Jones 		}
899e862375SLee Jones 		writel_relaxed(word, spi_st->base + SSC_TBUF);
909e862375SLee Jones 	}
919e862375SLee Jones }
929e862375SLee Jones 
939e862375SLee Jones /* Read the RX FIFO */
949e862375SLee Jones static void ssc_read_rx_fifo(struct spi_st *spi_st)
959e862375SLee Jones {
969e862375SLee Jones 	unsigned int count, i;
979e862375SLee Jones 	uint32_t word = 0;
989e862375SLee Jones 
999e862375SLee Jones 	if (spi_st->words_remaining > FIFO_SIZE)
1009e862375SLee Jones 		count = FIFO_SIZE;
1019e862375SLee Jones 	else
1029e862375SLee Jones 		count = spi_st->words_remaining;
1039e862375SLee Jones 
1049e862375SLee Jones 	for (i = 0; i < count; i++) {
1059e862375SLee Jones 		word = readl_relaxed(spi_st->base + SSC_RBUF);
1069e862375SLee Jones 
1079e862375SLee Jones 		if (spi_st->rx_ptr) {
1089e862375SLee Jones 			if (spi_st->bytes_per_word == 1) {
1099e862375SLee Jones 				*spi_st->rx_ptr++ = (uint8_t)word;
1109e862375SLee Jones 			} else {
1119e862375SLee Jones 				*spi_st->rx_ptr++ = (word >> 8);
1129e862375SLee Jones 				*spi_st->rx_ptr++ = word & 0xff;
1139e862375SLee Jones 			}
1149e862375SLee Jones 		}
1159e862375SLee Jones 	}
1169e862375SLee Jones 	spi_st->words_remaining -= count;
1179e862375SLee Jones }
1189e862375SLee Jones 
1199e862375SLee Jones static int spi_st_transfer_one(struct spi_master *master,
1209e862375SLee Jones 			       struct spi_device *spi, struct spi_transfer *t)
1219e862375SLee Jones {
1229e862375SLee Jones 	struct spi_st *spi_st = spi_master_get_devdata(master);
1239e862375SLee Jones 	uint32_t ctl = 0;
1249e862375SLee Jones 
1259e862375SLee Jones 	/* Setup transfer */
1269e862375SLee Jones 	spi_st->tx_ptr = t->tx_buf;
1279e862375SLee Jones 	spi_st->rx_ptr = t->rx_buf;
1289e862375SLee Jones 
1299e862375SLee Jones 	if (spi->bits_per_word > 8) {
1309e862375SLee Jones 		/*
1319e862375SLee Jones 		 * Anything greater than 8 bits-per-word requires 2
1329e862375SLee Jones 		 * bytes-per-word in the RX/TX buffers
1339e862375SLee Jones 		 */
1349e862375SLee Jones 		spi_st->bytes_per_word = 2;
1359e862375SLee Jones 		spi_st->words_remaining = t->len / 2;
1369e862375SLee Jones 
1379e862375SLee Jones 	} else if (spi->bits_per_word == 8 && !(t->len & 0x1)) {
1389e862375SLee Jones 		/*
1399e862375SLee Jones 		 * If transfer is even-length, and 8 bits-per-word, then
1409e862375SLee Jones 		 * implement as half-length 16 bits-per-word transfer
1419e862375SLee Jones 		 */
1429e862375SLee Jones 		spi_st->bytes_per_word = 2;
1439e862375SLee Jones 		spi_st->words_remaining = t->len / 2;
1449e862375SLee Jones 
1459e862375SLee Jones 		/* Set SSC_CTL to 16 bits-per-word */
1469e862375SLee Jones 		ctl = readl_relaxed(spi_st->base + SSC_CTL);
1479e862375SLee Jones 		writel_relaxed((ctl | 0xf), spi_st->base + SSC_CTL);
1489e862375SLee Jones 
1499e862375SLee Jones 		readl_relaxed(spi_st->base + SSC_RBUF);
1509e862375SLee Jones 
1519e862375SLee Jones 	} else {
1529e862375SLee Jones 		spi_st->bytes_per_word = 1;
1539e862375SLee Jones 		spi_st->words_remaining = t->len;
1549e862375SLee Jones 	}
1559e862375SLee Jones 
1569e862375SLee Jones 	reinit_completion(&spi_st->done);
1579e862375SLee Jones 
1589e862375SLee Jones 	/* Start transfer by writing to the TX FIFO */
1599e862375SLee Jones 	ssc_write_tx_fifo(spi_st);
1609e862375SLee Jones 	writel_relaxed(SSC_IEN_TEEN, spi_st->base + SSC_IEN);
1619e862375SLee Jones 
1629e862375SLee Jones 	/* Wait for transfer to complete */
1639e862375SLee Jones 	wait_for_completion(&spi_st->done);
1649e862375SLee Jones 
1659e862375SLee Jones 	/* Restore SSC_CTL if necessary */
1669e862375SLee Jones 	if (ctl)
1679e862375SLee Jones 		writel_relaxed(ctl, spi_st->base + SSC_CTL);
1689e862375SLee Jones 
1699e862375SLee Jones 	spi_finalize_current_transfer(spi->master);
1709e862375SLee Jones 
1719e862375SLee Jones 	return t->len;
1729e862375SLee Jones }
1739e862375SLee Jones 
1749e862375SLee Jones static void spi_st_cleanup(struct spi_device *spi)
1759e862375SLee Jones {
17642531686SAxel Lin 	gpio_free(spi->cs_gpio);
1779e862375SLee Jones }
1789e862375SLee Jones 
1799e862375SLee Jones /* the spi->mode bits understood by this driver: */
1809e862375SLee Jones #define MODEBITS  (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_LOOP | SPI_CS_HIGH)
1819e862375SLee Jones static int spi_st_setup(struct spi_device *spi)
1829e862375SLee Jones {
1839e862375SLee Jones 	struct spi_st *spi_st = spi_master_get_devdata(spi->master);
1849e862375SLee Jones 	u32 spi_st_clk, sscbrg, var;
1859e862375SLee Jones 	u32 hz = spi->max_speed_hz;
1869e862375SLee Jones 	int cs = spi->cs_gpio;
1879e862375SLee Jones 	int ret;
1889e862375SLee Jones 
1899e862375SLee Jones 	if (!hz)  {
1909e862375SLee Jones 		dev_err(&spi->dev, "max_speed_hz unspecified\n");
1919e862375SLee Jones 		return -EINVAL;
1929e862375SLee Jones 	}
1939e862375SLee Jones 
1949e862375SLee Jones 	if (!gpio_is_valid(cs)) {
1959e862375SLee Jones 		dev_err(&spi->dev, "%d is not a valid gpio\n", cs);
1969e862375SLee Jones 		return -EINVAL;
1979e862375SLee Jones 	}
1989e862375SLee Jones 
19942531686SAxel Lin 	ret = gpio_request(cs, dev_name(&spi->dev));
20042531686SAxel Lin 	if (ret) {
2019e862375SLee Jones 		dev_err(&spi->dev, "could not request gpio:%d\n", cs);
20242531686SAxel Lin 		return ret;
2039e862375SLee Jones 	}
2049e862375SLee Jones 
2059e862375SLee Jones 	ret = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH);
2069e862375SLee Jones 	if (ret)
20742531686SAxel Lin 		goto out_free_gpio;
2089e862375SLee Jones 
2099e862375SLee Jones 	spi_st_clk = clk_get_rate(spi_st->clk);
2109e862375SLee Jones 
2119e862375SLee Jones 	/* Set SSC_BRF */
2129e862375SLee Jones 	sscbrg = spi_st_clk / (2 * hz);
2139e862375SLee Jones 	if (sscbrg < 0x07 || sscbrg > BIT(16)) {
2149e862375SLee Jones 		dev_err(&spi->dev,
2159e862375SLee Jones 			"baudrate %d outside valid range %d\n", sscbrg, hz);
21642531686SAxel Lin 		ret = -EINVAL;
21742531686SAxel Lin 		goto out_free_gpio;
2189e862375SLee Jones 	}
2199e862375SLee Jones 
2209e862375SLee Jones 	spi_st->baud = spi_st_clk / (2 * sscbrg);
2219e862375SLee Jones 	if (sscbrg == BIT(16)) /* 16-bit counter wraps */
2229e862375SLee Jones 		sscbrg = 0x0;
2239e862375SLee Jones 
2249e862375SLee Jones 	writel_relaxed(sscbrg, spi_st->base + SSC_BRG);
2259e862375SLee Jones 
2269e862375SLee Jones 	dev_dbg(&spi->dev,
2279e862375SLee Jones 		"setting baudrate:target= %u hz, actual= %u hz, sscbrg= %u\n",
2289e862375SLee Jones 		hz, spi_st->baud, sscbrg);
2299e862375SLee Jones 
2309e862375SLee Jones 	/* Set SSC_CTL and enable SSC */
2319e862375SLee Jones 	var = readl_relaxed(spi_st->base + SSC_CTL);
2329e862375SLee Jones 	var |= SSC_CTL_MS;
2339e862375SLee Jones 
2349e862375SLee Jones 	if (spi->mode & SPI_CPOL)
2359e862375SLee Jones 		var |= SSC_CTL_PO;
2369e862375SLee Jones 	else
2379e862375SLee Jones 		var &= ~SSC_CTL_PO;
2389e862375SLee Jones 
2399e862375SLee Jones 	if (spi->mode & SPI_CPHA)
2409e862375SLee Jones 		var |= SSC_CTL_PH;
2419e862375SLee Jones 	else
2429e862375SLee Jones 		var &= ~SSC_CTL_PH;
2439e862375SLee Jones 
2449e862375SLee Jones 	if ((spi->mode & SPI_LSB_FIRST) == 0)
2459e862375SLee Jones 		var |= SSC_CTL_HB;
2469e862375SLee Jones 	else
2479e862375SLee Jones 		var &= ~SSC_CTL_HB;
2489e862375SLee Jones 
2499e862375SLee Jones 	if (spi->mode & SPI_LOOP)
2509e862375SLee Jones 		var |= SSC_CTL_LPB;
2519e862375SLee Jones 	else
2529e862375SLee Jones 		var &= ~SSC_CTL_LPB;
2539e862375SLee Jones 
2549e862375SLee Jones 	var &= ~SSC_CTL_DATA_WIDTH_MSK;
2559e862375SLee Jones 	var |= (spi->bits_per_word - 1);
2569e862375SLee Jones 
2579e862375SLee Jones 	var |= SSC_CTL_EN_TX_FIFO | SSC_CTL_EN_RX_FIFO;
2589e862375SLee Jones 	var |= SSC_CTL_EN;
2599e862375SLee Jones 
2609e862375SLee Jones 	writel_relaxed(var, spi_st->base + SSC_CTL);
2619e862375SLee Jones 
2629e862375SLee Jones 	/* Clear the status register */
2639e862375SLee Jones 	readl_relaxed(spi_st->base + SSC_RBUF);
2649e862375SLee Jones 
2659e862375SLee Jones 	return 0;
26642531686SAxel Lin 
26742531686SAxel Lin out_free_gpio:
26842531686SAxel Lin 	gpio_free(cs);
26942531686SAxel Lin 	return ret;
2709e862375SLee Jones }
2719e862375SLee Jones 
2729e862375SLee Jones /* Interrupt fired when TX shift register becomes empty */
2739e862375SLee Jones static irqreturn_t spi_st_irq(int irq, void *dev_id)
2749e862375SLee Jones {
2759e862375SLee Jones 	struct spi_st *spi_st = (struct spi_st *)dev_id;
2769e862375SLee Jones 
2779e862375SLee Jones 	/* Read RX FIFO */
2789e862375SLee Jones 	ssc_read_rx_fifo(spi_st);
2799e862375SLee Jones 
2809e862375SLee Jones 	/* Fill TX FIFO */
2819e862375SLee Jones 	if (spi_st->words_remaining) {
2829e862375SLee Jones 		ssc_write_tx_fifo(spi_st);
2839e862375SLee Jones 	} else {
2849e862375SLee Jones 		/* TX/RX complete */
2859e862375SLee Jones 		writel_relaxed(0x0, spi_st->base + SSC_IEN);
2869e862375SLee Jones 		/*
2879e862375SLee Jones 		 * read SSC_IEN to ensure that this bit is set
2889e862375SLee Jones 		 * before re-enabling interrupt
2899e862375SLee Jones 		 */
2909e862375SLee Jones 		readl(spi_st->base + SSC_IEN);
2919e862375SLee Jones 		complete(&spi_st->done);
2929e862375SLee Jones 	}
2939e862375SLee Jones 
2949e862375SLee Jones 	return IRQ_HANDLED;
2959e862375SLee Jones }
2969e862375SLee Jones 
2979e862375SLee Jones static int spi_st_probe(struct platform_device *pdev)
2989e862375SLee Jones {
2999e862375SLee Jones 	struct device_node *np = pdev->dev.of_node;
3009e862375SLee Jones 	struct spi_master *master;
3019e862375SLee Jones 	struct spi_st *spi_st;
3029e862375SLee Jones 	int irq, ret = 0;
3039e862375SLee Jones 	u32 var;
3049e862375SLee Jones 
3059e862375SLee Jones 	master = spi_alloc_master(&pdev->dev, sizeof(*spi_st));
3069e862375SLee Jones 	if (!master)
3079e862375SLee Jones 		return -ENOMEM;
3089e862375SLee Jones 
3099e862375SLee Jones 	master->dev.of_node		= np;
3109e862375SLee Jones 	master->mode_bits		= MODEBITS;
3119e862375SLee Jones 	master->setup			= spi_st_setup;
3129e862375SLee Jones 	master->cleanup			= spi_st_cleanup;
3139e862375SLee Jones 	master->transfer_one		= spi_st_transfer_one;
3149e862375SLee Jones 	master->bits_per_word_mask	= SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
3159e862375SLee Jones 	master->auto_runtime_pm		= true;
3169e862375SLee Jones 	master->bus_num			= pdev->id;
3179e862375SLee Jones 	spi_st				= spi_master_get_devdata(master);
3189e862375SLee Jones 
3199e862375SLee Jones 	spi_st->clk = devm_clk_get(&pdev->dev, "ssc");
3209e862375SLee Jones 	if (IS_ERR(spi_st->clk)) {
3219e862375SLee Jones 		dev_err(&pdev->dev, "Unable to request clock\n");
3221051550eSAxel Lin 		ret = PTR_ERR(spi_st->clk);
3231051550eSAxel Lin 		goto put_master;
3249e862375SLee Jones 	}
3259e862375SLee Jones 
326cf4b5cebSLee Jones 	ret = clk_prepare_enable(spi_st->clk);
3279e862375SLee Jones 	if (ret)
3281051550eSAxel Lin 		goto put_master;
3299e862375SLee Jones 
3309e862375SLee Jones 	init_completion(&spi_st->done);
3319e862375SLee Jones 
3329e862375SLee Jones 	/* Get resources */
333338dd352SYueHaibing 	spi_st->base = devm_platform_ioremap_resource(pdev, 0);
3349e862375SLee Jones 	if (IS_ERR(spi_st->base)) {
3359e862375SLee Jones 		ret = PTR_ERR(spi_st->base);
3369e862375SLee Jones 		goto clk_disable;
3379e862375SLee Jones 	}
3389e862375SLee Jones 
3399e862375SLee Jones 	/* Disable I2C and Reset SSC */
3409e862375SLee Jones 	writel_relaxed(0x0, spi_st->base + SSC_I2C);
3419e862375SLee Jones 	var = readw_relaxed(spi_st->base + SSC_CTL);
3429e862375SLee Jones 	var |= SSC_CTL_SR;
3439e862375SLee Jones 	writel_relaxed(var, spi_st->base + SSC_CTL);
3449e862375SLee Jones 
3459e862375SLee Jones 	udelay(1);
3469e862375SLee Jones 	var = readl_relaxed(spi_st->base + SSC_CTL);
3479e862375SLee Jones 	var &= ~SSC_CTL_SR;
3489e862375SLee Jones 	writel_relaxed(var, spi_st->base + SSC_CTL);
3499e862375SLee Jones 
3509e862375SLee Jones 	/* Set SSC into slave mode before reconfiguring PIO pins */
3519e862375SLee Jones 	var = readl_relaxed(spi_st->base + SSC_CTL);
3529e862375SLee Jones 	var &= ~SSC_CTL_MS;
3539e862375SLee Jones 	writel_relaxed(var, spi_st->base + SSC_CTL);
3549e862375SLee Jones 
3559e862375SLee Jones 	irq = irq_of_parse_and_map(np, 0);
3569e862375SLee Jones 	if (!irq) {
3579e862375SLee Jones 		dev_err(&pdev->dev, "IRQ missing or invalid\n");
3589e862375SLee Jones 		ret = -EINVAL;
3599e862375SLee Jones 		goto clk_disable;
3609e862375SLee Jones 	}
3619e862375SLee Jones 
3629e862375SLee Jones 	ret = devm_request_irq(&pdev->dev, irq, spi_st_irq, 0,
3639e862375SLee Jones 			       pdev->name, spi_st);
3649e862375SLee Jones 	if (ret) {
3659e862375SLee Jones 		dev_err(&pdev->dev, "Failed to request irq %d\n", irq);
3669e862375SLee Jones 		goto clk_disable;
3679e862375SLee Jones 	}
3689e862375SLee Jones 
3699e862375SLee Jones 	/* by default the device is on */
3709e862375SLee Jones 	pm_runtime_set_active(&pdev->dev);
3719e862375SLee Jones 	pm_runtime_enable(&pdev->dev);
3729e862375SLee Jones 
3739e862375SLee Jones 	platform_set_drvdata(pdev, master);
3749e862375SLee Jones 
3759e862375SLee Jones 	ret = devm_spi_register_master(&pdev->dev, master);
3769e862375SLee Jones 	if (ret) {
3779e862375SLee Jones 		dev_err(&pdev->dev, "Failed to register master\n");
378*5ef76dacSLukas Wunner 		goto rpm_disable;
3799e862375SLee Jones 	}
3809e862375SLee Jones 
3819e862375SLee Jones 	return 0;
3829e862375SLee Jones 
383*5ef76dacSLukas Wunner rpm_disable:
384cd050abeSChuhong Yuan 	pm_runtime_disable(&pdev->dev);
385*5ef76dacSLukas Wunner clk_disable:
386cf4b5cebSLee Jones 	clk_disable_unprepare(spi_st->clk);
3871051550eSAxel Lin put_master:
3881051550eSAxel Lin 	spi_master_put(master);
3899e862375SLee Jones 	return ret;
3909e862375SLee Jones }
3919e862375SLee Jones 
3929e862375SLee Jones static int spi_st_remove(struct platform_device *pdev)
3939e862375SLee Jones {
3949e862375SLee Jones 	struct spi_master *master = platform_get_drvdata(pdev);
3959e862375SLee Jones 	struct spi_st *spi_st = spi_master_get_devdata(master);
3969e862375SLee Jones 
397cd050abeSChuhong Yuan 	pm_runtime_disable(&pdev->dev);
398cd050abeSChuhong Yuan 
399cf4b5cebSLee Jones 	clk_disable_unprepare(spi_st->clk);
4009e862375SLee Jones 
4019e862375SLee Jones 	pinctrl_pm_select_sleep_state(&pdev->dev);
4029e862375SLee Jones 
4039e862375SLee Jones 	return 0;
4049e862375SLee Jones }
4059e862375SLee Jones 
4069e862375SLee Jones #ifdef CONFIG_PM
4079e862375SLee Jones static int spi_st_runtime_suspend(struct device *dev)
4089e862375SLee Jones {
4099e862375SLee Jones 	struct spi_master *master = dev_get_drvdata(dev);
4109e862375SLee Jones 	struct spi_st *spi_st = spi_master_get_devdata(master);
4119e862375SLee Jones 
4129e862375SLee Jones 	writel_relaxed(0, spi_st->base + SSC_IEN);
4139e862375SLee Jones 	pinctrl_pm_select_sleep_state(dev);
4149e862375SLee Jones 
415cf4b5cebSLee Jones 	clk_disable_unprepare(spi_st->clk);
4169e862375SLee Jones 
4179e862375SLee Jones 	return 0;
4189e862375SLee Jones }
4199e862375SLee Jones 
4209e862375SLee Jones static int spi_st_runtime_resume(struct device *dev)
4219e862375SLee Jones {
4229e862375SLee Jones 	struct spi_master *master = dev_get_drvdata(dev);
4239e862375SLee Jones 	struct spi_st *spi_st = spi_master_get_devdata(master);
4249e862375SLee Jones 	int ret;
4259e862375SLee Jones 
426cf4b5cebSLee Jones 	ret = clk_prepare_enable(spi_st->clk);
4279e862375SLee Jones 	pinctrl_pm_select_default_state(dev);
4289e862375SLee Jones 
4299e862375SLee Jones 	return ret;
4309e862375SLee Jones }
4319e862375SLee Jones #endif
4329e862375SLee Jones 
4339e862375SLee Jones #ifdef CONFIG_PM_SLEEP
4349e862375SLee Jones static int spi_st_suspend(struct device *dev)
4359e862375SLee Jones {
4369e862375SLee Jones 	struct spi_master *master = dev_get_drvdata(dev);
4379e862375SLee Jones 	int ret;
4389e862375SLee Jones 
4399e862375SLee Jones 	ret = spi_master_suspend(master);
4409e862375SLee Jones 	if (ret)
4419e862375SLee Jones 		return ret;
4429e862375SLee Jones 
4439e862375SLee Jones 	return pm_runtime_force_suspend(dev);
4449e862375SLee Jones }
4459e862375SLee Jones 
4469e862375SLee Jones static int spi_st_resume(struct device *dev)
4479e862375SLee Jones {
4489e862375SLee Jones 	struct spi_master *master = dev_get_drvdata(dev);
4499e862375SLee Jones 	int ret;
4509e862375SLee Jones 
4519e862375SLee Jones 	ret = spi_master_resume(master);
4529e862375SLee Jones 	if (ret)
4539e862375SLee Jones 		return ret;
4549e862375SLee Jones 
4559e862375SLee Jones 	return pm_runtime_force_resume(dev);
4569e862375SLee Jones }
4579e862375SLee Jones #endif
4589e862375SLee Jones 
4599e862375SLee Jones static const struct dev_pm_ops spi_st_pm = {
4609e862375SLee Jones 	SET_SYSTEM_SLEEP_PM_OPS(spi_st_suspend, spi_st_resume)
4619e862375SLee Jones 	SET_RUNTIME_PM_OPS(spi_st_runtime_suspend, spi_st_runtime_resume, NULL)
4629e862375SLee Jones };
4639e862375SLee Jones 
46409355402SFabian Frederick static const struct of_device_id stm_spi_match[] = {
4659e862375SLee Jones 	{ .compatible = "st,comms-ssc4-spi", },
4669e862375SLee Jones 	{},
4679e862375SLee Jones };
4689e862375SLee Jones MODULE_DEVICE_TABLE(of, stm_spi_match);
4699e862375SLee Jones 
4709e862375SLee Jones static struct platform_driver spi_st_driver = {
4719e862375SLee Jones 	.driver = {
4729e862375SLee Jones 		.name = "spi-st",
4739e862375SLee Jones 		.pm = &spi_st_pm,
4749e862375SLee Jones 		.of_match_table = of_match_ptr(stm_spi_match),
4759e862375SLee Jones 	},
4769e862375SLee Jones 	.probe = spi_st_probe,
4779e862375SLee Jones 	.remove = spi_st_remove,
4789e862375SLee Jones };
4799e862375SLee Jones module_platform_driver(spi_st_driver);
4809e862375SLee Jones 
4819e862375SLee Jones MODULE_AUTHOR("Patrice Chotard <patrice.chotard@st.com>");
4829e862375SLee Jones MODULE_DESCRIPTION("STM SSC SPI driver");
4839e862375SLee Jones MODULE_LICENSE("GPL v2");
484