diff options
author | Mark Brown <broonie@kernel.org> | 2019-11-22 19:56:33 +0000 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2019-11-22 19:56:33 +0000 |
commit | 8f3ed6d0b0db04db8297d951c26c809dd7b4778d (patch) | |
tree | 5813c89fa9245eb00e617b6dab89ddfe4a029184 /drivers/spi | |
parent | af42d3466bdc8f39806b26f593604fdc54140bcb (diff) | |
parent | c5923243eb3208ea63b5ed7905610039c4ca5201 (diff) |
Merge branch 'spi-5.4' into spi-linus
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-atmel.c | 10 | ||||
-rw-r--r-- | drivers/spi/spi-bcm2835.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-dw-mmio.c | 5 | ||||
-rw-r--r-- | drivers/spi/spi-dw.c | 3 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-cpm.c | 3 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-dspi.c | 5 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-lpspi.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-qspi.c | 38 | ||||
-rw-r--r-- | drivers/spi/spi-gpio.c | 4 | ||||
-rw-r--r-- | drivers/spi/spi-mxic.c | 6 | ||||
-rw-r--r-- | drivers/spi/spi-orion.c | 3 | ||||
-rw-r--r-- | drivers/spi/spi-pxa2xx.c | 19 | ||||
-rw-r--r-- | drivers/spi/spi-rspi.c | 8 | ||||
-rw-r--r-- | drivers/spi/spi-sifive.c | 11 | ||||
-rw-r--r-- | drivers/spi/spi-stm32-qspi.c | 3 | ||||
-rw-r--r-- | drivers/spi/spi.c | 19 | ||||
-rw-r--r-- | drivers/spi/spidev.c | 3 |
17 files changed, 95 insertions, 49 deletions
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index acf318e7330c..2f8c79ce05c8 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -302,7 +302,6 @@ struct atmel_spi { bool use_cs_gpios; bool keep_cs; - bool cs_active; u32 fifo_size; }; @@ -1376,11 +1375,9 @@ static int atmel_spi_one_transfer(struct spi_master *master, &msg->transfers)) { as->keep_cs = true; } else { - as->cs_active = !as->cs_active; - if (as->cs_active) - cs_activate(as, msg->spi); - else - cs_deactivate(as, msg->spi); + cs_deactivate(as, msg->spi); + udelay(10); + cs_activate(as, msg->spi); } } @@ -1403,7 +1400,6 @@ static int atmel_spi_transfer_one_message(struct spi_master *master, atmel_spi_lock(as); cs_activate(as, spi); - as->cs_active = true; as->keep_cs = false; msg->status = 0; diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index b4070c0de3df..fb61a620effc 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -1248,7 +1248,7 @@ static int bcm2835_spi_setup(struct spi_device *spi) /* * Retrieve the corresponding GPIO line used for CS. * The inversion semantics will be handled by the GPIO core - * code, so we pass GPIOS_OUT_LOW for "unasserted" and + * code, so we pass GPIOD_OUT_LOW for "unasserted" and * the correct flag for inversion semantics. The SPI_CS_HIGH * on spi->mode cannot be checked for polarity in this case * as the flag use_gpio_descriptors enforces SPI_CS_HIGH. diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index bd46fca3f094..db896475b8d1 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -9,6 +9,7 @@ #include <linux/err.h> #include <linux/interrupt.h> #include <linux/platform_device.h> +#include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/spi/spi.h> #include <linux/scatterlist.h> @@ -193,6 +194,8 @@ static int dw_spi_mmio_probe(struct platform_device *pdev) goto out; } + pm_runtime_enable(&pdev->dev); + ret = dw_spi_add_host(&pdev->dev, dws); if (ret) goto out; @@ -201,6 +204,7 @@ static int dw_spi_mmio_probe(struct platform_device *pdev) return 0; out: + pm_runtime_disable(&pdev->dev); clk_disable_unprepare(dwsmmio->pclk); out_clk: clk_disable_unprepare(dwsmmio->clk); @@ -212,6 +216,7 @@ static int dw_spi_mmio_remove(struct platform_device *pdev) struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev); dw_spi_remove_host(&dwsmmio->dws); + pm_runtime_disable(&pdev->dev); clk_disable_unprepare(dwsmmio->pclk); clk_disable_unprepare(dwsmmio->clk); diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 9a49e073e8b7..076652d3d051 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -308,7 +308,8 @@ static int dw_spi_transfer_one(struct spi_controller *master, cr0 = (transfer->bits_per_word - 1) | (chip->type << SPI_FRF_OFFSET) | ((((spi->mode & SPI_CPOL) ? 1 : 0) << SPI_SCOL_OFFSET) | - (((spi->mode & SPI_CPHA) ? 1 : 0) << SPI_SCPH_OFFSET)) + (((spi->mode & SPI_CPHA) ? 1 : 0) << SPI_SCPH_OFFSET) | + (((spi->mode & SPI_LOOP) ? 1 : 0) << SPI_SRL_OFFSET)) | (chip->tmode << SPI_TMOD_OFFSET); /* diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c index 858f0544289e..54ad0ac121e5 100644 --- a/drivers/spi/spi-fsl-cpm.c +++ b/drivers/spi/spi-fsl-cpm.c @@ -392,7 +392,8 @@ void fsl_spi_cpm_free(struct mpc8xxx_spi *mspi) dma_unmap_single(dev, mspi->dma_dummy_rx, SPI_MRBLR, DMA_FROM_DEVICE); dma_unmap_single(dev, mspi->dma_dummy_tx, PAGE_SIZE, DMA_TO_DEVICE); cpm_muram_free(cpm_muram_offset(mspi->tx_bd)); - cpm_muram_free(cpm_muram_offset(mspi->pram)); + if (!(mspi->flags & SPI_CPM1)) + cpm_muram_free(cpm_muram_offset(mspi->pram)); fsl_spi_free_dummy_rx(); } EXPORT_SYMBOL_GPL(fsl_spi_cpm_free); diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index bec758e978fb..7bb018eb67d0 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -707,7 +707,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) regmap_read(dspi->regmap, SPI_SR, &spi_sr); regmap_write(dspi->regmap, SPI_SR, spi_sr); - if (!(spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF))) + if (!(spi_sr & SPI_SR_EOQF)) return IRQ_NONE; if (dspi_rxtx(dspi) == 0) { @@ -1114,6 +1114,9 @@ static int dspi_probe(struct platform_device *pdev) dspi_init(dspi); + if (dspi->devtype_data->trans_mode == DSPI_TCFQ_MODE) + goto poll_mode; + dspi->irq = platform_get_irq(pdev, 0); if (dspi->irq <= 0) { dev_info(&pdev->dev, diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c index d08e9324140e..3528ed5eea9b 100644 --- a/drivers/spi/spi-fsl-lpspi.c +++ b/drivers/spi/spi-fsl-lpspi.c @@ -938,7 +938,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev) ret = pm_runtime_get_sync(fsl_lpspi->dev); if (ret < 0) { dev_err(fsl_lpspi->dev, "failed to enable clock\n"); - return ret; + goto out_controller_put; } temp = readl(fsl_lpspi->base + IMX7ULP_PARAM); diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c index c02e24c01136..63c9f7edaf6c 100644 --- a/drivers/spi/spi-fsl-qspi.c +++ b/drivers/spi/spi-fsl-qspi.c @@ -63,6 +63,11 @@ #define QUADSPI_IPCR 0x08 #define QUADSPI_IPCR_SEQID(x) ((x) << 24) +#define QUADSPI_FLSHCR 0x0c +#define QUADSPI_FLSHCR_TCSS_MASK GENMASK(3, 0) +#define QUADSPI_FLSHCR_TCSH_MASK GENMASK(11, 8) +#define QUADSPI_FLSHCR_TDH_MASK GENMASK(17, 16) + #define QUADSPI_BUF3CR 0x1c #define QUADSPI_BUF3CR_ALLMST_MASK BIT(31) #define QUADSPI_BUF3CR_ADATSZ(x) ((x) << 8) @@ -95,6 +100,9 @@ #define QUADSPI_FR 0x160 #define QUADSPI_FR_TFF_MASK BIT(0) +#define QUADSPI_RSER 0x164 +#define QUADSPI_RSER_TFIE BIT(0) + #define QUADSPI_SPTRCLR 0x16c #define QUADSPI_SPTRCLR_IPPTRC BIT(8) #define QUADSPI_SPTRCLR_BFPTRC BIT(0) @@ -112,9 +120,6 @@ #define QUADSPI_LCKER_LOCK BIT(0) #define QUADSPI_LCKER_UNLOCK BIT(1) -#define QUADSPI_RSER 0x164 -#define QUADSPI_RSER_TFIE BIT(0) - #define QUADSPI_LUT_BASE 0x310 #define QUADSPI_LUT_OFFSET (SEQID_LUT * 4 * 4) #define QUADSPI_LUT_REG(idx) \ @@ -181,6 +186,12 @@ */ #define QUADSPI_QUIRK_BASE_INTERNAL BIT(4) +/* + * Controller uses TDH bits in register QUADSPI_FLSHCR. + * They need to be set in accordance with the DDR/SDR mode. + */ +#define QUADSPI_QUIRK_USE_TDH_SETTING BIT(5) + struct fsl_qspi_devtype_data { unsigned int rxfifo; unsigned int txfifo; @@ -209,7 +220,8 @@ static const struct fsl_qspi_devtype_data imx7d_data = { .rxfifo = SZ_128, .txfifo = SZ_512, .ahb_buf_size = SZ_1K, - .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK, + .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK | + QUADSPI_QUIRK_USE_TDH_SETTING, .little_endian = true, }; @@ -217,7 +229,8 @@ static const struct fsl_qspi_devtype_data imx6ul_data = { .rxfifo = SZ_128, .txfifo = SZ_512, .ahb_buf_size = SZ_1K, - .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK, + .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK | + QUADSPI_QUIRK_USE_TDH_SETTING, .little_endian = true, }; @@ -275,6 +288,11 @@ static inline int needs_amba_base_offset(struct fsl_qspi *q) return !(q->devtype_data->quirks & QUADSPI_QUIRK_BASE_INTERNAL); } +static inline int needs_tdh_setting(struct fsl_qspi *q) +{ + return q->devtype_data->quirks & QUADSPI_QUIRK_USE_TDH_SETTING; +} + /* * An IC bug makes it necessary to rearrange the 32-bit data. * Later chips, such as IMX6SLX, have fixed this bug. @@ -710,6 +728,16 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q) qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK, base + QUADSPI_MCR); + /* + * Previous boot stages (BootROM, bootloader) might have used DDR + * mode and did not clear the TDH bits. As we currently use SDR mode + * only, clear the TDH bits if necessary. + */ + if (needs_tdh_setting(q)) + qspi_writel(q, qspi_readl(q, base + QUADSPI_FLSHCR) & + ~QUADSPI_FLSHCR_TDH_MASK, + base + QUADSPI_FLSHCR); + reg = qspi_readl(q, base + QUADSPI_SMPR); qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK | QUADSPI_SMPR_FSPHS_MASK diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 1d3e23ec20a6..f9c5bbb74714 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c @@ -371,8 +371,10 @@ static int spi_gpio_probe(struct platform_device *pdev) return -ENOMEM; status = devm_add_action_or_reset(&pdev->dev, spi_gpio_put, master); - if (status) + if (status) { + spi_master_put(master); return status; + } if (of_id) status = spi_gpio_probe_dt(pdev, master); diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index f48563c09b97..a736fdf47119 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -145,8 +145,8 @@ #define LWR_SUSP_CTRL_EN BIT(31) #define DMAS_CTRL 0x9c -#define DMAS_CTRL_DIR_READ BIT(31) -#define DMAS_CTRL_EN BIT(30) +#define DMAS_CTRL_EN BIT(31) +#define DMAS_CTRL_DIR_READ BIT(30) #define DATA_STROB 0xa0 #define DATA_STROB_EDO_EN BIT(2) @@ -275,7 +275,7 @@ static void mxic_spi_hw_init(struct mxic_spi *mxic) writel(0, mxic->regs + HC_EN); writel(0, mxic->regs + LRD_CFG); writel(0, mxic->regs + LRD_CTRL); - writel(HC_CFG_NIO(1) | HC_CFG_TYPE(0, HC_CFG_TYPE_SPI_NAND) | + writel(HC_CFG_NIO(1) | HC_CFG_TYPE(0, HC_CFG_TYPE_SPI_NOR) | HC_CFG_SLV_ACT(0) | HC_CFG_MAN_CS_EN | HC_CFG_IDLE_SIO_LVL(1), mxic->regs + HC_CFG); } diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 6643ccdc2508..81c991c4ddbf 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -772,9 +772,6 @@ static int orion_spi_probe(struct platform_device *pdev) if (status < 0) goto out_rel_pm; - pm_runtime_mark_last_busy(&pdev->dev); - pm_runtime_put_autosuspend(&pdev->dev); - master->dev.of_node = pdev->dev.of_node; status = spi_register_master(master); if (status < 0) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index bb6a14d1ab0f..1e0091259259 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1457,6 +1457,10 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = { { PCI_VDEVICE(INTEL, 0x02aa), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0x02ab), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0x02fb), LPSS_CNL_SSP }, + /* CML-H */ + { PCI_VDEVICE(INTEL, 0x06aa), LPSS_CNL_SSP }, + { PCI_VDEVICE(INTEL, 0x06ab), LPSS_CNL_SSP }, + { PCI_VDEVICE(INTEL, 0x06fb), LPSS_CNL_SSP }, /* TGL-LP */ { PCI_VDEVICE(INTEL, 0xa0aa), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0xa0ab), LPSS_CNL_SSP }, @@ -1545,17 +1549,15 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev) if (!pdata) return NULL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return NULL; - ssp = &pdata->ssp; - ssp->phys_base = res->start; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ssp->mmio_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(ssp->mmio_base)) return NULL; + ssp->phys_base = res->start; + #ifdef CONFIG_PCI if (pcidev_id) { pdata->tx_param = pdev->dev.parent; @@ -1602,6 +1604,11 @@ static int pxa2xx_spi_fw_translate_cs(struct spi_controller *controller, return cs; } +static size_t pxa2xx_spi_max_dma_transfer_size(struct spi_device *spi) +{ + return MAX_DMA_LEN; +} + static int pxa2xx_spi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1707,6 +1714,8 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) } else { controller->can_dma = pxa2xx_spi_can_dma; controller->max_dma_len = MAX_DMA_LEN; + controller->max_transfer_size = + pxa2xx_spi_max_dma_transfer_size; } } diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 15f5723d9f95..7222c7689c3c 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -1257,9 +1257,9 @@ static int rspi_probe(struct platform_device *pdev) ctlr->flags = ops->flags; ctlr->dev.of_node = pdev->dev.of_node; - ret = platform_get_irq_byname(pdev, "rx"); + ret = platform_get_irq_byname_optional(pdev, "rx"); if (ret < 0) { - ret = platform_get_irq_byname(pdev, "mux"); + ret = platform_get_irq_byname_optional(pdev, "mux"); if (ret < 0) ret = platform_get_irq(pdev, 0); if (ret >= 0) @@ -1270,10 +1270,6 @@ static int rspi_probe(struct platform_device *pdev) if (ret >= 0) rspi->tx_irq = ret; } - if (ret < 0) { - dev_err(&pdev->dev, "platform_get_irq error\n"); - goto error2; - } if (rspi->rx_irq == rspi->tx_irq) { /* Single multiplexed interrupt */ diff --git a/drivers/spi/spi-sifive.c b/drivers/spi/spi-sifive.c index 35254bdc42c4..f7c1e20432e0 100644 --- a/drivers/spi/spi-sifive.c +++ b/drivers/spi/spi-sifive.c @@ -357,14 +357,14 @@ static int sifive_spi_probe(struct platform_device *pdev) if (!cs_bits) { dev_err(&pdev->dev, "Could not auto probe CS lines\n"); ret = -EINVAL; - goto put_master; + goto disable_clk; } num_cs = ilog2(cs_bits) + 1; if (num_cs > SIFIVE_SPI_MAX_CS) { dev_err(&pdev->dev, "Invalid number of spi slaves\n"); ret = -EINVAL; - goto put_master; + goto disable_clk; } /* Define our master */ @@ -393,7 +393,7 @@ static int sifive_spi_probe(struct platform_device *pdev) dev_name(&pdev->dev), spi); if (ret) { dev_err(&pdev->dev, "Unable to bind to interrupt\n"); - goto put_master; + goto disable_clk; } dev_info(&pdev->dev, "mapped; irq=%d, cs=%d\n", @@ -402,11 +402,13 @@ static int sifive_spi_probe(struct platform_device *pdev) ret = devm_spi_register_master(&pdev->dev, master); if (ret < 0) { dev_err(&pdev->dev, "spi_register_master failed\n"); - goto put_master; + goto disable_clk; } return 0; +disable_clk: + clk_disable_unprepare(spi->clk); put_master: spi_master_put(master); @@ -420,6 +422,7 @@ static int sifive_spi_remove(struct platform_device *pdev) /* Disable all the interrupts just in case */ sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0); + clk_disable_unprepare(spi->clk); return 0; } diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c index 9ac6f9fe13cf..4e726929bb4f 100644 --- a/drivers/spi/spi-stm32-qspi.c +++ b/drivers/spi/spi-stm32-qspi.c @@ -528,7 +528,6 @@ static void stm32_qspi_release(struct stm32_qspi *qspi) stm32_qspi_dma_free(qspi); mutex_destroy(&qspi->lock); clk_disable_unprepare(qspi->clk); - spi_master_put(qspi->ctrl); } static int stm32_qspi_probe(struct platform_device *pdev) @@ -626,6 +625,8 @@ static int stm32_qspi_probe(struct platform_device *pdev) err: stm32_qspi_release(qspi); + spi_master_put(qspi->ctrl); + return ret; } diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index f9502dbbb5c1..26b91ee0855d 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1711,15 +1711,7 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, spi->mode |= SPI_3WIRE; if (of_property_read_bool(nc, "spi-lsb-first")) spi->mode |= SPI_LSB_FIRST; - - /* - * For descriptors associated with the device, polarity inversion is - * handled in the gpiolib, so all chip selects are "active high" in - * the logical sense, the gpiolib will invert the line if need be. - */ - if (ctlr->use_gpio_descriptors) - spi->mode |= SPI_CS_HIGH; - else if (of_property_read_bool(nc, "spi-cs-high")) + if (of_property_read_bool(nc, "spi-cs-high")) spi->mode |= SPI_CS_HIGH; /* Device DUAL/QUAD mode */ @@ -1783,6 +1775,15 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, } spi->chip_select = value; + /* + * For descriptors associated with the device, polarity inversion is + * handled in the gpiolib, so all gpio chip selects are "active high" + * in the logical sense, the gpiolib will invert the line if need be. + */ + if ((ctlr->use_gpio_descriptors) && ctlr->cs_gpiods && + ctlr->cs_gpiods[spi->chip_select]) + spi->mode |= SPI_CS_HIGH; + /* Device speed */ rc = of_property_read_u32(nc, "spi-max-frequency", &value); if (rc) { diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 255786f2e844..3ea9d8a3e6e8 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -627,6 +627,9 @@ static int spidev_release(struct inode *inode, struct file *filp) if (dofree) kfree(spidev); } +#ifdef CONFIG_SPI_SLAVE + spi_slave_abort(spidev->spi); +#endif mutex_unlock(&device_list_lock); return 0; |