Commit 4073195a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'spi-fix-v6.9-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi fixes from Mark Brown:
 "A small collection of fixes that came in since the merge window. Most
  of it is relatively minor driver specific fixes, there's also fixes
  for error handling with SPI flash devices and a fix restoring delay
  control functionality for non-GPIO chip selects managed by the core"

* tag 'spi-fix-v6.9-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: spi-mt65xx: Fix NULL pointer access in interrupt handler
  spi: docs: spidev: fix echo command format
  spi: spi-imx: fix off-by-one in mx51 CPU mode burst length
  spi: lm70llp: fix links in doc and comments
  spi: Fix error code checking in spi_mem_exec_op()
  spi: Restore delays for non-GPIO chip select
  spi: lpspi: Avoid potential use-after-free in probe()
parents 8c826bd9 a20ad450
...@@ -6,7 +6,7 @@ Supported board/chip: ...@@ -6,7 +6,7 @@ Supported board/chip:
* National Semiconductor LM70 LLP evaluation board * National Semiconductor LM70 LLP evaluation board
Datasheet: http://www.national.com/pf/LM/LM70.html Datasheet: https://www.ti.com/lit/gpn/lm70
Author: Author:
Kaiwan N Billimoria <kaiwan@designergraphix.com> Kaiwan N Billimoria <kaiwan@designergraphix.com>
...@@ -28,7 +28,7 @@ Hardware Interfacing ...@@ -28,7 +28,7 @@ Hardware Interfacing
The schematic for this particular board (the LM70EVAL-LLP) is The schematic for this particular board (the LM70EVAL-LLP) is
available (on page 4) here: available (on page 4) here:
http://www.national.com/appinfo/tempsensors/files/LM70LLPEVALmanual.pdf https://download.datasheets.com/pdfs/documentation/nat/kit&board/lm70llpevalmanual.pdf
The hardware interfacing on the LM70 LLP eval board is as follows: The hardware interfacing on the LM70 LLP eval board is as follows:
......
...@@ -61,7 +61,7 @@ the spidev driver failing to probe. ...@@ -61,7 +61,7 @@ the spidev driver failing to probe.
Sysfs also supports userspace driven binding/unbinding of drivers to Sysfs also supports userspace driven binding/unbinding of drivers to
devices that do not bind automatically using one of the tables above. devices that do not bind automatically using one of the tables above.
To make the spidev driver bind to such a device, use the following: To make the spidev driver bind to such a device, use the following::
echo spidev > /sys/bus/spi/devices/spiB.C/driver_override echo spidev > /sys/bus/spi/devices/spiB.C/driver_override
echo spiB.C > /sys/bus/spi/drivers/spidev/bind echo spiB.C > /sys/bus/spi/drivers/spidev/bind
......
...@@ -830,11 +830,11 @@ static int fsl_lpspi_probe(struct platform_device *pdev) ...@@ -830,11 +830,11 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
is_target = of_property_read_bool((&pdev->dev)->of_node, "spi-slave"); is_target = of_property_read_bool((&pdev->dev)->of_node, "spi-slave");
if (is_target) if (is_target)
controller = spi_alloc_target(&pdev->dev, controller = devm_spi_alloc_target(&pdev->dev,
sizeof(struct fsl_lpspi_data)); sizeof(struct fsl_lpspi_data));
else else
controller = spi_alloc_host(&pdev->dev, controller = devm_spi_alloc_host(&pdev->dev,
sizeof(struct fsl_lpspi_data)); sizeof(struct fsl_lpspi_data));
if (!controller) if (!controller)
return -ENOMEM; return -ENOMEM;
......
...@@ -668,8 +668,8 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx, ...@@ -668,8 +668,8 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx,
ctrl |= (MX51_ECSPI_CTRL_MAX_BURST * BITS_PER_BYTE - 1) ctrl |= (MX51_ECSPI_CTRL_MAX_BURST * BITS_PER_BYTE - 1)
<< MX51_ECSPI_CTRL_BL_OFFSET; << MX51_ECSPI_CTRL_BL_OFFSET;
else else
ctrl |= spi_imx->count / DIV_ROUND_UP(spi_imx->bits_per_word, ctrl |= (spi_imx->count / DIV_ROUND_UP(spi_imx->bits_per_word,
BITS_PER_BYTE) * spi_imx->bits_per_word BITS_PER_BYTE) * spi_imx->bits_per_word - 1)
<< MX51_ECSPI_CTRL_BL_OFFSET; << MX51_ECSPI_CTRL_BL_OFFSET;
} }
} }
......
...@@ -29,10 +29,10 @@ ...@@ -29,10 +29,10 @@
* *
* Datasheet and Schematic: * Datasheet and Schematic:
* The LM70 is a temperature sensor chip from National Semiconductor; its * The LM70 is a temperature sensor chip from National Semiconductor; its
* datasheet is available at http://www.national.com/pf/LM/LM70.html * datasheet is available at https://www.ti.com/lit/gpn/lm70
* The schematic for this particular board (the LM70EVAL-LLP) is * The schematic for this particular board (the LM70EVAL-LLP) is
* available (on page 4) here: * available (on page 4) here:
* http://www.national.com/appinfo/tempsensors/files/LM70LLPEVALmanual.pdf * https://download.datasheets.com/pdfs/documentation/nat/kit&board/lm70llpevalmanual.pdf
* *
* Also see Documentation/spi/spi-lm70llp.rst. The SPI<->parport code here is * Also see Documentation/spi/spi-lm70llp.rst. The SPI<->parport code here is
* (heavily) based on spi-butterfly by David Brownell. * (heavily) based on spi-butterfly by David Brownell.
......
...@@ -382,7 +382,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) ...@@ -382,7 +382,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
* read path) and expect the core to use the regular SPI * read path) and expect the core to use the regular SPI
* interface in other cases. * interface in other cases.
*/ */
if (!ret || ret != -ENOTSUPP || ret != -EOPNOTSUPP) { if (!ret || (ret != -ENOTSUPP && ret != -EOPNOTSUPP)) {
spi_mem_add_op_stats(ctlr->pcpu_statistics, op, ret); spi_mem_add_op_stats(ctlr->pcpu_statistics, op, ret);
spi_mem_add_op_stats(mem->spi->pcpu_statistics, op, ret); spi_mem_add_op_stats(mem->spi->pcpu_statistics, op, ret);
......
...@@ -788,17 +788,19 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) ...@@ -788,17 +788,19 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, len); mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, len);
mtk_spi_setup_packet(host); mtk_spi_setup_packet(host);
cnt = mdata->xfer_len / 4; if (trans->tx_buf) {
iowrite32_rep(mdata->base + SPI_TX_DATA_REG, cnt = mdata->xfer_len / 4;
trans->tx_buf + mdata->num_xfered, cnt); iowrite32_rep(mdata->base + SPI_TX_DATA_REG,
trans->tx_buf + mdata->num_xfered, cnt);
remainder = mdata->xfer_len % 4; remainder = mdata->xfer_len % 4;
if (remainder > 0) { if (remainder > 0) {
reg_val = 0; reg_val = 0;
memcpy(&reg_val, memcpy(&reg_val,
trans->tx_buf + (cnt * 4) + mdata->num_xfered, trans->tx_buf + (cnt * 4) + mdata->num_xfered,
remainder); remainder);
writel(reg_val, mdata->base + SPI_TX_DATA_REG); writel(reg_val, mdata->base + SPI_TX_DATA_REG);
}
} }
mtk_spi_enable_transfer(host); mtk_spi_enable_transfer(host);
......
...@@ -1063,10 +1063,14 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) ...@@ -1063,10 +1063,14 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
if (spi->mode & SPI_CS_HIGH) if (spi->mode & SPI_CS_HIGH)
enable = !enable; enable = !enable;
if (spi_is_csgpiod(spi)) { /*
if (!spi->controller->set_cs_timing && !activate) * Handle chip select delays for GPIO based CS or controllers without
spi_delay_exec(&spi->cs_hold, NULL); * programmable chip select timing.
*/
if ((spi_is_csgpiod(spi) || !spi->controller->set_cs_timing) && !activate)
spi_delay_exec(&spi->cs_hold, NULL);
if (spi_is_csgpiod(spi)) {
if (!(spi->mode & SPI_NO_CS)) { if (!(spi->mode & SPI_NO_CS)) {
/* /*
* Historically ACPI has no means of the GPIO polarity and * Historically ACPI has no means of the GPIO polarity and
...@@ -1099,16 +1103,16 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) ...@@ -1099,16 +1103,16 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
if ((spi->controller->flags & SPI_CONTROLLER_GPIO_SS) && if ((spi->controller->flags & SPI_CONTROLLER_GPIO_SS) &&
spi->controller->set_cs) spi->controller->set_cs)
spi->controller->set_cs(spi, !enable); spi->controller->set_cs(spi, !enable);
if (!spi->controller->set_cs_timing) {
if (activate)
spi_delay_exec(&spi->cs_setup, NULL);
else
spi_delay_exec(&spi->cs_inactive, NULL);
}
} else if (spi->controller->set_cs) { } else if (spi->controller->set_cs) {
spi->controller->set_cs(spi, !enable); spi->controller->set_cs(spi, !enable);
} }
if (spi_is_csgpiod(spi) || !spi->controller->set_cs_timing) {
if (activate)
spi_delay_exec(&spi->cs_setup, NULL);
else
spi_delay_exec(&spi->cs_inactive, NULL);
}
} }
#ifdef CONFIG_HAS_DMA #ifdef CONFIG_HAS_DMA
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment