diff options
author | Mika Westerberg <mika.westerberg@linux.intel.com> | 2024-01-09 18:53:53 +0300 |
---|---|---|
committer | Mika Westerberg <mika.westerberg@linux.intel.com> | 2024-02-16 13:29:22 +0300 |
commit | 37f49727cc53b1987859fc767ac637078d351c4d (patch) | |
tree | b16d9e12a014d3212d295853709a5309f693a4d3 /drivers | |
parent | 2ec67a48cf8f18b8c6cecc70dcd5d52cbf8eba7e (diff) | |
download | linux-37f49727cc53b1987859fc767ac637078d351c4d.tar.xz |
thunderbolt: Fail the failed bandwidth request properly
The USB4 spec says that if the Connection Manager writes Allocated_BW
that is smaller than Requested_BW, the DisplayPort IN adapter signals
this failure back to the DPTX (graphics driver). Implement this by
rewriting the same allocated bandwidth values back.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/thunderbolt/tb.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index abd86fd8d71f..9dbdf2770f0b 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -2270,11 +2270,11 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, */ ret = tb_tunnel_maximum_bandwidth(tunnel, &max_up, &max_down); if (ret) - return ret; + goto fail; ret = usb4_dp_port_granularity(in); if (ret < 0) - return ret; + goto fail; granularity = ret; max_up_rounded = roundup(max_up, granularity); @@ -2304,7 +2304,8 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, "bandwidth request too high (%d/%d Mb/s > %d/%d Mb/s)\n", requested_up_corrected, requested_down_corrected, max_up_rounded, max_down_rounded); - return -ENOBUFS; + ret = -ENOBUFS; + goto fail; } if ((*requested_up >= 0 && requested_up_corrected <= allocated_up) || @@ -2332,7 +2333,7 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, */ ret = tb_release_unused_usb3_bandwidth(tb, in, out); if (ret) - return ret; + goto fail; /* * Then go over all tunnels that cross the same USB4 ports (they @@ -2357,7 +2358,7 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, *requested_down); if (ret) { tb_configure_sym(tb, in, out, 0, 0, true); - return ret; + goto fail; } ret = tb_tunnel_alloc_bandwidth(tunnel, requested_up, @@ -2372,6 +2373,18 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, reclaim: tb_reclaim_usb3_bandwidth(tb, in, out); +fail: + if (ret && ret != -ENODEV) { + /* + * Write back the same allocated (so no change), this + * makes the DPTX request fail on graphics side. + */ + tb_tunnel_dbg(tunnel, + "failing the request by rewriting allocated %d/%d Mb/s\n", + allocated_up, allocated_down); + tb_tunnel_alloc_bandwidth(tunnel, &allocated_up, &allocated_down); + } + return ret; } |