Skip to content

Commit

Permalink
qca_spi: Make interrupt remembering atomic
Browse files Browse the repository at this point in the history
[ Upstream commit 2d71982 ]

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: 291ab06 ("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>
  • Loading branch information
lategoodbye authored and gregkh committed Jul 5, 2024
1 parent 2b82028 commit fb910ac
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 14 deletions.
6 changes: 2 additions & 4 deletions drivers/net/ethernet/qualcomm/qca_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
16 changes: 8 additions & 8 deletions drivers/net/ethernet/qualcomm/qca_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand Down Expand Up @@ -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);
Expand All @@ -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);

Expand Down
3 changes: 1 addition & 2 deletions drivers/net/ethernet/qualcomm/qca_spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit fb910ac

Please sign in to comment.