diff options
| -rw-r--r-- | drivers/dpll/dpll_core.c | 20 | ||||
| -rw-r--r-- | drivers/dpll/dpll_core.h | 2 | ||||
| -rw-r--r-- | drivers/dpll/dpll_netlink.c | 6 |
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) : |
