]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
dpll: add pin operstate attribute support
authorIvan Vecera <ivecera@redhat.com>
Wed, 13 May 2026 14:51:14 +0000 (16:51 +0200)
committerDavid Ahern <dsahern@kernel.org>
Fri, 15 May 2026 19:21:12 +0000 (13:21 -0600)
Kernel commit 781c8893a5da8 ("dpll: add pin operational state")
added the DPLL_A_PIN_OPERSTATE attribute which reports the operational
state of a pin with respect to its parent DPLL device. The attribute
is nested inside parent-device and can have values: active, standby,
no-signal, qual-failed.

Add operstate filtering for pin show command, allowing to filter pins
by their operational state on parent device. Update bash-completion
and man page accordingly.

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
bash-completion/dpll
dpll/dpll.c
man/man8/dpll.8

index 7ddcf529d429db0434645479ecea6efd3f11e4af..9ff38a46c279681fff800caac7b4ddb775cc6b2b 100644 (file)
@@ -190,10 +190,15 @@ _dpll_pin()
                         "connected disconnected selectable" -- "$cur" ) )
                     return 0
                     ;;
+                operstate)
+                    COMPREPLY=( $( compgen -W \
+                        "active standby no-signal qual-failed" -- "$cur" ) )
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=( $( compgen -W "id parent-device parent-pin \
                         module-name clock-id board-label panel-label \
-                        package-label type direction state" \
+                        package-label type direction state operstate" \
                         -- "$cur" ) )
                     return 0
                     ;;
index febf2a5d1fbdf4cb34a97eea763422ca72f8f921..bd9ab3c6033ff6e1fc392fc84724a9aef2e277e2 100644 (file)
@@ -59,6 +59,16 @@ static struct str_num_map pin_state_map[] = {
        },
 };
 
+static struct str_num_map pin_operstate_map[] = {
+       { .str = "active", .num = DPLL_PIN_OPERSTATE_ACTIVE },
+       { .str = "standby", .num = DPLL_PIN_OPERSTATE_STANDBY },
+       { .str = "no-signal", .num = DPLL_PIN_OPERSTATE_NO_SIGNAL },
+       { .str = "qual-failed", .num = DPLL_PIN_OPERSTATE_QUAL_FAILED },
+       {
+               .str = NULL,
+       },
+};
+
 static struct str_num_map pin_type_map[] = {
        { .str = "mux", .num = DPLL_PIN_TYPE_MUX },
        { .str = "ext", .num = DPLL_PIN_TYPE_EXT },
@@ -162,6 +172,17 @@ static int str_to_dpll_pin_state(const char *state_str, __u32 *state)
        return 0;
 }
 
+static int str_to_dpll_pin_operstate(const char *str, __u32 *operstate)
+{
+       int num;
+
+       num = str_map_lookup_str(pin_operstate_map, str);
+       if (num < 0)
+               return num;
+       *operstate = num;
+       return 0;
+}
+
 static int str_to_dpll_pin_direction(const char *dir_str, __u32 *direction)
 {
        int num;
@@ -968,6 +989,7 @@ static bool dpll_device_dump_filter(struct dpll_device_filter *filter,
 #define DPLL_FILTER_PIN_PARENT_PIN     BIT(7)
 #define DPLL_FILTER_PIN_DIRECTION      BIT(8)
 #define DPLL_FILTER_PIN_STATE          BIT(9)
+#define DPLL_FILTER_PIN_OPERSTATE      BIT(10)
 
 struct dpll_pin_filter {
        uint64_t present;
@@ -981,6 +1003,7 @@ struct dpll_pin_filter {
        __u32 parent_pin_id;
        __u32 direction;
        __u32 state;
+       __u32 operstate;
 };
 
 static bool filter_match_nested_id(const struct nlmsghdr *nlh,
@@ -1030,6 +1053,11 @@ static bool filter_match_nested_parent_device(const struct nlmsghdr *nlh,
                                      filter->state))
                        continue;
 
+               if ((filter->present & DPLL_FILTER_PIN_OPERSTATE) &&
+                   !filter_match_u32(tb_nest[DPLL_A_PIN_OPERSTATE],
+                                     filter->operstate))
+                       continue;
+
                return true;
        }
        return false;
@@ -1063,7 +1091,8 @@ static bool dpll_pin_dump_filter(struct dpll_pin_filter *filter,
                return false;
        if ((filter->present & (DPLL_FILTER_PIN_PARENT_DEVICE |
                                DPLL_FILTER_PIN_DIRECTION |
-                               DPLL_FILTER_PIN_STATE)) &&
+                               DPLL_FILTER_PIN_STATE |
+                               DPLL_FILTER_PIN_OPERSTATE)) &&
            !filter_match_nested_parent_device(nlh, filter))
                return false;
        if ((filter->present & DPLL_FILTER_PIN_PARENT_PIN) &&
@@ -1426,6 +1455,14 @@ static const char *dpll_pin_state_name(__u32 state)
        return str ? str : "unknown";
 }
 
+static const char *dpll_pin_operstate_name(__u32 operstate)
+{
+       const char *str;
+
+       str = str_map_lookup_uint(pin_operstate_map, operstate);
+       return str ? str : "unknown";
+}
+
 static const char *dpll_pin_direction_name(__u32 direction)
 {
        const char *str;
@@ -1561,6 +1598,9 @@ static void dpll_pin_print_parent_devices(struct nlattr *attr)
                                 " prio %u");
                DPLL_PR_ENUM_STR_FMT(tb_parent, DPLL_A_PIN_STATE, "state",
                                     " state %s", dpll_pin_state_name);
+               DPLL_PR_ENUM_STR_FMT(tb_parent, DPLL_A_PIN_OPERSTATE,
+                                    "operstate", " operstate %s",
+                                    dpll_pin_operstate_name);
                dpll_pr_phase_offset(tb_parent[DPLL_A_PIN_PHASE_OFFSET]);
 
                print_nl();
@@ -1992,6 +2032,14 @@ static int cmd_pin_show(struct dpll *dpll)
                                                   str_to_dpll_pin_state,
                                                   "connected/disconnected/selectable"))
                                return -EINVAL;
