Commit 2d719827 authored by Stefan Wahren's avatar Stefan Wahren Committed by Paolo Abeni

qca_spi: Make interrupt remembering atomic

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: 291ab06e ("net: qualcomm: new Ethernet over SPI driver for QCA7000")
Signed-off-by: default avatarStefan Wahren <wahrenst@gmx.net>
Link: https://lore.kernel.org/r/20240614145030.7781-1-wahrenst@gmx.netSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent ff960f9d
......@@ -98,10 +98,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);
......
......@@ -35,6 +35,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
......@@ -579,14 +581,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);
......@@ -600,8 +602,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) {
......@@ -663,7 +664,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)
wake_up_process(qca->spi_thread);
......@@ -679,8 +680,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);
......
......@@ -81,8 +81,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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment