mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-28 22:44:08 -04:00
The frequency monitoring feature uses shared hardware registers
that measure input reference frequencies independently of
individual DPLL channels. However, the freq_monitor flag was
incorrectly placed in the per-DPLL structure, causing each
channel to track its own enable/disable state independently.
Since the DPLL core calls measured_freq_get() only for the first
pin registration, the measured_freq_check() in the periodic worker
was gated by the per-DPLL freq_monitor flag of whichever channel
happens to be checked. If the first DPLL channel had frequency
monitoring disabled while another had it enabled, measurements
were never reported.
Move freq_monitor from struct zl3073x_dpll to struct zl3073x_dev
so all DPLL channels share a single flag, matching the hardware
behavior. Update freq_monitor_set() to notify other DPLL devices
about the change (like phase_offset_avg_factor_set() already does)
and remove the mode-dependent guard in zl3073x_dpll_changes_check()
since all input pin monitoring (pin state, phase offset, FFO, and
measured frequency) works correctly in all DPLL modes.
Fixes: bfc923b642 ("dpll: zl3073x: implement frequency monitoring")
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
Link: https://patch.msgid.link/20260526074525.1451008-4-ivecera@redhat.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
47 lines
1.3 KiB
C
47 lines
1.3 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
|
|
#ifndef _ZL3073X_DPLL_H
|
|
#define _ZL3073X_DPLL_H
|
|
|
|
#include <linux/dpll.h>
|
|
#include <linux/list.h>
|
|
|
|
#include "core.h"
|
|
|
|
/**
|
|
* struct zl3073x_dpll - ZL3073x DPLL sub-device structure
|
|
* @list: this DPLL list entry
|
|
* @dev: pointer to multi-function parent device
|
|
* @id: DPLL index
|
|
* @check_count: periodic check counter
|
|
* @phase_monitor: is phase offset monitor enabled
|
|
* @ops: DPLL device operations for this instance
|
|
* @dpll_dev: pointer to registered DPLL device
|
|
* @tracker: tracking object for the acquired reference
|
|
* @lock_status: last saved DPLL lock status
|
|
* @pins: list of pins
|
|
*/
|
|
struct zl3073x_dpll {
|
|
struct list_head list;
|
|
struct zl3073x_dev *dev;
|
|
u8 id;
|
|
u8 check_count;
|
|
bool phase_monitor;
|
|
struct dpll_device_ops ops;
|
|
struct dpll_device *dpll_dev;
|
|
dpll_tracker tracker;
|
|
enum dpll_lock_status lock_status;
|
|
struct list_head pins;
|
|
};
|
|
|
|
struct zl3073x_dpll *zl3073x_dpll_alloc(struct zl3073x_dev *zldev, u8 ch);
|
|
void zl3073x_dpll_free(struct zl3073x_dpll *zldpll);
|
|
|
|
int zl3073x_dpll_register(struct zl3073x_dpll *zldpll);
|
|
void zl3073x_dpll_unregister(struct zl3073x_dpll *zldpll);
|
|
|
|
int zl3073x_dpll_init_fine_phase_adjust(struct zl3073x_dev *zldev);
|
|
void zl3073x_dpll_changes_check(struct zl3073x_dpll *zldpll);
|
|
|
|
#endif /* _ZL3073X_DPLL_H */
|