Skip to content

Commit

Permalink
Merge tag 'spi-fix-v5.13-rc3' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/broonie/spi

Pull spi fixes from Mark Brown:
 "There's some device specific fixes here but also an unusually large
  number of fixes for the core, including both fixes for breakage
  introduced on ACPI systems while fixing the long standing confusion
  about the polarity of GPIO chip selects specified through DT, and
  fixes for ordering issues on unregistration which have been exposed
  through the wider usage of devm_."

* tag 'spi-fix-v5.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: sc18is602: implement .max_{transfer,message}_size() for the controller
  spi: sc18is602: don't consider the chip select byte in sc18is602_check_transfer
  MAINTAINERS: Add Alain Volmat as STM32 SPI maintainer
  dt-bindings: spi: spi-mux: rename flash node
  spi: Don't have controller clean up spi device before driver unbind
  spi: Assume GPIO CS active high in ACPI case
  spi: sprd: Add missing MODULE_DEVICE_TABLE
  spi: Switch to signed types for *_native_cs SPI controller fields
  spi: take the SPI IO-mutex in the spi_set_cs_timing method
  spi: spi-fsl-dspi: Fix a resource leak in an error handling path
  spi: spi-zynq-qspi: Fix stack violation bug
  spi: spi-zynq-qspi: Fix kernel-doc warning
  spi: altera: Make SPI_ALTERA_CORE invisible
  spi: Fix spi device unregister flow
  • Loading branch information
