From patchwork Tue Dec 15 19:03:16 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jyri Sarha X-Patchwork-Id: 58453 Delivered-To: patch@linaro.org Received: by 10.112.89.199 with SMTP id bq7csp233582lbb; Tue, 15 Dec 2015 11:04:01 -0800 (PST) X-Received: by 10.98.73.70 with SMTP id w67mr40167917pfa.106.1450206238024; Tue, 15 Dec 2015 11:03:58 -0800 (PST) Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTP id 82si3413670pfq.220.2015.12.15.11.03.57; Tue, 15 Dec 2015 11:03:57 -0800 (PST) Received-SPF: pass (google.com: domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; spf=pass (google.com: domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DB0B86E77F; Tue, 15 Dec 2015 11:03:56 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from bear.ext.ti.com (bear.ext.ti.com [192.94.94.41]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6B48F6E77E for ; Tue, 15 Dec 2015 11:03:54 -0800 (PST) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id tBFJ3prC026670; Tue, 15 Dec 2015 13:03:51 -0600 Received: from DFLE73.ent.ti.com (dfle73.ent.ti.com [128.247.5.110]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id tBFJ3ol1013891; Tue, 15 Dec 2015 13:03:50 -0600 Received: from dlep32.itg.ti.com (157.170.170.100) by DFLE73.ent.ti.com (128.247.5.110) with Microsoft SMTP Server id 14.3.224.2; Tue, 15 Dec 2015 13:03:50 -0600 Received: from imryr.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id tBFJ3bav015462; Tue, 15 Dec 2015 13:03:49 -0600 From: Jyri Sarha To: Subject: [PATCH 05/12] drm/tilcdc: fix kernel panic on suspend when no hdmi monitor connected Date: Tue, 15 Dec 2015 21:03:16 +0200 Message-ID: <71aa891d161b3bbbdc084d84334f619fbca1ba6a.1450202735.git.jsarha@ti.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: References: MIME-Version: 1.0 Cc: Jyri Sarha , Darren Etheridge , tomi.valkeinen@ti.com, laurent.pinchart@ideasonboard.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Darren Etheridge On BeagleBone Black if no HDMI monitor is connected and suspend is requested a kernel panic will result: root@am335x-evm:~# echo mem > /sys/power/state [ 65.548710] PM: Syncing filesystems ... done. [ 65.631311] Freezing user space processes ... (elapsed 0.006 seconds) done. [ 65.648619] Freezing remaining freezable tasks ... (elapsed 0.005 seconds) done. [ 65.833500] Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa30e004 [ 65.841692] Internal error: : 1028 [#1] SMP ARM [ 66.105287] [] (platform_pm_suspend) from [] (dpm_run_callback+0x34/0x70) [ 66.114370] [] (dpm_run_callback) from [] (__device_suspend+0x10c/0x2f4) [ 66.123357] [] (__device_suspend) from [] (dpm_suspend+0x58/0x218) [ 66.131796] [] (dpm_suspend) from [] (suspend_devices_and_enter+0x9c/0x3c0) [ 66.141055] [] (suspend_devices_and_enter) from [] (pm_suspend+0x210/0x24c) [ 66.150312] [] (pm_suspend) from [] (state_store+0x68/0xb8) [ 66.158103] [] (state_store) from [] (kobj_attr_store+0x14/0x20) [ 66.166355] [] (kobj_attr_store) from [] (sysfs_kf_write+0x4c/0x50) [ 66.174883] [] (sysfs_kf_write) from [] (kernfs_fop_write+0xb4/0x150) [ 66.183598] [] (kernfs_fop_write) from [] (vfs_write+0xa8/0x180) [ 66.191846] [] (vfs_write) from [] (SyS_write+0x40/0x8c) [ 66.199365] [] (SyS_write) from [] (ret_fast_syscall+0x0/0x48) [ 66.207426] Code: e595c210 e5932000 e59cc000 e08c2002 (e592c000) This is because the lcdc module is not enabled when no monitor is detected to save power. However the suspend handler just blindly tries to save the lcdc state by copying out the pertinent registers. However module is off so no good things happen when you try and access it. This patch only saves off the registers if the module is enabled, and then only restores the registers on resume if they were saved off during suspend. Signed-off-by: Darren Etheridge Tested-by: Dave Gerlach Acked-by: Felipe Balbi Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 23 +++++++++++++++++------ drivers/gpu/drm/tilcdc/tilcdc_drv.h | 1 + 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 146399a..083b8d4 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -597,13 +597,20 @@ static int tilcdc_pm_suspend(struct device *dev) drm_kms_helper_poll_disable(ddev); + /* Select sleep pin state */ + pinctrl_pm_select_sleep_state(dev); + + if (pm_runtime_suspended(dev)) { + priv->ctx_valid = false; + return 0; + } + /* Save register state: */ for (i = 0; i < ARRAY_SIZE(registers); i++) if (registers[i].save && (priv->rev >= registers[i].rev)) priv->saved_register[n++] = tilcdc_read(ddev, registers[i].reg); - /* Select sleep pin state */ - pinctrl_pm_select_sleep_state(dev); + priv->ctx_valid = true; return 0; } @@ -617,10 +624,14 @@ static int tilcdc_pm_resume(struct device *dev) /* Select default pin state */ pinctrl_pm_select_default_state(dev); - /* Restore register state: */ - for (i = 0; i < ARRAY_SIZE(registers); i++) - if (registers[i].save && (priv->rev >= registers[i].rev)) - tilcdc_write(ddev, registers[i].reg, priv->saved_register[n++]); + if (priv->ctx_valid == true) { + /* Restore register state: */ + for (i = 0; i < ARRAY_SIZE(registers); i++) + if (registers[i].save && + (priv->rev >= registers[i].rev)) + tilcdc_write(ddev, registers[i].reg, + priv->saved_register[n++]); + } drm_kms_helper_poll_enable(ddev); diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h index c00f518..7d214cc 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h @@ -67,6 +67,7 @@ struct tilcdc_drm_private { /* register contents saved across suspend/resume: */ u32 saved_register[12]; + bool ctx_valid; #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition;