xref: /openbmc/linux/drivers/spi/spi-st-ssc4.c (revision cf4b5ceb)
19e862375SLee Jones /*
29e862375SLee Jones  *  Copyright (c) 2008-2014 STMicroelectronics Limited
39e862375SLee Jones  *
49e862375SLee Jones  *  Author: Angus Clark <Angus.Clark@st.com>
59e862375SLee Jones  *          Patrice Chotard <patrice.chotard@st.com>
69e862375SLee Jones  *          Lee Jones <lee.jones@linaro.org>
79e862375SLee Jones  *
89e862375SLee Jones  *  SPI master mode controller driver, used in STMicroelectronics devices.
99e862375SLee Jones  *
109e862375SLee Jones  *  May be copied or modified under the terms of the GNU General Public
119e862375SLee Jones  *  License Version 2.0 only.  See linux/COPYING for more information.
129e862375SLee Jones  */
139e862375SLee Jones 
149e862375SLee Jones #include <linux/clk.h>
159e862375SLee Jones #include <linux/delay.h>
169e862375SLee Jones #include <linux/interrupt.h>
179e862375SLee Jones #include <linux/io.h>
189e862375SLee Jones #include <linux/module.h>
199e862375SLee Jones #include <linux/pinctrl/consumer.h>
209e862375SLee Jones #include <linux/platform_device.h>
219e862375SLee Jones #include <linux/of.h>
229e862375SLee Jones #include <linux/of_gpio.h>
239e862375SLee Jones #include <linux/of_irq.h>
249e862375SLee Jones #include <linux/pm_runtime.h>
259e862375SLee Jones #include <linux/spi/spi.h>
269e862375SLee Jones #include <linux/spi/spi_bitbang.h>
279e862375SLee Jones 
289e862375SLee Jones /* SSC registers */
299e862375SLee Jones #define SSC_BRG				0x000
309e862375SLee Jones #define SSC_TBUF			0x004
319e862375SLee Jones #define SSC_RBUF			0x008
329e862375SLee Jones #define SSC_CTL				0x00C
339e862375SLee Jones #define SSC_IEN				0x010
349e862375SLee Jones #define SSC_I2C				0x018
359e862375SLee Jones 
369e862375SLee Jones /* SSC Control */
379e862375SLee Jones #define SSC_CTL_DATA_WIDTH_9		0x8
389e862375SLee Jones #define SSC_CTL_DATA_WIDTH_MSK		0xf
399e862375SLee Jones #define SSC_CTL_BM			0xf
409e862375SLee Jones #define SSC_CTL_HB			BIT(4)
419e862375SLee Jones #define SSC_CTL_PH			BIT(5)
429e862375SLee Jones #define SSC_CTL_PO			BIT(6)
439e862375SLee Jones #define SSC_CTL_SR			BIT(7)
449e862375SLee Jones #define SSC_CTL_MS			BIT(8)
459e862375SLee Jones #define SSC_CTL_EN			BIT(9)
469e862375SLee Jones #define SSC_CTL_LPB			BIT(10)
479e862375SLee Jones #define SSC_CTL_EN_TX_FIFO		BIT(11)
489e862375SLee Jones #define SSC_CTL_EN_RX_FIFO		BIT(12)
499e862375SLee Jones #define SSC_CTL_EN_CLST_RX		BIT(13)
509e862375SLee Jones 
519e862375SLee Jones /* SSC Interrupt Enable */
529e862375SLee Jones #define SSC_IEN_TEEN			BIT(2)
539e862375SLee Jones 
549e862375SLee Jones #define FIFO_SIZE			8
559e862375SLee Jones 
569e862375SLee Jones struct spi_st {
579e862375SLee Jones 	/* SSC SPI Controller */
589e862375SLee Jones 	void __iomem		*base;
599e862375SLee Jones 	struct clk		*clk;
609e862375SLee Jones 	struct device		*dev;
619e862375SLee Jones 
629e862375SLee Jones 	/* SSC SPI current transaction */
639e862375SLee Jones 	const u8		*tx_ptr;
649e862375SLee Jones 	u8			*rx_ptr;
659e862375SLee Jones 	u16			bytes_per_word;
669e862375SLee Jones 	unsigned int		words_remaining;
679e862375SLee Jones 	unsigned int		baud;
689e862375SLee Jones 	struct completion	done;
699e862375SLee Jones };
709e862375SLee Jones 
719e862375SLee Jones /* Load the TX FIFO */
729e862375SLee Jones static void ssc_write_tx_fifo(struct spi_st *spi_st)
739e862375SLee Jones {
749e862375SLee Jones 	unsigned int count, i;
759e862375SLee Jones 	uint32_t word = 0;
769e862375SLee Jones 
779e862375SLee Jones 	if (spi_st->words_remaining > FIFO_SIZE)
789e862375SLee Jones 		count = FIFO_SIZE;
799e862375SLee Jones 	else
809e862375SLee Jones 		count = spi_st->words_remaining;
819e862375SLee Jones 
829e862375SLee Jones 	for (i = 0; i < count; i++) {
839e862375SLee Jones 		if (spi_st->tx_ptr) {
849e862375SLee Jones 			if (spi_st->bytes_per_word == 1) {
859e862375SLee Jones 				word = *spi_st->tx_ptr++;
869e862375SLee Jones 			} else {
879e862375SLee Jones 				word = *spi_st->tx_ptr++;
889e862375SLee Jones 				word = *spi_st->tx_ptr++ | (word << 8);
899e862375SLee Jones 			}
909e862375SLee Jones 		}
919e862375SLee Jones 		writel_relaxed(word, spi_st->base + SSC_TBUF);
929e862375SLee Jones 	}
939e862375SLee Jones }
949e862375SLee Jones 
959e862375SLee Jones /* Read the RX FIFO */
969e862375SLee Jones static void ssc_read_rx_fifo(struct spi_st *spi_st)
979e862375SLee Jones {
989e862375SLee Jones 	unsigned int count, i;
999e862375SLee Jones 	uint32_t word = 0;
1009e862375SLee Jones 
1019e862375SLee Jones 	if (spi_st->words_remaining > FIFO_SIZE)
1029e862375SLee Jones 		count = FIFO_SIZE;
1039e862375SLee Jones 	else
1049e862375SLee Jones 		count = spi_st->words_remaining;
1059e862375SLee Jones 
1069e862375SLee Jones 	for (i = 0; i < count; i++) {
1079e862375SLee Jones 		word = readl_relaxed(spi_st->base + SSC_RBUF);
1089e862375SLee Jones 
1099e862375SLee Jones 		if (spi_st->rx_ptr) {
1109e862375SLee Jones 			if (spi_st->bytes_per_word == 1) {
1119e862375SLee Jones 				*spi_st->rx_ptr++ = (uint8_t)word;
1129e862375SLee Jones 			} else {
1139e862375SLee Jones 				*spi_st->rx_ptr++ = (word >> 8);
1149e862375SLee Jones 				*spi_st->rx_ptr++ = word & 0xff;
1159e862375SLee Jones 			}
1169e862375SLee Jones 		}
1179e862375SLee Jones 	}
1189e862375SLee Jones 	spi_st->words_remaining -= count;
1199e862375SLee Jones }
1209e862375SLee Jones 
1219e862375SLee Jones static int spi_st_transfer_one(struct spi_master *master,
1229e862375SLee Jones 			       struct spi_device *spi, struct spi_transfer *t)
1239e862375SLee Jones {
1249e862375SLee Jones 	struct spi_st *spi_st = spi_master_get_devdata(master);
1259e862375SLee Jones 	uint32_t ctl = 0;
1269e862375SLee Jones 
1279e862375SLee Jones 	/* Setup transfer */
1289e862375SLee Jones 	spi_st->tx_ptr = t->tx_buf;
1299e862375SLee Jones 	spi_st->rx_ptr = t->rx_buf;
1309e862375SLee Jones 
1319e862375SLee Jones 	if (spi->bits_per_word > 8) {
1329e862375SLee Jones 		/*
1339e862375SLee Jones 		 * Anything greater than 8 bits-per-word requires 2
1349e862375SLee Jones 		 * bytes-per-word in the RX/TX buffers
1359e862375SLee Jones 		 */
1369e862375SLee Jones 		spi_st->bytes_per_word = 2;
1379e862375SLee Jones 		spi_st->words_remaining = t->len / 2;
1389e862375SLee Jones 
1399e862375SLee Jones 	} else if (spi->bits_per_word == 8 && !(t->len & 0x1)) {
1409e862375SLee Jones 		/*
1419e862375SLee Jones 		 * If transfer is even-length, and 8 bits-per-word, then
1429e862375SLee Jones 		 * implement as half-length 16 bits-per-word transfer
1439e862375SLee Jones 		 */
1449e862375SLee Jones 		spi_st->bytes_per_word = 2;
1459e862375SLee Jones 		spi_st->words_remaining = t->len / 2;
1469e862375SLee Jones 
1479e862375SLee Jones 		/* Set SSC_CTL to 16 bits-per-word */
1489e862375SLee Jones 		ctl = readl_relaxed(spi_st->base + SSC_CTL);
1499e862375SLee Jones 		writel_relaxed((ctl | 0xf), spi_st->base + SSC_CTL);
1509e862375SLee Jones 
1519e862375SLee Jones 		readl_relaxed(spi_st->base + SSC_RBUF);
1529e862375SLee Jones 
1539e862375SLee Jones 	} else {
1549e862375SLee Jones 		spi_st->bytes_per_word = 1;
1559e862375SLee Jones 		spi_st->words_remaining = t->len;
1569e862375SLee Jones 	}
1579e862375SLee Jones 
1589e862375SLee Jones 	reinit_completion(&spi_st->done);
1599e862375SLee Jones 
1609e862375SLee Jones 	/* Start transfer by writing to the TX FIFO */
1619e862375SLee Jones 	ssc_write_tx_fifo(spi_st);
1629e862375SLee Jones 	writel_relaxed(SSC_IEN_TEEN, spi_st->base + SSC_IEN);
1639e862375SLee Jones 
1649e862375SLee Jones 	/* Wait for transfer to complete */
1659e862375SLee Jones 	wait_for_completion(&spi_st->done);
1669e862375SLee Jones 
1679e862375SLee Jones 	/* Restore SSC_CTL if necessary */
1689e862375SLee Jones 	if (ctl)
1699e862375SLee Jones 		writel_relaxed(ctl, spi_st->base + SSC_CTL);
1709e862375SLee Jones 
1719e862375SLee Jones 	spi_finalize_current_transfer(spi->master);
1729e862375SLee Jones 
1739e862375SLee Jones 	return t->len;
1749e862375SLee Jones }
1759e862375SLee Jones 
1769e862375SLee Jones static void spi_st_cleanup(struct spi_device *spi)
1779e862375SLee Jones {
1789e862375SLee Jones 	int cs = spi->cs_gpio;
1799e862375SLee Jones 
1809e862375SLee Jones 	if (gpio_is_valid(cs))
1819e862375SLee Jones 		devm_gpio_free(&spi->dev, cs);
1829e862375SLee Jones }
1839e862375SLee Jones 
1849e862375SLee Jones /* the spi->mode bits understood by this driver: */
1859e862375SLee Jones #define MODEBITS  (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_LOOP | SPI_CS_HIGH)
1869e862375SLee Jones static int spi_st_setup(struct spi_device *spi)
1879e862375SLee Jones {
1889e862375SLee Jones 	struct spi_st *spi_st = spi_master_get_devdata(spi->master);
1899e862375SLee Jones 	u32 spi_st_clk, sscbrg, var;
1909e862375SLee Jones 	u32 hz = spi->max_speed_hz;
1919e862375SLee Jones 	int cs = spi->cs_gpio;
1929e862375SLee Jones 	int ret;
1939e862375SLee Jones 
1949e862375SLee Jones 	if (!hz)  {
1959e862375SLee Jones 		dev_err(&spi->dev, "max_speed_hz unspecified\n");
1969e862375SLee Jones 		return -EINVAL;
1979e862375SLee Jones 	}
1989e862375SLee Jones 
1999e862375SLee Jones 	if (!gpio_is_valid(cs)) {
2009e862375SLee Jones 		dev_err(&spi->dev, "%d is not a valid gpio\n", cs);
2019e862375SLee Jones 		return -EINVAL;
2029e862375SLee Jones 	}
2039e862375SLee Jones 
2049e862375SLee Jones 	if (devm_gpio_request(&spi->dev, cs, dev_name(&spi->dev))) {
2059e862375SLee Jones 		dev_err(&spi->dev, "could not request gpio:%d\n", cs);
2069e862375SLee Jones 		return -EINVAL;
2079e862375SLee Jones 	}
2089e862375SLee Jones 
2099e862375SLee Jones 	ret = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH);
2109e862375SLee Jones 	if (ret)
2119e862375SLee Jones 		return ret;
2129e862375SLee Jones 
2139e862375SLee Jones 	spi_st_clk = clk_get_rate(spi_st->clk);
2149e862375SLee Jones 
2159e862375SLee Jones 	/* Set SSC_BRF */
2169e862375SLee Jones 	sscbrg = spi_st_clk / (2 * hz);
2179e862375SLee Jones 	if (sscbrg < 0x07 || sscbrg > BIT(16)) {
2189e862375SLee Jones 		dev_err(&spi->dev,
2199e862375SLee Jones 			"baudrate %d outside valid range %d\n", sscbrg, hz);
2209e862375SLee Jones 		return -EINVAL;
2219e862375SLee Jones 	}
2229e862375SLee Jones 
2239e862375SLee Jones 	spi_st->baud = spi_st_clk / (2 * sscbrg);
2249e862375SLee Jones 	if (sscbrg == BIT(16)) /* 16-bit counter wraps */
2259e862375SLee Jones 		sscbrg = 0x0;
2269e862375SLee Jones 
2279e862375SLee Jones 	writel_relaxed(sscbrg, spi_st->base + SSC_BRG);
2289e862375SLee Jones 
2299e862375SLee Jones 	dev_dbg(&spi->dev,
2309e862375SLee Jones 		"setting baudrate:target= %u hz, actual= %u hz, sscbrg= %u\n",
2319e862375SLee Jones 		hz, spi_st->baud, sscbrg);
2329e862375SLee Jones 
2339e862375SLee Jones 	 /* Set SSC_CTL and enable SSC */
2349e862375SLee Jones 	 var = readl_relaxed(spi_st->base + SSC_CTL);
2359e862375SLee Jones 	 var |= SSC_CTL_MS;
2369e862375SLee Jones 
2379e862375SLee Jones 	 if (spi->mode & SPI_CPOL)
2389e862375SLee Jones 		var |= SSC_CTL_PO;
2399e862375SLee Jones 	 else
2409e862375SLee Jones 		var &= ~SSC_CTL_PO;
2419e862375SLee Jones 
2429e862375SLee Jones 	 if (spi->mode & SPI_CPHA)
2439e862375SLee Jones 		var |= SSC_CTL_PH;
2449e862375SLee Jones 	 else
2459e862375SLee Jones 		var &= ~SSC_CTL_PH;
2469e862375SLee Jones 
2479e862375SLee Jones 	 if ((spi->mode & SPI_LSB_FIRST) == 0)
2489e862375SLee Jones 		var |= SSC_CTL_HB;
2499e862375SLee Jones 	 else
2509e862375SLee Jones 		var &= ~SSC_CTL_HB;
2519e862375SLee Jones 
2529e862375SLee Jones 	 if (spi->mode & SPI_LOOP)
2539e862375SLee Jones 		var |= SSC_CTL_LPB;
2549e862375SLee Jones 	 else
2559e862375SLee Jones 		var &= ~SSC_CTL_LPB;
2569e862375SLee Jones 
2579e862375SLee Jones 	 var &= ~SSC_CTL_DATA_WIDTH_MSK;
2589e862375SLee Jones 	 var |= (spi->bits_per_word - 1);
2599e862375SLee Jones 
2609e862375SLee Jones 	 var |= SSC_CTL_EN_TX_FIFO | SSC_CTL_EN_RX_FIFO;
2619e862375SLee Jones 	 var |= SSC_CTL_EN;
2629e862375SLee Jones 
2639e862375SLee Jones 	 writel_relaxed(var, spi_st->base + SSC_CTL);
2649e862375SLee Jones 
2659e862375SLee Jones 	 /* Clear the status register */
2669e862375SLee Jones 	 readl_relaxed(spi_st->base + SSC_RBUF);
2679e862375SLee Jones 
2689e862375SLee Jones 	 return 0;
2699e862375SLee Jones }
2709e862375SLee Jones 
2719e862375SLee Jones /* Interrupt fired when TX shift register becomes empty */
2729e862375SLee Jones static irqreturn_t spi_st_irq(int irq, void *dev_id)
2739e862375SLee Jones {
2749e862375SLee Jones 	struct spi_st *spi_st = (struct spi_st *)dev_id;
2759e862375SLee Jones 
2769e862375SLee Jones 	/* Read RX FIFO */
2779e862375SLee Jones 	ssc_read_rx_fifo(spi_st);
2789e862375SLee Jones 
2799e862375SLee Jones 	/* Fill TX FIFO */
2809e862375SLee Jones 	if (spi_st->words_remaining) {
2819e862375SLee Jones 		ssc_write_tx_fifo(spi_st);
2829e862375SLee Jones 	} else {
2839e862375SLee Jones 		/* TX/RX complete */
2849e862375SLee Jones 		writel_relaxed(0x0, spi_st->base + SSC_IEN);
2859e862375SLee Jones 		/*
2869e862375SLee Jones 		 * read SSC_IEN to ensure that this bit is set
2879e862375SLee Jones 		 * before re-enabling interrupt
2889e862375SLee Jones 		 */
2899e862375SLee Jones 		readl(spi_st->base + SSC_IEN);
2909e862375SLee Jones 		complete(&spi_st->done);
2919e862375SLee Jones 	}
2929e862375SLee Jones 
2939e862375SLee Jones 	return IRQ_HANDLED;
2949e862375SLee Jones }
2959e862375SLee Jones 
2969e862375SLee Jones static int spi_st_probe(struct platform_device *pdev)
2979e862375SLee Jones {
2989e862375SLee Jones 	struct device_node *np = pdev->dev.of_node;
2999e862375SLee Jones 	struct spi_master *master;
3009e862375SLee Jones 	struct resource *res;
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 */
3339e862375SLee Jones 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3349e862375SLee Jones 	spi_st->base = devm_ioremap_resource(&pdev->dev, res);
3359e862375SLee Jones 	if (IS_ERR(spi_st->base)) {
3369e862375SLee Jones 		ret = PTR_ERR(spi_st->base);
3379e862375SLee Jones 		goto clk_disable;
3389e862375SLee Jones 	}
3399e862375SLee Jones 
3409e862375SLee Jones 	/* Disable I2C and Reset SSC */
3419e862375SLee Jones 	writel_relaxed(0x0, spi_st->base + SSC_I2C);
3429e862375SLee Jones 	var = readw_relaxed(spi_st->base + SSC_CTL);
3439e862375SLee Jones 	var |= SSC_CTL_SR;
3449e862375SLee Jones 	writel_relaxed(var, spi_st->base + SSC_CTL);
3459e862375SLee Jones 
3469e862375SLee Jones 	udelay(1);
3479e862375SLee Jones 	var = readl_relaxed(spi_st->base + SSC_CTL);
3489e862375SLee Jones 	var &= ~SSC_CTL_SR;
3499e862375SLee Jones 	writel_relaxed(var, spi_st->base + SSC_CTL);
3509e862375SLee Jones 
3519e862375SLee Jones 	/* Set SSC into slave mode before reconfiguring PIO pins */
3529e862375SLee Jones 	var = readl_relaxed(spi_st->base + SSC_CTL);
3539e862375SLee Jones 	var &= ~SSC_CTL_MS;
3549e862375SLee Jones 	writel_relaxed(var, spi_st->base + SSC_CTL);
3559e862375SLee Jones 
3569e862375SLee Jones 	irq = irq_of_parse_and_map(np, 0);
3579e862375SLee Jones 	if (!irq) {
3589e862375SLee Jones 		dev_err(&pdev->dev, "IRQ missing or invalid\n");
3599e862375SLee Jones 		ret = -EINVAL;
3609e862375SLee Jones 		goto clk_disable;
3619e862375SLee Jones 	}
3629e862375SLee Jones 
3639e862375SLee Jones 	ret = devm_request_irq(&pdev->dev, irq, spi_st_irq, 0,
3649e862375SLee Jones 			       pdev->name, spi_st);
3659e862375SLee Jones 	if (ret) {
3669e862375SLee Jones 		dev_err(&pdev->dev, "Failed to request irq %d\n", irq);
3679e862375SLee Jones 		goto clk_disable;
3689e862375SLee Jones 	}
3699e862375SLee Jones 
3709e862375SLee Jones 	/* by default the device is on */
3719e862375SLee Jones 	pm_runtime_set_active(&pdev->dev);
3729e862375SLee Jones 	pm_runtime_enable(&pdev->dev);
3739e862375SLee Jones 
3749e862375SLee Jones 	platform_set_drvdata(pdev, master);
3759e862375SLee Jones 
3769e862375SLee Jones 	ret = devm_spi_register_master(&pdev->dev, master);
3779e862375SLee Jones 	if (ret) {
3789e862375SLee Jones 		dev_err(&pdev->dev, "Failed to register master\n");
3799e862375SLee Jones 		goto clk_disable;
3809e862375SLee Jones 	}
3819e862375SLee Jones 
3829e862375SLee Jones 	return 0;
3839e862375SLee Jones 
3849e862375SLee Jones clk_disable:
385cf4b5cebSLee Jones 	clk_disable_unprepare(spi_st->clk);
3861051550eSAxel Lin put_master:
3871051550eSAxel Lin 	spi_master_put(master);
3889e862375SLee Jones 	return ret;
3899e862375SLee Jones }
3909e862375SLee Jones 
3919e862375SLee Jones static int spi_st_remove(struct platform_device *pdev)
3929e862375SLee Jones {
3939e862375SLee Jones 	struct spi_master *master = platform_get_drvdata(pdev);
3949e862375SLee Jones 	struct spi_st *spi_st = spi_master_get_devdata(master);
3959e862375SLee Jones 
396cf4b5cebSLee Jones 	clk_disable_unprepare(spi_st->clk);
3979e862375SLee Jones 
3989e862375SLee Jones 	pinctrl_pm_select_sleep_state(&pdev->dev);
3999e862375SLee Jones 
4009e862375SLee Jones 	return 0;
4019e862375SLee Jones }
4029e862375SLee Jones 
4039e862375SLee Jones #ifdef CONFIG_PM
4049e862375SLee Jones static int spi_st_runtime_suspend(struct device *dev)
4059e862375SLee Jones {
4069e862375SLee Jones 	struct spi_master *master = dev_get_drvdata(dev);
4079e862375SLee Jones 	struct spi_st *spi_st = spi_master_get_devdata(master);
4089e862375SLee Jones 
4099e862375SLee Jones 	writel_relaxed(0, spi_st->base + SSC_IEN);
4109e862375SLee Jones 	pinctrl_pm_select_sleep_state(dev);
4119e862375SLee Jones 
412cf4b5cebSLee Jones 	clk_disable_unprepare(spi_st->clk);
4139e862375SLee Jones 
4149e862375SLee Jones 	return 0;
4159e862375SLee Jones }
4169e862375SLee Jones 
4179e862375SLee Jones static int spi_st_runtime_resume(struct device *dev)
4189e862375SLee Jones {
4199e862375SLee Jones 	struct spi_master *master = dev_get_drvdata(dev);
4209e862375SLee Jones 	struct spi_st *spi_st = spi_master_get_devdata(master);
4219e862375SLee Jones 	int ret;
4229e862375SLee Jones 
423cf4b5cebSLee Jones 	ret = clk_prepare_enable(spi_st->clk);
4249e862375SLee Jones 	pinctrl_pm_select_default_state(dev);
4259e862375SLee Jones 
4269e862375SLee Jones 	return ret;
4279e862375SLee Jones }
4289e862375SLee Jones #endif
4299e862375SLee Jones 
4309e862375SLee Jones #ifdef CONFIG_PM_SLEEP
4319e862375SLee Jones static int spi_st_suspend(struct device *dev)
4329e862375SLee Jones {
4339e862375SLee Jones 	struct spi_master *master = dev_get_drvdata(dev);
4349e862375SLee Jones 	int ret;
4359e862375SLee Jones 
4369e862375SLee Jones 	ret = spi_master_suspend(master);
4379e862375SLee Jones 	if (ret)
4389e862375SLee Jones 		return ret;
4399e862375SLee Jones 
4409e862375SLee Jones 	return pm_runtime_force_suspend(dev);
4419e862375SLee Jones }
4429e862375SLee Jones 
4439e862375SLee Jones static int spi_st_resume(struct device *dev)
4449e862375SLee Jones {
4459e862375SLee Jones 	struct spi_master *master = dev_get_drvdata(dev);
4469e862375SLee Jones 	int ret;
4479e862375SLee Jones 
4489e862375SLee Jones 	ret = spi_master_resume(master);
4499e862375SLee Jones 	if (ret)
4509e862375SLee Jones 		return ret;
4519e862375SLee Jones 
4529e862375SLee Jones 	return pm_runtime_force_resume(dev);
4539e862375SLee Jones }
4549e862375SLee Jones #endif
4559e862375SLee Jones 
4569e862375SLee Jones static const struct dev_pm_ops spi_st_pm = {
4579e862375SLee Jones 	SET_SYSTEM_SLEEP_PM_OPS(spi_st_suspend, spi_st_resume)
4589e862375SLee Jones 	SET_RUNTIME_PM_OPS(spi_st_runtime_suspend, spi_st_runtime_resume, NULL)
4599e862375SLee Jones };
4609e862375SLee Jones 
46109355402SFabian Frederick static const struct of_device_id stm_spi_match[] = {
4629e862375SLee Jones 	{ .compatible = "st,comms-ssc4-spi", },
4639e862375SLee Jones 	{},
4649e862375SLee Jones };
4659e862375SLee Jones MODULE_DEVICE_TABLE(of, stm_spi_match);
4669e862375SLee Jones 
4679e862375SLee Jones static struct platform_driver spi_st_driver = {
4689e862375SLee Jones 	.driver = {
4699e862375SLee Jones 		.name = "spi-st",
4709e862375SLee Jones 		.pm = &spi_st_pm,
4719e862375SLee Jones 		.of_match_table = of_match_ptr(stm_spi_match),
4729e862375SLee Jones 	},
4739e862375SLee Jones 	.probe = spi_st_probe,
4749e862375SLee Jones 	.remove = spi_st_remove,
4759e862375SLee Jones };
4769e862375SLee Jones module_platform_driver(spi_st_driver);
4779e862375SLee Jones 
4789e862375SLee Jones MODULE_AUTHOR("Patrice Chotard <patrice.chotard@st.com>");
4799e862375SLee Jones MODULE_DESCRIPTION("STM SSC SPI driver");
4809e862375SLee Jones MODULE_LICENSE("GPL v2");
481