This is possibly a bit of a unique case, but I'm having trouble bringing up the outputs of the AD9545 on a custom board, running Linux on a Xilinx Zynq-7000 SoC, and utilising the clk-ad9545 driver from ADI.
My kernel version is Xilinx's 2021.2 release (5.10), which is slightly ahead of ADI's kernel (which is based on linux-xlnx 2021.1). I've added the drivers/clk/adi directory from ADI's kernel branch and updated my drivers/clk/Kconfig & drivers/clk/Makefile to build this module. I've added the necessary 'nshot' functions that are referenced by clk-ad9545.c, and have added some additional changes to catch divide-by-zero errors when reading from certain registers (happy to provide diffs if required).
I've been able to successfully build the module and lock PLL0 and PLL1, however the outputs appear to be muted and I cannot seem to enable them even when forcing a call to 'clk_enable' at the end of ad9545_setup. The relevant section of my dts looks like this:
ref_clk0: ref_clk_0 { compatible = "fixed-clock"; #clock-cells = <1>; clock-frequency = <100000000>; clock-output-names = "Ref-A"; }; ref_clk1: ref_clk_1 { compatible = "fixed-clock"; #clock-cells = <1>; clock-frequency = <100000000>; clock-output-names = "Ref-AA"; }; ref_clk2: ref_clk_2 { compatible = "fixed-clock"; #clock-cells = <1>; clock-frequency = <100000000>; clock-output-names = "Ref-B"; }; ref_clk3: ref_clk_3 { compatible = "fixed-clock"; #clock-cells = <1>; clock-frequency = <100000000>; clock-output-names = "Ref-BB"; }; spi@e0007000 { compatible = "xlnx,zynq-spi-r1p6"; reg = <0xe0007000 0x1000>; status = "okay"; interrupt-parent = <0x04>; interrupts = <0x00 0x31 0x04>; clocks = <0x01 0x1a 0x01 0x23>; clock-names = "ref_clk\0pclk"; #address-cells = <0x01>; #size-cells = <0x00>; phandle = <0x22>; ad9545_clock: ad9545@4A { compatible = "adi,ad9545"; reg = <0x00>; #address-cells = <1>; #size-cells = <0>; spi-max-frequency = <0xe4e1c0>; clock-names = "Ref-A", "Ref-AA", "Ref-B", "Ref-BB"; clocks = <&ref_clk0 0>, <&ref_clk1 1>, <&ref_clk2 2>, <&ref_clk3 3>; #clock-cells = <2>; adi,ref-crystal; adi,ref-frequency-hz = <54000000>; assigned-clocks = <&ad9545_clock 0x02 0x00>, // AD9545_CLK_NCO, AD9545_NCO0 <&ad9545_clock 0x01 0x00>, // AD9545_CLK_PLL, AD9545_PLL0 <&ad9545_clock 0x01 0x01>, // AD9545_CLK_PLL, AD9545_PLL1 <&ad9545_clock 0x00 0x00>, // AD9545_CLK_OUT, AD9545_Q0A <&ad9545_clock 0x00 0x02>, // AD9545_CLK_OUT, AD9545_Q0B <&ad9545_clock 0x00 0x04>, // AD9545_CLK_OUT, AD9545_Q0C <&ad9545_clock 0x00 0x08>; // AD9545_CLK_OUT, AD9545_Q1B assigned-clock-rates = <1000>, <1228800000>, // APLL0 must be in range 1.212GHz -> 1.616GHz, this value is 245.76MHz * 6 <1875000000>, // 156.25MHz*12, the VCO for PLL0 is twice this val <122880000>, <153600000>, <153600000>, <156250000>; assigned-clock-phases = <0>, <0>, <0>, <0>, <0>, <0>, <0>; // Ref-A (Pin 47) ref-input-clk@0 { reg = <0>; adi,single-ended-mode = <0>; // DRIVER_MODE_AC_COUPLED_IF adi,r-divider-ratio = <508>; adi,ref-dtol-pbb = <10000000>; adi,ref-monitor-hysteresis-pbb = <87500>; adi,ref-validation-timer-ms = <1>; adi,freq-lock-threshold-ps = <0xFFFFFF>; adi,phase-lock-threshold-ps = <0xFFFFFF>; adi,freq-lock-fill-rate = <200>; adi,freq-lock-drain-rate = <20>; adi,phase-lock-fill-rate = <200>; adi,phase-lock-drain-rate = <20>; }; // Ref-AA (Pin 46) ref-input-clk@1 { reg = <1>; adi,single-ended-mode = <0>; // DRIVER_MODE_AC_COUPLED_IF adi,r-divider-ratio = <508>; adi,ref-dtol-pbb = <10000000>; adi,ref-monitor-hysteresis-pbb = <87500>; adi,ref-validation-timer-ms = <1>; adi,freq-lock-threshold-ps = <0xFFFFFF>; adi,phase-lock-threshold-ps = <0xFFFFFF>; adi,freq-lock-fill-rate = <200>; adi,freq-lock-drain-rate = <20>; adi,phase-lock-fill-rate = <200>; adi,phase-lock-drain-rate = <20>; }; // Ref-B (Pin 38) ref-input-clk@2 { reg = <2>; adi,differential-mode = <0>; // DRIVER_MODE_AC_COUPLED adi,r-divider-ratio = <508>; adi,ref-dtol-pbb = <10000000>; adi,ref-monitor-hysteresis-pbb = <87500>; adi,ref-validation-timer-ms = <1>; adi,freq-lock-threshold-ps = <0xFFFFFF>; adi,phase-lock-threshold-ps = <0xFFFFFF>; adi,freq-lock-fill-rate = <200>; adi,freq-lock-drain-rate = <20>; adi,phase-lock-fill-rate = <200>; adi,phase-lock-drain-rate = <20>; }; // Ref-BB (Pin 38) ref-input-clk@3 { reg = <3>; adi,differential-mode = <0>; // DRIVER_MODE_AC_COUPLED adi,r-divider-ratio = <508>; adi,ref-dtol-pbb = <10000000>; adi,ref-monitor-hysteresis-pbb = <87500>; adi,ref-validation-timer-ms = <1>; adi,freq-lock-threshold-ps = <0xFFFFFF>; adi,phase-lock-threshold-ps = <0xFFFFFF>; adi,freq-lock-fill-rate = <200>; adi,freq-lock-drain-rate = <20>; adi,phase-lock-fill-rate = <200>; adi,phase-lock-drain-rate = <20>; }; ad9545_apll0: pll-clk@0x00 { reg = <0x00>; #address-cells = <1>; #size-cells = <0>; profile@0 { reg = <0>; adi,pll-source = <2>; adi,profile-priority = <0>; adi,pll-loop-bandwidth-uhz = <200000000>; }; }; ad9545_apll1: pll-clk@0x01 { reg = <0x01>; #address-cells = <1>; #size-cells = <0>; profile@0 { reg = <0>; adi,pll-source = <2>; adi,profile-priority = <0>; adi,pll-loop-bandwidth-uhz = <200000000>; }; }; output-clk@0x00 { reg = <0x00>; adi,output-mode = <0x00>; adi,current-source-microamp = <7500>; }; output-clk@0x02 { reg = <0x02>; adi,output-mode = <0x00>; adi,current-source-microamp = <7500>; }; output-clk@0x04 { reg = <0x04>; adi,output-mode = <0x00>; adi,current-source-microamp = <7500>; }; output-clk@0x08 { reg = <0x08>; adi,output-mode = <0x00>; adi,current-source-microamp = <7500>; }; }; };
And here's the output from /sys/kernel/debug/clk_summary:

...and the output showing both PLLs locked:
root@target-zynq7:~# cat /sys/kernel/debug/clk/PLL0/PLL0 PLL0: PLL status: Locked Freerun Mode: Off Holdover Mode: Off PLL Profile: On Profile Number: 0 Temperature: 46 C root@target-zynq7:~# cat /sys/kernel/debug/clk/PLL1/PLL1 PLL1: PLL status: Locked Freerun Mode: Off Holdover Mode: Off PLL Profile: On Profile Number: 0 Temperature: 46 C root@target-zynq7:~#vav
When I attempt to force a call to 'clk_enable' I hit a 'scheduling while atomic' bug, which I believe is caused by the call to 'regmap_read' within 'ad9545_out_clk_get_nshot', as this function eventually calls 'spi_write_then_read' which later hits '__schedule' - since this call to '__schedule' comes between calls to 'clk_enable_lock' and 'clk_enable_unlock' (I can provide the exception stack for this if required, but it's probably not necessary just yet).
What I'm trying to determine is how the callback to 'ad9545_out_clk_enable' from ops->enable is supposed to be invoked during the driver's standard operation. I'm sure I'm missing something within the clock framework, but as far as I can tell, this callback will never be invoked during the probe of the device and there is no interface available to force it to be called from userspace. If I do enable the debugfs clk_prepare_enable interface, I end up with the same 'scheduling while atomic' bug I encounter when forcing the call within 'ad9545_setup'.
I'm going to attempt forcing the unmute from outside of the clock API (i.e. I'm going to directly call 'ad9545_out_clk_enable'), but I would be keen to understand if there's anything I'm doing wrong here.