mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 02:36:02 +00:00
pwm: Three fixes for the pwm-stm32 driver
The first patch prevents an integer wrap-around for small periods. In the second patch the calculation of the prescaler is fixed which resulted in values for the ARR register that don't fit into the corresponding register bit field. The last commit improves an error message that was wrongly copied from another error path. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEP4GsaTp6HlmJrf7Tj4D7WH0S/k4FAmZ24fcACgkQj4D7WH0S /k5qRQf+O/ecsqX8Pd/axIKpdl7JXWlyNbt8AroSLOBUW2BieqtDVMb6sdxJwOyl xt2EvQtvBe0bfRJyBCQteRoY2CkWEzPZDtpx3B4dqTzavFv3jNTtss/Pg4m+O3w/ pXH3SPtly40+cnwliMoq36warNT0Gv3qSNCeS6sGBGVuheTRxklNZKsEnTgNYVpp qz2JyiPLTEymQv0fgVvU4bp94oZXhlRMjAcT7T6S6bC1up0dbV1GY1KgdSOEKodI Wh2AhugiaA6oorHtuTNUGRZ1A2k8fKnHe88MldZXIxt3dWGNh6l2Ut6JSvwQvBMj 4Rxx7NzbnhuRXsTqDKfFs2m8TPhTyQ== =xmrq -----END PGP SIGNATURE----- Merge tag 'pwm/for-6.10-rc5-fixes-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux Pull pwm fixes from Uwe Kleine-König: "Three fixes for the pwm-stm32 driver. The first patch prevents an integer wrap-around for small periods. In the second patch the calculation of the prescaler is fixed which resulted in values for the ARR register that don't fit into the corresponding register bit field. The last commit improves an error message that was wrongly copied from another error path" * tag 'pwm/for-6.10-rc5-fixes-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux: pwm: stm32: Fix error message to not describe the previous error path pwm: stm32: Fix calculation of prescaler pwm: stm32: Refuse too small period requests
This commit is contained in:
commit
1f5c537182
@ -321,22 +321,30 @@ static int stm32_pwm_config(struct stm32_pwm *priv, unsigned int ch,
|
||||
* First we need to find the minimal value for prescaler such that
|
||||
*
|
||||
* period_ns * clkrate
|
||||
* ------------------------------
|
||||
* ------------------------------ < max_arr + 1
|
||||
* NSEC_PER_SEC * (prescaler + 1)
|
||||
*
|
||||
* isn't bigger than max_arr.
|
||||
* This equation is equivalent to
|
||||
*
|
||||
* period_ns * clkrate
|
||||
* ---------------------------- < prescaler + 1
|
||||
* NSEC_PER_SEC * (max_arr + 1)
|
||||
*
|
||||
* Using integer division and knowing that the right hand side is
|
||||
* integer, this is further equivalent to
|
||||
*
|
||||
* (period_ns * clkrate) // (NSEC_PER_SEC * (max_arr + 1)) ≤ prescaler
|
||||
*/
|
||||
|
||||
prescaler = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk),
|
||||
(u64)NSEC_PER_SEC * priv->max_arr);
|
||||
if (prescaler > 0)
|
||||
prescaler -= 1;
|
||||
|
||||
(u64)NSEC_PER_SEC * ((u64)priv->max_arr + 1));
|
||||
if (prescaler > MAX_TIM_PSC)
|
||||
return -EINVAL;
|
||||
|
||||
prd = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk),
|
||||
(u64)NSEC_PER_SEC * (prescaler + 1));
|
||||
if (!prd)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* All channels share the same prescaler and counter so when two
|
||||
@ -673,7 +681,8 @@ static int stm32_pwm_probe(struct platform_device *pdev)
|
||||
* .apply() won't overflow.
|
||||
*/
|
||||
if (clk_get_rate(priv->clk) > 1000000000)
|
||||
return dev_err_probe(dev, -EINVAL, "Failed to lock clock\n");
|
||||
return dev_err_probe(dev, -EINVAL, "Clock freq too high (%lu)\n",
|
||||
clk_get_rate(priv->clk));
|
||||
|
||||
chip->ops = &stm32pwm_ops;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user