Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

pwm: sifive: Reduce time the controller lock is held

The lock is only to serialize access and update to user_count and
approx_period between different PWMs served by the same pwm_chip.
So the lock needs only to be taken during the check if the (chip global)
period can and/or needs to be changed.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Tested-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>

authored by

Uwe Kleine-König and committed by
Thierry Reding
0f02f491 61180f68

+5 -3
+5 -3
drivers/pwm/pwm-sifive.c
··· 41 41 42 42 struct pwm_sifive_ddata { 43 43 struct pwm_chip chip; 44 - struct mutex lock; /* lock to protect user_count */ 44 + struct mutex lock; /* lock to protect user_count and approx_period */ 45 45 struct notifier_block notifier; 46 46 struct clk *clk; 47 47 void __iomem *regs; ··· 76 76 mutex_unlock(&ddata->lock); 77 77 } 78 78 79 + /* Called holding ddata->lock */ 79 80 static void pwm_sifive_update_clock(struct pwm_sifive_ddata *ddata, 80 81 unsigned long rate) 81 82 { ··· 145 144 return ret; 146 145 } 147 146 148 - mutex_lock(&ddata->lock); 149 147 cur_state = pwm->state; 150 148 enabled = cur_state.enabled; 151 149 ··· 163 163 /* The hardware cannot generate a 100% duty cycle */ 164 164 frac = min(frac, (1U << PWM_SIFIVE_CMPWIDTH) - 1); 165 165 166 + mutex_lock(&ddata->lock); 166 167 if (state->period != ddata->approx_period) { 167 168 if (ddata->user_count != 1) { 169 + mutex_unlock(&ddata->lock); 168 170 ret = -EBUSY; 169 171 goto exit; 170 172 } 171 173 ddata->approx_period = state->period; 172 174 pwm_sifive_update_clock(ddata, clk_get_rate(ddata->clk)); 173 175 } 176 + mutex_unlock(&ddata->lock); 174 177 175 178 writel(frac, ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm)); 176 179 ··· 188 185 189 186 exit: 190 187 clk_disable(ddata->clk); 191 - mutex_unlock(&ddata->lock); 192 188 return ret; 193 189 } 194 190