From 0068a2ec5e3cb5d2c314f6f71ee0d03bd892fbae Mon Sep 17 00:00:00 2001 From: zhangwei Date: Fri, 9 Aug 2019 20:49:25 +0800 Subject: [PATCH] ACC: add qm workqueue support driver inclusion category: bugfix bugzilla: NA CVE: NA Feature or Bugfix:Feature Signed-off-by: Zhangwei Reviewed-by: hucheng.hu Signed-off-by: lingmingqiang Reviewed-by: lingmingqiang Reviewed-by: Yang Yingliang Signed-off-by: Yang Yingliang --- drivers/crypto/hisilicon/qm.c | 30 ++++++++++++++++++++++++------ drivers/crypto/hisilicon/qm.h | 4 ++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index 785d8c02bdae..0a0851b688fc 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -519,7 +519,15 @@ static void qm_poll_qp(struct hisi_qp *qp, struct hisi_qm *qm) } } -static irqreturn_t qm_irq_thread(int irq, void *data) +static void qp_work_process(struct work_struct *work) +{ + struct hisi_qp *qp; + + qp = container_of(work, struct hisi_qp, work); + qm_poll_qp(qp, qp->qm); +} + +static irqreturn_t do_qm_irq(int irq, void *data) { struct hisi_qm *qm = data; struct qm_eqe *eqe = qm->eqe + qm->status.eq_head; @@ -529,8 +537,12 @@ static irqreturn_t qm_irq_thread(int irq, void *data) while (QM_EQE_PHASE(eqe) == qm->status.eqc_phase) { eqe_num++; qp = qm_to_hisi_qp(qm, eqe); - if (qp) - qm_poll_qp(qp, qm); + if (qp) { + if (qm->wq) + queue_work(qm->wq, &qp->work); + else + schedule_work(&qp->work); + } if (qm->status.eq_head == QM_EQ_DEPTH - 1) { qm->status.eqc_phase = !qm->status.eqc_phase; @@ -557,7 +569,7 @@ static irqreturn_t qm_irq(int irq, void *data) struct hisi_qm *qm = data; if (readl(qm->io_base + QM_VF_EQ_INT_SOURCE)) - return IRQ_WAKE_THREAD; + return do_qm_irq(irq, data); dev_err(&qm->pdev->dev, "invalid int source\n"); qm_db(qm, 0, QM_DOORBELL_CMD_EQ, qm->status.eq_head, 0); @@ -604,6 +616,11 @@ static irqreturn_t qm_abnormal_irq(int irq, void *data) struct device *dev = &qm->pdev->dev; u32 error_status, tmp; + if (qm->abnormal_fix) { + qm->abnormal_fix(qm); + return IRQ_HANDLED; + } + /* read err sts */ tmp = readl(qm->io_base + QM_ABNORMAL_INT_STATUS); error_status = qm->msi_mask & tmp; @@ -627,8 +644,8 @@ static int qm_irq_register(struct hisi_qm *qm) struct pci_dev *pdev = qm->pdev; int ret; - ret = request_threaded_irq(pci_irq_vector(pdev, QM_EQ_EVENT_IRQ_VECTOR), - qm_irq, qm_irq_thread, IRQF_SHARED, + ret = request_irq(pci_irq_vector(pdev, QM_EQ_EVENT_IRQ_VECTOR), + qm_irq, IRQF_SHARED, qm->dev_name, qm); if (ret) return ret; @@ -1172,6 +1189,7 @@ static struct hisi_qp *hisi_qm_create_qp_lockless(struct hisi_qm *qm, qp->qp_id = qp_id; qp->alg_type = alg_type; qp->c_flag = 1; + INIT_WORK(&qp->work, qp_work_process); init_completion(&qp->completion); atomic_set(&qp->qp_status.flags, QP_INIT); diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h index c805cb73e805..945275128c6c 100644 --- a/drivers/crypto/hisilicon/qm.h +++ b/drivers/crypto/hisilicon/qm.h @@ -280,6 +280,9 @@ struct hisi_qm { void *reserve; dma_addr_t reserve_dma; #endif + struct workqueue_struct *wq; + /* design for module not support aer, such as rde */ + int (*abnormal_fix)(struct hisi_qm *qm); }; struct hisi_qp_status { @@ -321,6 +324,7 @@ struct hisi_qp { u16 pasid; struct uacce_queue *uacce_q; #endif + struct work_struct work; }; int hisi_qm_init(struct hisi_qm *qm); -- GitLab