diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index 8f628967f389..7c5a7c6fd782 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -152,6 +153,7 @@ struct qcom_smp2p { struct regmap *ipc_regmap; int ipc_offset; int ipc_bit; + struct wakeup_source ws; struct mbox_client mbox_client; struct mbox_chan *mbox_chan; @@ -288,6 +290,14 @@ static void qcom_smp2p_notify_in(struct qcom_smp2p *smp2p) } } +static irqreturn_t qcom_smp2p_isr(int irq, void *data) +{ + struct qcom_smp2p *smp2p = data; + + __pm_stay_awake(&smp2p->ws); + return IRQ_WAKE_THREAD; +} + /** * qcom_smp2p_intr() - interrupt handler for incoming notifications * @irq: unused @@ -312,7 +322,7 @@ static irqreturn_t qcom_smp2p_intr(int irq, void *data) if (IS_ERR(in)) { dev_err(smp2p->dev, "Unable to acquire remote smp2p item\n"); - return IRQ_HANDLED; + goto out; } smp2p->in = in; @@ -331,6 +341,8 @@ static irqreturn_t qcom_smp2p_intr(int irq, void *data) qcom_smp2p_do_ssr_ack(smp2p); } +out: + __pm_relax(&smp2p->ws); return IRQ_HANDLED; } @@ -627,12 +639,13 @@ static int qcom_smp2p_probe(struct platform_device *pdev) list_add(&entry->node, &smp2p->outbound); } } + wakeup_source_init(&smp2p->ws, "smp2p"); /* Kick the outgoing edge after allocating entries */ qcom_smp2p_kick(smp2p); ret = devm_request_threaded_irq(&pdev->dev, smp2p->irq, - NULL, qcom_smp2p_intr, + qcom_smp2p_isr, qcom_smp2p_intr, IRQF_ONESHOT, "smp2p", (void *)smp2p); if (ret) {