From patchwork Wed Aug 10 21:24:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 9274195 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 114616022E for ; Wed, 10 Aug 2016 21:24:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F25B828306 for ; Wed, 10 Aug 2016 21:24:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E7284283E9; Wed, 10 Aug 2016 21:24:52 +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=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id 967ED28306 for ; Wed, 10 Aug 2016 21:24:52 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bXazc-0000iv-7Z; Wed, 10 Aug 2016 21:24:52 +0000 Received: from mail-qk0-x236.google.com ([2607:f8b0:400d:c09::236]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1bXazX-0000dA-Cf for linux-rockchip@lists.infradead.org; Wed, 10 Aug 2016 21:24:48 +0000 Received: by mail-qk0-x236.google.com with SMTP id l2so56861103qkf.3 for ; Wed, 10 Aug 2016 14:24:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Xc0DWyS2LDUWnDT/xCvOy98YtU1jV8vXmIWipfduMRs=; b=aAh0S7XChL5ICuey5dwP7K4pSKoq613zaFtbGBkYQIwI2xb88JqR9TeDJqnca5nQHe RB/iV9vuDwB0zLfdgkfoqxzQNHYrAlt7pn5MPc5h1uE6xBAneTh2mbIPWvO6EeUBa8eP loJIYb/IV7bfZel63BTW6y0C439uJChL7oYj4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Xc0DWyS2LDUWnDT/xCvOy98YtU1jV8vXmIWipfduMRs=; b=MqZANaCPS8tr2Zb9ADA4Qm50u6WwOILn/U61sQcfKSDseRBcLa1sU7zojD/EywC/LQ O+7Sm3RmFjmbjwPUxnOnAwCuKjRZPPRo4dfvmX2JcuMrCAhTiqYg27wdYP/PgR1yysSr etNgsOoLI7yPn7ipAd9czibWapy+6y6AiO/KRZrti/PHJyg9fG6ahJc5nZJdiFazyxvg HzGcrb0I7nsOcJDC6vIVDKrlAUQ+gyi9qUPfiHWf+UdXjYKRnbEdQN8vrrO30oHYoveE yzp5SXTzdrrJfFSSztJSgOUPLlBnCbiKSMJ7RKqcQ1ZplBChQu8rckY3zmODmqELmD/T XScg== X-Gm-Message-State: AEkoouuAV8Rt0K1g5z8YiWs0fr6NtqtiM83X4iVsCAjC9WVEmFxPbicxiqtDm0cGGMsNoVqy X-Received: by 10.55.103.145 with SMTP id b139mr6940839qkc.15.1470864266299; Wed, 10 Aug 2016 14:24:26 -0700 (PDT) Received: from boxwood.roam.corp.google.com (cpe-75-189-128-87.nc.res.rr.com. [75.189.128.87]) by smtp.gmail.com with ESMTPSA id l32sm24452678qta.23.2016.08.10.14.24.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 10 Aug 2016 14:24:25 -0700 (PDT) From: Sean Paul To: mark.yao@rock-chips.com, dri-devel@lists.freedesktop.org, ykk@rock-chips.com Subject: [PATCH 2/6] drm/rockchip: Change state_mutex to spinlock Date: Wed, 10 Aug 2016 17:24:15 -0400 Message-Id: <1470864258-22680-3-git-send-email-seanpaul@chromium.org> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 In-Reply-To: <1470864258-22680-1-git-send-email-seanpaul@chromium.org> References: <1470864258-22680-1-git-send-email-seanpaul@chromium.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160810_142447_531201_8E4B28BC X-CRM114-Status: GOOD ( 15.11 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: marcheu@chromium.org, Sean Paul , dianders@chromium.org, linux-rockchip@lists.infradead.org MIME-Version: 1.0 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP So we can change the state while holding another spinlock (such as vblank_lock). Also add some locking around the flush function to ensure there are no races. Signed-off-by: Sean Paul --- drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 54 +++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c index 6a51851..1fe271b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c @@ -29,7 +29,7 @@ enum psr_state { struct psr_drv { struct list_head list; enum psr_state state; - struct mutex state_mutex; + spinlock_t lock; struct timer_list flush_timer; @@ -55,16 +55,33 @@ out: return psr; } -static void psr_set_state(struct psr_drv *psr, enum psr_state state) +static void psr_set_state_locked(struct psr_drv *psr, enum psr_state state) { - mutex_lock(&psr->state_mutex); + /* + * Allowed finite state machine: + * + * PSR_ENABLE < = = = = = > PSR_FLUSH + * | ^ | + * | | | + * v | | + * PSR_DISABLE < - - - - - - - - - + */ + + /* Forbid no state change */ + if (state == psr->state) + return; - if (psr->state == state) { - mutex_unlock(&psr->state_mutex); + /* Forbid DISABLE change to FLUSH */ + if (state == PSR_FLUSH && psr->state == PSR_DISABLE) return; - } psr->state = state; + + /* Allow but no need hardware change, just need assign the state */ + if (state == PSR_DISABLE && psr->state == PSR_FLUSH) + return; + + /* Refact to hardware state change */ switch (state) { case PSR_ENABLE: psr->set(psr->encoder, true); @@ -74,19 +91,30 @@ static void psr_set_state(struct psr_drv *psr, enum psr_state state) case PSR_FLUSH: psr->set(psr->encoder, false); break; - }; + } +} - mutex_unlock(&psr->state_mutex); +static void psr_set_state(struct psr_drv *psr, enum psr_state state) +{ + unsigned long flags; + + spin_lock_irqsave(&psr->lock, flags); + psr_set_state_locked(psr, state); + spin_unlock_irqrestore(&psr->lock, flags); } static void psr_flush_handler(unsigned long data) { struct psr_drv *psr = (struct psr_drv *)data; + unsigned long flags; - if (!psr || psr->state != PSR_FLUSH) + if (!psr) return; - psr_set_state(psr, PSR_ENABLE); + spin_lock_irqsave(&psr->lock, flags); + if (psr->state == PSR_FLUSH) + psr_set_state_locked(psr, PSR_ENABLE); + spin_unlock_irqrestore(&psr->lock, flags); } /** @@ -147,9 +175,6 @@ void rockchip_drm_psr_flush(struct drm_device *dev) spin_lock_irqsave(&drm_drv->psr_list_lock, flags); list_for_each_entry(psr, &drm_drv->psr_list, list) { - if (psr->state == PSR_DISABLE) - continue; - mod_timer(&psr->flush_timer, round_jiffies_up(jiffies + PSR_FLUSH_TIMEOUT)); @@ -182,8 +207,7 @@ int rockchip_drm_psr_register(struct drm_encoder *encoder, return -ENOMEM; setup_timer(&psr->flush_timer, psr_flush_handler, (unsigned long)psr); - - mutex_init(&psr->state_mutex); + spin_lock_init(&psr->lock); psr->state = PSR_DISABLE; psr->encoder = encoder;