From patchwork Thu May 5 16:13:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Murphy X-Patchwork-Id: 9025911 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id C3343BF29F for ; Thu, 5 May 2016 16:15:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DC0362038F for ; Thu, 5 May 2016 16:15:25 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EBA92201E4 for ; Thu, 5 May 2016 16:15:24 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ayLum-0004ZP-PZ; Thu, 05 May 2016 16:14:12 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ayLui-00045s-Kh for linux-arm-kernel@lists.infradead.org; Thu, 05 May 2016 16:14:09 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8D36F3A; Thu, 5 May 2016 09:13:53 -0700 (PDT) Received: from e104324-lin.cambridge.arm.com (e104324-lin.cambridge.arm.com [10.1.205.154]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 4BBAF3F252; Thu, 5 May 2016 09:13:45 -0700 (PDT) From: Robin Murphy To: airlied@linux.ie, liviu.dudau@arm.com, dri-devel@lists.freedesktop.org Subject: [PATCH 1/2] drm: hdlcd: Skip PM callbacks if unbound Date: Thu, 5 May 2016 17:13:37 +0100 Message-Id: X-Mailer: git-send-email 2.8.1.dirty X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160505_091408_711246_9A3BB64B X-CRM114-Status: GOOD ( 11.61 ) X-Spam-Score: -9.0 (---------) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-6.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Until an encoder component is available to trigger the HDLCD's component master bind callback, the drm_device we keep in drvdata isn't allocated. Since it is quite possible to, say, hibernate the system without having loaded the encoder driver, the PM callbacks need to check for a valid drm_device before trying to take the lock and suspend/resume the crtcs, otherwise this happens: [ 51.779092] Unable to handle kernel NULL pointer dereference at virtual address 00000200 [ 51.787143] pgd = ffff800974462000 [ 51.790514] [00000200] *pgd=0000000000000000 [ 51.794768] Internal error: Oops: 96000004 [#1] PREEMPT SMP [ 51.800291] Modules linked in: [ 51.803325] CPU: 4 PID: 2098 Comm: systemd-sleep Not tainted 4.6.0-rc6+ #4 [ 51.810140] Hardware name: ARM Juno development board (r1) (DT) [ 51.816008] task: ffff800974430000 ti: ffff80097380c000 task.ti: ffff80097380c000 [ 51.823433] PC is at mutex_lock+0x14/0x60 [ 51.827411] LR is at drm_modeset_lock_all+0x3c/0xe0 [ 51.832246] pc : [] lr : [] pstate: 40000145 [ 51.839577] sp : ffff80097380faf0 [ 51.842859] x29: ffff80097380faf0 x28: 0000000000000000 [ 51.848132] x27: 0000000000000002 x26: ffff000008e01000 [ 51.853405] x25: ffff0000084cc000 x24: ffff000008dcb408 [ 51.858678] x23: ffff000008e7c000 x22: ffff8009760e8870 [ 51.863962] x21: 0000000000000200 x20: 0000000000000000 [ 51.869244] x19: 0000000000000200 x18: ffff800079357dd0 [ 51.874527] x17: 0000ffff8a00ab88 x16: 0000000000000018 [ 51.879809] x15: 0000000000000018 x14: 0000000000000000 [ 51.885091] x13: 0000000000000002 x12: 0000000000000000 [ 51.890374] x11: ffff0000087ff904 x10: 0000000000000840 [ 51.895656] x9 : 0000000000000000 x8 : ffff800973821680 [ 51.900938] x7 : 0000000000000000 x6 : 000000000000003f [ 51.906220] x5 : 0000000000000040 x4 : 0000000000000000 [ 51.911502] x3 : 0000000000000004 x2 : 0000000000000000 [ 51.916784] x1 : 0000000000000001 x0 : 0000000000000200 ... [ 52.339406] [] mutex_lock+0x14/0x60 [ 52.344425] [] drm_modeset_lock_all+0x3c/0xe0 [ 52.350305] [] hdlcd_pm_suspend+0x2c/0x90 [ 52.355842] [] platform_pm_suspend+0x24/0x58 [ 52.361638] [] dpm_run_callback.isra.4+0x20/0x68 [ 52.367778] [] __device_suspend+0xe4/0x238 [ 52.373400] [] dpm_suspend+0x10c/0x240 [ 52.378679] [] dpm_suspend_start+0x70/0x80 [ 52.384302] [] suspend_devices_and_enter+0x9c/0x480 [ 52.390699] [] pm_suspend+0x1d0/0x240 [ 52.395890] [] state_store+0x80/0x100 [ 52.401084] [] kobj_attr_store+0x14/0x28 [ 52.406535] [] sysfs_kf_write+0x48/0x58 [ 52.411899] [] kernfs_fop_write+0xbc/0x188 [ 52.417521] [] __vfs_write+0x1c/0xe0 [ 52.422626] [] vfs_write+0x8c/0x1a8 [ 52.427644] [] SyS_write+0x44/0xa0 [ 52.432578] [] __sys_trace_return+0x0/0x4 [ 52.438114] Code: 910003fd f9000bf3 aa0003f3 f9800011 (885ffc01) [ 52.444229] ---[ end trace 34b87a5fb9453f65 ]--- Acked-by: Liviu Dudau Signed-off-by: Robin Murphy --- drivers/gpu/drm/arm/hdlcd_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index 734899c4e4bb..86a5eea4cf53 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -498,7 +498,7 @@ static int __maybe_unused hdlcd_pm_suspend(struct device *dev) struct drm_device *drm = dev_get_drvdata(dev); struct drm_crtc *crtc; - if (pm_runtime_suspended(dev)) + if (pm_runtime_suspended(dev) || !drm) return 0; drm_modeset_lock_all(drm); @@ -513,7 +513,7 @@ static int __maybe_unused hdlcd_pm_resume(struct device *dev) struct drm_device *drm = dev_get_drvdata(dev); struct drm_crtc *crtc; - if (!pm_runtime_suspended(dev)) + if (!pm_runtime_suspended(dev) || !drm) return 0; drm_modeset_lock_all(drm);