@@ -126,6 +126,26 @@ dpll_msg_add_mode_supported(struct sk_buff *msg, struct dpll_device *dpll,
126126 return 0 ;
127127}
128128
129+ static int
130+ dpll_msg_add_phase_offset_monitor (struct sk_buff * msg , struct dpll_device * dpll ,
131+ struct netlink_ext_ack * extack )
132+ {
133+ const struct dpll_device_ops * ops = dpll_device_ops (dpll );
134+ enum dpll_feature_state state ;
135+ int ret ;
136+
137+ if (ops -> phase_offset_monitor_set && ops -> phase_offset_monitor_get ) {
138+ ret = ops -> phase_offset_monitor_get (dpll , dpll_priv (dpll ),
139+ & state , extack );
140+ if (ret )
141+ return ret ;
142+ if (nla_put_u32 (msg , DPLL_A_PHASE_OFFSET_MONITOR , state ))
143+ return - EMSGSIZE ;
144+ }
145+
146+ return 0 ;
147+ }
148+
129149static int
130150dpll_msg_add_lock_status (struct sk_buff * msg , struct dpll_device * dpll ,
131151 struct netlink_ext_ack * extack )
@@ -591,6 +611,9 @@ dpll_device_get_one(struct dpll_device *dpll, struct sk_buff *msg,
591611 return ret ;
592612 if (nla_put_u32 (msg , DPLL_A_TYPE , dpll -> type ))
593613 return - EMSGSIZE ;
614+ ret = dpll_msg_add_phase_offset_monitor (msg , dpll , extack );
615+ if (ret )
616+ return ret ;
594617
595618 return 0 ;
596619}
@@ -746,6 +769,31 @@ int dpll_pin_change_ntf(struct dpll_pin *pin)
746769}
747770EXPORT_SYMBOL_GPL (dpll_pin_change_ntf );
748771
772+ static int
773+ dpll_phase_offset_monitor_set (struct dpll_device * dpll , struct nlattr * a ,
774+ struct netlink_ext_ack * extack )
775+ {
776+ const struct dpll_device_ops * ops = dpll_device_ops (dpll );
777+ enum dpll_feature_state state = nla_get_u32 (a ), old_state ;
778+ int ret ;
779+
780+ if (!(ops -> phase_offset_monitor_set && ops -> phase_offset_monitor_get )) {
781+ NL_SET_ERR_MSG_ATTR (extack , a , "dpll device not capable of phase offset monitor" );
782+ return - EOPNOTSUPP ;
783+ }
784+ ret = ops -> phase_offset_monitor_get (dpll , dpll_priv (dpll ), & old_state ,
785+ extack );
786+ if (ret ) {
787+ NL_SET_ERR_MSG (extack , "unable to get current state of phase offset monitor" );
788+ return ret ;
789+ }
790+ if (state == old_state )
791+ return 0 ;
792+
793+ return ops -> phase_offset_monitor_set (dpll , dpll_priv (dpll ), state ,
794+ extack );
795+ }
796+
749797static int
750798dpll_pin_freq_set (struct dpll_pin * pin , struct nlattr * a ,
751799 struct netlink_ext_ack * extack )
@@ -1533,12 +1581,29 @@ int dpll_nl_device_get_doit(struct sk_buff *skb, struct genl_info *info)
15331581 return genlmsg_reply (msg , info );
15341582}
15351583
1536- int dpll_nl_device_set_doit (struct sk_buff * skb , struct genl_info * info )
1584+ static int
1585+ dpll_set_from_nlattr (struct dpll_device * dpll , struct genl_info * info )
15371586{
1538- /* placeholder for set command */
1587+ int ret ;
1588+
1589+ if (info -> attrs [DPLL_A_PHASE_OFFSET_MONITOR ]) {
1590+ struct nlattr * a = info -> attrs [DPLL_A_PHASE_OFFSET_MONITOR ];
1591+
1592+ ret = dpll_phase_offset_monitor_set (dpll , a , info -> extack );
1593+ if (ret )
1594+ return ret ;
1595+ }
1596+
15391597 return 0 ;
15401598}
15411599
1600+ int dpll_nl_device_set_doit (struct sk_buff * skb , struct genl_info * info )
1601+ {
1602+ struct dpll_device * dpll = info -> user_ptr [0 ];
1603+
1604+ return dpll_set_from_nlattr (dpll , info );
1605+ }
1606+
15421607int dpll_nl_device_get_dumpit (struct sk_buff * skb , struct netlink_callback * cb )
15431608{
15441609 struct dpll_dump_ctx * ctx = dpll_dump_context (cb );
0 commit comments