<feed xmlns='http://www.w3.org/2005/Atom'>
<title>laptop-kernel/drivers/dpll, branch master</title>
<subtitle>Linux kernel tree for laptop</subtitle>
<id>https://git.zx2c4.com/laptop-kernel/atom/drivers/dpll?h=master</id>
<link rel='self' href='https://git.zx2c4.com/laptop-kernel/atom/drivers/dpll?h=master'/>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/'/>
<updated>2026-09-22T00:19:42Z</updated>
<entry>
<title>dpll: use exact lookup for reference sync pin id</title>
<updated>2026-09-22T00:19:42Z</updated>
<author>
<name>Ivan Vecera</name>
<email>ivecera@redhat.com</email>
</author>
<published>2026-09-17T14:37:36Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=7cce782d8327b7291334c4a304cf3fd909a74d9d'/>
<id>urn:sha1:7cce782d8327b7291334c4a304cf3fd909a74d9d</id>
<content type='text'>
dpll_pin_ref_sync_state_set() looks up the reference sync pin in the
pin-&gt;ref_sync_pins xarray, which is keyed by the sync pin's id (see
dpll_pin_ref_sync_pair_add() using xa_insert() with ref_sync_pin-&gt;id).
The pin id to operate on is supplied by userspace via DPLL_A_PIN_ID.

The lookup however used xa_find() with a ULONG_MAX limit, which returns
the first present entry with an index greater than or equal to the
requested id, not the entry stored exactly at that id. If userspace
passes an id that is not paired as a reference sync pin, but another
pin with a higher id is present in the xarray, xa_find() silently
returns that wrong pin and the subsequent ref_sync_set() operates on
it. The request only fails when the given id is larger than every
present key.

Use xa_load() for an exact-key lookup instead, mirroring the deletion
path in dpll_pin_ref_sync_pair_del().

Fixes: 58256a26bfb3 ("dpll: add reference sync get/set")
Signed-off-by: Ivan Vecera &lt;ivecera@redhat.com&gt;
Link: https://patch.msgid.link/20260917143736.526221-1-ivecera@redhat.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>dpll: reject a reference sync pin which is not on the pin's dpll</title>
<updated>2026-09-17T12:51:23Z</updated>
<author>
<name>Jakub Kicinski</name>
<email>kuba@kernel.org</email>
</author>
<published>2026-09-15T21:30:47Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=d798162eb364df2e77a56fdbe5bae54440152d3b'/>
<id>urn:sha1:d798162eb364df2e77a56fdbe5bae54440152d3b</id>
<content type='text'>
dpll_pin_ref_sync_state_set() resolves the partner's driver private data
with dpll_pin_on_dpll_priv() and passes the result to ref_sync_get() and
ref_sync_set() without looking at it. The helper returns NULL when the
partner holds no ref on that dpll. Of the two drivers implementing the
feature only zl3073x dereferences the pointer (sync_pin-&gt;id); ice ignores
it, so ice cannot fault here.

The NULL is a teardown race, not a steady state - zl3073x registers every
input pin with every channel, so the partner is normally present on the
dpll the base pin resolves to. zl3073x_dev_stop() unregisters pins one at
a time, taking and dropping dpll_lock for each, and between the partner's
turn and the base pin's the partner is out of that dpll's pin_refs while
still registered with the channels not yet torn down, so
dpll_pin_available() keeps passing. That path is not only driver removal:
devlink reload and devlink dev flash both run zl3073x_dev_stop().

