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(-)
--
2.35.1
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: <[email protected]>
Signed-off-by: Heikki Krogerus <[email protected]>
---
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);
--
2.35.1
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: <[email protected]>
Signed-off-by: Heikki Krogerus <[email protected]>
---
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,
--
2.35.1
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,
--
heikki