Thread (53 messages) 53 messages, 4 authors, 26d ago

Re: [PATCH net-next v8 06/15] dpll: sit9531x: implement input pin state on a DPLL

flat view

From: sashiko-bot@kernel.org
Date: 2026-09-03 21:41:17

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] Missing hardware rollback in `sit9531x_dpll_input_pin_state_on_dpll_set` leaves the physical receiver powered on if adding to the priority table fails.
- [Medium] Overwriting the last priority slot in `sit9531x_input_prio_add` drops a unique source and leaks its hardware enable state.
--

commit 30ff5313804d1b26035265c46d0a4c6573cce4d4
Author: Oleg Zadorozhnyi [off-list ref]

dpll: sit9531x: implement input pin state on a DPLL

This commit implements pin state reporting and configuration for the DPLL.
It sets or removes inputs from a priority table that the hardware uses for 
reference selection, translating DPLL connected/disconnected states to 
table membership.
quoted hunk ↗ jump to hunk
diff --git a/drivers/dpll/sit9531x/core.c b/drivers/dpll/sit9531x/core.c
index 1394ea1077d9c..f42c41d8a42e4 100644
--- a/drivers/dpll/sit9531x/core.c
+++ b/drivers/dpll/sit9531x/core.c
[ ... ]
quoted hunk ↗ jump to hunk
+/*
+ * sit9531x_input_prio_add - make an input eligible in a PLL's table
+ * @input_idx:	input source in hardware encoding
+ *
+ * Ensures the source appears in the priority table so it can be picked
+ * by automatic reference selection again after a disconnect.  If the
+ * source is already listed the table is left untouched; otherwise it is
+ * placed in the lowest-priority slot.  The original priority is not
+ * restored -- use sit9531x_input_prio_set() to reassign it.
+ *
+ * Caller must hold sitdev->multiop_lock.
+ */
+int sit9531x_input_prio_add(struct sit9531x_dev *sitdev, u8 pll_idx,
+			    u8 input_idx)
+{
+	u8 srcs[SIT9531X_PRIO_MAX_SLOTS];
+	u8 slot;
+	int rc;
+
+	lockdep_assert_held(&sitdev->multiop_lock);
+
+	if (pll_idx >= SIT9531X_NUM_PLLS)
+		return -EINVAL;
+
+	rc = sit9531x_prio_table_read(sitdev, pll_idx, srcs);
+	if (rc)
+		return rc;
+
+	for (slot = 0; slot < SIT9531X_PRIO_MAX_SLOTS; slot++)
+		if (srcs[slot] == input_idx)
+			return 0;
+
+	srcs[SIT9531X_PRIO_MAX_SLOTS - 1] = input_idx;
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

[Severity: Medium]
Does unconditionally overwriting the last slot in the priority table risk
dropping a unique source?

If the source in slot SIT9531X_PRIO_MAX_SLOTS - 1 is unique and removed from
the table here, does its ref->pll_mask become permanently out of sync with the
hardware, leaking its physical receiver?
quoted hunk ↗ jump to hunk
+
+	return sit9531x_prio_table_commit(sitdev, pll_idx, srcs);
+}
quoted hunk ↗ jump to hunk
diff --git a/drivers/dpll/sit9531x/dpll.c b/drivers/dpll/sit9531x/dpll.c
index 821370ddeab00..29088707a3e62 100644
--- a/drivers/dpll/sit9531x/dpll.c
+++ b/drivers/dpll/sit9531x/dpll.c
[ ... ]
quoted hunk ↗ jump to hunk
+/*
+ * sit9531x_dpll_input_pin_state_on_dpll_set - set input pin DPLL state
+ *
+ * Enables or disables the physical input receiver via Page 0x02
+ * force/state registers (sit9531x_input_disable/enable()) and updates
+ * this DPLL's Page 1 priority table so the state is honoured by the
+ * PLL's automatic reference selection, not just at the input buffer.
+ * Selection role; see the pin-state contract above for the states.
+ *
+ * The priority table is per PLL, so it is always updated for this DPLL.
+ * A single physical input feeds every DPLL, so the hardware receiver is
+ * only cut off once the last DPLL has released it: ref->pll_mask tracks
+ * which DPLLs currently claim the input, and the physical disable
+ * happens on the transition to an empty mask.
+ */
+static int
+sit9531x_dpll_input_pin_state_on_dpll_set(const struct dpll_pin *pin,
+					  void *pin_priv,
+					  const struct dpll_device *dpll,
+					  void *dpll_priv,
+					  enum dpll_pin_state state,
+					  struct netlink_ext_ack *extack)
+{
[ ... ]
quoted hunk ↗ jump to hunk
+	case DPLL_PIN_STATE_SELECTABLE:
+		rc = sit9531x_input_enable(sitdev, dpin->id);
+		if (rc)
+			break;
+		rc = sit9531x_input_prio_add(sitdev, sitdpll->id, hw_src);
+		if (rc)
+			break;
                        ^^^^^

[Severity: Medium]
If sit9531x_input_prio_add() fails, should the physical receiver that was just
enabled by sit9531x_input_enable() be disabled again on the error path?

Since ref->pll_mask is not updated before breaking out, could this leave the
receiver powered on indefinitely?
quoted hunk ↗ jump to hunk
+		/*
+		 * Claim the input for this DPLL only once it is both enabled
+		 * and present in the priority table.  Setting the mask before
+		 * prio_add would leak the claim if prio_add failed, keeping the
+		 * shared input receiver powered even after every DPLL released
+		 * it.
+		 */
+		ref->pll_mask |= pll_bit;
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	mutex_unlock(&sitdev->multiop_lock);
-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902214030.20955-1-arouhi@sitime.com?part=6
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help