mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									61180f68ad
								
							
						
					
					
						commit
						0f02f491b7
					
				
					 1 changed files with 5 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -41,7 +41,7 @@
 | 
			
		|||
 | 
			
		||||
struct pwm_sifive_ddata {
 | 
			
		||||
	struct pwm_chip	chip;
 | 
			
		||||
	struct mutex lock; /* lock to protect user_count */
 | 
			
		||||
	struct mutex lock; /* lock to protect user_count and approx_period */
 | 
			
		||||
	struct notifier_block notifier;
 | 
			
		||||
	struct clk *clk;
 | 
			
		||||
	void __iomem *regs;
 | 
			
		||||
| 
						 | 
				
			
			@ -76,6 +76,7 @@ static void pwm_sifive_free(struct pwm_chip *chip, struct pwm_device *pwm)
 | 
			
		|||
	mutex_unlock(&ddata->lock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Called holding ddata->lock */
 | 
			
		||||
static void pwm_sifive_update_clock(struct pwm_sifive_ddata *ddata,
 | 
			
		||||
				    unsigned long rate)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -144,7 +145,6 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 | 
			
		|||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&ddata->lock);
 | 
			
		||||
	cur_state = pwm->state;
 | 
			
		||||
	enabled = cur_state.enabled;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -163,14 +163,17 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 | 
			
		|||
	/* The hardware cannot generate a 100% duty cycle */
 | 
			
		||||
	frac = min(frac, (1U << PWM_SIFIVE_CMPWIDTH) - 1);
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&ddata->lock);
 | 
			
		||||
	if (state->period != ddata->approx_period) {
 | 
			
		||||
		if (ddata->user_count != 1) {
 | 
			
		||||
			mutex_unlock(&ddata->lock);
 | 
			
		||||
			ret = -EBUSY;
 | 
			
		||||
			goto exit;
 | 
			
		||||
		}
 | 
			
		||||
		ddata->approx_period = state->period;
 | 
			
		||||
		pwm_sifive_update_clock(ddata, clk_get_rate(ddata->clk));
 | 
			
		||||
	}
 | 
			
		||||
	mutex_unlock(&ddata->lock);
 | 
			
		||||
 | 
			
		||||
	writel(frac, ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -185,7 +188,6 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 | 
			
		|||
 | 
			
		||||
exit:
 | 
			
		||||
	clk_disable(ddata->clk);
 | 
			
		||||
	mutex_unlock(&ddata->lock);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue