crypto: hisilicon/qm - use request_threaded_irq instead
authorWeili Qian <qianweili@huawei.com>
Sat, 11 Dec 2021 11:25:17 +0000 (19:25 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 17 Dec 2021 05:59:49 +0000 (16:59 +1100)
The abnormal interrupt method needs to be changed, and the changed method
needs to be locked in order to maintain atomicity. Therefore,
replace request_irq() with request_threaded_irq().

Signed-off-by: Weili Qian <qianweili@huawei.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/hisilicon/qm.c

index beea3a0..93abe1f 100644 (file)
@@ -988,16 +988,12 @@ static void qm_set_qp_disable(struct hisi_qp *qp, int offset)
        mb();
 }
 
-static irqreturn_t qm_aeq_irq(int irq, void *data)
+static irqreturn_t qm_aeq_thread(int irq, void *data)
 {
        struct hisi_qm *qm = data;
        struct qm_aeqe *aeqe = qm->aeqe + qm->status.aeq_head;
        u32 type;
 
-       atomic64_inc(&qm->debug.dfx.aeq_irq_cnt);
-       if (!readl(qm->io_base + QM_VF_AEQ_INT_SOURCE))
-               return IRQ_NONE;
-
        while (QM_AEQE_PHASE(aeqe) == qm->status.aeqc_phase) {
                type = le32_to_cpu(aeqe->dw0) >> QM_AEQE_TYPE_SHIFT;
                if (type < ARRAY_SIZE(qm_fifo_overflow))
@@ -1022,6 +1018,17 @@ static irqreturn_t qm_aeq_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
+static irqreturn_t qm_aeq_irq(int irq, void *data)
+{
+       struct hisi_qm *qm = data;
+
+       atomic64_inc(&qm->debug.dfx.aeq_irq_cnt);
+       if (!readl(qm->io_base + QM_VF_AEQ_INT_SOURCE))
+               return IRQ_NONE;
+
+       return IRQ_WAKE_THREAD;
+}
+
 static void qm_irq_unregister(struct hisi_qm *qm)
 {
        struct pci_dev *pdev = qm->pdev;
@@ -5299,8 +5306,10 @@ static int qm_irq_register(struct hisi_qm *qm)
                return ret;
 
        if (qm->ver > QM_HW_V1) {
-               ret = request_irq(pci_irq_vector(pdev, QM_AEQ_EVENT_IRQ_VECTOR),
-                                 qm_aeq_irq, 0, qm->dev_name, qm);
+               ret = request_threaded_irq(pci_irq_vector(pdev,
+                                          QM_AEQ_EVENT_IRQ_VECTOR),
+                                          qm_aeq_irq, qm_aeq_thread,
+                                          0, qm->dev_name, qm);
                if (ret)
                        goto err_aeq_irq;