Linus Torvalds committed May 24, 2021
2 parents c468154 + b4e46c9 commit f71d49e
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Documentation/devicetree/bindings/spi/spi-mux.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ examples:
mux-controls = <&mux>;
spi-flash@0 {
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <40000000>;
Expand Down
6 changes: 6 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -17304,6 +17304,12 @@ L: linux-i2c@vger.kernel.org
S: Maintained
F: drivers/i2c/busses/i2c-stm32*

ST STM32 SPI DRIVER
M: Alain Volmat <alain.volmat@foss.st.com>
L: linux-spi@vger.kernel.org
S: Maintained
F: drivers/spi/spi-stm32.c

ST STPDDC60 DRIVER
M: Daniel Nilsson <daniel.nilsson@flex.com>
L: linux-hwmon@vger.kernel.org
Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ config SPI_ALTERA
This is the driver for the Altera SPI Controller.

config SPI_ALTERA_CORE
tristate "Altera SPI Controller core code"
tristate "Altera SPI Controller core code" if COMPILE_TEST
select REGMAP
help
"The core code for the Altera SPI Controller"
Expand Down
4 changes: 3 additions & 1 deletion drivers/spi/spi-fsl-dspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1375,11 +1375,13 @@ static int dspi_probe(struct platform_device *pdev)
ret = spi_register_controller(ctlr);
if (ret != 0) {
dev_err(&pdev->dev, "Problem registering DSPI ctlr\n");
goto out_free_irq;
goto out_release_dma;
}

return ret;

out_release_dma:
dspi_release_dma(dspi);
out_free_irq:
if (dspi->irq)
free_irq(dspi->irq, dspi);
Expand Down
9 changes: 8 additions & 1 deletion drivers/spi/spi-sc18is602.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ static int sc18is602_setup_transfer(struct sc18is602 *hw, u32 hz, u8 mode)
static int sc18is602_check_transfer(struct spi_device *spi,
struct spi_transfer *t, int tlen)
{
if (t && t->len + tlen > SC18IS602_BUFSIZ)
if (t && t->len + tlen > SC18IS602_BUFSIZ + 1)
return -EINVAL;

return 0;
Expand Down Expand Up @@ -219,6 +219,11 @@ static int sc18is602_transfer_one(struct spi_master *master,
return status;
}

static size_t sc18is602_max_transfer_size(struct spi_device *spi)
{
return SC18IS602_BUFSIZ;
}

static int sc18is602_setup(struct spi_device *spi)
{
struct sc18is602 *hw = spi_master_get_devdata(spi->master);
Expand Down Expand Up @@ -293,6 +298,8 @@ static int sc18is602_probe(struct i2c_client *client,
master->bits_per_word_mask = SPI_BPW_MASK(8);
master->setup = sc18is602_setup;
master->transfer_one_message = sc18is602_transfer_one;
master->max_transfer_size = sc18is602_max_transfer_size;
master->max_message_size = sc18is602_max_transfer_size;
master->dev.of_node = np;
master->min_speed_hz = hw->freq / 128;
master->max_speed_hz = hw->freq / 4;
Expand Down
1 change: 1 addition & 0 deletions drivers/spi/spi-sprd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,7 @@ static const struct of_device_id sprd_spi_of_match[] = {
{ .compatible = "sprd,sc9860-spi", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sprd_spi_of_match);

static struct platform_driver sprd_spi_driver = {
.driver = {
Expand Down
9 changes: 4 additions & 5 deletions drivers/spi/spi-zynq-qspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ static int zynq_qspi_config_op(struct zynq_qspi *xqspi, struct spi_device *spi)
}

/**
* zynq_qspi_setup - Configure the QSPI controller
* zynq_qspi_setup_op - Configure the QSPI controller
* @spi: Pointer to the spi_device structure
*
* Sets the operational mode of QSPI controller for the next QSPI transfer, baud
Expand Down Expand Up @@ -528,18 +528,17 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
struct zynq_qspi *xqspi = spi_controller_get_devdata(mem->spi->master);
int err = 0, i;
u8 *tmpbuf;
u8 opcode = op->cmd.opcode;

dev_dbg(xqspi->dev, "cmd:%#x mode:%d.%d.%d.%d\n",
opcode, op->cmd.buswidth, op->addr.buswidth,
op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
op->dummy.buswidth, op->data.buswidth);

zynq_qspi_chipselect(mem->spi, true);
zynq_qspi_config_op(xqspi, mem->spi);

if (op->cmd.nbytes) {
if (op->cmd.opcode) {
reinit_completion(&xqspi->data_completion);
xqspi->txbuf = &opcode;
xqspi->txbuf = (u8 *)&op->cmd.opcode;
xqspi->rxbuf = NULL;
xqspi->tx_bytes = op->cmd.nbytes;
xqspi->rx_bytes = op->cmd.nbytes;
Expand Down
51 changes: 38 additions & 13 deletions drivers/spi/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@ static void spidev_release(struct device *dev)
{
struct spi_device *spi = to_spi_device(dev);

/* spi controllers may cleanup for released devices */
if (spi->controller->cleanup)
spi->controller->cleanup(spi);

spi_controller_put(spi->controller);
kfree(spi->driver_override);
kfree(spi);
Expand Down Expand Up @@ -558,6 +554,12 @@ static int spi_dev_check(struct device *dev, void *data)
return 0;
}

static void spi_cleanup(struct spi_device *spi)
{
if (spi->controller->cleanup)
spi->controller->cleanup(spi);
}

/**
* spi_add_device - Add spi_device allocated with spi_alloc_device
* @spi: spi_device to register
Expand Down Expand Up @@ -622,11 +624,13 @@ int spi_add_device(struct spi_device *spi)

/* Device may be bound to an active driver when this returns */
status = device_add(&spi->dev);
if (status < 0)
if (status < 0) {
dev_err(dev, "can't add %s, status %d\n",
dev_name(&spi->dev), status);
else
spi_cleanup(spi);
} else {
dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev));
}

done:
mutex_unlock(&spi_add_lock);
Expand Down Expand Up @@ -717,7 +721,9 @@ void spi_unregister_device(struct spi_device *spi)
if (ACPI_COMPANION(&spi->dev))
acpi_device_clear_enumerated(ACPI_COMPANION(&spi->dev));
device_remove_software_node(&spi->dev);
device_unregister(&spi->dev);
device_del(&spi->dev);
spi_cleanup(spi);
put_device(&spi->dev);
}
EXPORT_SYMBOL_GPL(spi_unregister_device);

Expand Down Expand Up @@ -814,15 +820,29 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)

if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio)) {
if (!(spi->mode & SPI_NO_CS)) {
if (spi->cs_gpiod)
/* polarity handled by gpiolib */
gpiod_set_value_cansleep(spi->cs_gpiod, activate);
else
if (spi->cs_gpiod) {
/*
* Historically ACPI has no means of the GPIO polarity and
* thus the SPISerialBus() resource defines it on the per-chip
* basis. In order to avoid a chain of negations, the GPIO
* polarity is considered being Active High. Even for the cases
* when _DSD() is involved (in the updated versions of ACPI)
* the GPIO CS polarity must be defined Active High to avoid
* ambiguity. That's why we use enable, that takes SPI_CS_HIGH
* into account.
*/
if (has_acpi_companion(&spi->dev))
gpiod_set_value_cansleep(spi->cs_gpiod, !enable);
else
/* Polarity handled by GPIO library */
gpiod_set_value_cansleep(spi->cs_gpiod, activate);
} else {
/*
* invert the enable line, as active low is
* default for SPI.
*/
gpio_set_value_cansleep(spi->cs_gpio, !enable);
}
}
/* Some SPI masters need both GPIO CS & slave_select */
if ((spi->controller->flags & SPI_MASTER_GPIO_SS) &&
Expand Down Expand Up @@ -3451,9 +3471,12 @@ int spi_set_cs_timing(struct spi_device *spi, struct spi_delay *setup,

if (spi->controller->set_cs_timing &&
!(spi->cs_gpiod || gpio_is_valid(spi->cs_gpio))) {
mutex_lock(&spi->controller->io_mutex);

if (spi->controller->auto_runtime_pm) {
status = pm_runtime_get_sync(parent);
if (status < 0) {
mutex_unlock(&spi->controller->io_mutex);
pm_runtime_put_noidle(parent);
dev_err(&spi->controller->dev, "Failed to power device: %d\n",
status);
Expand All @@ -3464,11 +3487,13 @@ int spi_set_cs_timing(struct spi_device *spi, struct spi_delay *setup,
hold, inactive);
pm_runtime_mark_last_busy(parent);
pm_runtime_put_autosuspend(parent);
return status;
} else {
return spi->controller->set_cs_timing(spi, setup, hold,
status = spi->controller->set_cs_timing(spi, setup, hold,
inactive);
}

mutex_unlock(&spi->controller->io_mutex);
return status;
}

if ((setup && setup->unit == SPI_DELAY_UNIT_SCK) ||
Expand Down
4 changes: 2 additions & 2 deletions include/linux/spi/spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -644,8 +644,8 @@ struct spi_controller {
int *cs_gpios;
struct gpio_desc **cs_gpiods;
bool use_gpio_descriptors;
u8 unused_native_cs;
u8 max_native_cs;
s8 unused_native_cs;
s8 max_native_cs;

/* statistics */
struct spi_statistics statistics;
Expand Down

0 comments on commit f71d49e

Please sign in to comment.