Skip to content

Commit 85a9aaa

Browse files
ivecerakuba-moo
authored andcommitted
dpll: zl3073x: Include current frequency in supported frequencies list
Ensure the current pin frequency is always present in the list of supported frequencies reported to userspace. Previously, if the firmware node was missing or didn't include the current operating frequency in the supported-frequencies-hz property, the pin would report a frequency that wasn't in its supported list. Get the current frequency early in zl3073x_pin_props_get(): - For input pins: use zl3073x_dev_ref_freq_get() - For output pins: use zl3073x_dev_output_pin_freq_get() Place the current frequency at index 0 of the supported frequencies array, then append frequencies from the firmware node (if present), skipping any duplicate of the current frequency. Signed-off-by: Ivan Vecera <ivecera@redhat.com> Link: https://patch.msgid.link/20260205154350.3180465-3-ivecera@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 24e4336 commit 85a9aaa

1 file changed

Lines changed: 21 additions & 11 deletions

File tree

drivers/dpll/zl3073x/prop.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,10 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev,
193193
{
194194
struct dpll_pin_frequency *ranges;
195195
struct zl3073x_pin_props *props;
196-
int i, j, num_freqs, rc;
196+
int i, j, num_freqs = 0, rc;
197+
u64 *freqs = NULL;
197198
const char *type;
198-
u64 *freqs;
199+
u32 curr_freq;
199200

200201
props = kzalloc(sizeof(*props), GFP_KERNEL);
201202
if (!props)
@@ -207,6 +208,7 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev,
207208
props->dpll_props.capabilities =
208209
DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
209210
DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
211+
curr_freq = zl3073x_dev_ref_freq_get(zldev, index);
210212
} else {
211213
u8 out, synth;
212214
u32 f;
@@ -220,6 +222,7 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev,
220222
synth = zl3073x_dev_out_synth_get(zldev, out);
221223
f = 2 * zl3073x_dev_synth_freq_get(zldev, synth);
222224
props->dpll_props.phase_gran = f ? div_u64(PSEC_PER_SEC, f) : 1;
225+
curr_freq = zl3073x_dev_output_pin_freq_get(zldev, index);
223226
}
224227

225228
props->dpll_props.phase_range.min = S32_MIN;
@@ -230,7 +233,7 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev,
230233
/* Get firmware node for the given pin */
231234
rc = zl3073x_prop_pin_fwnode_get(zldev, props, dir, index);
232235
if (rc)
233-
return props; /* Return if it does not exist */
236+
goto skip_fwnode_props;
234237

235238
/* Look for label property and store the value as board label */
236239
fwnode_property_read_string(props->fwnode, "label",
@@ -264,9 +267,10 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev,
264267
/* Read supported frequencies property if it is specified */
265268
num_freqs = fwnode_property_count_u64(props->fwnode,
266269
"supported-frequencies-hz");
267-
if (num_freqs <= 0)
268-
/* Return if the property does not exist or number is 0 */
269-
return props;
270+
if (num_freqs <= 0) {
271+
num_freqs = 0;
272+
goto skip_fwnode_props;
273+
}
270274

271275
/* The firmware node specifies list of supported frequencies while
272276
* DPLL core pin properties requires list of frequency ranges.
@@ -283,19 +287,25 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev,
283287
"supported-frequencies-hz", freqs,
284288
num_freqs);
285289

286-
/* Allocate frequency ranges list and fill it */
287-
ranges = kcalloc(num_freqs, sizeof(*ranges), GFP_KERNEL);
290+
skip_fwnode_props:
291+
/* Allocate frequency ranges list - extra slot for current frequency */
292+
ranges = kcalloc(num_freqs + 1, sizeof(*ranges), GFP_KERNEL);
288293
if (!ranges) {
289294
rc = -ENOMEM;
290295
goto err_alloc_ranges;
291296
}
292297

293-
/* Convert list of frequencies to list of frequency ranges but
294-
* filter-out frequencies that are not representable by device
298+
/* Start with current frequency at index 0 */
299+
ranges[0] = (struct dpll_pin_frequency)DPLL_PIN_FREQUENCY(curr_freq);
300+
301+
/* Add frequencies from firmware node, skipping current frequency
302+
* and filtering out frequencies not representable by device
295303
*/
296-
for (i = 0, j = 0; i < num_freqs; i++) {
304+
for (i = 0, j = 1; i < num_freqs; i++) {
297305
struct dpll_pin_frequency freq = DPLL_PIN_FREQUENCY(freqs[i]);
298306

307+
if (freqs[i] == curr_freq)
308+
continue;
299309
if (zl3073x_pin_check_freq(zldev, dir, index, freqs[i])) {
300310
ranges[j] = freq;
301311
j++;

0 commit comments

Comments
 (0)