Skip to content

Commit 71a1fa0

Browse files
Heikki Krogerusgregkh
authored andcommitted
usb: typec: ucsi: Store the notification mask
The driver needs to ignore any Connector Change Events before the Connector Change Indication notifications have actually been enabled. This adds a check to ucsi_connector_change() function to make sure the function does not try to process the event unless the Connector Change notifications have been enabled. It is quite common that the firmware representing the "PPM" (Platform Policy Manager) starts generating Connector Change notifications even when only the Command Completion notifications are enabled. Signed-off-by: Heikki Krogerus <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 5311f88 commit 71a1fa0

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

drivers/usb/typec/ucsi/ucsi.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ int ucsi_resume(struct ucsi *ucsi)
189189
u64 command;
190190

191191
/* Restore UCSI notification enable mask after system resume */
192-
command = UCSI_SET_NOTIFICATION_ENABLE | UCSI_ENABLE_NTFY_ALL;
192+
command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
193193

194194
return ucsi_send_command(ucsi, command, NULL, 0);
195195
}
@@ -589,6 +589,11 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num)
589589
{
590590
struct ucsi_connector *con = &ucsi->connector[num - 1];
591591

592+
if (!(ucsi->ntfy & UCSI_ENABLE_NTFY_CONNECTOR_CHANGE)) {
593+
dev_dbg(ucsi->dev, "Bogus connetor change event\n");
594+
return;
595+
}
596+
592597
if (!test_and_set_bit(EVENT_PENDING, &ucsi->flags))
593598
schedule_work(&con->work);
594599
}
@@ -656,7 +661,7 @@ static int ucsi_role_cmd(struct ucsi_connector *con, u64 command)
656661
ucsi_reset_ppm(con->ucsi);
657662
mutex_unlock(&con->ucsi->ppm_lock);
658663

659-
c = UCSI_SET_NOTIFICATION_ENABLE | UCSI_ENABLE_NTFY_ALL;
664+
c = UCSI_SET_NOTIFICATION_ENABLE | con->ucsi->ntfy;
660665
ucsi_send_command(con->ucsi, c, NULL, 0);
661666

662667
ucsi_reset_connector(con, true);
@@ -890,8 +895,8 @@ int ucsi_init(struct ucsi *ucsi)
890895
}
891896

892897
/* Enable basic notifications */
893-
command = UCSI_SET_NOTIFICATION_ENABLE;
894-
command |= UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
898+
ucsi->ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
899+
command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
895900
ret = ucsi_run_command(ucsi, command, NULL, 0);
896901
if (ret < 0)
897902
goto err_reset;
@@ -923,7 +928,7 @@ int ucsi_init(struct ucsi *ucsi)
923928
}
924929

925930
/* Enable all notifications */
926-
command = UCSI_SET_NOTIFICATION_ENABLE | UCSI_ENABLE_NTFY_ALL;
931+
command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
927932
ret = ucsi_run_command(ucsi, command, NULL, 0);
928933
if (ret < 0)
929934
goto err_unregister;

drivers/usb/typec/ucsi/ucsi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,9 @@ struct ucsi {
269269
/* PPM Communication lock */
270270
struct mutex ppm_lock;
271271

272+
/* The latest "Notification Enable" bits (SET_NOTIFICATION_ENABLE) */
273+
u64 ntfy;
274+
272275
/* PPM communication flags */
273276
unsigned long flags;
274277
#define EVENT_PENDING 0

0 commit comments

Comments
 (0)