]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
dpll: add direction and state filtering for pin show
authorPetr Oros <poros@redhat.com>
Tue, 31 Mar 2026 13:59:18 +0000 (15:59 +0200)
committerDavid Ahern <dsahern@kernel.org>
Sun, 5 Apr 2026 16:06:10 +0000 (10:06 -0600)
Allow filtering pins by direction (input/output) and state
(connected/disconnected/selectable) in the pin show command.
These filters match against parent-device nested attributes and
can be combined with the parent-device filter to check a specific
parent-device relationship.

Example: dpll pin show parent-device 0 direction input state connected
Signed-off-by: Petr Oros <poros@redhat.com>
Tested-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 b3ba0d306183ac4e2db4deac32bfdd730d1cc277..542b99c2fce264cfa3411332372dfeb2c9bb3091 100644 (file)
@@ -181,10 +181,19 @@ _dpll_pin()
                         int-oscillator gnss" -- "$cur" ) )
                     return 0
                     ;;
+                direction)
+                    COMPREPLY=( $( compgen -W "input output" -- "$cur" ) )
+                    return 0
+                    ;;
+                state)
+                    COMPREPLY=( $( compgen -W \
+                        "connected disconnected selectable" -- "$cur" ) )
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=( $( compgen -W "id parent-device parent-pin \
                         module-name clock-id board-label panel-label \
-                        package-label type" \
+                        package-label type direction state" \
                         -- "$cur" ) )
                     return 0
                     ;;
index 9893ca8c41d5fd98c470fd2b659f627511fb7b17..413c628d20ce31630cea709a31ff86aad1ca3da4 100644 (file)
@@ -162,6 +162,17 @@ static int str_to_dpll_pin_state(const char *state_str, __u32 *state)
        return 0;
 }
 
+static int str_to_dpll_pin_direction(const char *dir_str, __u32 *direction)
+{
+       int num;
+
+       num = str_map_lookup_str(pin_direction_map, dir_str);
+       if (num < 0)
+               return num;
+       *direction = num;
+       return 0;
+}
+
 static int str_to_dpll_pin_type(const char *type_str, __u32 *type)
 {
        int num;
@@ -891,6 +902,8 @@ static bool dpll_device_dump_filter(struct dpll_device_filter *filter,
 #define DPLL_FILTER_PIN_TYPE           BIT(5)
 #define DPLL_FILTER_PIN_PARENT_DEVICE  BIT(6)
 #define DPLL_FILTER_PIN_PARENT_PIN     BIT(7)
+#define DPLL_FILTER_PIN_DIRECTION      BIT(8)
+#define DPLL_FILTER_PIN_STATE          BIT(9)
 
 struct dpll_pin_filter {
        uint64_t present;
@@ -902,6 +915,8 @@ struct dpll_pin_filter {
        __u32 type;
        __u32 parent_device_id;
        __u32 parent_pin_id;
+       __u32 direction;
+       __u32 state;
 };
 
 static bool filter_match_nested_id(const struct nlmsghdr *nlh,
@@ -923,6 +938,39 @@ static bool filter_match_nested_id(const struct nlmsghdr *nlh,
        return false;
 }
 
+static bool filter_match_nested_parent_device(const struct nlmsghdr *nlh,
+                                             struct dpll_pin_filter *filter)
+{
+       const struct nlattr *attr;
+
+       mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+               struct nlattr *tb_nest[DPLL_A_PIN_MAX + 1] = {};
+
+               if (mnl_attr_get_type(attr) != DPLL_A_PIN_PARENT_DEVICE)
+                       continue;
+
+               mnl_attr_parse_nested(attr, attr_pin_cb, tb_nest);
+
+               if ((filter->present & DPLL_FILTER_PIN_PARENT_DEVICE) &&
+                   !filter_match_u32(tb_nest[DPLL_A_PIN_PARENT_ID],
+                                     filter->parent_device_id))
+                       continue;
+
+               if ((filter->present & DPLL_FILTER_PIN_DIRECTION) &&
+                   !filter_match_u32(tb_nest[DPLL_A_PIN_DIRECTION],
+                                     filter->direction))
+                       continue;
+
+               if ((filter->present & DPLL_FILTER_PIN_STATE) &&
+                   !filter_match_u32(tb_nest[DPLL_A_PIN_STATE],
+                                     filter->state))
+                       continue;
+
+               return true;
+       }
+       return false;
+}
+
 static bool dpll_pin_dump_filter(struct dpll_pin_filter *filter,
                                 const struct nlmsghdr *nlh,
                                 struct nlattr **tb)
@@ -949,9 +997,10 @@ static bool dpll_pin_dump_filter(struct dpll_pin_filter *filter,
        if ((filter->present & DPLL_FILTER_PIN_TYPE) &&
            !filter_match_u32(tb[DPLL_A_PIN_TYPE], filter->type))
                return false;
-       if ((filter->present & DPLL_FILTER_PIN_PARENT_DEVICE) &&
-           !filter_match_nested_id(nlh, DPLL_A_PIN_PARENT_DEVICE,
-                                   filter->parent_device_id))
+       if ((filter->present & (DPLL_FILTER_PIN_PARENT_DEVICE |
+                               DPLL_FILTER_PIN_DIRECTION |
+                               DPLL_FILTER_PIN_STATE)) &&
+           !filter_match_nested_parent_device(nlh, filter))
                return false;
        if ((filter->present & DPLL_FILTER_PIN_PARENT_PIN) &&
            !filter_match_nested_id(nlh, DPLL_A_PIN_PARENT_PIN,
@@ -1861,6 +1910,22 @@ static int cmd_pin_show(struct dpll *dpll)
                                                   str_to_dpll_pin_type,
                                                   "mux/ext/synce-eth-port/int-oscillator/gnss"))
                                return -EINVAL;
+               } else if (dpll_argv_match(dpll, "direction")) {
+                       if (dpll_filter_parse_enum(dpll, "direction",
+                                                  &filter.direction,
+                                                  &filter.present,
+                                                  DPLL_FILTER_PIN_DIRECTION,
+                                                  str_to_dpll_pin_direction,
+                                                  "input/output"))
+                               return -EINVAL;
+               } else if (dpll_argv_match(dpll, "state")) {
+                       if (dpll_filter_parse_enum(dpll, "state",
+                                                  &filter.state,
+                                                  &filter.present,
+                                                  DPLL_FILTER_PIN_STATE,
+                                                  str_to_dpll_pin_state,
+                                                  "connected/disconnected/selectable"))
+                               return -EINVAL;
                } else {
                        pr_err("unknown option: %s\n", dpll_argv(dpll));
                        return -EINVAL;
index 86bc1a7e56d9f8ba8f526938b2f83afec4f40296..89f17af749233cd7bf82aebb755f8eed66207358 100644 (file)
@@ -161,7 +161,7 @@ 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 ]
+.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 ]
 
 Display information about DPLL pins. If no arguments are specified,
 shows all pins in the system.
@@ -203,6 +203,22 @@ Show only pins with the specified package label.
 Show only pins of the specified type:
 .BR mux ", " ext ", " synce-eth-port ", " int-oscillator ", " gnss .
 
+.TP
+.BI direction " DIR"
+Show only pins that have a parent-device relationship with the specified direction:
+.BR input ", " output .
+When combined with
+.BR parent-device ,
+only the specified parent-device relationship is checked.
+
+.TP
+.BI state " STATE"
+Show only pins that have a parent-device relationship with the specified state:
+.BR connected ", " disconnected ", " selectable .
+When combined with
+.BR parent-device ,
+only the specified parent-device relationship is checked.
+
 .PP
 Output includes:
 .RS
@@ -386,6 +402,11 @@ Press Ctrl+C to stop monitoring.
 .B dpll -jp pin show id 5
 .fi
 
+.SS Show connected input pins on device 0
+.nf
+.B dpll pin show parent-device 0 direction input state connected
+.fi
+
 .SS Set pin frequency to 10 MHz
 .nf
 .B dpll pin set id 0 frequency 10000000