summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/dpll/dpll_core.c20
-rw-r--r--drivers/dpll/dpll_core.h2
-rw-r--r--drivers/dpll/dpll_netlink.c6
3 files changed, 21 insertions, 7 deletions
diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c
index 20a54728549c..6dc7e93ece75 100644
--- a/drivers/dpll/dpll_core.c
+++ b/drivers/dpll/dpll_core.c
@@ -11,6 +11,7 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/idr.h>
+#include <linux/module.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -652,6 +653,7 @@ dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module,
pin->pin_idx = pin_idx;
pin->clock_id = clock_id;
pin->module = module;
+ strscpy(pin->module_name, module_name(module));
if (WARN_ON(prop->type < DPLL_PIN_TYPE_MUX ||
prop->type > DPLL_PIN_TYPE_MAX)) {
ret = -EINVAL;
@@ -884,11 +886,21 @@ dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin,
return -EINVAL;
mutex_lock(&dpll_lock);
- if (WARN_ON(!(dpll->module == pin->module &&
- dpll->clock_id == pin->clock_id)))
+
+ /*
+ * For pins identified via firmware (pin->fwnode), allow registration
+ * even if the pin's (module, clock_id) differs from the target DPLL.
+ * For non-fwnode pins, require a strict (module, clock_id) match.
+ */
+ if (!pin->fwnode &&
+ WARN_ON_ONCE(dpll->module != pin->module ||
+ dpll->clock_id != pin->clock_id)) {
ret = -EINVAL;
- else
- ret = __dpll_pin_register(dpll, pin, ops, priv, NULL);
+ goto out_unlock;
+ }
+
+ ret = __dpll_pin_register(dpll, pin, ops, priv, NULL);
+out_unlock:
mutex_unlock(&dpll_lock);
return ret;
diff --git a/drivers/dpll/dpll_core.h b/drivers/dpll/dpll_core.h
index 71ac88ef2017..26d1537ada82 100644
--- a/drivers/dpll/dpll_core.h
+++ b/drivers/dpll/dpll_core.h
@@ -45,6 +45,7 @@ struct dpll_device {
* @pin_idx: index of a pin given by dev driver
* @clock_id: clock_id of creator
* @module: module of creator
+ * @module_name: module name of creator
* @fwnode: optional reference to firmware node
* @dpll_refs: hold referencees to dplls pin was registered with
* @parent_refs: hold references to parent pins pin was registered with
@@ -59,6 +60,7 @@ struct dpll_pin {
u32 pin_idx;
u64 clock_id;
struct module *module;
+ char module_name[MODULE_NAME_LEN];
struct fwnode_handle *fwnode;
struct xarray dpll_refs;
struct xarray parent_refs;
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
index d62350b18107..6a23298244cc 100644
--- a/drivers/dpll/dpll_netlink.c
+++ b/drivers/dpll/dpll_netlink.c
@@ -703,7 +703,7 @@ dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
if (ret)
return ret;
if (nla_put_string(msg, DPLL_A_PIN_MODULE_NAME,
- module_name(pin->module)))
+ pin->module_name))
return -EMSGSIZE;
if (nla_put_64bit(msg, DPLL_A_PIN_CLOCK_ID, sizeof(pin->clock_id),
&pin->clock_id, DPLL_A_PIN_PAD))
@@ -1650,9 +1650,9 @@ dpll_pin_find(u64 clock_id, struct nlattr *mod_name_attr,
xa_for_each_marked(&dpll_pin_xa, i, pin, DPLL_REGISTERED) {
prop = &pin->prop;
cid_match = clock_id ? pin->clock_id == clock_id : true;
- mod_match = mod_name_attr && module_name(pin->module) ?
+ mod_match = mod_name_attr && pin->module_name[0] ?
!nla_strcmp(mod_name_attr,
- module_name(pin->module)) : true;
+ pin->module_name) : true;
type_match = type ? prop->type == type : true;
board_match = board_label ? (prop->board_label ?
!nla_strcmp(board_label, prop->board_label) : false) :