hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/usb/typec/altmodes/displayport.c
....@@ -114,8 +114,12 @@
114114 if (dp->data.status & DP_STATUS_PREFER_MULTI_FUNC &&
115115 pin_assign & DP_PIN_ASSIGN_MULTI_FUNC_MASK)
116116 pin_assign &= DP_PIN_ASSIGN_MULTI_FUNC_MASK;
117
- else if (pin_assign & DP_PIN_ASSIGN_DP_ONLY_MASK)
117
+ else if (pin_assign & DP_PIN_ASSIGN_DP_ONLY_MASK) {
118118 pin_assign &= DP_PIN_ASSIGN_DP_ONLY_MASK;
119
+ /* Default to pin assign C if available */
120
+ if (pin_assign & BIT(DP_PIN_ASSIGN_C))
121
+ pin_assign = BIT(DP_PIN_ASSIGN_C);
122
+ }
119123
120124 /*
121125 * DFP_U never selects Pin Assignment E when Pin Assignment C
....@@ -444,6 +448,18 @@
444448 [DP_PIN_ASSIGN_F] = "F",
445449 };
446450
451
+/*
452
+ * Helper function to extract a peripheral's currently supported
453
+ * Pin Assignments from its DisplayPort alternate mode state.
454
+ */
455
+static u8 get_current_pin_assignments(struct dp_altmode *dp)
456
+{
457
+ if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D)
458
+ return DP_CAP_PIN_ASSIGN_DFP_D(dp->alt->vdo);
459
+ else
460
+ return DP_CAP_PIN_ASSIGN_UFP_D(dp->alt->vdo);
461
+}
462
+
447463 static ssize_t
448464 pin_assignment_store(struct device *dev, struct device_attribute *attr,
449465 const char *buf, size_t size)
....@@ -470,7 +486,7 @@
470486 goto out_unlock;
471487 }
472488
473
- assignments = DP_CAP_PIN_ASSIGN(dp->alt->vdo);
489
+ assignments = get_current_pin_assignments(dp);
474490
475491 if (!(DP_CONF_GET_PIN_ASSIGN(conf) & assignments)) {
476492 ret = -EINVAL;
....@@ -507,7 +523,7 @@
507523
508524 cur = get_count_order(DP_CONF_GET_PIN_ASSIGN(dp->data.conf));
509525
510
- assignments = DP_CAP_PIN_ASSIGN(dp->alt->vdo);
526
+ assignments = get_current_pin_assignments(dp);
511527
512528 for (i = 0; assignments; assignments >>= 1, i++) {
513529 if (assignments & 1) {
....@@ -521,6 +537,10 @@
521537 }
522538
523539 mutex_unlock(&dp->lock);
540
+
541
+ /* get_current_pin_assignments can return 0 when no matching pin assignments are found */
542
+ if (len == 0)
543
+ len++;
524544
525545 buf[len - 1] = '\n';
526546 return len;
....@@ -548,10 +568,10 @@
548568 /* FIXME: Port can only be DFP_U. */
549569
550570 /* Make sure we have compatiple pin configurations */
551
- if (!(DP_CAP_DFP_D_PIN_ASSIGN(port->vdo) &
552
- DP_CAP_UFP_D_PIN_ASSIGN(alt->vdo)) &&
553
- !(DP_CAP_UFP_D_PIN_ASSIGN(port->vdo) &
554
- DP_CAP_DFP_D_PIN_ASSIGN(alt->vdo)))
571
+ if (!(DP_CAP_PIN_ASSIGN_DFP_D(port->vdo) &
572
+ DP_CAP_PIN_ASSIGN_UFP_D(alt->vdo)) &&
573
+ !(DP_CAP_PIN_ASSIGN_UFP_D(port->vdo) &
574
+ DP_CAP_PIN_ASSIGN_DFP_D(alt->vdo)))
555575 return -ENODEV;
556576
557577 ret = sysfs_create_group(&alt->dev.kobj, &dp_altmode_group);