summaryrefslogtreecommitdiff
path: root/drivers/dpll/dpll_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dpll/dpll_netlink.c')
-rw-r--r--drivers/dpll/dpll_netlink.c70
1 files changed, 54 insertions, 16 deletions
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
index a6dc3997bf5c..3370dbddb86b 100644
--- a/drivers/dpll/dpll_netlink.c
+++ b/drivers/dpll/dpll_netlink.c
@@ -101,13 +101,17 @@ dpll_msg_add_mode_supported(struct sk_buff *msg, struct dpll_device *dpll,
{
const struct dpll_device_ops *ops = dpll_device_ops(dpll);
enum dpll_mode mode;
+ int ret;
- if (!ops->mode_supported)
- return 0;
- for (mode = DPLL_MODE_MANUAL; mode <= DPLL_MODE_MAX; mode++)
- if (ops->mode_supported(dpll, dpll_priv(dpll), mode, extack))
- if (nla_put_u32(msg, DPLL_A_MODE_SUPPORTED, mode))
- return -EMSGSIZE;
+ /* No mode change is supported now, so the only supported mode is the
+ * one obtained by mode_get().
+ */
+
+ ret = ops->mode_get(dpll, dpll_priv(dpll), &mode, extack);
+ if (ret)
+ return ret;
+ if (nla_put_u32(msg, DPLL_A_MODE_SUPPORTED, mode))
+ return -EMSGSIZE;
return 0;
}
@@ -259,6 +263,27 @@ dpll_msg_add_phase_offset(struct sk_buff *msg, struct dpll_pin *pin,
return 0;
}
+static int dpll_msg_add_ffo(struct sk_buff *msg, struct dpll_pin *pin,
+ struct dpll_pin_ref *ref,
+ struct netlink_ext_ack *extack)
+{
+ const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
+ struct dpll_device *dpll = ref->dpll;
+ s64 ffo;
+ int ret;
+
+ if (!ops->ffo_get)
+ return 0;
+ ret = ops->ffo_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
+ dpll, dpll_priv(dpll), &ffo, extack);
+ if (ret) {
+ if (ret == -ENODATA)
+ return 0;
+ return ret;
+ }
+ return nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET, ffo);
+}
+
static int
dpll_msg_add_pin_freq(struct sk_buff *msg, struct dpll_pin *pin,
struct dpll_pin_ref *ref, struct netlink_ext_ack *extack)
@@ -438,6 +463,9 @@ dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
ret = dpll_msg_add_pin_phase_adjust(msg, pin, ref, extack);
if (ret)
return ret;
+ ret = dpll_msg_add_ffo(msg, pin, ref, extack);
+ if (ret)
+ return ret;
if (xa_empty(&pin->parent_refs))
ret = dpll_msg_add_pin_dplls(msg, pin, extack);
else
@@ -925,7 +953,6 @@ dpll_pin_parent_pin_set(struct dpll_pin *pin, struct nlattr *parent_nest,
struct netlink_ext_ack *extack)
{
struct nlattr *tb[DPLL_A_PIN_MAX + 1];
- enum dpll_pin_state state;
u32 ppin_idx;
int ret;
@@ -936,10 +963,14 @@ dpll_pin_parent_pin_set(struct dpll_pin *pin, struct nlattr *parent_nest,
return -EINVAL;
}
ppin_idx = nla_get_u32(tb[DPLL_A_PIN_PARENT_ID]);
- state = nla_get_u32(tb[DPLL_A_PIN_STATE]);
- ret = dpll_pin_on_pin_state_set(pin, ppin_idx, state, extack);
- if (ret)
- return ret;
+
+ if (tb[DPLL_A_PIN_STATE]) {
+ enum dpll_pin_state state = nla_get_u32(tb[DPLL_A_PIN_STATE]);
+
+ ret = dpll_pin_on_pin_state_set(pin, ppin_idx, state, extack);
+ if (ret)
+ return ret;
+ }
return 0;
}
@@ -1093,9 +1124,10 @@ int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info)
return -ENOMEM;
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
DPLL_CMD_PIN_ID_GET);
- if (!hdr)
+ if (!hdr) {
+ nlmsg_free(msg);
return -EMSGSIZE;
-
+ }
pin = dpll_pin_find_from_nlattr(info);
if (!IS_ERR(pin)) {
ret = dpll_msg_add_pin_handle(msg, pin);
@@ -1123,8 +1155,10 @@ int dpll_nl_pin_get_doit(struct sk_buff *skb, struct genl_info *info)
return -ENOMEM;
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
DPLL_CMD_PIN_GET);
- if (!hdr)
+ if (!hdr) {
+ nlmsg_free(msg);
return -EMSGSIZE;
+ }
ret = dpll_cmd_pin_get_one(msg, pin, info->extack);
if (ret) {
nlmsg_free(msg);
@@ -1256,8 +1290,10 @@ int dpll_nl_device_id_get_doit(struct sk_buff *skb, struct genl_info *info)
return -ENOMEM;
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
DPLL_CMD_DEVICE_ID_GET);
- if (!hdr)
+ if (!hdr) {
+ nlmsg_free(msg);
return -EMSGSIZE;
+ }
dpll = dpll_device_find_from_nlattr(info);
if (!IS_ERR(dpll)) {
@@ -1284,8 +1320,10 @@ int dpll_nl_device_get_doit(struct sk_buff *skb, struct genl_info *info)
return -ENOMEM;
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
DPLL_CMD_DEVICE_GET);
- if (!hdr)
+ if (!hdr) {
+ nlmsg_free(msg);
return -EMSGSIZE;
+ }
ret = dpll_device_get_one(dpll, msg, info->extack);
if (ret) {