From patchwork Wed Apr 5 07:28:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrzej Hajda X-Patchwork-Id: 9663133 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B8D3D60353 for ; Wed, 5 Apr 2017 07:28:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AA5AC284D5 for ; Wed, 5 Apr 2017 07:28:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9F6E42853E; Wed, 5 Apr 2017 07:28:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1DCD0284D5 for ; Wed, 5 Apr 2017 07:28:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754002AbdDEH2z (ORCPT ); Wed, 5 Apr 2017 03:28:55 -0400 Received: from mailout1.w1.samsung.com ([210.118.77.11]:28484 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753980AbdDEH2x (ORCPT ); Wed, 5 Apr 2017 03:28:53 -0400 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0ONX008HWE3WQW20@mailout1.w1.samsung.com> for linux-samsung-soc@vger.kernel.org; Wed, 05 Apr 2017 08:28:44 +0100 (BST) Received: from eusmges3.samsung.com (unknown [203.254.199.242]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170405072843eucas1p2e4671efee3f113054d6f90684b9a5f12~yb8Y-xD_T2379823798eucas1p24; Wed, 5 Apr 2017 07:28:43 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges3.samsung.com (EUCPMTA) with SMTP id C4.A3.17464.BAC94E85; Wed, 5 Apr 2017 08:28:43 +0100 (BST) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170405072843eucas1p11a2b4418812541e0a11e93e36cfba202~yb8YYwuGZ1661016610eucas1p11; Wed, 5 Apr 2017 07:28:43 +0000 (GMT) X-AuditID: cbfec7f2-f797e6d000004438-3d-58e49cabf137 Received: from eusync3.samsung.com ( [203.254.199.213]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id D0.4F.17452.12D94E85; Wed, 5 Apr 2017 08:30:41 +0100 (BST) Received: from AMDC2768.DIGITAL.local ([106.120.43.17]) by eusync3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0ONX000HIE3TW560@eusync3.samsung.com>; Wed, 05 Apr 2017 08:28:43 +0100 (BST) From: Andrzej Hajda To: Inki Dae Cc: Andrzej Hajda , Bartlomiej Zolnierkiewicz , Marek Szyprowski , dri-devel@lists.freedesktop.org, linux-samsung-soc@vger.kernel.org Subject: [PATCH 4/9] drm/exynos/decon5433: move TE handling to DECON Date: Wed, 05 Apr 2017 09:28:32 +0200 Message-id: <1491377317-8042-5-git-send-email-a.hajda@samsung.com> X-Mailer: git-send-email 2.7.4 In-reply-to: <1491377317-8042-1-git-send-email-a.hajda@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrFIsWRmVeSWpSXmKPExsWy7djPc7qr5zyJMFj6VtXi1rpzrBYbZ6xn tbjy9T2bxaT7E1gsZpzfx2Sx9shddgc2j/vdx5k8+rasYvT4vEkugDmKyyYlNSezLLVI3y6B K+PvmpWsBc90K1ZM3MrewDhBtYuRk0NCwETi3d8dzBC2mMSFe+vZuhi5OIQEljJKLDr/hA0k ISTwmVHi82ZpmIaeozNZIIqWMUpcX3wequM/o8TlH69ZQarYBDQl/m6+CdYtIqAssWpfOztI EbPAJUaJ1ye7GbsYOTiEBVwkurd5gJgsAqoSixvdQMp5BZwkrt/8wQixTE7i5rlOsOs4BZwl zuy4DLZLQuA+m8Sy40uZQXolBGQlNh2A+sBFon1CLxOELSzx6vgWdghbRqKz4yATRG83o8Sn /hPsEM4URol/H2ZAdVtLHD5+EewBZgE+iUnbpkMt4JXoaBOCKPGQ2PhzOSuE7Sjx8fp2Jojn pzFKdH/uYJ/AKLOAkWEVo0hqaXFuemqxsV5xYm5xaV66XnJ+7iZGYIye/nf80w7GryesDjEK cDAq8fBemPE4Qog1say4MvcQowQHs5II74/pTyKEeFMSK6tSi/Lji0pzUosPMUpzsCiJ83Kd uhYhJJCeWJKanZpakFoEk2Xi4JRqYFwiOS06NHxL1T155TZenmkewZJ1Fnv5Nb10jfYoddXf /SQnnXXhp2BOR4p14f4nd1Sjrl9fGW6UoXl5qq7tDfvOzPcbal59/LaOf/9Mka1B684yixb/ VH/DN+ebu0Ck09uLVwKTd2sqBm2Iz/R9VPfa7tXeyZPfqPjaf/kTe3dj/quAuZ0VV5VYijMS DbWYi4oTAZ13sGLNAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrBLMWRmVeSWpSXmKPExsVy+t/xq7qKc59EGFztVbK4te4cq8XGGetZ La58fc9mMen+BBaLGef3MVmsPXKX3YHN4373cSaPvi2rGD0+b5ILYI5ys8lITUxJLVJIzUvO T8nMS7dVCg1x07VQUshLzE21VYrQ9Q0JUlIoS8wpBfKMDNCAg3OAe7CSvl2CW8bfNStZC57p VqyYuJW9gXGCahcjJ4eEgIlEz9GZLBC2mMSFe+vZuhi5OIQEljBKdPQuYwZJCAk0Mkk8vuoF YrMJaEr83XyTDcQWEVCWWLWvnR2kgVngCqNE+7cuIIeDQ1jARaJ7mweIySKgKrG40Q2knFfA SeL6zR+MELvkJG6e6wQbzyngLHFmx2U2iFVOEq2Nr1kmMPIuYGRYxSiSWlqcm55bbKhXnJhb XJqXrpecn7uJERiq24793LyD8dLG4EOMAhyMSjy8FdMeRwixJpYVV+YeYpTgYFYS4f0x/UmE EG9KYmVValF+fFFpTmrxIUZToJsmMkuJJucD4yivJN7QxNDc0tDI2MLC3MhISZy35MOVcCGB 9MSS1OzU1ILUIpg+Jg5OqQZGh1iBvEuJ+surVOqDmHw1HfnC+JREFqRFO9TbHG6Jb2yK/+Ed 2MKzzEVZfvkm3VCuznmvitx5lNu3yYlUTL0gWsL70GbnZo41wWllwscqTnMump4Q9X3D1gub PFjizLrTw/V/LDvgsjf5+PYdB2dbVew9eZzhft1bqwNSNcwnvrCFde27KKDEUpyRaKjFXFSc CAD2/Z9jawIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170405072843eucas1p11a2b4418812541e0a11e93e36cfba202 X-Msg-Generator: CA X-Sender-IP: 182.198.249.179 X-Local-Sender: =?UTF-8?B?QW5kcnplaiBIYWpkYRtTUlBPTC1LZXJuZWwgKFRQKRvsgrw=?= =?UTF-8?B?7ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?UTF-8?B?QW5kcnplaiBIYWpkYRtTUlBPTC1LZXJuZWwgKFRQKRtTYW1z?= =?UTF-8?B?dW5nIEVsZWN0cm9uaWNzG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Sender-Code: =?UTF-8?B?QzEwG0VIURtDMTBDRDAyQ0QwMjczOTI=?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20170405072843eucas1p11a2b4418812541e0a11e93e36cfba202 X-RootMTR: 20170405072843eucas1p11a2b4418812541e0a11e93e36cfba202 References: <1491377317-8042-1-git-send-email-a.hajda@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP DECON is the only user of TE signal, moving all TE related code to DECON driver allows to precise control of IRQ handlers. This control allows to fix race between IRQ handler and DECON disable code - now it is possible to disable DECON during IRQ handling which can result in kernel crash. Beside race fixing this change allows further code simplification. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 94 ++++++++++++++++++++------- 1 file changed, 71 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 028a657..5bdf1a0 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -63,6 +63,8 @@ struct decon_context { void __iomem *addr; struct regmap *sysreg; struct clk *clks[ARRAY_SIZE(decon_clks_name)]; + unsigned int irq; + unsigned int te_irq; unsigned long flags; unsigned long out_type; int first_win; @@ -105,6 +107,11 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc) val |= VIDINTCON0_INTFRMEN | VIDINTCON0_FRAMESEL_FP; writel(val, ctx->addr + DECON_VIDINTCON0); + + enable_irq(ctx->irq); + if (!(ctx->out_type & I80_HW_TRG)) + enable_irq(ctx->te_irq); + set_bit(BIT_IRQS_ENABLED, &ctx->flags); return 0; @@ -118,6 +125,10 @@ static void decon_disable_vblank(struct exynos_drm_crtc *crtc) if (test_bit(BIT_SUSPENDED, &ctx->flags)) return; + if (!(ctx->out_type & I80_HW_TRG)) + disable_irq_nosync(ctx->te_irq); + disable_irq_nosync(ctx->irq); + writel(0, ctx->addr + DECON_VIDINTCON0); } @@ -491,6 +502,10 @@ static void decon_disable(struct exynos_drm_crtc *crtc) struct decon_context *ctx = crtc->ctx; int i; + if (!(ctx->out_type & I80_HW_TRG)) + synchronize_irq(ctx->te_irq); + synchronize_irq(ctx->irq); + if (test_bit(BIT_SUSPENDED, &ctx->flags)) return; @@ -513,17 +528,19 @@ static void decon_disable(struct exynos_drm_crtc *crtc) set_bit(BIT_SUSPENDED, &ctx->flags); } -static void decon_te_irq_handler(struct exynos_drm_crtc *crtc) +static irqreturn_t decon_te_irq_handler(int irq, void *dev_id) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = dev_id; if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags) || (ctx->out_type & I80_HW_TRG)) - return; + return IRQ_HANDLED; if (test_and_clear_bit(BIT_WIN_UPDATED, &ctx->flags) || test_bit(BIT_IRQS_ENABLED, &ctx->flags)) decon_set_bits(ctx, DECON_TRIGCON, TRIGCON_SWTRIGCMD, ~0); + + return IRQ_HANDLED; } static void decon_clear_channels(struct exynos_drm_crtc *crtc) @@ -564,7 +581,6 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = { .update_plane = decon_update_plane, .disable_plane = decon_disable_plane, .atomic_flush = decon_atomic_flush, - .te_handler = decon_te_irq_handler, }; static int decon_bind(struct device *dev, struct device *master, void *data) @@ -717,6 +733,31 @@ static const struct of_device_id exynos5433_decon_driver_dt_match[] = { }; MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match); +static int decon_conf_irq(struct decon_context *ctx, const char *name, + irq_handler_t handler, unsigned long int flags, bool required) +{ + struct platform_device *pdev = to_platform_device(ctx->dev); + int ret, irq = platform_get_irq_byname(pdev, name); + + if (irq < 0) { + if (irq == -EPROBE_DEFER) + return irq; + if (required) + dev_err(ctx->dev, "cannot get %s IRQ\n", name); + else + irq = 0; + return irq; + } + irq_set_status_flags(irq, IRQ_NOAUTOEN); + ret = devm_request_irq(ctx->dev, irq, handler, flags, "drm_decon", ctx); + if (ret < 0) { + dev_err(ctx->dev, "IRQ %s request failed\n", name); + return ret; + } + + return irq; +} + static int exynos5433_decon_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -740,15 +781,6 @@ static int exynos5433_decon_probe(struct platform_device *pdev) ctx->out_type |= IFTYPE_I80; } - if (ctx->out_type & I80_HW_TRG) { - ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, - "samsung,disp-sysreg"); - if (IS_ERR(ctx->sysreg)) { - dev_err(dev, "failed to get system register\n"); - return PTR_ERR(ctx->sysreg); - } - } - for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) { struct clk *clk; @@ -771,18 +803,34 @@ static int exynos5433_decon_probe(struct platform_device *pdev) return PTR_ERR(ctx->addr); } - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, - (ctx->out_type & IFTYPE_I80) ? "lcd_sys" : "vsync"); - if (!res) { - dev_err(dev, "cannot find IRQ resource\n"); - return -ENXIO; + if (ctx->out_type & IFTYPE_I80) { + ret = decon_conf_irq(ctx, "lcd_sys", decon_irq_handler, 0, true); + if (ret < 0) + return ret; + ctx->irq = ret; + + ret = decon_conf_irq(ctx, "te", decon_te_irq_handler, + IRQF_TRIGGER_RISING, false); + if (ret < 0) + return ret; + if (ret) { + ctx->te_irq = ret; + ctx->out_type &= ~I80_HW_TRG; + } + } else { + ret = decon_conf_irq(ctx, "vsync", decon_irq_handler, 0, true); + if (ret < 0) + return ret; + ctx->irq = ret; } - ret = devm_request_irq(dev, res->start, decon_irq_handler, 0, - "drm_decon", ctx); - if (ret < 0) { - dev_err(dev, "lcd_sys irq request failed\n"); - return ret; + if (ctx->out_type & I80_HW_TRG) { + ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, + "samsung,disp-sysreg"); + if (IS_ERR(ctx->sysreg)) { + dev_err(dev, "failed to get system register\n"); + return PTR_ERR(ctx->sysreg); + } } platform_set_drvdata(pdev, ctx);