Skip to content

Commit

Permalink
usb: typec: ucsi: Store the notification mask
Browse files Browse the repository at this point in the history
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 <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20191230133431.63445-2-heikki.krogerus@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Heikki Krogerus authored and Greg Kroah-Hartman committed Dec 30, 2019
1 parent 5311f88 commit 71a1fa0
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 5 deletions.
15 changes: 10 additions & 5 deletions drivers/usb/typec/ucsi/ucsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ int ucsi_resume(struct ucsi *ucsi)
u64 command;

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

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

if (!(ucsi->ntfy & UCSI_ENABLE_NTFY_CONNECTOR_CHANGE)) {
dev_dbg(ucsi->dev, "Bogus connetor change event\n");
return;
}

if (!test_and_set_bit(EVENT_PENDING, &ucsi->flags))
schedule_work(&con->work);
}
Expand Down Expand Up @@ -656,7 +661,7 @@ static int ucsi_role_cmd(struct ucsi_connector *con, u64 command)
ucsi_reset_ppm(con->ucsi);
mutex_unlock(&con->ucsi->ppm_lock);

c = UCSI_SET_NOTIFICATION_ENABLE | UCSI_ENABLE_NTFY_ALL;
c = UCSI_SET_NOTIFICATION_ENABLE | con->ucsi->ntfy;
ucsi_send_command(con->ucsi, c, NULL, 0);

ucsi_reset_connector(con, true);
Expand Down Expand Up @@ -890,8 +895,8 @@ int ucsi_init(struct ucsi *ucsi)
}

/* Enable basic notifications */
command = UCSI_SET_NOTIFICATION_ENABLE;
command |= UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
ucsi->ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
ret = ucsi_run_command(ucsi, command, NULL, 0);
if (ret < 0)
goto err_reset;
Expand Down Expand Up @@ -923,7 +928,7 @@ int ucsi_init(struct ucsi *ucsi)
}

/* Enable all notifications */
command = UCSI_SET_NOTIFICATION_ENABLE | UCSI_ENABLE_NTFY_ALL;
command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
ret = ucsi_run_command(ucsi, command, NULL, 0);
if (ret < 0)
goto err_unregister;
Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/typec/ucsi/ucsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ struct ucsi {
/* PPM Communication lock */
struct mutex ppm_lock;

/* The latest "Notification Enable" bits (SET_NOTIFICATION_ENABLE) */
u64 ntfy;

/* PPM communication flags */
unsigned long flags;
#define EVENT_PENDING 0
Expand Down

0 comments on commit 71a1fa0

Please sign in to comment.