spi: Fies for v6.16

A collection of driver specific fixes, most minor apart from the OMAP
 ones which disable some recent performance optimisations in some
 non-standard cases where we could start driving the bus incorrectly.
 
 The change to the stm32-ospi driver to use the newer reset APIs is a fix
 for interactions with other IP sharing the same reset line in some SoCs.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmhMXiEACgkQJNaLcl1U
 h9DfLwf9F7yAsLh7eGYPCqjDB365LaAuroOWuM5hB74cTFis9WJpcEI1pk9GdaD0
 m7TAkc+cxo0KBvpe0/t0+oqSBkUdcZ4ASXZp4zYnsj9dGhBcmlS0szHIOZWknMxZ
 E2pzHWj6p4/+zntWa+CCiiVGHz0PV3I9Oq3V1kI1EqyAZXc9uf5hj0hITVulJ4ih
 8+Y+927MpJ2dis8CaHeubDfNxnwJlCLS5GFwZaEhTXWp6IttxjH5KmeZu2Wtahdw
 ZcqUDLPYxdzoirDoGvdGBTHc0NMF843WD9wFWb29BzuyPLZYGAwGXDhGtHqSaGAo
 6HB5529nuKDAC1XNyRN6NA4bQosMaw==
 =ShaP
 -----END PGP SIGNATURE-----

Merge tag 'spi-fix-v6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi fixes from Mark Brown:
 "A collection of driver specific fixes, most minor apart from the OMAP
  ones which disable some recent performance optimisations in some
  non-standard cases where we could start driving the bus incorrectly.

  The change to the stm32-ospi driver to use the newer reset APIs is a
  fix for interactions with other IP sharing the same reset line in some
  SoCs"

* tag 'spi-fix-v6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: spi-pci1xxxx: Drop MSI-X usage as unsupported by DMA engine
  spi: stm32-ospi: clean up on error in probe()
  spi: stm32-ospi: Make usage of reset_control_acquire/release() API
  spi: offload: check offload ops existence before disabling the trigger
  spi: spi-pci1xxxx: Fix error code in probe
  spi: loongson: Fix build warnings about export.h
  spi: omap2-mcspi: Disable multi-mode when the previous message kept CS asserted
  spi: omap2-mcspi: Disable multi mode when CS should be kept asserted after message
This commit is contained in:
Linus Torvalds 2025-06-13 11:01:44 -07:00
commit 02adc1490e
5 changed files with 41 additions and 20 deletions

View File

@ -5,6 +5,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>

View File

@ -297,7 +297,7 @@ int spi_offload_trigger_enable(struct spi_offload *offload,
if (trigger->ops->enable) {
ret = trigger->ops->enable(trigger, config);
if (ret) {
if (offload->ops->trigger_disable)
if (offload->ops && offload->ops->trigger_disable)
offload->ops->trigger_disable(offload);
return ret;
}

View File

@ -134,6 +134,7 @@ struct omap2_mcspi {
size_t max_xfer_len;
u32 ref_clk_hz;
bool use_multi_mode;
bool last_msg_kept_cs;
};
struct omap2_mcspi_cs {
@ -1269,6 +1270,10 @@ static int omap2_mcspi_prepare_message(struct spi_controller *ctlr,
* multi-mode is applicable.
*/
mcspi->use_multi_mode = true;
if (mcspi->last_msg_kept_cs)
mcspi->use_multi_mode = false;
list_for_each_entry(tr, &msg->transfers, transfer_list) {
if (!tr->bits_per_word)
bits_per_word = msg->spi->bits_per_word;
@ -1287,18 +1292,19 @@ static int omap2_mcspi_prepare_message(struct spi_controller *ctlr,
mcspi->use_multi_mode = false;
}
/* Check if transfer asks to change the CS status after the transfer */
if (!tr->cs_change)
mcspi->use_multi_mode = false;
/*
* If at least one message is not compatible, switch back to single mode
*
* The bits_per_word of certain transfer can be different, but it will have no
* impact on the signal itself.
*/
if (!mcspi->use_multi_mode)
break;
if (list_is_last(&tr->transfer_list, &msg->transfers)) {
/* Check if transfer asks to keep the CS status after the whole message */
if (tr->cs_change) {
mcspi->use_multi_mode = false;
mcspi->last_msg_kept_cs = true;
} else {
mcspi->last_msg_kept_cs = false;
}
} else {
/* Check if transfer asks to change the CS status after the transfer */
if (!tr->cs_change)
mcspi->use_multi_mode = false;
}
}
omap2_mcspi_set_mode(ctlr);

View File

@ -762,10 +762,10 @@ static int pci1xxxx_spi_probe(struct pci_dev *pdev, const struct pci_device_id *
return -EINVAL;
num_vector = pci_alloc_irq_vectors(pdev, 1, hw_inst_cnt,
PCI_IRQ_ALL_TYPES);
PCI_IRQ_INTX | PCI_IRQ_MSI);
if (num_vector < 0) {
dev_err(&pdev->dev, "Error allocating MSI vectors\n");
return ret;
return num_vector;
}
init_completion(&spi_sub_ptr->spi_xfer_done);

View File

@ -804,7 +804,7 @@ static int stm32_ospi_get_resources(struct platform_device *pdev)
return ret;
}
ospi->rstc = devm_reset_control_array_get_exclusive(dev);
ospi->rstc = devm_reset_control_array_get_exclusive_released(dev);
if (IS_ERR(ospi->rstc))
return dev_err_probe(dev, PTR_ERR(ospi->rstc),
"Can't get reset\n");
@ -936,12 +936,16 @@ static int stm32_ospi_probe(struct platform_device *pdev)
if (ret < 0)
goto err_pm_enable;
if (ospi->rstc) {
reset_control_assert(ospi->rstc);
udelay(2);
reset_control_deassert(ospi->rstc);
ret = reset_control_acquire(ospi->rstc);
if (ret) {
dev_err_probe(dev, ret, "Can not acquire reset %d\n", ret);
goto err_pm_resume;
}
reset_control_assert(ospi->rstc);
udelay(2);
reset_control_deassert(ospi->rstc);
ret = spi_register_controller(ctrl);
if (ret) {
/* Disable ospi */
@ -987,6 +991,8 @@ static void stm32_ospi_remove(struct platform_device *pdev)
if (ospi->dma_chrx)
dma_release_channel(ospi->dma_chrx);
reset_control_release(ospi->rstc);
pm_runtime_put_sync_suspend(ospi->dev);
pm_runtime_force_suspend(ospi->dev);
}
@ -997,6 +1003,8 @@ static int __maybe_unused stm32_ospi_suspend(struct device *dev)
pinctrl_pm_select_sleep_state(dev);
reset_control_release(ospi->rstc);
return pm_runtime_force_suspend(ospi->dev);
}
@ -1016,6 +1024,12 @@ static int __maybe_unused stm32_ospi_resume(struct device *dev)
if (ret < 0)
return ret;
ret = reset_control_acquire(ospi->rstc);
if (ret) {
dev_err(dev, "Can not acquire reset\n");
return ret;
}
writel_relaxed(ospi->cr_reg, regs_base + OSPI_CR);
writel_relaxed(ospi->dcr_reg, regs_base + OSPI_DCR1);
pm_runtime_mark_last_busy(ospi->dev);