diff options
Diffstat (limited to 'drivers/spi/spi-st-ssc4.c')
| -rw-r--r-- | drivers/spi/spi-st-ssc4.c | 131 |
1 files changed, 51 insertions, 80 deletions
diff --git a/drivers/spi/spi-st-ssc4.c b/drivers/spi/spi-st-ssc4.c index a4e43fc19ece..c07c61dc4938 100644 --- a/drivers/spi/spi-st-ssc4.c +++ b/drivers/spi/spi-st-ssc4.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2008-2014 STMicroelectronics Limited * @@ -5,10 +6,7 @@ * Patrice Chotard <patrice.chotard@st.com> * Lee Jones <lee.jones@linaro.org> * - * SPI master mode controller driver, used in STMicroelectronics devices. - * - * May be copied or modified under the terms of the GNU General Public - * License Version 2.0 only. See linux/COPYING for more information. + * SPI host mode controller driver, used in STMicroelectronics devices. */ #include <linux/clk.h> @@ -19,7 +17,6 @@ #include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> #include <linux/of.h> -#include <linux/of_gpio.h> #include <linux/of_irq.h> #include <linux/pm_runtime.h> #include <linux/spi/spi.h> @@ -118,10 +115,10 @@ static void ssc_read_rx_fifo(struct spi_st *spi_st) spi_st->words_remaining -= count; } -static int spi_st_transfer_one(struct spi_master *master, +static int spi_st_transfer_one(struct spi_controller *host, struct spi_device *spi, struct spi_transfer *t) { - struct spi_st *spi_st = spi_master_get_devdata(master); + struct spi_st *spi_st = spi_controller_get_devdata(host); uint32_t ctl = 0; /* Setup transfer */ @@ -168,46 +165,29 @@ static int spi_st_transfer_one(struct spi_master *master, if (ctl) writel_relaxed(ctl, spi_st->base + SSC_CTL); - spi_finalize_current_transfer(spi->master); + spi_finalize_current_transfer(spi->controller); return t->len; } -static void spi_st_cleanup(struct spi_device *spi) -{ - gpio_free(spi->cs_gpio); -} - /* the spi->mode bits understood by this driver: */ #define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_LOOP | SPI_CS_HIGH) static int spi_st_setup(struct spi_device *spi) { - struct spi_st *spi_st = spi_master_get_devdata(spi->master); + struct spi_st *spi_st = spi_controller_get_devdata(spi->controller); u32 spi_st_clk, sscbrg, var; u32 hz = spi->max_speed_hz; - int cs = spi->cs_gpio; - int ret; if (!hz) { dev_err(&spi->dev, "max_speed_hz unspecified\n"); return -EINVAL; } - if (!gpio_is_valid(cs)) { - dev_err(&spi->dev, "%d is not a valid gpio\n", cs); + if (!spi_get_csgpiod(spi, 0)) { + dev_err(&spi->dev, "no valid gpio assigned\n"); return -EINVAL; } - ret = gpio_request(cs, dev_name(&spi->dev)); - if (ret) { - dev_err(&spi->dev, "could not request gpio:%d\n", cs); - return ret; - } - - ret = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH); - if (ret) - goto out_free_gpio; - spi_st_clk = clk_get_rate(spi_st->clk); /* Set SSC_BRF */ @@ -215,8 +195,7 @@ static int spi_st_setup(struct spi_device *spi) if (sscbrg < 0x07 || sscbrg > BIT(16)) { dev_err(&spi->dev, "baudrate %d outside valid range %d\n", sscbrg, hz); - ret = -EINVAL; - goto out_free_gpio; + return -EINVAL; } spi_st->baud = spi_st_clk / (2 * sscbrg); @@ -265,10 +244,6 @@ static int spi_st_setup(struct spi_device *spi) readl_relaxed(spi_st->base + SSC_RBUF); return 0; - -out_free_gpio: - gpio_free(cs); - return ret; } /* Interrupt fired when TX shift register becomes empty */ @@ -299,42 +274,40 @@ static irqreturn_t spi_st_irq(int irq, void *dev_id) static int spi_st_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - struct spi_master *master; - struct resource *res; + struct spi_controller *host; struct spi_st *spi_st; int irq, ret = 0; u32 var; - master = spi_alloc_master(&pdev->dev, sizeof(*spi_st)); - if (!master) + host = spi_alloc_host(&pdev->dev, sizeof(*spi_st)); + if (!host) return -ENOMEM; - master->dev.of_node = np; - master->mode_bits = MODEBITS; - master->setup = spi_st_setup; - master->cleanup = spi_st_cleanup; - master->transfer_one = spi_st_transfer_one; - master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); - master->auto_runtime_pm = true; - master->bus_num = pdev->id; - spi_st = spi_master_get_devdata(master); + host->dev.of_node = np; + host->mode_bits = MODEBITS; + host->setup = spi_st_setup; + host->transfer_one = spi_st_transfer_one; + host->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); + host->auto_runtime_pm = true; + host->bus_num = pdev->id; + host->use_gpio_descriptors = true; + spi_st = spi_controller_get_devdata(host); spi_st->clk = devm_clk_get(&pdev->dev, "ssc"); if (IS_ERR(spi_st->clk)) { dev_err(&pdev->dev, "Unable to request clock\n"); ret = PTR_ERR(spi_st->clk); - goto put_master; + goto put_host; } ret = clk_prepare_enable(spi_st->clk); if (ret) - goto put_master; + goto put_host; init_completion(&spi_st->done); /* Get resources */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - spi_st->base = devm_ioremap_resource(&pdev->dev, res); + spi_st->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(spi_st->base)) { ret = PTR_ERR(spi_st->base); goto clk_disable; @@ -351,7 +324,7 @@ static int spi_st_probe(struct platform_device *pdev) var &= ~SSC_CTL_SR; writel_relaxed(var, spi_st->base + SSC_CTL); - /* Set SSC into slave mode before reconfiguring PIO pins */ + /* Set SSC into target mode before reconfiguring PIO pins */ var = readl_relaxed(spi_st->base + SSC_CTL); var &= ~SSC_CTL_MS; writel_relaxed(var, spi_st->base + SSC_CTL); @@ -374,40 +347,41 @@ static int spi_st_probe(struct platform_device *pdev) pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); - platform_set_drvdata(pdev, master); + platform_set_drvdata(pdev, host); - ret = devm_spi_register_master(&pdev->dev, master); + ret = devm_spi_register_controller(&pdev->dev, host); if (ret) { - dev_err(&pdev->dev, "Failed to register master\n"); - goto clk_disable; + dev_err(&pdev->dev, "Failed to register host\n"); + goto rpm_disable; } return 0; +rpm_disable: + pm_runtime_disable(&pdev->dev); clk_disable: clk_disable_unprepare(spi_st->clk); -put_master: - spi_master_put(master); +put_host: + spi_controller_put(host); return ret; } -static int spi_st_remove(struct platform_device *pdev) +static void spi_st_remove(struct platform_device *pdev) { - struct spi_master *master = platform_get_drvdata(pdev); - struct spi_st *spi_st = spi_master_get_devdata(master); + struct spi_controller *host = platform_get_drvdata(pdev); + struct spi_st *spi_st = spi_controller_get_devdata(host); + + pm_runtime_disable(&pdev->dev); clk_disable_unprepare(spi_st->clk); pinctrl_pm_select_sleep_state(&pdev->dev); - - return 0; } -#ifdef CONFIG_PM static int spi_st_runtime_suspend(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct spi_st *spi_st = spi_master_get_devdata(master); + struct spi_controller *host = dev_get_drvdata(dev); + struct spi_st *spi_st = spi_controller_get_devdata(host); writel_relaxed(0, spi_st->base + SSC_IEN); pinctrl_pm_select_sleep_state(dev); @@ -419,8 +393,8 @@ static int spi_st_runtime_suspend(struct device *dev) static int spi_st_runtime_resume(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct spi_st *spi_st = spi_master_get_devdata(master); + struct spi_controller *host = dev_get_drvdata(dev); + struct spi_st *spi_st = spi_controller_get_devdata(host); int ret; ret = clk_prepare_enable(spi_st->clk); @@ -428,37 +402,34 @@ static int spi_st_runtime_resume(struct device *dev) return ret; } -#endif -#ifdef CONFIG_PM_SLEEP -static int spi_st_suspend(struct device *dev) +static int __maybe_unused spi_st_suspend(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); + struct spi_controller *host = dev_get_drvdata(dev); int ret; - ret = spi_master_suspend(master); + ret = spi_controller_suspend(host); if (ret) return ret; return pm_runtime_force_suspend(dev); } -static int spi_st_resume(struct device *dev) +static int __maybe_unused spi_st_resume(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); + struct spi_controller *host = dev_get_drvdata(dev); int ret; - ret = spi_master_resume(master); + ret = spi_controller_resume(host); if (ret) return ret; return pm_runtime_force_resume(dev); } -#endif static const struct dev_pm_ops spi_st_pm = { - SET_SYSTEM_SLEEP_PM_OPS(spi_st_suspend, spi_st_resume) - SET_RUNTIME_PM_OPS(spi_st_runtime_suspend, spi_st_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(spi_st_suspend, spi_st_resume) + RUNTIME_PM_OPS(spi_st_runtime_suspend, spi_st_runtime_resume, NULL) }; static const struct of_device_id stm_spi_match[] = { @@ -470,7 +441,7 @@ MODULE_DEVICE_TABLE(of, stm_spi_match); static struct platform_driver spi_st_driver = { .driver = { .name = "spi-st", - .pm = &spi_st_pm, + .pm = pm_ptr(&spi_st_pm), .of_match_table = of_match_ptr(stm_spi_match), }, .probe = spi_st_probe, |
