Hi Greg,
These two patches fix an issue where the ucsi drivers fail to detect changes on the connection status (connections/disconnections) that happen while the system is suspended.
Heikki Krogerus (2): usb: typec: ucsi: Check the connection on resume usb: typec: ucsi: acpi: Implement resume callback
drivers/usb/typec/ucsi/ucsi.c | 42 +++++++++++++++++++++--------- drivers/usb/typec/ucsi/ucsi_acpi.c | 10 +++++++ 2 files changed, 39 insertions(+), 13 deletions(-)
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: a94ecde41f7e ("usb: typec: ucsi: ccg: enable runtime pm support") Cc: stable@vger.kernel.org Signed-off-by: Heikki Krogerus heikki.krogerus@linux.intel.com --- drivers/usb/typec/ucsi/ucsi.c | 42 ++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 13 deletions(-)
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 74fb5a4c6f21b..a7987fc764cc6 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -183,16 +183,6 @@ int ucsi_send_command(struct ucsi *ucsi, u64 command, } 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 @@ static int ucsi_init(struct ucsi *ucsi) 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);
The ACPI driver needs to resume the interface by calling ucsi_resume(). Otherwise we may fail to detect connections and disconnections that happen while the system is suspended.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=210425 Fixes: a94ecde41f7e ("usb: typec: ucsi: ccg: enable runtime pm support") Cc: stable@vger.kernel.org Signed-off-by: Heikki Krogerus heikki.krogerus@linux.intel.com --- drivers/usb/typec/ucsi/ucsi_acpi.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c index 8873c1644a295..ce0c8ef80c043 100644 --- a/drivers/usb/typec/ucsi/ucsi_acpi.c +++ b/drivers/usb/typec/ucsi/ucsi_acpi.c @@ -185,6 +185,15 @@ static int ucsi_acpi_remove(struct platform_device *pdev) return 0; }
+static int ucsi_acpi_resume(struct device *dev) +{ + struct ucsi_acpi *ua = dev_get_drvdata(dev); + + return ucsi_resume(ua->ucsi); +} + +static DEFINE_SIMPLE_DEV_PM_OPS(ucsi_acpi_pm_ops, NULL, ucsi_acpi_resume); + static const struct acpi_device_id ucsi_acpi_match[] = { { "PNP0CA0", 0 }, { }, @@ -194,6 +203,7 @@ MODULE_DEVICE_TABLE(acpi, ucsi_acpi_match); static struct platform_driver ucsi_acpi_platform_driver = { .driver = { .name = "ucsi_acpi", + .pm = pm_ptr(&ucsi_acpi_pm_ops), .acpi_match_table = ACPI_PTR(ucsi_acpi_match), }, .probe = ucsi_acpi_probe,
On Fri, Oct 07, 2022 at 01:09:49PM +0300, Heikki Krogerus wrote:
Hi Greg,
These two patches fix an issue where the ucsi drivers fail to detect changes on the connection status (connections/disconnections) that happen while the system is suspended.
Heikki Krogerus (2): usb: typec: ucsi: Check the connection on resume usb: typec: ucsi: acpi: Implement resume callback
drivers/usb/typec/ucsi/ucsi.c | 42 +++++++++++++++++++++--------- drivers/usb/typec/ucsi/ucsi_acpi.c | 10 +++++++ 2 files changed, 39 insertions(+), 13 deletions(-)
These are ok to go in after -rc1, right?
thanks,
greg k-h
On Fri, Oct 07, 2022 at 04:39:57PM +0200, Greg Kroah-Hartman wrote:
On Fri, Oct 07, 2022 at 01:09:49PM +0300, Heikki Krogerus wrote:
Hi Greg,
These two patches fix an issue where the ucsi drivers fail to detect changes on the connection status (connections/disconnections) that happen while the system is suspended.
Heikki Krogerus (2): usb: typec: ucsi: Check the connection on resume usb: typec: ucsi: acpi: Implement resume callback
drivers/usb/typec/ucsi/ucsi.c | 42 +++++++++++++++++++++--------- drivers/usb/typec/ucsi/ucsi_acpi.c | 10 +++++++ 2 files changed, 39 insertions(+), 13 deletions(-)
These are ok to go in after -rc1, right?
Yes, I think so.
thanks,
linux-stable-mirror@lists.linaro.org