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 */ 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 */ 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 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) 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 */ 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 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 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 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 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 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 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