Reproduced by holding that state open with a mock dpll device, which is
where the frame name comes from:

 BUG: kernel NULL pointer dereference, address: 0000000000000000
 Oops: Oops: 0000 [#1] SMP NOPTI
 RIP: 0010:mock_ref_sync_get+0x5/0x30
 Call Trace:
  &lt;TASK&gt;
  dpll_pin_ref_sync_set+0x19f/0x4a0
  dpll_nl_pin_set_doit+0x17d/0x840
  genl_family_rcv_msg_doit+0xd6/0x130
  genl_rcv_msg+0x181/0x2b0
  netlink_rcv_skb+0x55/0x100
  genl_rcv+0x23/0x30
  netlink_unicast+0x24d/0x370
  netlink_sendmsg+0x1e2/0x420
  __sys_sendto+0x1db/0x1f0
  __x64_sys_sendto+0x1f/0x30
  do_syscall_64+0xe1/0x490

Commit d2e914a4a0d0 ("dpll: fix NULL pointer dereference in
dpll_msg_add_pin_ref_sync()") added the same guard to the read side, which
the kernel walks into by itself because the delete notification is emitted
from inside the unregister; the write side needs a pin-set to land in the
window and was left alone. Test the priv rather than look up pin_refs
directly, so that the two halves key off the same condition.

Fixes: 58256a26bfb3 ("dpll: add reference sync get/set")
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
Reviewed-by: Ivan Vecera &lt;ivecera@redhat.com&gt;
Link: https://patch.msgid.link/20260915213047.1352286-1-kuba@kernel.org
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;
</content>
</entry>
<entry>
<title>Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net</title>
<updated>2026-08-18T17:42:41Z</updated>
<author>
<name>Jakub Kicinski</name>
<email>kuba@kernel.org</email>
</author>
<published>2026-08-18T17:42:15Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=61eb236c41c2a4717015dff18016a75a5eb90052'/>
<id>urn:sha1:61eb236c41c2a4717015dff18016a75a5eb90052</id>
<content type='text'>
Merge in late fixes in preparation for the net-next PR.

Conflicts:

drivers/dpll/dpll_core.c
drivers/dpll/dpll_netlink.c
  33f016b23a219 ("dpll: fix NULL deref in dpll_device_ops() during teardown race")
  b1d0c412088e3 ("dpll: add STATE_CONNECTED_OVERRIDE pin capability")
https://lore.kernel.org/aoR9YYY2P5--3x0N@sirena.org.uk
https://lore.kernel.org/aoR9VmKllVGwmQn_@sirena.org.uk

No adjacent changes.

Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>dpll: zl3073x: add PTP clock support</title>
<updated>2026-08-18T16:40:06Z</updated>
<author>
<name>Ivan Vecera</name>
<email>ivecera@redhat.com</email>
</author>
<published>2026-08-14T08:26:56Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=1db73ce01856c983bcc7789c4dffc6b5b8f41a23'/>
<id>urn:sha1:1db73ce01856c983bcc7789c4dffc6b5b8f41a23</id>
<content type='text'>
Add PTP clock support for the ZL3073x DPLL driver. A PTP clock device
is registered for each DPLL channel regardless of the initial channel
state, providing gettimex64, settime64, adjtime, adjfine, adjphase
and getmaxphase callbacks.

Callback availability depends on the current channel state:
- adjfine: when NCO pin is connected (returns -EOPNOTSUPP otherwise)
- adjphase: available when tracking a reference, uses TIE write
- adjtime: always available and uses
  * phase step for sub-second deltas when NCO pin is connected
  * TIE write when tracking a reference
  * plain ToD read-modify-write otherwise
- gettime/settime: always available

The adjtime callback splits multi-second adjustments into a ToD
read-modify-write for the seconds part and a sub-second mechanism
(phase step or TIE write) for the remainder. On partial failure
where seconds were already committed, success is returned to
prevent the PTP servo from retrying and applying seconds again.

All PTP callbacks are serialized by the existing per-DPLL zldpll-&gt;lock
mutex, which is also used by DPLL pin and device callbacks.

Reviewed-by: Petr Oros &lt;poros@redhat.com&gt;
Reviewed-by: Vadim Fedorenko &lt;vadim.fedorenko@linux.dev&gt;
Tested-by: Chris du Quesnay &lt;Chris.duQuesnay@microchip.com&gt;
Signed-off-by: Ivan Vecera &lt;ivecera@redhat.com&gt;
Link: https://patch.msgid.link/20260814082656.306534-4-ivecera@redhat.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>dpll: zl3073x: add channel ToD, phase step and TIE operations</title>
<updated>2026-08-18T16:40:05Z</updated>
<author>
<name>Ivan Vecera</name>
<email>ivecera@redhat.com</email>
</author>
<published>2026-08-14T08:26:55Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=2dbf9b75627914f4392ef244718fa888f23bcea4'/>
<id>urn:sha1:2dbf9b75627914f4392ef244718fa888f23bcea4</id>
<content type='text'>
Add low-level DPLL channel operations for ToD read/write/adjust,
output phase step, delta frequency offset write and TIE (Time
Interval Error) write. These serve as building blocks for the PTP
clock callbacks added in the next patch.

ToD operations use a wait-before-write pattern to avoid blocking
after each operation.

The tod_ready_wait helper selects the poll timeout based on the
current ToD command - write operations use a longer timeout (1000 ms)
than reads (30 ms).

The ToD read captures system timestamps (ptp_system_timestamp) around
the HW command and completion poll to support cross-timestamping.

The TIE write operation provides sub-picosecond resolution phase
adjustment for modes where the DPLL is tracking a reference
(AUTO and REFLOCK).

Add output step-time mask to struct zl3073x_dev and
zl3073x_dev_out_is_stepped() helper to check if an output
participates in step-time operations.

Reviewed-by: Petr Oros &lt;poros@redhat.com&gt;
Tested-by: Chris du Quesnay &lt;Chris.duQuesnay@microchip.com&gt;
Signed-off-by: Ivan Vecera &lt;ivecera@redhat.com&gt;
Link: https://patch.msgid.link/20260814082656.306534-3-ivecera@redhat.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>dpll: zl3073x: scale poll interval proportionally to timeout</title>
<updated>2026-08-18T16:40:05Z</updated>
<author>
<name>Ivan Vecera</name>
<email>ivecera@redhat.com</email>
</author>
<published>2026-08-14T08:26:54Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=c36461825469a9ceee2346a2e89286c522525da7'/>
<id>urn:sha1:c36461825469a9ceee2346a2e89286c522525da7</id>
<content type='text'>
Replace the fixed 10 us poll sleep in zl3073x_poll_zero_u8() with
timeout_us / 50, scaling the sleep interval proportionally to the
timeout for all callers.

Testing showed that existing callers (mailbox, HWREG, DF read,
frequency measurement and phase error polls with 25-50 ms timeouts)
typically completed in low hundreds of sleep cycles with the fixed
10 us interval. With the scaled interval the cycle count drops to
single digits. The longer PTP-related timeouts (up to 3000 ms for
phase step) added in the following patches benefit most, avoiding
on the order of 10^5 bus transactions per wait.

Reviewed-by: Vadim Fedorenko &lt;vadim.fedorenko@linux.dev&gt;
Signed-off-by: Ivan Vecera &lt;ivecera@redhat.com&gt;
Link: https://patch.msgid.link/20260814082656.306534-2-ivecera@redhat.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>dpll: fix NULL deref in dpll_device_ops() during teardown race</title>
<updated>2026-08-17T20:35:28Z</updated>
<author>
<name>Petr Oros</name>
<email>poros@redhat.com</email>
</author>
<published>2026-08-13T14:08:17Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=33f016b23a219fe034213849b51436b8e79df251'/>
<id>urn:sha1:33f016b23a219fe034213849b51436b8e79df251</id>
<content type='text'>
When the last owner of a dpll device unregisters while a foreign driver
still holds a pin on it via dpll_pin_on_pin_register(), the dpll object
stays alive with an empty registration list. A pin notification queued
before the unregister (e.g. ice reacting to zl3073x_i2c removal) then
walks pin-&gt;dpll_refs into dpll_device_ops(), which trips the WARN_ON and
dereferences the missing registration. dpll_lock cannot help because the
notification work was queued before the unregistering driver took the
lock.

Treat the empty registration list as a legitimate transient state. Make
dpll_priv() and dpll_device_ops() return NULL in that case and make
every pin netlink path that resolves a device from a pin skip such
dplls. dpll_cmd_pin_get_one() picks a ref with a live registration and
returns -ENODEV when there is none, the pin dumpit skips such a pin
instead of aborting the dump, dpll_msg_add_pin_dplls() and the
frequency, esync, reference sync and phase adjust set paths skip dead
refs, and dpll_pin_parent_device_set() validates the parent with
dpll_device_get_by_id(). dpll_pin_register() is the last caller that
dereferenced the device ops without a check, so move its frequency
monitor validation under dpll_lock and tolerate a missing registration
there as well.

The empty registration list is equivalent to a cleared DPLL_REGISTERED
mark, both transitions happen under dpll_lock in dpll_device_register()
and dpll_device_unregister(). A pin notification for a pin whose dplls
are all gone is now dropped with -ENODEV instead of crashing, all
callers in the core ignore that return value.

 WARNING: drivers/dpll/dpll_core.c:1092 at dpll_device_ops+0x24/0x40,
 CPU#83: kworker/u576:3/23471
 Modules linked in: ... ice ... zl3073x_i2c(-) ... zl3073x ...
 Workqueue: ice_dpll_wq ice_dpll_pin_notify_work [ice]
 RIP: 0010:dpll_device_ops+0x24/0x40
 Call Trace:
  &lt;TASK&gt;
  dpll_cmd_pin_get_one+0x336/0x520
  dpll_pin_event_send+0x82/0x140
  dpll_pin_on_pin_unregister+0xbb/0x160
  ice_dpll_pin_notify_work+0x1bc/0x1f0 [ice]
  process_one_work+0x19e/0x370
  worker_thread+0x1a6/0x310
  kthread+0xe4/0x120
  ret_from_fork+0x1a1/0x270
  ret_from_fork_asm+0x1a/0x30
  &lt;/TASK&gt;
 ---[ end trace 0000000000000000 ]---
 BUG: kernel NULL pointer dereference, address: 0000000000000010
 #PF: supervisor read access in kernel mode
 #PF: error_code(0x0000) - not-present page

Fixes: 9431063ad323 ("dpll: core: Add DPLL framework base functions")
Signed-off-by: Petr Oros &lt;poros@redhat.com&gt;
Tested-by: Ivan Vecera &lt;ivecera@redhat.com&gt;
Reviewed-by: Vadim Fedorenko &lt;vadim.fedorenko@linux.dev&gt;
Link: https://patch.msgid.link/20260813140817.1051388-1-poros@redhat.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>dpll: use pin owner's dpll ref for pin-level attribute setting</title>
<updated>2026-08-11T09:30:07Z</updated>
<author>
<name>Ivan Vecera</name>
<email>ivecera@redhat.com</email>
</author>
<published>2026-08-07T09:59:26Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=84e85c325e5ed6781758685bf236021cc6aeed17'/>
<id>urn:sha1:84e85c325e5ed6781758685bf236021cc6aeed17</id>
<content type='text'>
Pin-level attributes (frequency, phase adjust, embedded sync, reference
sync) are properties of the pin itself, not of a particular DPLL device.
The get callbacks already use only the pin owner's DPLL reference
(via dpll_pin_own_dpll_ref_first()), but the set callbacks iterate over
all registered DPLL references and invoke the set operation on each one.

This is redundant because a pin is a single physical entity - setting
its frequency or phase adjust once through the owner's ops is sufficient.
Calling set on every registered DPLL just results in duplicate HW writes
for drivers that share a pin across multiple DPLL devices (e.g. ice
registers each input pin with both the EEC and PPS DPLL, zl3073x
registers input pins with every DPLL channel).

Simplify dpll_pin_freq_set(), dpll_pin_esync_set(),
dpll_pin_ref_sync_state_set() and dpll_pin_phase_adj_set() to call the
set callback only through the owner's DPLL reference, matching the
existing get-side behavior. This removes the xa_for_each iteration
loops, the now-unnecessary rollback logic, and several local variables.

The -EOPNOTSUPP validation loop, which checked ops support across all
owner-matching references, is replaced with a direct check on the
single owner reference returned by dpll_pin_own_dpll_ref_first().

The documentation in dpll.rst is updated to reflect that pin-level
attributes are set through the pin owner's dpll reference only.

No existing driver is affected:
  - ptp_ocp and mlx5 register each pin with a single DPLL.
  - ice registers input pins with two DPLLs (EEC and PPS) using
    identical ops and pin_priv; the set callbacks address the HW by
    pin index, not by DPLL, so the second call was a no-op.
  - zl3073x registers input pins with every DPLL channel; the set
    callbacks address HW by pin/ref ID regardless of DPLL. The
    ref_sync_set callback was the only one with per-channel behavior,
    addressed by the preceding patch.

Signed-off-by: Ivan Vecera &lt;ivecera@redhat.com&gt;
Reviewed-by: Jiri Pirko &lt;jiri@nvidia.com&gt;
Link: https://patch.msgid.link/20260807095926.386923-3-ivecera@redhat.com
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;
</content>
</entry>
<entry>
<title>dpll: zl3073x: update all DPLL channels on ref_sync_set</title>
<updated>2026-08-11T09:30:07Z</updated>
<author>
<name>Ivan Vecera</name>
<email>ivecera@redhat.com</email>
</author>
<published>2026-08-07T09:59:25Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=346630e46b387ad6db7b3b254ba6f6d513d64d14'/>
<id>urn:sha1:346630e46b387ad6db7b3b254ba6f6d513d64d14</id>
<content type='text'>
zl3073x_dpll_input_pin_ref_sync_set() excludes the sync source from
automatic reference selection by setting its priority to NONE, but
currently only does this on the single DPLL channel whose pin_priv
was passed to the callback.

Since input pins are registered with every DPLL channel, the datasheet
recommends covering all channels to prevent the sync source from
remaining a selectable candidate on the other channels. This is
a preparation for the following patch which changes the DPLL core to
invoke pin-level set callbacks only through the pin owner's reference
instead of iterating over all registered DPLL devices.

Replace the single-channel priority write with a list_for_each_entry()
loop over all DPLL channels. Each channel's lock is acquired
individually for its read-modify-write sequence. The guard(mutex) is
replaced with explicit mutex_lock/mutex_unlock to allow releasing the
owner's lock before iterating, avoiding nested locking of the same
mutex class. A change notification is sent for the sync pin if any
channel's priority was actually modified.

Signed-off-by: Ivan Vecera &lt;ivecera@redhat.com&gt;
Reviewed-by: Petr Oros &lt;poros@redhat.com&gt;
Link: https://patch.msgid.link/20260807095926.386923-2-ivecera@redhat.com
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;
</content>
</entry>
<entry>
<title>dpll: zl3073x: recognize the ZL30643 chip ID (0x0E3B)</title>
<updated>2026-08-06T02:00:32Z</updated>
<author>
<name>Vincent Jardin</name>
<email>vjardin@free.fr</email>
</author>
<published>2026-07-30T17:35:36Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=24e4aff8983fe663a85b5b157476f87ae0819e2c'/>
<id>urn:sha1:24e4aff8983fe663a85b5b157476f87ae0819e2c</id>
<content type='text'>
The Microchip ZL30643 is a 3-channel ZL3064x line-card part that is
register compatible with the ZL30733. Only the runtime chip-ID table
needs the 0x0E3B entry so the probe resolves the channel count (3)
and flags.

The ZL3073X_FLAG_REF_PHASE_COMP_32 flag applies unchanged: the
ref_phase path
  dpll_meas_ctrl::en -&gt; ref_phase_0P/0N
  -&gt; ref_phase_offset_compensation -&gt; ref_phase_err_read_rqst
is identical between ZL3064x and ZL3073x. No new device flag is needed.

Test: once register, for instance, we get:

  devlink dev param set spi/spi0.0 name clock_id value 3733 cmode driverinit
  devlink dev reload spi/spi0.0
  devlink dev param set spi/spi2.1 name clock_id value 3643 cmode driverinit
  devlink dev reload spi/spi2.1

  dpll device show | grep clock-id
    clock-id: 3733
    clock-id: 3733
    clock-id: 3733
    clock-id: 3643
    clock-id: 3643
    clock-id: 3643

Signed-off-by: Vincent Jardin &lt;vjardin@free.fr&gt;
Link: https://patch.msgid.link/20260730-for-upstream-zl30643-v2-2-0ea0bbd03755@free.fr
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
</feed>
