diff options
author | Leo Chen <yinchiuan@google.com> | 2022-08-29 07:42:24 +0000 |
---|---|---|
committer | TreeHugger Robot <treehugger-gerrit@google.com> | 2022-10-25 08:37:50 +0000 |
commit | a813fadefd619fd1f516740fb61e90bfb7f2d1e8 (patch) | |
tree | 3840a59e981759939ff6c46798d853d6b3c1af32 /samsung/exynos_drm_dsim.c | |
parent | 79f4fa9e58933af5055484f25fc07b88aa7aadef (diff) | |
download | display-a813fadefd619fd1f516740fb61e90bfb7f2d1e8.tar.gz |
drm: samsung: error flag pin detection
Enable the err_fg irq in bridge_enable and disable in bridge_disable.
Bug: 198991985
test: enable err_fg
Signed-off-by: linpeter <linpeter@google.com>
Signed-off-by: Leo Chen <yinchiuan@google.com>
(Cherry picked from commit 35be5639d5467393dee729a555c28bb2a689f744)
Change-Id: If83807cd129bb91a8aee462f3596adb2949c3633
Diffstat (limited to 'samsung/exynos_drm_dsim.c')
-rw-r--r-- | samsung/exynos_drm_dsim.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/samsung/exynos_drm_dsim.c b/samsung/exynos_drm_dsim.c index 894bcaf..2bfdce1 100644 --- a/samsung/exynos_drm_dsim.c +++ b/samsung/exynos_drm_dsim.c @@ -1415,6 +1415,10 @@ static int dsim_parse_dt(struct dsim_device *dsim) } } + dsim->err_fg_gpio = of_get_named_gpio(np, "errfg-gpio", 0); + if (dsim->err_fg_gpio < 0) + dsim_debug(dsim, "failed to get ERR_FG gpio\n"); + return 0; } @@ -1601,6 +1605,75 @@ static int dsim_register_irq(struct dsim_device *dsim) return 0; } +static irqreturn_t dsim_err_fg_irq_handler(int irq, void *dev_id) +{ + struct dsim_device *dsim = dev_id; + struct decon_device *decon; + int recovering; + + dsim_debug(dsim, "%s +\n", __func__); + + decon = (struct decon_device *)dsim_get_decon(dsim); + if (!decon) { + dsim_warn(dsim, "%s: decon is NULL\n", __func__); + goto end_err_fg_handler; + } + + if (decon->state != DECON_STATE_ON && decon->state != DECON_STATE_HIBERNATION) { + dsim_debug(dsim, "%s: decon state is %d\n", __func__, decon->state); + goto end_err_fg_handler; + } + + recovering = atomic_read(&decon->recovery.recovering); + dsim_warn(dsim, "error flag detected (decon%d), try to recover (recovering=%d)", + decon->id, recovering); + + decon_force_vblank_event(decon); + if (!recovering) + decon_trigger_recovery(decon); + +end_err_fg_handler: + dsim_debug(dsim, "%s -\n", __func__); + + return IRQ_HANDLED; +} + +static int dsim_register_err_fg_irq(struct dsim_device *dsim) +{ + struct device *dev = dsim->dev; + struct platform_device *pdev; + int ret, irq; + + pdev = container_of(dev, struct platform_device, dev); + dsim->irq_err_fg = -1; + + if (dsim->err_fg_gpio < 0) { + /* If the project doesn't specify the errfg-gpio, just return here */ + dsim_debug(dsim, "No dedicated ERR_FG for dsim, skip irq registration\n"); + return 0; + } + + ret = gpio_to_irq(dsim->err_fg_gpio); + if (ret < 0) { + dsim_err(dsim, "Failed to get irq number for err_fg_gpio: %d\n", ret); + return ret; + } + + irq = ret; + irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); + ret = devm_request_irq(dsim->dev, irq, dsim_err_fg_irq_handler, IRQF_TRIGGER_RISING, + pdev->name, dsim); + if (ret) { + dsim_err(dsim, "Request err_fg irq number(%d) failed: %d\n", irq, ret); + return ret; + } + disable_irq(irq); + dsim->irq_err_fg = irq; + dsim_info(dsim, "Request err_fg irq number(%d) okay\n", irq); + + return ret; +} + static int dsim_get_phys(struct dsim_device *dsim) { if (IS_ENABLED(CONFIG_BOARD_EMULATOR)) @@ -1633,6 +1706,8 @@ static int dsim_init_resources(struct dsim_device *dsim) if (ret) goto err; + dsim_register_err_fg_irq(dsim); + ret = dsim_get_phys(dsim); if (ret) goto err; |