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