Introducing struct typec_operations which has the same callbacks as struct typec_capability. The old callbacks are kept for now, but after all users have been converted, they will be removed.
Unified · Split
| @@ -54,6 +54,7 @@ struct typec_port { · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | const struct typec_capability *orig_cap; /* to be removed */ |
| 56 | 56 | const struct typec_capability *cap; |
| 57 | + const struct typec_operations *ops; | |
| 57 | 58 | }; |
| 58 | 59 | |
| 59 | 60 | #define to_typec_port(_dev_) container_of(_dev_, struct typec_port, dev) |
| @@ -956,7 +957,7 @@ preferred_role_store(struct device *dev, struct device_attribute *attr, · 896 unmodified lines | ||
| 956 | 957 | return -EOPNOTSUPP; |
| 957 | 958 | } |
| 958 | 959 | |
| 959 | − if (!port->cap->try_role) { | |
| 960 | + if (!port->cap->try_role && (!port->ops || !port->ops->try_role)) { | |
| 960 | 961 | dev_dbg(dev, "Setting preferred role not supported\n"); |
| 961 | 962 | return -EOPNOTSUPP; |
| 962 | 963 | } |
| @@ -969,7 +970,10 @@ preferred_role_store(struct device *dev, struct device_attribute *attr, · 6 unmodified lines | ||
| 969 | 970 | return -EINVAL; |
| 970 | 971 | } |
| 971 | 972 | |
| 972 | − ret = port->cap->try_role(port->orig_cap, role); | |
| 973 | + if (port->ops && port->ops->try_role) | |
| 974 | + ret = port->ops->try_role(port, role); | |
| 975 | + else | |
| 976 | + ret = port->cap->try_role(port->orig_cap, role); | |
| 973 | 977 | if (ret) |
| 974 | 978 | return ret; |
| 975 | 979 | |
| @@ -1000,7 +1004,7 @@ static ssize_t data_role_store(struct device *dev, · 24 unmodified lines | ||
| 1000 | 1004 | struct typec_port *port = to_typec_port(dev); |
| 1001 | 1005 | int ret; |
| 1002 | 1006 | |
| 1003 | − if (!port->cap->dr_set) { | |
| 1007 | + if (!port->cap->dr_set && (!port->ops || !port->ops->dr_set)) { | |
| 1004 | 1008 | dev_dbg(dev, "data role swapping not supported\n"); |
| 1005 | 1009 | return -EOPNOTSUPP; |
| 1006 | 1010 | } |
| @@ -1015,7 +1019,10 @@ static ssize_t data_role_store(struct device *dev, · 8 unmodified lines | ||
| 1015 | 1019 | goto unlock_and_ret; |
| 1016 | 1020 | } |
| 1017 | 1021 | |
| 1018 | − ret = port->cap->dr_set(port->orig_cap, ret); | |
| 1022 | + if (port->ops && port->ops->dr_set) | |
| 1023 | + ret = port->ops->dr_set(port, ret); | |
| 1024 | + else | |
| 1025 | + ret = port->cap->dr_set(port->orig_cap, ret); | |
| 1019 | 1026 | if (ret) |
| 1020 | 1027 | goto unlock_and_ret; |
| 1021 | 1028 | |
| @@ -1050,7 +1057,7 @@ static ssize_t power_role_store(struct device *dev, · 28 unmodified lines | ||
| 1050 | 1057 | return -EOPNOTSUPP; |
| 1051 | 1058 | } |
| 1052 | 1059 | |
| 1053 | − if (!port->cap->pr_set) { | |
| 1060 | + if (!port->cap->pr_set && (!port->ops || !port->ops->pr_set)) { | |
| 1054 | 1061 | dev_dbg(dev, "power role swapping not supported\n"); |
| 1055 | 1062 | return -EOPNOTSUPP; |
| 1056 | 1063 | } |
| @@ -1072,7 +1079,10 @@ static ssize_t power_role_store(struct device *dev, · 15 unmodified lines | ||
| 1072 | 1079 | goto unlock_and_ret; |
| 1073 | 1080 | } |
| 1074 | 1081 | |
| 1075 | − ret = port->cap->pr_set(port->orig_cap, ret); | |
| 1082 | + if (port->ops && port->ops->dr_set) | |
| 1083 | + ret = port->ops->pr_set(port, ret); | |
| 1084 | + else | |
| 1085 | + ret = port->cap->pr_set(port->orig_cap, ret); | |
| 1076 | 1086 | if (ret) |
| 1077 | 1087 | goto unlock_and_ret; |
| 1078 | 1088 | |
| @@ -1103,7 +1113,8 @@ port_type_store(struct device *dev, struct device_attribute *attr, · 24 unmodified lines | ||
| 1103 | 1113 | int ret; |
| 1104 | 1114 | enum typec_port_type type; |
| 1105 | 1115 | |
| 1106 | − if (!port->cap->port_type_set || port->cap->type != TYPEC_PORT_DRP) { | |
| 1116 | + if (port->cap->type != TYPEC_PORT_DRP || (!port->cap->port_type_set && | |
| 1117 | + (!port->ops || !port->ops->port_type_set))) { | |
| 1107 | 1118 | dev_dbg(dev, "changing port type not supported\n"); |
| 1108 | 1119 | return -EOPNOTSUPP; |
| 1109 | 1120 | } |
| @@ -1120,7 +1131,10 @@ port_type_store(struct device *dev, struct device_attribute *attr, · 10 unmodified lines | ||
| 1120 | 1131 | goto unlock_and_ret; |
| 1121 | 1132 | } |
| 1122 | 1133 | |
| 1123 | − ret = port->cap->port_type_set(port->orig_cap, type); | |
| 1134 | + if (port->ops && port->ops->port_type_set) | |
| 1135 | + ret = port->ops->port_type_set(port, type); | |
| 1136 | + else | |
| 1137 | + ret = port->cap->port_type_set(port->orig_cap, type); | |
| 1124 | 1138 | if (ret) |
| 1125 | 1139 | goto unlock_and_ret; |
| 1126 | 1140 | |
| @@ -1176,7 +1190,7 @@ static ssize_t vconn_source_store(struct device *dev, · 49 unmodified lines | ||
| 1176 | 1190 | return -EOPNOTSUPP; |
| 1177 | 1191 | } |
| 1178 | 1192 | |
| 1179 | − if (!port->cap->vconn_set) { | |
| 1193 | + if (!port->cap->vconn_set && (!port->ops || !port->ops->vconn_set)) { | |
| 1180 | 1194 | dev_dbg(dev, "VCONN swapping not supported\n"); |
| 1181 | 1195 | return -EOPNOTSUPP; |
| 1182 | 1196 | } |
| @@ -1185,7 +1199,11 @@ static ssize_t vconn_source_store(struct device *dev, · 2 unmodified lines | ||
| 1185 | 1199 | if (ret) |
| 1186 | 1200 | return ret; |
| 1187 | 1201 | |
| 1188 | − ret = port->cap->vconn_set(port->orig_cap, (enum typec_role)source); | |
| 1202 | + if (port->ops && port->ops->vconn_set) | |
| 1203 | + ret = port->ops->vconn_set(port, (enum typec_role)source); | |
| 1204 | + else | |
| 1205 | + ret = port->cap->vconn_set(port->orig_cap, | |
| 1206 | + (enum typec_role)source); | |
| 1189 | 1207 | if (ret) |
| 1190 | 1208 | return ret; |
| 1191 | 1209 | |
| @@ -1591,6 +1609,7 @@ struct typec_port *typec_register_port(struct device *parent, · 399 unmodified lines | ||
| 1591 | 1609 | mutex_init(&port->port_type_lock); |
| 1592 | 1610 | |
| 1593 | 1611 | port->id = id; |
| 1612 | + port->ops = cap->ops; | |
| 1594 | 1613 | port->orig_cap = cap; |
| 1595 | 1614 | port->port_type = cap->type; |
| 1596 | 1615 | port->prefer_role = cap->prefer_role; |
| @@ -168,6 +168,23 @@ struct typec_partner_desc { · 167 unmodified lines | ||
| 168 | 168 | struct usb_pd_identity *identity; |
| 169 | 169 | }; |
| 170 | 170 | |
| 171 | +/** | |
| 172 | + * struct typec_operations - USB Type-C Port Operations | |
| 173 | + * @try_role: Set data role preference for DRP port | |
| 174 | + * @dr_set: Set Data Role | |
| 175 | + * @pr_set: Set Power Role | |
| 176 | + * @vconn_set: Source VCONN | |
| 177 | + * @port_type_set: Set port type | |
| 178 | + */ | |
| 179 | +struct typec_operations { | |
| 180 | + int (*try_role)(struct typec_port *port, int role); | |
| 181 | + int (*dr_set)(struct typec_port *port, enum typec_data_role role); | |
| 182 | + int (*pr_set)(struct typec_port *port, enum typec_role role); | |
| 183 | + int (*vconn_set)(struct typec_port *port, enum typec_role role); | |
| 184 | + int (*port_type_set)(struct typec_port *port, | |
| 185 | + enum typec_port_type type); | |
| 186 | +}; | |
| 187 | + | |
| 171 | 188 | /* |
| 172 | 189 | * struct typec_capability - USB Type-C Port Capabilities |
| 173 | 190 | * @type: Supported power role of the port |
| @@ -180,6 +197,7 @@ struct typec_partner_desc { · 6 unmodified lines | ||
| 180 | 197 | * @mux: Multiplexer switch for Alternate/Accessory Modes |
| 181 | 198 | * @fwnode: Optional fwnode of the port |
| 182 | 199 | * @driver_data: Private pointer for driver specific info |
| 200 | + * @ops: Port operations vector | |
| 183 | 201 | * @try_role: Set data role preference for DRP port |
| 184 | 202 | * @dr_set: Set Data Role |
| 185 | 203 | * @pr_set: Set Power Role |
| @@ -201,6 +219,8 @@ struct typec_capability { · 15 unmodified lines | ||
| 201 | 219 | struct fwnode_handle *fwnode; |
| 202 | 220 | void *driver_data; |
| 203 | 221 | |
| 222 | + const struct typec_operations *ops; | |
| 223 | + | |
| 204 | 224 | int (*try_role)(const struct typec_capability *, |
| 205 | 225 | int role); |
| 206 | 226 | |