mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
dpll: zl3073x: do not offer 0 Hz as a supported pin frequency
zl3073x_pin_props_get() always adds the current pin frequency to the supported list without checking it. A sub-Hz frequency reads back as 0 Hz, so 0 Hz can then be requested and the output frequency set callback divides by zero. A 0 Hz entry in the firmware node is not rejected either: it is offered for an input pin, and for an output pin zl3073x_pin_check_freq() divides by it at probe time. Do not add a 0 Hz current frequency and reject 0 Hz in zl3073x_pin_check_freq(). If the list ends up empty, do not publish it at all, as the DPLL core rejects an empty non-NULL list. Found by code inspection, not triggered at runtime. Fixes:85a9aaac4a("dpll: zl3073x: Include current frequency in supported frequencies list") Reviewed-by: Petr Oros <poros@redhat.com> Signed-off-by: Ivan Vecera <ivecera@redhat.com> Fixes:a99a9f0ebd("dpll: zl3073x: Read DPLL types and pin properties from system firmware") Link: https://patch.msgid.link/20261011061211.448373-2-ivecera@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
f42d67a504
commit
23171065fb
|
|
@ -30,7 +30,7 @@ static bool
|
|||
zl3073x_pin_check_freq(struct zl3073x_dev *zldev, enum dpll_pin_direction dir,
|
||||
u8 id, u64 freq)
|
||||
{
|
||||
if (freq > U32_MAX)
|
||||
if (!freq || freq > U32_MAX)
|
||||
goto err_inv_freq;
|
||||
|
||||
if (dir == DPLL_PIN_DIRECTION_INPUT) {
|
||||
|
|
@ -295,13 +295,20 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev,
|
|||
goto err_alloc_ranges;
|
||||
}
|
||||
|
||||
/* Start with current frequency at index 0 */
|
||||
ranges[0] = (struct dpll_pin_frequency)DPLL_PIN_FREQUENCY(curr_freq);
|
||||
/* Start with current frequency at index 0. A sub-Hz frequency is
|
||||
* read back as 0 Hz and cannot be set, so it is not offered.
|
||||
*/
|
||||
j = 0;
|
||||
if (curr_freq) {
|
||||
struct dpll_pin_frequency freq = DPLL_PIN_FREQUENCY(curr_freq);
|
||||
|
||||
ranges[j++] = freq;
|
||||
}
|
||||
|
||||
/* Add frequencies from firmware node, skipping current frequency
|
||||
* and filtering out frequencies not representable by device
|
||||
*/
|
||||
for (i = 0, j = 1; i < num_freqs; i++) {
|
||||
for (i = 0; i < num_freqs; i++) {
|
||||
struct dpll_pin_frequency freq = DPLL_PIN_FREQUENCY(freqs[i]);
|
||||
|
||||
if (freqs[i] == curr_freq)
|
||||
|
|
@ -312,6 +319,14 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev,
|
|||
}
|
||||
}
|
||||
|
||||
/* The DPLL core rejects a non-NULL list without entries, so do
|
||||
* not publish the array at all when nothing is settable.
|
||||
*/
|
||||
if (!j) {
|
||||
kfree(ranges);
|
||||
ranges = NULL;
|
||||
}
|
||||
|
||||
/* Save number of freq ranges and pointer to them into pin properties */
|
||||
props->dpll_props.freq_supported = ranges;
|
||||
props->dpll_props.freq_supported_num = j;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user