Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp221040imm; Thu, 26 Jul 2018 02:16:57 -0700 (PDT) X-Google-Smtp-Source: AAOMgpecClkUoyqhUqfnJuhGnskI9F1oHlFkuFL2hsUVBnaIPA15BCH/MB3CP9JxMx9MlU2TDxbC X-Received: by 2002:aa7:87d0:: with SMTP id i16-v6mr1305025pfo.82.1532596617194; Thu, 26 Jul 2018 02:16:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532596617; cv=none; d=google.com; s=arc-20160816; b=TnoOBeqWcF6KrUZy+lNOZVSCfGGn0LCqMJGsREv1eyQ1OGk+Ae7qKewAK0bX8x3sDq j9t2zcNuksze/9QJ5y4cZ7Cf4YOAs1xvhL/Iw3XKZ8RPxzj/72mFKseHS214vG+Z9wWo YTWDU2pUhDfscD8vLQfLy4FE/F4e4rtVG4NUMzx/Uct7mD+Lm4Aqkw0VMoj+FCMu79td DP6LzFYkRmRiwRG3lbw1sWNfKW3YC17uY1Wvr4pV2qs5qXKekWwbyHt7bxe/0XrrlJjc 3FC80x6doQ/xeEt52fjO8pfO96IP8x1zSUMMkR+SojyYakrDCOP952PfhpSjNdQHN278 jWOg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=AtnQWCq5Hh1SGPJ6/ie2Xnr7LJx4oLO6zZqw7CgsiIA=; b=PoPBQC0+7p8ut61KDc/2ckqI88MCondO+Hlcga8cy8cBrKzx3Ye2j84DKAgv6yt4fs pXDe+4Oiuyrv08LpqDGngCCR28I1OXMTltJthf1yDSP8sUzelQ0dBrhw/GEl6CyDwJoQ +1nzKyQYTRUqmS1idg/M9kSXh0c2ByKD6CKOmAQ5tZzshh8rKWy663Uvs++uyOfYYZ4w lsQu4iJdxmsSIk4Fx46EV7o0NiYnFvQ7I3y52CCaNZTmsm/3KmN2mHhUQ/K/wbSeTTV8 BgZ1PCAb+J6sn3tD3qCNO1M3DNSAOPlb4+IrwWR5IbY6N0Tvg3VQEKudn9jhiwd3lVxX j0lw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q9-v6si862440pgc.685.2018.07.26.02.16.42; Thu, 26 Jul 2018 02:16:57 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729152AbeGZKbn (ORCPT + 99 others); Thu, 26 Jul 2018 06:31:43 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:39884 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727799AbeGZKbm (ORCPT ); Thu, 26 Jul 2018 06:31:42 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: eballetbo) with ESMTPSA id 4171726048B From: Enric Balletbo i Serra To: linux-kernel@vger.kernel.org Cc: kernel@collabora.com, cl@rock-chips.com, linux-pwm@vger.kernel.org, linux-fbdev@vger.kernel.org, Daniel Thompson , Thierry Reding , Bartlomiej Zolnierkiewicz , dri-devel@lists.freedesktop.org, Jingoo Han , Lee Jones Subject: [PATCH] backlight: pwm_bl: switch to using "atomic" PWM API Date: Thu, 26 Jul 2018 11:15:34 +0200 Message-Id: <20180726091534.27521-1-enric.balletbo@collabora.com> X-Mailer: git-send-email 2.18.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The "atomic" API allows us to configure PWM period and duty_cycle and enable it in one call. The patch also moves the pwm_init_state just before any use of the pwm_state struct, this fixes a potential bug where pwm_get_state can be called before pwm_init_state. Signed-off-by: Enric Balletbo i Serra --- drivers/video/backlight/pwm_bl.c | 48 ++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index bdfcc0a71db1..2c734d55d607 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -46,7 +46,8 @@ struct pwm_bl_data { void (*exit)(struct device *); }; -static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness) +static void pwm_backlight_power_on(struct pwm_bl_data *pb, + struct pwm_state *state) { int err; @@ -57,7 +58,8 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness) if (err < 0) dev_err(pb->dev, "failed to enable power supply\n"); - pwm_enable(pb->pwm); + state->enabled = true; + pwm_apply_state(pb->pwm, state); if (pb->post_pwm_on_delay) msleep(pb->post_pwm_on_delay); @@ -70,6 +72,8 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness) static void pwm_backlight_power_off(struct pwm_bl_data *pb) { + struct pwm_state state; + if (!pb->enabled) return; @@ -79,8 +83,11 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb) if (pb->pwm_off_delay) msleep(pb->pwm_off_delay); - pwm_config(pb->pwm, 0, pb->period); - pwm_disable(pb->pwm); + pwm_get_state(pb->pwm, &state); + state.enabled = false; + state.period = pb->period; + state.duty_cycle = 0; + pwm_apply_state(pb->pwm, &state); regulator_disable(pb->power_supply); pb->enabled = false; @@ -106,6 +113,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl) { struct pwm_bl_data *pb = bl_get_data(bl); int brightness = bl->props.brightness; + struct pwm_state state; int duty_cycle; if (bl->props.power != FB_BLANK_UNBLANK || @@ -118,8 +126,13 @@ static int pwm_backlight_update_status(struct backlight_device *bl) if (brightness > 0) { duty_cycle = compute_duty_cycle(pb, brightness); - pwm_config(pb->pwm, duty_cycle, pb->period); - pwm_backlight_power_on(pb, brightness); + pwm_get_state(pb->pwm, &state); + state.duty_cycle = duty_cycle; + state.period = pb->period; + if (!state.enabled) + pwm_backlight_power_on(pb, &state); + else + pwm_apply_state(pb->pwm, &state); } else pwm_backlight_power_off(pb); @@ -447,7 +460,6 @@ static int pwm_backlight_probe(struct platform_device *pdev) struct device_node *node = pdev->dev.of_node; struct pwm_bl_data *pb; struct pwm_state state; - struct pwm_args pargs; unsigned int i; int ret; @@ -539,10 +551,17 @@ static int pwm_backlight_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "got pwm for backlight\n"); - if (!data->levels) { - /* Get the PWM period (in nanoseconds) */ - pwm_get_state(pb->pwm, &state); + /* Sync up PWM state and ensure it is off. */ + pwm_init_state(pb->pwm, &state); + state.enabled = false; + ret = pwm_apply_state(pb->pwm, &state); + if (ret) { + dev_err(&pdev->dev, "failed to apply initial PWM state: %d\n", + ret); + goto err_alloc; + } + if (!data->levels) { ret = pwm_backlight_brightness_default(&pdev->dev, data, state.period); if (ret < 0) { @@ -559,20 +578,13 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->levels = data->levels; } - /* - * FIXME: pwm_apply_args() should be removed when switching to - * the atomic PWM API. - */ - pwm_apply_args(pb->pwm); - /* * The DT case will set the pwm_period_ns field to 0 and store the * period, parsed from the DT, in the PWM device. For the non-DT case, * set the period from platform data if it has not already been set * via the PWM lookup table. */ - pwm_get_args(pb->pwm, &pargs); - pb->period = pargs.period; + pb->period = state.period; if (!pb->period && (data->pwm_period_ns > 0)) pb->period = data->pwm_period_ns; -- 2.18.0