Skip to content

Commit 18445bf

Browse files
committed
Merge tag 'spi-fix-v5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi fixes from Mark Brown: "A bunch of fixes that came in for SPI during the merge window. Some from ST and others for their controller, one from Lukas for a race between device addition and controller unregistration and one from fix from Geert for the DT bindings which unbreaks validation" * tag 'spi-fix-v5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: dt-bindings: lpspi: Add missing boolean type for fsl,spi-only-use-cs1-sel spi: stm32: always perform registers configuration prior to transfer spi: stm32: fixes suspend/resume management spi: stm32: fix stm32_spi_prepare_mbr in case of odd clk_rate spi: stm32: fix fifo threshold level in case of short transfer spi: stm32h7: fix race condition at end of transfer spi: stm32: clear only asserted irq flags on interrupt spi: Prevent adding devices below an unregistering controller
2 parents 9899b58 + 8cb61d6 commit 18445bf

File tree

4 files changed

+86
-39
lines changed

4 files changed

+86
-39
lines changed

Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ properties:
3939
spi common code does not support use of CS signals discontinuously.
4040
i.MX8DXL-EVK board only uses CS1 without using CS0. Therefore, add
4141
this property to re-config the chipselect value in the LPSPI driver.
42+
type: boolean
4243

4344
required:
4445
- compatible

drivers/spi/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,4 +1017,7 @@ config SPI_SLAVE_SYSTEM_CONTROL
10171017

10181018
endif # SPI_SLAVE
10191019

1020+
config SPI_DYNAMIC
1021+
def_bool ACPI || OF_DYNAMIC || SPI_SLAVE
1022+
10201023
endif # SPI

drivers/spi/spi-stm32.c

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/iopoll.h>
1414
#include <linux/module.h>
1515
#include <linux/of_platform.h>
16+
#include <linux/pinctrl/consumer.h>
1617
#include <linux/pm_runtime.h>
1718
#include <linux/reset.h>
1819
#include <linux/spi/spi.h>
@@ -441,7 +442,8 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,
441442
{
442443
u32 div, mbrdiv;
443444

444-
div = DIV_ROUND_UP(spi->clk_rate, speed_hz);
445+
/* Ensure spi->clk_rate is even */
446+
div = DIV_ROUND_UP(spi->clk_rate & ~0x1, speed_hz);
445447

446448
/*
447449
* SPI framework set xfer->speed_hz to master->max_speed_hz if
@@ -467,27 +469,37 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,
467469
/**
468470
* stm32h7_spi_prepare_fthlv - Determine FIFO threshold level
469471
* @spi: pointer to the spi controller data structure
472+
* @xfer_len: length of the message to be transferred
470473
*/
471-
static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi)
474+
static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi, u32 xfer_len)
472475
{
473-
u32 fthlv, half_fifo;
476+
u32 fthlv, half_fifo, packet;
474477

475478
/* data packet should not exceed 1/2 of fifo space */
476479
half_fifo = (spi->fifo_size / 2);
477480

481+
/* data_packet should not exceed transfer length */
482+
if (half_fifo > xfer_len)
483+
packet = xfer_len;
484+
else
485+
packet = half_fifo;
486+
478487
if (spi->cur_bpw <= 8)
479-
fthlv = half_fifo;
488+
fthlv = packet;
480489
else if (spi->cur_bpw <= 16)
481-
fthlv = half_fifo / 2;
490+
fthlv = packet / 2;
482491
else
483-
fthlv = half_fifo / 4;
492+
fthlv = packet / 4;
484493

485494
/* align packet size with data registers access */
486495
if (spi->cur_bpw > 8)
487496
fthlv -= (fthlv % 2); /* multiple of 2 */
488497
else
489498
fthlv -= (fthlv % 4); /* multiple of 4 */
490499

500+
if (!fthlv)
501+
fthlv = 1;
502+
491503
return fthlv;
492504
}
493505

@@ -966,13 +978,13 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
966978
if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
967979
stm32h7_spi_read_rxfifo(spi, false);
968980

