Commit e8878ab8 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'spi-fix-v5.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi fixes from Mark Brown:
 "There's some driver specific fixes here plus one core fix for memory
  leaks that could be triggered by a potential race condition when
  cleaning up after we have split transfers to fit into what the
  controller can support"

* tag 'spi-fix-v5.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: stm32: fix pm_runtime_get_sync() error checking
  spi: Fix memory leak on splited transfers
  spi: spi-cadence-quadspi: Fix mapping of buffers for DMA reads
  spi: stm32: Rate-limit the 'Communication suspended' message
  spi: spi-loopback-test: Fix out-of-bounds read
  spi: spi-cadence-quadspi: Populate get_name() interface
  MAINTAINERS: add myself as maintainer for spi-fsl-dspi driver
parents 8b6ce251 c170a5a3
...@@ -6901,6 +6901,14 @@ L: linuxppc-dev@lists.ozlabs.org ...@@ -6901,6 +6901,14 @@ L: linuxppc-dev@lists.ozlabs.org
S: Maintained S: Maintained
F: drivers/dma/fsldma.* F: drivers/dma/fsldma.*
FREESCALE DSPI DRIVER
M: Vladimir Oltean <olteanv@gmail.com>
L: linux-spi@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt
F: drivers/spi/spi-fsl-dspi.c
F: include/linux/spi/spi-fsl-dspi.h
FREESCALE ENETC ETHERNET DRIVERS FREESCALE ENETC ETHERNET DRIVERS
M: Claudiu Manoil <claudiu.manoil@nxp.com> M: Claudiu Manoil <claudiu.manoil@nxp.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
......
...@@ -907,14 +907,16 @@ static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata, ...@@ -907,14 +907,16 @@ static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
struct dma_async_tx_descriptor *tx; struct dma_async_tx_descriptor *tx;
dma_cookie_t cookie; dma_cookie_t cookie;
dma_addr_t dma_dst; dma_addr_t dma_dst;
struct device *ddev;
if (!cqspi->rx_chan || !virt_addr_valid(buf)) { if (!cqspi->rx_chan || !virt_addr_valid(buf)) {
memcpy_fromio(buf, cqspi->ahb_base + from, len); memcpy_fromio(buf, cqspi->ahb_base + from, len);
return 0; return 0;
} }
dma_dst = dma_map_single(dev, buf, len, DMA_FROM_DEVICE); ddev = cqspi->rx_chan->device->dev;
if (dma_mapping_error(dev, dma_dst)) { dma_dst = dma_map_single(ddev, buf, len, DMA_FROM_DEVICE);
if (dma_mapping_error(ddev, dma_dst)) {
dev_err(dev, "dma mapping failed\n"); dev_err(dev, "dma mapping failed\n");
return -ENOMEM; return -ENOMEM;
} }
...@@ -948,7 +950,7 @@ static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata, ...@@ -948,7 +950,7 @@ static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
} }
err_unmap: err_unmap:
dma_unmap_single(dev, dma_dst, len, DMA_FROM_DEVICE); dma_unmap_single(ddev, dma_dst, len, DMA_FROM_DEVICE);
return ret; return ret;
} }
...@@ -1128,8 +1130,17 @@ static int cqspi_request_mmap_dma(struct cqspi_st *cqspi) ...@@ -1128,8 +1130,17 @@ static int cqspi_request_mmap_dma(struct cqspi_st *cqspi)
return 0; return 0;
} }
static const char *cqspi_get_name(struct spi_mem *mem)
{
struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master);
struct device *dev = &cqspi->pdev->dev;
return devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev), mem->spi->chip_select);
}
static const struct spi_controller_mem_ops cqspi_mem_ops = { static const struct spi_controller_mem_ops cqspi_mem_ops = {
.exec_op = cqspi_exec_mem_op, .exec_op = cqspi_exec_mem_op,
.get_name = cqspi_get_name,
}; };
static int cqspi_setup_flash(struct cqspi_st *cqspi) static int cqspi_setup_flash(struct cqspi_st *cqspi)
......
...@@ -90,7 +90,7 @@ static struct spi_test spi_tests[] = { ...@@ -90,7 +90,7 @@ static struct spi_test spi_tests[] = {
{ {
.description = "tx/rx-transfer - crossing PAGE_SIZE", .description = "tx/rx-transfer - crossing PAGE_SIZE",
.fill_option = FILL_COUNT_8, .fill_option = FILL_COUNT_8,
.iterate_len = { ITERATE_MAX_LEN }, .iterate_len = { ITERATE_LEN },
.iterate_tx_align = ITERATE_ALIGN, .iterate_tx_align = ITERATE_ALIGN,
.iterate_rx_align = ITERATE_ALIGN, .iterate_rx_align = ITERATE_ALIGN,
.transfer_count = 1, .transfer_count = 1,
......
...@@ -936,7 +936,11 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id) ...@@ -936,7 +936,11 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
} }
if (sr & STM32H7_SPI_SR_SUSP) { if (sr & STM32H7_SPI_SR_SUSP) {
dev_warn(spi->dev, "Communication suspended\n"); static DEFINE_RATELIMIT_STATE(rs,
DEFAULT_RATELIMIT_INTERVAL * 10,
1);
if (__ratelimit(&rs))
dev_dbg_ratelimited(spi->dev, "Communication suspended\n");
if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0))) if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
stm32h7_spi_read_rxfifo(spi, false); stm32h7_spi_read_rxfifo(spi, false);
/* /*
...@@ -2060,7 +2064,7 @@ static int stm32_spi_resume(struct device *dev) ...@@ -2060,7 +2064,7 @@ static int stm32_spi_resume(struct device *dev)
} }
ret = pm_runtime_get_sync(dev); ret = pm_runtime_get_sync(dev);
if (ret) { if (ret < 0) {
dev_err(dev, "Unable to power device:%d\n", ret); dev_err(dev, "Unable to power device:%d\n", ret);
return ret; return ret;
} }
......
...@@ -1327,8 +1327,6 @@ static int spi_transfer_one_message(struct spi_controller *ctlr, ...@@ -1327,8 +1327,6 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
if (msg->status && ctlr->handle_err) if (msg->status && ctlr->handle_err)
ctlr->handle_err(ctlr, msg); ctlr->handle_err(ctlr, msg);
spi_res_release(ctlr, msg);
spi_finalize_current_message(ctlr); spi_finalize_current_message(ctlr);
return ret; return ret;
...@@ -1725,6 +1723,13 @@ void spi_finalize_current_message(struct spi_controller *ctlr) ...@@ -1725,6 +1723,13 @@ void spi_finalize_current_message(struct spi_controller *ctlr)
spi_unmap_msg(ctlr, mesg); spi_unmap_msg(ctlr, mesg);
/* In the prepare_messages callback the spi bus has the opportunity to
* split a transfer to smaller chunks.
* Release splited transfers here since spi_map_msg is done on the
* splited transfers.
*/
spi_res_release(ctlr, mesg);
if (ctlr->cur_msg_prepared && ctlr->unprepare_message) { if (ctlr->cur_msg_prepared && ctlr->unprepare_message) {
ret = ctlr->unprepare_message(ctlr, mesg); ret = ctlr->unprepare_message(ctlr, mesg);
if (ret) { if (ret) {
......
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