diff options
-rw-r--r-- | drivers/spi/spi-fsl-spi.c | 18 | ||||
-rw-r--r-- | drivers/spi/spi-img-spfi.c | 56 | ||||
-rw-r--r-- | drivers/spi/spi-lantiq-ssc.c | 4 | ||||
-rw-r--r-- | drivers/spi/spi-npcm-pspi.c | 28 | ||||
-rw-r--r-- | drivers/spi/spi.c | 11 | ||||
-rw-r--r-- | include/linux/spi/spi.h | 4 |
6 files changed, 28 insertions, 93 deletions
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 67f022b8c81d..299e9870cf58 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -90,7 +90,7 @@ static void fsl_spi_change_mode(struct spi_device *spi) { struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master); struct spi_mpc8xxx_cs *cs = spi->controller_state; - struct fsl_spi_reg *reg_base = mspi->reg_base; + struct fsl_spi_reg __iomem *reg_base = mspi->reg_base; __be32 __iomem *mode = ®_base->mode; unsigned long flags; @@ -291,7 +291,7 @@ static int fsl_spi_cpu_bufs(struct mpc8xxx_spi *mspi, struct spi_transfer *t, unsigned int len) { u32 word; - struct fsl_spi_reg *reg_base = mspi->reg_base; + struct fsl_spi_reg __iomem *reg_base = mspi->reg_base; mspi->count = len; @@ -309,7 +309,7 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t, bool is_dma_mapped) { struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); - struct fsl_spi_reg *reg_base; + struct fsl_spi_reg __iomem *reg_base; unsigned int len = t->len; u8 bits_per_word; int ret; @@ -440,7 +440,7 @@ static int fsl_spi_do_one_msg(struct spi_master *master, static int fsl_spi_setup(struct spi_device *spi) { struct mpc8xxx_spi *mpc8xxx_spi; - struct fsl_spi_reg *reg_base; + struct fsl_spi_reg __iomem *reg_base; int retval; u32 hw_mode; struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi); @@ -495,7 +495,7 @@ static void fsl_spi_cleanup(struct spi_device *spi) static void fsl_spi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) { - struct fsl_spi_reg *reg_base = mspi->reg_base; + struct fsl_spi_reg __iomem *reg_base = mspi->reg_base; /* We need handle RX first */ if (events & SPIE_NE) { @@ -530,7 +530,7 @@ static irqreturn_t fsl_spi_irq(s32 irq, void *context_data) struct mpc8xxx_spi *mspi = context_data; irqreturn_t ret = IRQ_NONE; u32 events; - struct fsl_spi_reg *reg_base = mspi->reg_base; + struct fsl_spi_reg __iomem *reg_base = mspi->reg_base; /* Get interrupt events(tx/rx) */ events = mpc8xxx_spi_read_reg(®_base->event); @@ -550,7 +550,7 @@ static irqreturn_t fsl_spi_irq(s32 irq, void *context_data) static void fsl_spi_grlib_cs_control(struct spi_device *spi, bool on) { struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); - struct fsl_spi_reg *reg_base = mpc8xxx_spi->reg_base; + struct fsl_spi_reg __iomem *reg_base = mpc8xxx_spi->reg_base; u32 slvsel; u16 cs = spi->chip_select; @@ -568,7 +568,7 @@ static void fsl_spi_grlib_probe(struct device *dev) struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); struct spi_master *master = dev_get_drvdata(dev); struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); - struct fsl_spi_reg *reg_base = mpc8xxx_spi->reg_base; + struct fsl_spi_reg __iomem *reg_base = mpc8xxx_spi->reg_base; int mbits; u32 capabilities; @@ -594,7 +594,7 @@ static struct spi_master *fsl_spi_probe(struct device *dev, struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); struct spi_master *master; struct mpc8xxx_spi *mpc8xxx_spi; - struct fsl_spi_reg *reg_base; + struct fsl_spi_reg __iomem *reg_base; u32 regval; int ret = 0; diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index 8543f5ed1099..b068537375d6 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c @@ -9,7 +9,6 @@ #include <linux/clk.h> #include <linux/delay.h> #include <linux/dmaengine.h> -#include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/irq.h> @@ -102,10 +101,6 @@ struct img_spfi { bool rx_dma_busy; }; -struct img_spfi_device_data { - bool gpio_requested; -}; - static inline u32 spfi_readl(struct img_spfi *spfi, u32 reg) { return readl(spfi->regs + reg); @@ -442,54 +437,6 @@ static int img_spfi_unprepare(struct spi_master *master, return 0; } -static int img_spfi_setup(struct spi_device *spi) -{ - int ret = -EINVAL; - struct img_spfi_device_data *spfi_data = spi_get_ctldata(spi); - - if (!spfi_data) { - spfi_data = kzalloc(sizeof(*spfi_data), GFP_KERNEL); - if (!spfi_data) - return -ENOMEM; - spfi_data->gpio_requested = false; - spi_set_ctldata(spi, spfi_data); - } - if (!spfi_data->gpio_requested) { - ret = gpio_request_one(spi->cs_gpio, - (spi->mode & SPI_CS_HIGH) ? - GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, - dev_name(&spi->dev)); - if (ret) - dev_err(&spi->dev, "can't request chipselect gpio %d\n", - spi->cs_gpio); - else - spfi_data->gpio_requested = true; - } else { - if (gpio_is_valid(spi->cs_gpio)) { - int mode = ((spi->mode & SPI_CS_HIGH) ? - GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH); - - ret = gpio_direction_output(spi->cs_gpio, mode); - if (ret) - dev_err(&spi->dev, "chipselect gpio %d setup failed (%d)\n", - spi->cs_gpio, ret); - } - } - return ret; -} - -static void img_spfi_cleanup(struct spi_device *spi) -{ - struct img_spfi_device_data *spfi_data = spi_get_ctldata(spi); - - if (spfi_data) { - if (spfi_data->gpio_requested) - gpio_free(spi->cs_gpio); - kfree(spfi_data); - spi_set_ctldata(spi, NULL); - } -} - static void img_spfi_config(struct spi_master *master, struct spi_device *spi, struct spi_transfer *xfer) { @@ -659,12 +606,11 @@ static int img_spfi_probe(struct platform_device *pdev) master->max_speed_hz = max_speed_hz; } - master->setup = img_spfi_setup; - master->cleanup = img_spfi_cleanup; master->transfer_one = img_spfi_transfer_one; master->prepare_message = img_spfi_prepare; master->unprepare_message = img_spfi_unprepare; master->handle_err = img_spfi_handle_err; + master->use_gpio_descriptors = true; spfi->tx_ch = dma_request_chan(spfi->dev, "tx"); if (IS_ERR(spfi->tx_ch)) { diff --git a/drivers/spi/spi-lantiq-ssc.c b/drivers/spi/spi-lantiq-ssc.c index 1fd7ee53d451..1cf650e25e31 100644 --- a/drivers/spi/spi-lantiq-ssc.c +++ b/drivers/spi/spi-lantiq-ssc.c @@ -15,7 +15,6 @@ #include <linux/completion.h> #include <linux/spinlock.h> #include <linux/err.h> -#include <linux/gpio.h> #include <linux/pm_runtime.h> #include <linux/spi/spi.h> @@ -391,7 +390,7 @@ static int lantiq_ssc_setup(struct spi_device *spidev) u32 gpocon; /* GPIOs are used for CS */ - if (gpio_is_valid(spidev->cs_gpio)) + if (spidev->cs_gpiod) return 0; dev_dbg(spi->dev, "using internal chipselect %u\n", cs); @@ -888,6 +887,7 @@ static int lantiq_ssc_probe(struct platform_device *pdev) master->dev.of_node = pdev->dev.of_node; master->num_chipselect = num_cs; + master->use_gpio_descriptors = true; master->setup = lantiq_ssc_setup; master->set_cs = lantiq_ssc_set_cs; master->handle_err = lantiq_ssc_handle_err; diff --git a/drivers/spi/spi-npcm-pspi.c b/drivers/spi/spi-npcm-pspi.c index 87cd0233c60b..56d10c4511db 100644 --- a/drivers/spi/spi-npcm-pspi.c +++ b/drivers/spi/spi-npcm-pspi.c @@ -10,8 +10,6 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> -#include <linux/gpio.h> -#include <linux/of_gpio.h> #include <linux/reset.h> #include <asm/unaligned.h> @@ -344,16 +342,9 @@ static int npcm_pspi_probe(struct platform_device *pdev) struct npcm_pspi *priv; struct spi_master *master; unsigned long clk_hz; - struct device_node *np = pdev->dev.of_node; - int num_cs, i; - int csgpio; int irq; int ret; - num_cs = of_gpio_named_count(np, "cs-gpios"); - if (num_cs < 0) - return num_cs; - master = spi_alloc_master(&pdev->dev, sizeof(*priv)); if (!master) return -ENOMEM; @@ -418,24 +409,7 @@ static int npcm_pspi_probe(struct platform_device *pdev) npcm_pspi_prepare_transfer_hardware; master->unprepare_transfer_hardware = npcm_pspi_unprepare_transfer_hardware; - master->num_chipselect = num_cs; - - for (i = 0; i < num_cs; i++) { - csgpio = of_get_named_gpio(np, "cs-gpios", i); - if (csgpio < 0) { - dev_err(&pdev->dev, "failed to get csgpio#%u\n", i); - goto out_disable_clk; - } - dev_dbg(&pdev->dev, "csgpio#%u = %d\n", i, csgpio); - ret = devm_gpio_request_one(&pdev->dev, csgpio, - GPIOF_OUT_INIT_HIGH, DRIVER_NAME); - if (ret < 0) { - dev_err(&pdev->dev, - "failed to configure csgpio#%u %d\n" - , i, csgpio); - goto out_disable_clk; - } - } + master->use_gpio_descriptors = true; /* set to default clock rate */ npcm_pspi_set_baudrate(priv, NPCM_PSPI_DEFAULT_CLK); diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 6fa56590bba2..d4ba723a30da 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -778,6 +778,17 @@ static void spi_set_cs(struct spi_device *spi, bool enable) { bool enable1 = enable; + /* + * Avoid calling into the driver (or doing delays) if the chip select + * isn't actually changing from the last time this was called. + */ + if ((spi->controller->last_cs_enable == enable) && + (spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH))) + return; + + spi->controller->last_cs_enable = enable; + spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH; + if (!spi->controller->set_cs_timing) { if (enable1) spi_delay_exec(&spi->controller->cs_setup, NULL); diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index b4917df79637..0e67a9a3a1d3 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -368,6 +368,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @cur_msg_prepared: spi_prepare_message was called for the currently * in-flight message * @cur_msg_mapped: message has been mapped for DMA + * @last_cs_enable: was enable true on the last call to set_cs. + * @last_cs_mode_high: was (mode & SPI_CS_HIGH) true on the last call to set_cs. * @xfer_completion: used by core transfer_one_message() * @busy: message pump is busy * @running: message pump is running @@ -604,6 +606,8 @@ struct spi_controller { bool auto_runtime_pm; bool cur_msg_prepared; bool cur_msg_mapped; + bool last_cs_enable; + bool last_cs_mode_high; bool fallback; struct completion xfer_completion; size_t max_dma_len; |