969-
writel_relaxed(mask, spi->base + STM32H7_SPI_IFCR);
981+
writel_relaxed(sr & mask, spi->base + STM32H7_SPI_IFCR);
970982

971983
spin_unlock_irqrestore(&spi->lock, flags);
972984

973985
if (end) {
974-
spi_finalize_current_transfer(master);
975986
stm32h7_spi_disable(spi);
987+
spi_finalize_current_transfer(master);
976988
}
977989

978990
return IRQ_HANDLED;
@@ -1393,7 +1405,7 @@ static void stm32h7_spi_set_bpw(struct stm32_spi *spi)
13931405
cfg1_setb |= (bpw << STM32H7_SPI_CFG1_DSIZE_SHIFT) &
13941406
STM32H7_SPI_CFG1_DSIZE;
13951407

1396-
spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi);
1408+
spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi, spi->cur_xferlen);
13971409
fthlv = spi->cur_fthlv - 1;
13981410

13991411
cfg1_clrb |= STM32H7_SPI_CFG1_FTHLV;
@@ -1585,39 +1597,33 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
15851597
unsigned long flags;
15861598
unsigned int comm_type;
15871599
int nb_words, ret = 0;
1600+
int mbr;
15881601

15891602
spin_lock_irqsave(&spi->lock, flags);
15901603

1591-
if (spi->cur_bpw != transfer->bits_per_word) {
1592-
spi->cur_bpw = transfer->bits_per_word;
1593-
spi->cfg->set_bpw(spi);
1594-
}
1595-
1596-
if (spi->cur_speed != transfer->speed_hz) {
1597-
int mbr;
1604+
spi->cur_xferlen = transfer->len;
15981605

1599-
/* Update spi->cur_speed with real clock speed */
1600-
mbr = stm32_spi_prepare_mbr(spi, transfer->speed_hz,
1601-
spi->cfg->baud_rate_div_min,
1602-
spi->cfg->baud_rate_div_max);
1603-
if (mbr < 0) {
1604-
ret = mbr;
1605-
goto out;
1606-
}
1606+
spi->cur_bpw = transfer->bits_per_word;
1607+
spi->cfg->set_bpw(spi);
16071608

1608-
transfer->speed_hz = spi->cur_speed;
1609-
stm32_spi_set_mbr(spi, mbr);
1609+
/* Update spi->cur_speed with real clock speed */
1610+
mbr = stm32_spi_prepare_mbr(spi, transfer->speed_hz,
1611+
spi->cfg->baud_rate_div_min,
1612+
spi->cfg->baud_rate_div_max);
1613+
if (mbr < 0) {
1614+
ret = mbr;
1615+
goto out;
16101616
}
16111617

1618+
transfer->speed_hz = spi->cur_speed;
1619+
stm32_spi_set_mbr(spi, mbr);
1620+
16121621
comm_type = stm32_spi_communication_type(spi_dev, transfer);
1613-
if (spi->cur_comm != comm_type) {
1614-
ret = spi->cfg->set_mode(spi, comm_type);
1622+
ret = spi->cfg->set_mode(spi, comm_type);
1623+
if (ret < 0)
1624+
goto out;
16151625

1616-
if (ret < 0)
1617-
goto out;
1618-
1619-
spi->cur_comm = comm_type;
1620-
}
1626+
spi->cur_comm = comm_type;
16211627

16221628
if (spi->cfg->set_data_idleness)
16231629
spi->cfg->set_data_idleness(spi, transfer->len);
@@ -1635,8 +1641,6 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
16351641
goto out;
16361642
}
16371643

1638-
spi->cur_xferlen = transfer->len;
1639-
16401644
dev_dbg(spi->dev, "transfer communication mode set to %d\n",
16411645
spi->cur_comm);
16421646
dev_dbg(spi->dev,
@@ -1996,6 +2000,8 @@ static int stm32_spi_remove(struct platform_device *pdev)
19962000

19972001
pm_runtime_disable(&pdev->dev);
19982002

2003+
pinctrl_pm_select_sleep_state(&pdev->dev);
2004+
19992005
return 0;
20002006
}
20012007

