From c8d3578f8b76ebd2ed4793b365651ffe8093a675 Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Mon, 3 Jul 2017 12:44:59 +0800 Subject: [PATCH] pwm: pwm-qpnp: Ignore changing period setting if it's not requested It's not necessary to reprogram PWM period setting if only changing PWM duty cycle. Change-Id: I366e17a5e2f18c09ab0850d00ec08a35e0f1cb9f Signed-off-by: Fenglin Wu --- drivers/pwm/pwm-qpnp.c | 46 +++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/pwm/pwm-qpnp.c b/drivers/pwm/pwm-qpnp.c index d57bf2f3b80c..e46b1d583f40 100644 --- a/drivers/pwm/pwm-qpnp.c +++ b/drivers/pwm/pwm-qpnp.c @@ -317,6 +317,7 @@ struct _qpnp_pwm_config { struct pwm_period_config period; int supported_sizes; int force_pwm_size; + bool update_period; }; /* Public facing structure */ @@ -1209,30 +1210,34 @@ static int _pwm_config(struct qpnp_pwm_chip *chip, duty_value / NSEC_PER_USEC; qpnp_lpg_calc_pwm_value(pwm_config, period_value, duty_value); rc = qpnp_lpg_save_pwm_value(chip); - if (rc) - goto out; - rc = qpnp_lpg_configure_pwm(chip); - if (rc) - goto out; - rc = qpnp_configure_pwm_control(chip); if (rc) goto out; - if (!rc && chip->enabled) { - rc = qpnp_lpg_configure_pwm_state(chip, QPNP_PWM_ENABLE); - if (rc) { - pr_err("Error in configuring pwm state, rc=%d\n", rc); - return rc; - } + if (pwm_config->update_period) { + rc = qpnp_lpg_configure_pwm(chip); + if (rc) + goto out; + rc = qpnp_configure_pwm_control(chip); + if (rc) + goto out; + if (!rc && chip->enabled) { + rc = qpnp_lpg_configure_pwm_state(chip, + QPNP_PWM_ENABLE); + if (rc) { + pr_err("Error in configuring pwm state, rc=%d\n", + rc); + return rc; + } - /* Enable the glitch removal after PWM is enabled */ - rc = qpnp_lpg_glitch_removal(chip, true); - if (rc) { - pr_err("Error in enabling glitch control, rc=%d\n", rc); - return rc; + /* Enable the glitch removal after PWM is enabled */ + rc = qpnp_lpg_glitch_removal(chip, true); + if (rc) { + pr_err("Error in enabling glitch control, rc=%d\n", + rc); + return rc; + } } } - pr_debug("duty/period=%u/%u %s: pwm_value=%d (of %d)\n", (unsigned int)duty_value, (unsigned int)period_value, (tm_lvl == LVL_USEC) ? "usec" : "nsec", @@ -1375,12 +1380,14 @@ static int qpnp_pwm_config(struct pwm_chip *pwm_chip, spin_lock_irqsave(&chip->lpg_lock, flags); + chip->pwm_config.update_period = false; if (prev_period_us > INT_MAX / NSEC_PER_USEC || prev_period_us * NSEC_PER_USEC != period_ns) { qpnp_lpg_calc_period(LVL_NSEC, period_ns, chip); qpnp_lpg_save_period(chip); pwm->period = period_ns; chip->pwm_config.pwm_period = period_ns / NSEC_PER_USEC; + chip->pwm_config.update_period = true; } rc = _pwm_config(chip, LVL_NSEC, duty_ns, period_ns); @@ -1619,6 +1626,7 @@ int pwm_config_us(struct pwm_device *pwm, int duty_us, int period_us) spin_lock_irqsave(&chip->lpg_lock, flags); + chip->pwm_config.update_period = false; if (chip->pwm_config.pwm_period != period_us) { qpnp_lpg_calc_period(LVL_USEC, period_us, chip); qpnp_lpg_save_period(chip); @@ -1628,6 +1636,7 @@ int pwm_config_us(struct pwm_device *pwm, int duty_us, int period_us) pwm->period = 0; else pwm->period = (unsigned int)period_us * NSEC_PER_USEC; + chip->pwm_config.update_period = true; } rc = _pwm_config(chip, LVL_USEC, duty_us, period_us); @@ -1734,6 +1743,7 @@ static int qpnp_parse_pwm_dt_config(struct device_node *of_pwm_node, qpnp_lpg_calc_period(LVL_USEC, period, chip); qpnp_lpg_save_period(chip); chip->pwm_config.pwm_period = period; + chip->pwm_config.update_period = true; rc = _pwm_config(chip, LVL_USEC, chip->pwm_config.pwm_duty, period);