]> www.infradead.org Git - users/willy/pagecache.git/commitdiff
qca_spi: Make interrupt remembering atomic
authorStefan Wahren <wahrenst@gmx.net>
Fri, 14 Jun 2024 14:50:30 +0000 (16:50 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 18 Jun 2024 09:38:51 +0000 (11:38 +0200)
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>
drivers/net/ethernet/qualcomm/qca_debug.c
drivers/net/ethernet/qualcomm/qca_spi.c
drivers/net/ethernet/qualcomm/qca_spi.h

index ff3b89e9028e9b72039a692955c5aa83bfa11a13..ad06da0fdaa04a29b0a2d2f53825561ab7df2d49 100644 (file)
@@ -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);
index 5799ecc88a875b70752dce3a9a1b405e9e836e3a..8f7ce6b51a1c9b42f5cf8d120a0f855bc6828643 100644 (file)
@@ -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);
 
index d59cb2352ceecc3c65bbf4bc70edcb4b44f67510..8f4808695e82069c6c10f598ac982bb89d7ac5a0 100644 (file)
@@ -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