@@ -2007,13 +2013,18 @@ static int stm32_spi_runtime_suspend(struct device *dev)
20072013

20082014
clk_disable_unprepare(spi->clk);
20092015

2010-
return 0;
2016+
return pinctrl_pm_select_sleep_state(dev);
20112017
}
20122018

20132019
static int stm32_spi_runtime_resume(struct device *dev)
20142020
{
20152021
struct spi_master *master = dev_get_drvdata(dev);
20162022
struct stm32_spi *spi = spi_master_get_devdata(master);
2023+
int ret;
2024+
2025+
ret = pinctrl_pm_select_default_state(dev);
2026+
if (ret)
2027+
return ret;
20172028

20182029
return clk_prepare_enable(spi->clk);
20192030
}
@@ -2043,10 +2054,23 @@ static int stm32_spi_resume(struct device *dev)
20432054
return ret;
20442055

20452056
ret = spi_master_resume(master);
2046-
if (ret)
2057+
if (ret) {
20472058
clk_disable_unprepare(spi->clk);
2059+
return ret;
2060+
}
20482061

2049-
return ret;
2062+
ret = pm_runtime_get_sync(dev);
2063+
if (ret) {
2064+
dev_err(dev, "Unable to power device:%d\n", ret);
2065+
return ret;
2066+
}
2067+
2068+
spi->cfg->config(spi);
2069+
2070+
pm_runtime_mark_last_busy(dev);
2071+
pm_runtime_put_autosuspend(dev);
2072+
2073+
return 0;
20502074
}
20512075
#endif
20522076

drivers/spi/spi.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,12 @@ static LIST_HEAD(spi_controller_list);
475475
*/
476476
static DEFINE_MUTEX(board_lock);
477477

478+
/*
479+
* Prevents addition of devices with same chip select and
480+
* addition of devices below an unregistering controller.
481+
*/
482+
static DEFINE_MUTEX(spi_add_lock);
483+
478484
/**
479485
* spi_alloc_device - Allocate a new SPI device
480486
* @ctlr: Controller to which device is connected
@@ -554,7 +560,6 @@ static int spi_dev_check(struct device *dev, void *data)
554560
*/
555561
int spi_add_device(struct spi_device *spi)
556562
{
557-
static DEFINE_MUTEX(spi_add_lock);
558563
struct spi_controller *ctlr = spi->controller;
559564
struct device *dev = ctlr->dev.parent;
560565
int status;
@@ -582,6 +587,13 @@ int spi_add_device(struct spi_device *spi)
582587
goto done;
583588
}
584589

590+
/* Controller may unregister concurrently */
591+
if (IS_ENABLED(CONFIG_SPI_DYNAMIC) &&
592+
!device_is_registered(&ctlr->dev)) {
593+
status = -ENODEV;
594+
goto done;
595+
}
596+
585597
/* Descriptors take precedence */
586598
if (ctlr->cs_gpiods)
587599
spi->cs_gpiod = ctlr->cs_gpiods[spi->chip_select];
@@ -2795,6 +2807,10 @@ void spi_unregister_controller(struct spi_controller *ctlr)
27952807
struct spi_controller *found;
27962808
int id = ctlr->bus_num;
27972809

2810+
/* Prevent addition of new devices, unregister existing ones */
2811+
if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
2812+
mutex_lock(&spi_add_lock);
2813+
27982814
device_for_each_child(&ctlr->dev, NULL, __unregister);
27992815

28002816
/* First make sure that this controller was ever added */
@@ -2815,6 +2831,9 @@ void spi_unregister_controller(struct spi_controller *ctlr)
28152831
if (found == ctlr)
28162832
idr_remove(&spi_master_idr, id);
28172833
mutex_unlock(&board_lock);
2834+
2835+
if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
2836+
mutex_unlock(&spi_add_lock);
28182837
}
28192838
EXPORT_SYMBOL_GPL(spi_unregister_controller);
28202839

0 commit comments

Comments
 (0)