From patchwork Sat May 7 01:00:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 570508 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE420C433F5 for ; Sat, 7 May 2022 01:00:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1445138AbiEGBEL (ORCPT ); Fri, 6 May 2022 21:04:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59986 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229608AbiEGBEJ (ORCPT ); Fri, 6 May 2022 21:04:09 -0400 Received: from mail-lj1-x234.google.com (mail-lj1-x234.google.com [IPv6:2a00:1450:4864:20::234]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E07E1108B for ; Fri, 6 May 2022 18:00:23 -0700 (PDT) Received: by mail-lj1-x234.google.com with SMTP id b32so2805484ljf.1 for ; Fri, 06 May 2022 18:00:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=ngE+uUnpqy2X2QZyw0O6g/YBVbGSsViwtHRZu1XP7Rs=; b=dRUHF+cfD4Kh9YCPJ3EsR7wpGimq6v4bQNCilccjoLHvMjZskCZ77sMHXlSDx8d8cO Eyqz1SP4cw7X188B74wzoodvZAxjMvDPV4mpkR3J6Ud49dyRkAw4kK3Dj+QMzEaqVKxa +ThCFLQPzCp1n8pwBiAo19KqfwXoLq8Hy4n8C1/9e0Hh1e/obqEFWkelygZUxm8ZYvbB vDNFXid+5tvHL8sOoMtODyI4oedbd76UIqAp/Zg1I4sWtzERIR2QtLkuUhARNk8a22xJ kBlgCNOnXqBQWSnI7NUJjFJ5Jksp4RT6yvI7rzkiNULsDD8vxRrO11KmwlLxGtT55RXV lOTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=ngE+uUnpqy2X2QZyw0O6g/YBVbGSsViwtHRZu1XP7Rs=; b=n8yBrqLcu4GsSQEEBpdHm6KbP+RcEdCQ52BIPIKmXDNd9jR0WBzp4ckyS9OIL8/4LS GVWbGoVOfkJeHaxJNF5Dy4Qz5mvdvikQVhO9qqe4X/WeLH+XZpLEAjqX4WD8PlcSKEZe pIotSz6RDppDNczcs0dfugfSTsRXTbemvmeX7h6z0bo8HfiQLoXvthIDBu8lzTCnVQGN EgIMShbkWIyPdXILDjbT4mhkSBianP18e0o/lL/qE9msCKjqouZ9Ze76QyLih4vaDkAt wjdNUikb2fVtB9E+BFNHz/eXvzqCBPCKGsuljjT8Qi0VDrhfgI6BKQ0NvPrdZSGR/rew spJg== X-Gm-Message-State: AOAM531T9ILn94wHoaTueSI8J4s2Pb7rlHRguCxoZ4BF6KBuw/n4kOJ9 z6nWLB+m90ZDQYIV8w1gJxZV6w== X-Google-Smtp-Source: ABdhPJyEvKFiZd44iWvem/eGq6cHHgZ5jCFhY9a8X60ksb1eQZ0q44v0MLzDcTKphsaYDN4jnosWnw== X-Received: by 2002:a2e:9d5a:0:b0:24f:763:fc47 with SMTP id y26-20020a2e9d5a000000b0024f0763fc47mr3536697ljj.384.1651885222228; Fri, 06 May 2022 18:00:22 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id g15-20020a056512118f00b0047255d2110csm882907lfr.59.2022.05.06.18.00.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 May 2022 18:00:21 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar Cc: Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Subject: [PATCH 1/2] drm/msm: don't free the IRQ if it was not requested Date: Sat, 7 May 2022 04:00:20 +0300 Message-Id: <20220507010021.1667700-1-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org As msm_drm_uninit() is called from the msm_drm_init() error path, additional care should be necessary as not to call the free_irq() for the IRQ that was not requested before (because an error occured earlier than the request_irq() call). This fixed the issue reported with the following backtrace: [ 8.571329] Trying to free already-free IRQ 187 [ 8.571339] WARNING: CPU: 0 PID: 76 at kernel/irq/manage.c:1895 free_irq+0x1e0/0x35c [ 8.588746] Modules linked in: pmic_glink pdr_interface fastrpc qrtr_smd snd_soc_hdmi_codec msm fsa4480 gpu_sched drm_dp_aux_bus qrtr i2c_qcom_geni crct10dif_ce qcom_stats qcom_q6v5_pas drm_display_helper gpi qcom_pil_info drm_kms_helper qcom_q6v5 qcom_sysmon qcom_common qcom_glink_smem qcom_rng mdt_loader qmi_helpers phy_qcom_qmp ufs_qcom typec qnoc_sm8350 socinfo rmtfs_mem fuse drm ipv6 [ 8.624154] CPU: 0 PID: 76 Comm: kworker/u16:2 Not tainted 5.18.0-rc5-next-20220506-00033-g6cee8cab6089-dirty #419 [ 8.624161] Hardware name: Qualcomm Technologies, Inc. SM8350 HDK (DT) [ 8.641496] Workqueue: events_unbound deferred_probe_work_func [ 8.647510] pstate: 604000c5 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 8.654681] pc : free_irq+0x1e0/0x35c [ 8.658454] lr : free_irq+0x1e0/0x35c [ 8.662228] sp : ffff800008ab3950 [ 8.665642] x29: ffff800008ab3950 x28: 0000000000000000 x27: ffff16350f56a700 [ 8.672994] x26: ffff1635025df080 x25: ffff16350251badc x24: ffff16350251bb90 [ 8.680343] x23: 0000000000000000 x22: 00000000000000bb x21: ffff16350e8f9800 [ 8.687690] x20: ffff16350251ba00 x19: ffff16350cbd5880 x18: ffffffffffffffff [ 8.695039] x17: 0000000000000000 x16: ffffa2dd12179434 x15: ffffa2dd1431d02d [ 8.702391] x14: 0000000000000000 x13: ffffa2dd1431d028 x12: 662d79646165726c [ 8.709740] x11: ffffa2dd13fd2438 x10: 000000000000000a x9 : 00000000000000bb [ 8.717111] x8 : ffffa2dd13fd23f0 x7 : ffff800008ab3750 x6 : 00000000fffff202 [ 8.724487] x5 : ffff16377e870a18 x4 : 00000000fffff202 x3 : ffff735a6ae1b000 [ 8.731851] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff1635015f8000 [ 8.739217] Call trace: [ 8.741755] free_irq+0x1e0/0x35c [ 8.745198] msm_drm_uninit.isra.0+0x14c/0x294 [msm] [ 8.750548] msm_drm_bind+0x28c/0x5d0 [msm] [ 8.755081] try_to_bring_up_aggregate_device+0x164/0x1d0 [ 8.760657] __component_add+0xa0/0x170 [ 8.764626] component_add+0x14/0x20 [ 8.768337] dp_display_probe+0x2a4/0x464 [msm] [ 8.773242] platform_probe+0x68/0xe0 [ 8.777043] really_probe.part.0+0x9c/0x28c [ 8.781368] __driver_probe_device+0x98/0x144 [ 8.785871] driver_probe_device+0x40/0x140 [ 8.790191] __device_attach_driver+0xb4/0x120 [ 8.794788] bus_for_each_drv+0x78/0xd0 [ 8.798751] __device_attach+0xdc/0x184 [ 8.802713] device_initial_probe+0x14/0x20 [ 8.807031] bus_probe_device+0x9c/0xa4 [ 8.810991] deferred_probe_work_func+0x88/0xc0 [ 8.815667] process_one_work+0x1d0/0x320 [ 8.819809] worker_thread+0x14c/0x444 [ 8.823688] kthread+0x10c/0x110 [ 8.827036] ret_from_fork+0x10/0x20 Reported-by: Bjorn Andersson Fixes: f026e431cf86 ("drm/msm: Convert to Linux IRQ interfaces") Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Reviewed-by: Stephen Boyd --- drivers/gpu/drm/msm/msm_drv.c | 7 ++++++- drivers/gpu/drm/msm/msm_kms.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 4a3dda23e3e0..44485363f37a 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -113,6 +113,8 @@ static int msm_irq_postinstall(struct drm_device *dev) static int msm_irq_install(struct drm_device *dev, unsigned int irq) { + struct msm_drm_private *priv = dev->dev_private; + struct msm_kms *kms = priv->kms; int ret; if (irq == IRQ_NOTCONNECTED) @@ -124,6 +126,8 @@ static int msm_irq_install(struct drm_device *dev, unsigned int irq) if (ret) return ret; + kms->irq_requested = true; + ret = msm_irq_postinstall(dev); if (ret) { free_irq(irq, dev); @@ -139,7 +143,8 @@ static void msm_irq_uninstall(struct drm_device *dev) struct msm_kms *kms = priv->kms; kms->funcs->irq_uninstall(kms); - free_irq(kms->irq, dev); + if (kms->irq_requested) + free_irq(kms->irq, dev); } struct msm_vblank_work { diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index ab25fff271f9..f8ed7588928c 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -148,6 +148,7 @@ struct msm_kms { /* irq number to be passed on to msm_irq_install */ int irq; + bool irq_requested; /* mapper-id used to request GEM buffer mapped for scanout: */ struct msm_gem_address_space *aspace; From patchwork Sat May 7 01:00:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 570763 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 455C5C4332F for ; Sat, 7 May 2022 01:00:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229608AbiEGBEM (ORCPT ); Fri, 6 May 2022 21:04:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60014 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1445135AbiEGBEK (ORCPT ); Fri, 6 May 2022 21:04:10 -0400 Received: from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com [IPv6:2a00:1450:4864:20::12a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F22CA115D for ; Fri, 6 May 2022 18:00:24 -0700 (PDT) Received: by mail-lf1-x12a.google.com with SMTP id p10so15136609lfa.12 for ; Fri, 06 May 2022 18:00:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=4Xjc3Hv9IBU6m3GG1D4xZiH521v6YGheJpIE5cEUwCc=; b=GDWtw3xVkiQsPE896Dksj7FISU8ExonameA1uJYu9hhAgeu1/IaT3rar1Rv1+YMVRL CKx+Y0qwXML3jZETvMkah8JzHZzPsuCYjtY1Uvl0YNKbgVaV3vd4D1F/YwttixV357rp FhnM2rzUKgUvgQ0NbizsU1gAW+JR8mxx/8YjC+51pG7tY9HcbnmJILeiJbm18diG7O/Y akZ4cTWg0YnSt1wa+d6fZBlsFJ4qT9pibtcf6Rp04NYgHzctnEVW0xwaUBaW4ijgBDmn WH9Xtzoj+o0eLkpgZh9unm9atOh68rL6U8cms7xGuEsjWeYP8IF3IjbY6k5it5sE+AOL 1VCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4Xjc3Hv9IBU6m3GG1D4xZiH521v6YGheJpIE5cEUwCc=; b=gRpFeH19+EU2Oe9KVyYLSCCcBrIWjf46cC+/z37YIxVC/agkLvov7N5UlVf0/EmMgV VWIFod4kOwTs78+XkSUwPi9yMo/W6Hd7CBUN+CmglNUq98QkhKQEzUYjB1bAuCAps8g5 2+xE+9vPbNiqnWSG87rXmxF+aDKbr45q/qRJ+Y767dn+1RXvQA86ZfmnGcZCyBhBQG1K O6LsnEkd4wCUq/aSGhbU6C3eCoz1uCgRG53D70DA2k8k2vCrR2LivLfs6nTOxggkPBQG QQbBFCXkvVTHjEN6sMTL/JvIfeho7N03qV5CcihJKxJi8vR7O8QQEceKdqMhBK0XTidV Ll0Q== X-Gm-Message-State: AOAM5303vDhiTcRA5DqDXZjqbIX1S2C1AOHoYLXEdOKvXjrJczm60iVW JQuXOVvRzqt3FU0Xj8zKkpuAIg== X-Google-Smtp-Source: ABdhPJwMs9XNRlJ0IKsyFD7+8w243rXrvj/NOkWs1o4eVYx7Gxnkmbq7t0Xu7JYhoz70MI01S4nXaQ== X-Received: by 2002:a05:6512:c01:b0:448:6aec:65c5 with SMTP id z1-20020a0565120c0100b004486aec65c5mr4405142lfu.193.1651885223281; Fri, 06 May 2022 18:00:23 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id g15-20020a056512118f00b0047255d2110csm882907lfr.59.2022.05.06.18.00.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 May 2022 18:00:22 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar Cc: Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Subject: [PATCH 2/2] drm/msm: push IRQ setup into individual drivers Date: Sat, 7 May 2022 04:00:21 +0300 Message-Id: <20220507010021.1667700-2-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220507010021.1667700-1-dmitry.baryshkov@linaro.org> References: <20220507010021.1667700-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Afther the commit f026e431cf86 ("drm/msm: Convert to Linux IRQ interfaces") converted MSM DRM driver to handle IRQs on it's own (rather than using the DRM IRQ mid-layer), there is little point in keeping irq wrapper in the msm_drv.c which just call into individual drivers. Push respective code into the mdp4/mdp5/dpu drivers and drop irq_preinstall/irq_postinstall/irq msm_kms funcs. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h | 13 +--- .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 28 ++++++++- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 6 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 7 +++ drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c | 30 ++++++++- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 4 +- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h | 4 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c | 30 ++++++++- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 4 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h | 4 +- drivers/gpu/drm/msm/msm_drv.c | 62 +++---------------- drivers/gpu/drm/msm/msm_kms.h | 4 +- 12 files changed, 105 insertions(+), 91 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h index b5b6e7031fb9..c6938b1f1870 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h @@ -8,13 +8,6 @@ #include "dpu_kms.h" #include "dpu_hw_interrupts.h" -/** - * dpu_core_irq_preinstall - perform pre-installation of core IRQ handler - * @kms: MSM KMS handle - * @return: none - */ -void dpu_core_irq_preinstall(struct msm_kms *kms); - /** * dpu_core_irq_uninstall - uninstall core IRQ handler * @kms: MSM KMS handle @@ -23,11 +16,11 @@ void dpu_core_irq_preinstall(struct msm_kms *kms); void dpu_core_irq_uninstall(struct msm_kms *kms); /** - * dpu_core_irq - core IRQ handler + * dpu_core_irq_install - install core IRQ handler * @kms: MSM KMS handle - * @return: interrupt handling status + * @return: non-zero in case of an error */ -irqreturn_t dpu_core_irq(struct msm_kms *kms); +int dpu_core_irq_install(struct msm_kms *kms); /** * dpu_core_irq_read - IRQ helper function for reading IRQ status diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c index d6498e45dc2c..fa4f99034a08 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c @@ -164,8 +164,9 @@ static void dpu_core_irq_callback_handler(struct dpu_kms *dpu_kms, int irq_idx) dpu_kms->hw_intr->irq_tbl[irq_idx].cb(dpu_kms->hw_intr->irq_tbl[irq_idx].arg, irq_idx); } -irqreturn_t dpu_core_irq(struct msm_kms *kms) +static irqreturn_t dpu_irq(int irq, void *arg) { + struct msm_kms *kms = arg; struct dpu_kms *dpu_kms = to_dpu_kms(kms); struct dpu_hw_intr *intr = dpu_kms->hw_intr; int reg_idx; @@ -541,7 +542,7 @@ void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms, } #endif -void dpu_core_irq_preinstall(struct msm_kms *kms) +static void dpu_core_irq_preinstall(struct msm_kms *kms) { struct dpu_kms *dpu_kms = to_dpu_kms(kms); int i; @@ -570,5 +571,28 @@ void dpu_core_irq_uninstall(struct msm_kms *kms) dpu_clear_irqs(dpu_kms); dpu_disable_all_irqs(dpu_kms); + if (kms->irq_requested) + free_irq(kms->irq, kms); pm_runtime_put_sync(&dpu_kms->pdev->dev); } + +int dpu_core_irq_install(struct msm_kms *kms) +{ + int ret; + + dpu_core_irq_preinstall(kms); + + ret = request_irq(kms->irq, dpu_irq, 0, "dpu", kms); + if (ret) + return ret; + + kms->irq_requested = true; + + ret = dpu_irq_postinstall(kms); + if (ret) { + free_irq(kms->irq, kms); + return ret; + } + + return 0; +} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 2b9d931474e0..494978da7785 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -884,7 +884,7 @@ static void dpu_kms_destroy(struct msm_kms *kms) pm_runtime_disable(&dpu_kms->pdev->dev); } -static int dpu_irq_postinstall(struct msm_kms *kms) +int dpu_irq_postinstall(struct msm_kms *kms) { struct msm_drm_private *priv; struct dpu_kms *dpu_kms = to_dpu_kms(kms); @@ -960,10 +960,8 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_k static const struct msm_kms_funcs kms_funcs = { .hw_init = dpu_kms_hw_init, - .irq_preinstall = dpu_core_irq_preinstall, - .irq_postinstall = dpu_irq_postinstall, + .irq_install = dpu_core_irq_install, .irq_uninstall = dpu_core_irq_uninstall, - .irq = dpu_core_irq, .enable_commit = dpu_kms_enable_commit, .disable_commit = dpu_kms_disable_commit, .vsync_time = dpu_kms_vsync_time, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 832a0769f2e7..559184c64045 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -204,4 +204,11 @@ void dpu_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); */ u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name); +/** + * dpu_irq_postinstall - perform post-installation of core IRQ handler + * @kms: MSM KMS handle + * @return: non-zero in case of error + */ +int dpu_irq_postinstall(struct msm_kms *kms); + #endif /* __dpu_kms_H__ */ diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c index 4d49f3ba6a96..87675c162eea 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c @@ -32,7 +32,7 @@ static void mdp4_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus) } } -void mdp4_irq_preinstall(struct msm_kms *kms) +static void mdp4_irq_preinstall(struct msm_kms *kms) { struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); mdp4_enable(mdp4_kms); @@ -41,7 +41,7 @@ void mdp4_irq_preinstall(struct msm_kms *kms) mdp4_disable(mdp4_kms); } -int mdp4_irq_postinstall(struct msm_kms *kms) +static int mdp4_irq_postinstall(struct msm_kms *kms) { struct mdp_kms *mdp_kms = to_mdp_kms(kms); struct mdp4_kms *mdp4_kms = to_mdp4_kms(mdp_kms); @@ -62,10 +62,13 @@ void mdp4_irq_uninstall(struct msm_kms *kms) mdp4_enable(mdp4_kms); mdp4_write(mdp4_kms, REG_MDP4_INTR_ENABLE, 0x00000000); mdp4_disable(mdp4_kms); + if (kms->irq_requested) + free_irq(kms->irq, kms); } -irqreturn_t mdp4_irq(struct msm_kms *kms) +static irqreturn_t mdp4_irq(int irq, void *arg) { + struct msm_kms *kms = arg; struct mdp_kms *mdp_kms = to_mdp_kms(kms); struct mdp4_kms *mdp4_kms = to_mdp4_kms(mdp_kms); struct drm_device *dev = mdp4_kms->dev; @@ -88,6 +91,27 @@ irqreturn_t mdp4_irq(struct msm_kms *kms) return IRQ_HANDLED; } +int mdp4_irq_install(struct msm_kms *kms) +{ + int ret; + + mdp4_irq_preinstall(kms); + + ret = request_irq(kms->irq, mdp4_irq, 0, "mdp4", kms); + if (ret) + return ret; + + kms->irq_requested = true; + + ret = mdp4_irq_postinstall(kms); + if (ret) { + free_irq(kms->irq, kms); + return ret; + } + + return 0; +} + int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) { struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index fb48c8c19ec3..b7aced272af9 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -148,10 +148,8 @@ static void mdp4_destroy(struct msm_kms *kms) static const struct mdp_kms_funcs kms_funcs = { .base = { .hw_init = mdp4_hw_init, - .irq_preinstall = mdp4_irq_preinstall, - .irq_postinstall = mdp4_irq_postinstall, + .irq_install = mdp4_irq_install, .irq_uninstall = mdp4_irq_uninstall, - .irq = mdp4_irq, .enable_vblank = mdp4_enable_vblank, .disable_vblank = mdp4_disable_vblank, .enable_commit = mdp4_enable_commit, diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h index e8ee92ab7956..b24a63872232 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h @@ -157,10 +157,8 @@ int mdp4_enable(struct mdp4_kms *mdp4_kms); void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask, uint32_t old_irqmask); -void mdp4_irq_preinstall(struct msm_kms *kms); -int mdp4_irq_postinstall(struct msm_kms *kms); +int mdp4_irq_install(struct msm_kms *kms); void mdp4_irq_uninstall(struct msm_kms *kms); -irqreturn_t mdp4_irq(struct msm_kms *kms); int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c index 9b4c8d92ff32..d573ff29d5a4 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c @@ -36,7 +36,7 @@ static void mdp5_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus) } } -void mdp5_irq_preinstall(struct msm_kms *kms) +static void mdp5_irq_preinstall(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); struct device *dev = &mdp5_kms->pdev->dev; @@ -47,7 +47,7 @@ void mdp5_irq_preinstall(struct msm_kms *kms) pm_runtime_put_sync(dev); } -int mdp5_irq_postinstall(struct msm_kms *kms) +static int mdp5_irq_postinstall(struct msm_kms *kms) { struct mdp_kms *mdp_kms = to_mdp_kms(kms); struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms); @@ -74,11 +74,14 @@ void mdp5_irq_uninstall(struct msm_kms *kms) pm_runtime_get_sync(dev); mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000); + if (kms->irq_requested) + free_irq(kms->irq, kms); pm_runtime_put_sync(dev); } -irqreturn_t mdp5_irq(struct msm_kms *kms) +static irqreturn_t mdp5_irq(int irq, void *arg) { + struct msm_kms *kms = arg; struct mdp_kms *mdp_kms = to_mdp_kms(kms); struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms); struct drm_device *dev = mdp5_kms->dev; @@ -101,6 +104,27 @@ irqreturn_t mdp5_irq(struct msm_kms *kms) return IRQ_HANDLED; } +int mdp5_irq_install(struct msm_kms *kms) +{ + int ret; + + mdp5_irq_preinstall(kms); + + ret = request_irq(kms->irq, mdp5_irq, 0, "mdp5", kms); + if (ret) + return ret; + + kms->irq_requested = true; + + ret = mdp5_irq_postinstall(kms); + if (ret) { + free_irq(kms->irq, kms); + return ret; + } + + return 0; +} + int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 3d5621a68f85..18cf0ff4da6c 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -262,10 +262,8 @@ static int mdp5_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor) static const struct mdp_kms_funcs kms_funcs = { .base = { .hw_init = mdp5_hw_init, - .irq_preinstall = mdp5_irq_preinstall, - .irq_postinstall = mdp5_irq_postinstall, + .irq_install = mdp5_irq_install, .irq_uninstall = mdp5_irq_uninstall, - .irq = mdp5_irq, .enable_vblank = mdp5_enable_vblank, .disable_vblank = mdp5_disable_vblank, .flush_commit = mdp5_flush_commit, diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h index 29bf11f08601..630b5f812f24 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h @@ -263,10 +263,8 @@ static inline uint32_t lm2ppdone(struct mdp5_hw_mixer *mixer) void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask, uint32_t old_irqmask); -void mdp5_irq_preinstall(struct msm_kms *kms); -int mdp5_irq_postinstall(struct msm_kms *kms); +int mdp5_irq_install(struct msm_kms *kms); void mdp5_irq_uninstall(struct msm_kms *kms); -irqreturn_t mdp5_irq(struct msm_kms *kms); int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); int mdp5_irq_domain_init(struct mdp5_kms *mdp5_kms); diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 44485363f37a..d2fbe54fec4d 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -77,64 +77,15 @@ static bool modeset = true; MODULE_PARM_DESC(modeset, "Use kernel modesetting [KMS] (1=on (default), 0=disable)"); module_param(modeset, bool, 0600); -static irqreturn_t msm_irq(int irq, void *arg) -{ - struct drm_device *dev = arg; - struct msm_drm_private *priv = dev->dev_private; - struct msm_kms *kms = priv->kms; - - BUG_ON(!kms); - - return kms->funcs->irq(kms); -} - -static void msm_irq_preinstall(struct drm_device *dev) -{ - struct msm_drm_private *priv = dev->dev_private; - struct msm_kms *kms = priv->kms; - - BUG_ON(!kms); - - kms->funcs->irq_preinstall(kms); -} - -static int msm_irq_postinstall(struct drm_device *dev) -{ - struct msm_drm_private *priv = dev->dev_private; - struct msm_kms *kms = priv->kms; - - BUG_ON(!kms); - - if (kms->funcs->irq_postinstall) - return kms->funcs->irq_postinstall(kms); - - return 0; -} - static int msm_irq_install(struct drm_device *dev, unsigned int irq) { struct msm_drm_private *priv = dev->dev_private; struct msm_kms *kms = priv->kms; - int ret; - - if (irq == IRQ_NOTCONNECTED) - return -ENOTCONN; - - msm_irq_preinstall(dev); - - ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev); - if (ret) - return ret; - - kms->irq_requested = true; - ret = msm_irq_postinstall(dev); - if (ret) { - free_irq(irq, dev); - return ret; - } + if (!kms->funcs->irq_install) + return -EINVAL; - return 0; + return kms->funcs->irq_install(kms); } static void msm_irq_uninstall(struct drm_device *dev) @@ -143,8 +94,6 @@ static void msm_irq_uninstall(struct drm_device *dev) struct msm_kms *kms = priv->kms; kms->funcs->irq_uninstall(kms); - if (kms->irq_requested) - free_irq(kms->irq, dev); } struct msm_vblank_work { @@ -450,6 +399,11 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) } if (kms) { + if (kms->irq == IRQ_NOTCONNECTED) { + ret = -ENOTCONN; + goto err_msm_uninit; + } + pm_runtime_get_sync(dev); ret = msm_irq_install(ddev, kms->irq); pm_runtime_put_sync(dev); diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index f8ed7588928c..71d497a8fb8b 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -24,10 +24,8 @@ struct msm_kms_funcs { /* hw initialization: */ int (*hw_init)(struct msm_kms *kms); /* irq handling: */ - void (*irq_preinstall)(struct msm_kms *kms); - int (*irq_postinstall)(struct msm_kms *kms); + int (*irq_install)(struct msm_kms *kms); void (*irq_uninstall)(struct msm_kms *kms); - irqreturn_t (*irq)(struct msm_kms *kms); int (*enable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc); void (*disable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc);