From patchwork Mon Mar 13 15:33:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 738230 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3vhhjQ4ts1z9s1h for ; Tue, 14 Mar 2017 02:33:46 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751703AbdCMPdj (ORCPT ); Mon, 13 Mar 2017 11:33:39 -0400 Received: from mx1.redhat.com ([209.132.183.28]:60464 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752452AbdCMPdh (ORCPT ); Mon, 13 Mar 2017 11:33:37 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 46BAB21915; Mon, 13 Mar 2017 15:33:37 +0000 (UTC) Received: from shalem.localdomain.com (ovpn-116-138.ams2.redhat.com [10.36.116.138]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v2DFXZdW021242; Mon, 13 Mar 2017 11:33:36 -0400 From: Hans de Goede To: Thierry Reding , Andy Shevchenko Cc: Hans de Goede , linux-pwm@vger.kernel.org, Ilkka Koskinen Subject: [PATCH v2] pwm: lpss: Set enable-bit before waiting for update-bit to go low Date: Mon, 13 Mar 2017 16:33:34 +0100 Message-Id: <20170313153334.6200-1-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Mon, 13 Mar 2017 15:33:37 +0000 (UTC) Sender: linux-pwm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org At least on cherrytrail, the update bit will never go low when the enabled bit is not set. This causes the backlight on my cube iwork8 air tablet to never turn on again after being turned off because in the pwm_lpss_apply enable path pwm_lpss_update will fail causing an error exit and the enable-bit to never get set. Any following pwm_lpss_apply calls will fail the pwm_lpss_is_updating check. Since the docs say that the update bit should be set before the enable-bit, split pwm_lpss_update into setting the update-bit and pwm_lpss_wait_for_update, and move the pwm_lpss_wait_for_update call in the enable path to after setting the enable-bit. Fixes: 10d56a4 ("pwm: lpss: Avoid reconfiguring while UPDATE bit...") Cc: Ilkka Koskinen Signed-off-by: Hans de Goede --- Changes in v2: -This is a new approach to fixing the problem, replacing "pwm: lpss: Do not set / wait_for update_bit when not enabled" --- drivers/pwm/pwm-lpss.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c index a7c0b4b..d89b0c3 100644 --- a/drivers/pwm/pwm-lpss.c +++ b/drivers/pwm/pwm-lpss.c @@ -57,7 +57,7 @@ static inline void pwm_lpss_write(const struct pwm_device *pwm, u32 value) writel(value, lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM); } -static int pwm_lpss_update(struct pwm_device *pwm) +static int pwm_lpss_wait_for_update(struct pwm_device *pwm) { struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip); const void __iomem *addr = lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM; @@ -65,8 +65,6 @@ static int pwm_lpss_update(struct pwm_device *pwm) u32 val; int err; - pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE); - /* * PWM Configuration register has SW_UPDATE bit that is set when a new * configuration is written to the register. The bit is automatically @@ -137,18 +135,20 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm, return ret; } pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period); - ret = pwm_lpss_update(pwm); + pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE); + pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE); + ret = pwm_lpss_wait_for_update(pwm); if (ret) { pm_runtime_put(chip->dev); return ret; } - pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE); } else { ret = pwm_lpss_is_updating(pwm); if (ret) return ret; pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period); - return pwm_lpss_update(pwm); + pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE); + return pwm_lpss_wait_for_update(pwm); } } else if (pwm_is_enabled(pwm)) { pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE);