Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp581676ybt; Fri, 19 Jun 2020 08:38:56 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwIpePFaNEn4bM4k99ViqGGhVAaXuhsEV3zeHLsUuyoA8y7jsp/LH6XKIPAjKoFOHY/DKNE X-Received: by 2002:a05:6402:1bde:: with SMTP id ch30mr4024917edb.163.1592581136289; Fri, 19 Jun 2020 08:38:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1592581136; cv=none; d=google.com; s=arc-20160816; b=FNMKOPL956IKWax1sdgQA5A4tX1FcXdKnMaUV4krafdovfXH/UfrnlNBoQVZ3+BlJJ v/p0P1tn17oDa4x+srZGz5DMug7QDxDhFZlPfXKXYCuGa9k6lBEuUrvVQz7UXZaFGbf1 2QPQ+GPy1uLiEd4A5JLkq55avIebPP1/rLOf/zYhMyk0QoVHWBUo61zvndfgI7tqfc/Y novDUPNZGwbc25kIFjZ6aK0BDTa+ukgkehnxZxuq/CdM4uoajHbuWHavAWeabA2lg63p S0v2nx0q/t2xni9qRs3PP7Unctcc4lbjtD/XKjmdBhrt5c4e+wdUr52tKMIE3+sw5s0G iSYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=RzOeGnU5w7hOSKy8OZ484xhrDqamGMYMmafZ9tdhmRY=; b=BKWENJv72huIYsix23BBifkBYdcsS9Cko0btMKum/FGAmCHZcUbNAJoCAejUtcVdJD Kd4SONXoibQH7MlRwzfyPXCN9hpCJ/5TDMWTjtWqm68R3YKY18xmJ8zIt5lrIIPRdBRm vKGqqKb1hrIrvmqlaDyW3L1D/7hFvepm6P2MZM9Odup3kPua5WAzQAOrGNx8KwBoqqIN JvC+ZDbRjp9Au4Q0Ih9g4i2Pv90VhHhCqiAQ2sePEZSeFd1EjVdZ/jP9nnLqmX+bJFIH YBQhupkOJGu/9YzjWAnOtcyjlAz4/R6KbMFw83/Q1lzdTaBKPG3UKWF4HH8EKQaxo134 GNxQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=An3xlAUc; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r16si4250057eds.6.2020.06.19.08.38.34; Fri, 19 Jun 2020 08:38:56 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=An3xlAUc; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2393973AbgFSPd4 (ORCPT + 99 others); Fri, 19 Jun 2020 11:33:56 -0400 Received: from mail.kernel.org ([198.145.29.99]:37050 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2404895AbgFSPdD (ORCPT ); Fri, 19 Jun 2020 11:33:03 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id A984B2166E; Fri, 19 Jun 2020 15:33:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1592580782; bh=thQfZr/q8RAdyDUbyWCNv25/gg/BpfzE787BTka3u6c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=An3xlAUc7TfD/GJVt6wTHmoNH2wkRHeSgIKerGjpFXsS0TWMJlIbgtW4E9bJQ0hf9 YRfCChW2PEcQdSbn9e0pCG0rKskRPWx0EF+doKaFz39fwhJcMAuu5PaPS9eCCYq+04 oOO0n26YgoHFHh/vMtvibrN88GZDzFq1iRGzbCRo= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Hans de Goede , Andy Shevchenko , Thierry Reding Subject: [PATCH 5.7 350/376] pwm: lpss: Fix get_state runtime-pm reference handling Date: Fri, 19 Jun 2020 16:34:28 +0200 Message-Id: <20200619141726.893185565@linuxfoundation.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200619141710.350494719@linuxfoundation.org> References: <20200619141710.350494719@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Hans de Goede commit 01aa905d4791da7d3630f6030ff99d58105cca00 upstream. Before commit cfc4c189bc70 ("pwm: Read initial hardware state at request time"), a driver's get_state callback would get called once per PWM from pwmchip_add(). pwm-lpss' runtime-pm code was relying on this, getting a runtime-pm ref for PWMs which are enabled at probe time from within its get_state callback, before enabling runtime-pm. The change to calling get_state at request time causes a number of problems: 1. PWMs enabled at probe time may get runtime suspended before they are requested, causing e.g. a LCD backlight controlled by the PWM to turn off. 2. When the request happens when the PWM has been runtime suspended, the ctrl register will read all 1 / 0xffffffff, causing get_state to store bogus values in the pwm_state. 3. get_state was using an async pm_runtime_get() call, because it assumed that runtime-pm has not been enabled yet. If shortly after the request an apply call is made, then the pwm_lpss_is_updating() check may trigger because the resume triggered by the pm_runtime_get() call is not complete yet, so the ctrl register still reads all 1 / 0xffffffff. This commit fixes these issues by moving the initial pm_runtime_get() call for PWMs which are enabled at probe time to the pwm_lpss_probe() function; and by making get_state take a runtime-pm ref before reading the ctrl reg. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1828927 Fixes: cfc4c189bc70 ("pwm: Read initial hardware state at request time") Cc: stable@vger.kernel.org Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko Signed-off-by: Thierry Reding Signed-off-by: Greg Kroah-Hartman --- drivers/pwm/pwm-lpss.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) --- a/drivers/pwm/pwm-lpss.c +++ b/drivers/pwm/pwm-lpss.c @@ -158,7 +158,6 @@ static int pwm_lpss_apply(struct pwm_chi return 0; } -/* This function gets called once from pwmchip_add to get the initial state */ static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state) { @@ -167,6 +166,8 @@ static void pwm_lpss_get_state(struct pw unsigned long long base_unit, freq, on_time_div; u32 ctrl; + pm_runtime_get_sync(chip->dev); + base_unit_range = BIT(lpwm->info->base_unit_bits); ctrl = pwm_lpss_read(pwm); @@ -187,8 +188,7 @@ static void pwm_lpss_get_state(struct pw state->polarity = PWM_POLARITY_NORMAL; state->enabled = !!(ctrl & PWM_ENABLE); - if (state->enabled) - pm_runtime_get(chip->dev); + pm_runtime_put(chip->dev); } static const struct pwm_ops pwm_lpss_ops = { @@ -202,7 +202,8 @@ struct pwm_lpss_chip *pwm_lpss_probe(str { struct pwm_lpss_chip *lpwm; unsigned long c; - int ret; + int i, ret; + u32 ctrl; if (WARN_ON(info->npwm > MAX_PWMS)) return ERR_PTR(-ENODEV); @@ -232,6 +233,12 @@ struct pwm_lpss_chip *pwm_lpss_probe(str return ERR_PTR(ret); } + for (i = 0; i < lpwm->info->npwm; i++) { + ctrl = pwm_lpss_read(&lpwm->chip.pwms[i]); + if (ctrl & PWM_ENABLE) + pm_runtime_get(dev); + } + return lpwm; } EXPORT_SYMBOL_GPL(pwm_lpss_probe);