Commit 02adc149 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 601dddb6 9f0ad43b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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>
+1 −1
Original line number Diff line number Diff line
@@ -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;
		}
+18 −12
Original line number Diff line number Diff line
@@ -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;
		}

		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;

		/*
		 * 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;
		}
	}

	omap2_mcspi_set_mode(ctlr);
+2 −2
Original line number Diff line number Diff line
@@ -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);
+19 −5
Original line number Diff line number Diff line
@@ -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,11 +936,15 @@ static int stm32_ospi_probe(struct platform_device *pdev)
	if (ret < 0)
		goto err_pm_enable;

	if (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) {
@@ -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);