2
0
mirror of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2025-09-04 20:19:47 +08:00

thunderbolt: Notify userspace about firmware CM tunneling events

In the same way we do for software connection manager, send
notifications about tunneling changes done by the firmware connection
manager as well. There are some limitations with this though, for
example we only get "DP Configuration Changed" message from the firmware
without any indication if DisplayPort tunnel was activated or
deactivated. Also we don't get information about the tunnel itself
either so the event then looks like:

  TUNNEL_EVENT=changed
  TUNNEL_DETAILS=(DP)

XDomain connections are similar to what the software connection manager
sends.

Signed-off-by: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
This commit is contained in:
Alan Borzeszkowski 2025-01-20 19:19:22 +01:00 committed by Mika Westerberg
parent 785da9e6a1
commit 607063f08e
2 changed files with 36 additions and 1 deletions

View File

@ -22,6 +22,7 @@
#include "ctl.h"
#include "nhi_regs.h"
#include "tb.h"
#include "tunnel.h"
#define PCIE2CIO_CMD 0x30
#define PCIE2CIO_CMD_TIMEOUT BIT(31)
@ -379,6 +380,27 @@ static bool icm_firmware_running(const struct tb_nhi *nhi)
return !!(val & REG_FW_STS_ICM_EN);
}
static void icm_xdomain_activated(struct tb_xdomain *xd, bool activated)
{
struct tb_port *nhi_port, *dst_port;
struct tb *tb = xd->tb;
nhi_port = tb_switch_find_port(tb->root_switch, TB_TYPE_NHI);
dst_port = tb_xdomain_downstream_port(xd);
if (activated)
tb_tunnel_event(tb, TB_TUNNEL_ACTIVATED, TB_TUNNEL_DMA,
nhi_port, dst_port);
else
tb_tunnel_event(tb, TB_TUNNEL_DEACTIVATED, TB_TUNNEL_DMA,
nhi_port, dst_port);
}
static void icm_dp_event(struct tb *tb)
{
tb_tunnel_event(tb, TB_TUNNEL_CHANGED, TB_TUNNEL_DP, NULL, NULL);
}
static bool icm_fr_is_supported(struct tb *tb)
{
return !x86_apple_machine;
@ -584,6 +606,7 @@ static int icm_fr_approve_xdomain_paths(struct tb *tb, struct tb_xdomain *xd,
if (reply.hdr.flags & ICM_FLAGS_ERROR)
return -EIO;
icm_xdomain_activated(xd, true);
return 0;
}
@ -603,6 +626,8 @@ static int icm_fr_disconnect_xdomain_paths(struct tb *tb, struct tb_xdomain *xd,
nhi_mailbox_cmd(tb->nhi, cmd, 1);
usleep_range(10, 50);
nhi_mailbox_cmd(tb->nhi, cmd, 2);
icm_xdomain_activated(xd, false);
return 0;
}
@ -1151,6 +1176,7 @@ static int icm_tr_approve_xdomain_paths(struct tb *tb, struct tb_xdomain *xd,
if (reply.hdr.flags & ICM_FLAGS_ERROR)
return -EIO;
icm_xdomain_activated(xd, true);
return 0;
}
@ -1191,7 +1217,12 @@ static int icm_tr_disconnect_xdomain_paths(struct tb *tb, struct tb_xdomain *xd,
return ret;
usleep_range(10, 50);
return icm_tr_xdomain_tear_down(tb, xd, 2);
ret = icm_tr_xdomain_tear_down(tb, xd, 2);
if (ret)
return ret;
icm_xdomain_activated(xd, false);
return 0;
}
static void
@ -1718,6 +1749,9 @@ static void icm_handle_notification(struct work_struct *work)
if (tb_is_xdomain_enabled())
icm->xdomain_disconnected(tb, n->pkg);
break;
case ICM_EVENT_DP_CONFIG_CHANGED:
icm_dp_event(tb);
break;
case ICM_EVENT_RTD3_VETO:
icm->rtd3_veto(tb, n->pkg);
break;

View File

@ -118,6 +118,7 @@ enum icm_event_code {
ICM_EVENT_DEVICE_DISCONNECTED = 0x4,
ICM_EVENT_XDOMAIN_CONNECTED = 0x6,
ICM_EVENT_XDOMAIN_DISCONNECTED = 0x7,
ICM_EVENT_DP_CONFIG_CHANGED = 0x8,
ICM_EVENT_RTD3_VETO = 0xa,
};