qca_spi: Make interrupt remembering atomic

[ Upstream commit 2d7198278ece01818cd95a3beffbdf8b2a353fa0 ]

The whole mechanism to remember occurred SPI interrupts is not atomic,
which could lead to unexpected behavior. So fix this by using atomic bit
operations instead.

Fixes: 291ab06ecf67 ("net: qualcomm: new Ethernet over SPI driver for QCA7000")
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
Link: https://lore.kernel.org/r/20240614145030.7781-1-wahrenst@gmx.net
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Stefan Wahren 2024-06-14 16:50:30 +02:00 committed by Ksawlii
parent 4f76885213
commit 97e0652f23
3 changed files with 11 additions and 14 deletions

View file

@ -110,10 +110,8 @@ qcaspi_info_show(struct seq_file *s, void *what)
seq_printf(s, "IRQ : %d\n",
qca->spi_dev->irq);
seq_printf(s, "INTR REQ : %u\n",
qca->intr_req);
seq_printf(s, "INTR SVC : %u\n",
qca->intr_svc);
seq_printf(s, "INTR : %lx\n",
qca->intr);
seq_printf(s, "SPI max speed : %lu\n",
(unsigned long)qca->spi_dev->max_speed_hz);

View file

@ -49,6 +49,8 @@
#define MAX_DMA_BURST_LEN 5000
#define SPI_INTR 0
/* Modules parameters */
#define QCASPI_CLK_SPEED_MIN 1000000
#define QCASPI_CLK_SPEED_MAX 16000000
@ -585,14 +587,14 @@ qcaspi_spi_thread(void *data)
continue;
}
if ((qca->intr_req == qca->intr_svc) &&
if (!test_bit(SPI_INTR, &qca->intr) &&
!qca->txr.skb[qca->txr.head])
schedule();
set_current_state(TASK_RUNNING);
netdev_dbg(qca->net_dev, "have work to do. int: %d, tx_skb: %p\n",
qca->intr_req - qca->intr_svc,
netdev_dbg(qca->net_dev, "have work to do. int: %lu, tx_skb: %p\n",
qca->intr,
qca->txr.skb[qca->txr.head]);
qcaspi_qca7k_sync(qca, QCASPI_EVENT_UPDATE);
@ -606,8 +608,7 @@ qcaspi_spi_thread(void *data)
msleep(QCASPI_QCA7K_REBOOT_TIME_MS);
}
if (qca->intr_svc != qca->intr_req) {
qca->intr_svc = qca->intr_req;
if (test_and_clear_bit(SPI_INTR, &qca->intr)) {
start_spi_intr_handling(qca, &intr_cause);
if (intr_cause & SPI_INT_CPU_ON) {
@ -669,7 +670,7 @@ qcaspi_intr_handler(int irq, void *data)
{
struct qcaspi *qca = data;
qca->intr_req++;
set_bit(SPI_INTR, &qca->intr);
if (qca->spi_thread &&
qca->spi_thread->state != TASK_RUNNING)
wake_up_process(qca->spi_thread);
@ -686,8 +687,7 @@ qcaspi_netdev_open(struct net_device *dev)
if (!qca)
return -EINVAL;
qca->intr_req = 1;
qca->intr_svc = 0;
set_bit(SPI_INTR, &qca->intr);
qca->sync = QCASPI_SYNC_UNKNOWN;
qcafrm_fsm_init_spi(&qca->frm_handle);

View file

@ -92,8 +92,7 @@ struct qcaspi {
struct qcafrm_handle frm_handle;
struct sk_buff *rx_skb;
unsigned int intr_req;
unsigned int intr_svc;
unsigned long intr;
u16 reset_count;
#ifdef CONFIG_DEBUG_FS