+               } else if (dpll_argv_match(dpll, "operstate")) {
+                       if (dpll_filter_parse_enum(dpll, "operstate",
+                                                  &filter.operstate,
+                                                  &filter.present,
+                                                  DPLL_FILTER_PIN_OPERSTATE,
+                                                  str_to_dpll_pin_operstate,
+                                                  "active/standby/no-signal/qual-failed"))
+                               return -EINVAL;
                } else {
                        pr_err("unknown option: %s\n", dpll_argv(dpll));
                        return -EINVAL;
index c0d4b9caef2a6cc670f5e28ff875e42aad591413..f4cbcfc005c12f309bca4b087aa56d55ca530e9b 100644 (file)
@@ -171,7 +171,10 @@ Device type:
 
 .SH PIN COMMANDS
 
-.SS dpll pin show [ id ID ] [ parent-device DEVICE_ID ] [ parent-pin PIN_ID ] [ module-name NAME ] [ clock-id ID ] [ board-label LABEL ] [ panel-label LABEL ] [ package-label LABEL ] [ type TYPE ] [ direction DIR ] [ state STATE ]
+.SS dpll pin show [ id ID ] [ parent-device DEVICE_ID ] \
+[ parent-pin PIN_ID ] [ module-name NAME ] [ clock-id ID ] \
+[ board-label LABEL ] [ panel-label LABEL ] [ package-label LABEL ] \
+[ type TYPE ] [ direction DIR ] [ state STATE ] [ operstate OPERSTATE ]
 
 Display information about DPLL pins. If no arguments are specified,
 shows all pins in the system.
@@ -229,6 +232,15 @@ When combined with
 .BR parent-device ,
 only the specified parent-device relationship is checked.
 
+.TP
+.BI operstate " OPERSTATE"
+Show only pins that have a parent-device relationship with the specified
+operational state:
+.BR active ", " standby ", " no-signal ", " qual-failed .
+When combined with
+.BR parent-device ,
+only the specified parent-device relationship is checked.
+
 .PP
 Output includes:
 .RS
@@ -251,7 +263,7 @@ Capabilities (state-can-change, priority-can-change, direction-can-change)
 .IP \[bu]
 Phase adjustment range, granularity, and current value
 .IP \[bu]
-Parent device relationships (direction, priority, state, phase offset)
+Parent device relationships (direction, priority, state, operstate, phase offset)
 .IP \[bu]
 Parent pin relationships
 .IP \[bu]