usb: typec: ucsi: Check the connection on resume
commit99f6d43611upstream. Checking the connection status of every port on resume. This fixes an issue where the partner device is not unregistered properly after resume if it was unplugged while the system was suspended. The function ucsi_check_connection() is also modified so that it can be used also for registering the connection on top of unregistering it. Link: https://bugzilla.kernel.org/show_bug.cgi?id=210425 Fixes:a94ecde41f("usb: typec: ucsi: ccg: enable runtime pm support") Cc: <stable@vger.kernel.org> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Link: https://lore.kernel.org/r/20221007100951.43798-2-heikki.krogerus@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
d1b9d6a568
commit
76bac6cfb0
@@ -183,16 +183,6 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ucsi_send_command);
|
||||
|
||||
int ucsi_resume(struct ucsi *ucsi)
|
||||
{
|
||||
u64 command;
|
||||
|
||||
/* Restore UCSI notification enable mask after system resume */
|
||||
command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
|
||||
|
||||
return ucsi_send_command(ucsi, command, NULL, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ucsi_resume);
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
struct ucsi_work {
|
||||
@@ -744,6 +734,7 @@ static void ucsi_partner_change(struct ucsi_connector *con)
|
||||
|
||||
static int ucsi_check_connection(struct ucsi_connector *con)
|
||||
{
|
||||
u8 prev_flags = con->status.flags;
|
||||
u64 command;
|
||||
int ret;
|
||||
|
||||
@@ -754,10 +745,13 @@ static int ucsi_check_connection(struct ucsi_connector *con)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (con->status.flags == prev_flags)
|
||||
return 0;
|
||||
|
||||
if (con->status.flags & UCSI_CONSTAT_CONNECTED) {
|
||||
if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) ==
|
||||
UCSI_CONSTAT_PWR_OPMODE_PD)
|
||||
ucsi_partner_task(con, ucsi_check_altmodes, 30, 0);
|
||||
ucsi_register_partner(con);
|
||||
ucsi_pwr_opmode_change(con);
|
||||
ucsi_partner_change(con);
|
||||
} else {
|
||||
ucsi_partner_change(con);
|
||||
ucsi_port_psy_changed(con);
|
||||
@@ -1276,6 +1270,28 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ucsi_resume(struct ucsi *ucsi)
|
||||
{
|
||||
struct ucsi_connector *con;
|
||||
u64 command;
|
||||
int ret;
|
||||
|
||||
/* Restore UCSI notification enable mask after system resume */
|
||||
command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
|
||||
ret = ucsi_send_command(ucsi, command, NULL, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (con = ucsi->connector; con->port; con++) {
|
||||
mutex_lock(&con->lock);
|
||||
ucsi_check_connection(con);
|
||||
mutex_unlock(&con->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ucsi_resume);
|
||||
|
||||
static void ucsi_init_work(struct work_struct *work)
|
||||
{
|
||||
struct ucsi *ucsi = container_of(work, struct ucsi, work.work);
|
||||
|
||||
Reference in New Issue
Block a user