summaryrefslogtreecommitdiff
path: root/drivers/dpll
diff options
context:
space:
mode:
authorIvan Vecera <ivecera@redhat.com>2026-01-21 14:00:11 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-01-30 10:32:21 +0100
commit236a657422a564859dcd0db7bdb486abb21a721a (patch)
treecbf6d12fa1d9c37357ff08bbd2c011c1dea9cde7 /drivers/dpll
parent6c75fed55080014545f262b7055081cec4768b20 (diff)
dpll: Prevent duplicate registrations
[ Upstream commit f3ddbaaaaf4d0633b40482f471753f9c71294a4a ] Modify the internal registration helpers dpll_xa_ref_{dpll,pin}_add() to reject duplicate registration attempts. Previously, if a caller attempted to register the same pin multiple times (with the same ops, priv, and cookie) on the same device, the core silently increments the reference count and return success. This behavior is incorrect because if the caller makes these duplicate registrations then for the first one dpll_pin_registration is allocated and for others the associated dpll_pin_ref.refcount is incremented. During the first unregistration the associated dpll_pin_registration is freed and for others WARN is fired. Fix this by updating the logic to return `-EEXIST` if a matching registration is found to enforce a strict "register once" policy. Fixes: 9431063ad323 ("dpll: core: Add DPLL framework base functions") Signed-off-by: Ivan Vecera <ivecera@redhat.com> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Link: https://patch.msgid.link/20260121130012.112606-1-ivecera@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/dpll')
-rw-r--r--drivers/dpll/dpll_core.c12
1 files changed, 4 insertions, 8 deletions
diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c
index a461095efd8a..8879a7235156 100644
--- a/drivers/dpll/dpll_core.c
+++ b/drivers/dpll/dpll_core.c
@@ -83,10 +83,8 @@ dpll_xa_ref_pin_add(struct xarray *xa_pins, struct dpll_pin *pin,
if (ref->pin != pin)
continue;
reg = dpll_pin_registration_find(ref, ops, priv, cookie);
- if (reg) {
- refcount_inc(&ref->refcount);
- return 0;
- }
+ if (reg)
+ return -EEXIST;
ref_exists = true;
break;
}
@@ -164,10 +162,8 @@ dpll_xa_ref_dpll_add(struct xarray *xa_dplls, struct dpll_device *dpll,
if (ref->dpll != dpll)
continue;
reg = dpll_pin_registration_find(ref, ops, priv, cookie);
- if (reg) {
- refcount_inc(&ref->refcount);
- return 0;
- }
+ if (reg)
+ return -EEXIST;
ref_exists = true;
break;
}