Skip to content

Commit

Permalink
usb: ucsi_acpi: Fix command completion handling
Browse files Browse the repository at this point in the history
In case of a spurious or otherwise delayed notification it is
possible that CCI still reports the previous completion. The
UCSI spec is aware of this and provides two completion bits in
CCI, one for normal commands and one for acks. As acks and commands
alternate the notification handler can determine if the completion
bit is from the current command.

The initial UCSI code correctly handled this but the distinction
between the two completion bits was lost with the introduction of
the new API.

To fix this revive the ACK_PENDING bit for ucsi_acpi and only complete
commands if the completion bit matches.

Fixes: f56de27 ("usb: typec: ucsi: acpi: Move to the new API")
Cc: [email protected]
Signed-off-by: "Christian A. Ehrhardt" <[email protected]>
Acked-by: Heikki Krogerus <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
Christian A. Ehrhardt authored and gregkh committed Jan 28, 2024
1 parent c9aed03 commit 2840143
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions drivers/usb/typec/ucsi/ucsi_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,13 @@ static int ucsi_acpi_sync_write(struct ucsi *ucsi, unsigned int offset,
const void *val, size_t val_len)
{
struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
bool ack = UCSI_COMMAND(*(u64 *)val) == UCSI_ACK_CC_CI;
int ret;

set_bit(COMMAND_PENDING, &ua->flags);
if (ack)
set_bit(ACK_PENDING, &ua->flags);
else
set_bit(COMMAND_PENDING, &ua->flags);

ret = ucsi_acpi_async_write(ucsi, offset, val, val_len);
if (ret)
Expand All @@ -85,7 +89,10 @@ static int ucsi_acpi_sync_write(struct ucsi *ucsi, unsigned int offset,
ret = -ETIMEDOUT;

out_clear_bit:
clear_bit(COMMAND_PENDING, &ua->flags);
if (ack)
clear_bit(ACK_PENDING, &ua->flags);
else
clear_bit(COMMAND_PENDING, &ua->flags);

return ret;
}
Expand Down Expand Up @@ -142,8 +149,10 @@ static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data)
if (UCSI_CCI_CONNECTOR(cci))
ucsi_connector_change(ua->ucsi, UCSI_CCI_CONNECTOR(cci));

if (test_bit(COMMAND_PENDING, &ua->flags) &&
cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE))
if (cci & UCSI_CCI_ACK_COMPLETE && test_bit(ACK_PENDING, &ua->flags))
complete(&ua->complete);
if (cci & UCSI_CCI_COMMAND_COMPLETE &&
test_bit(COMMAND_PENDING, &ua->flags))
complete(&ua->complete);
}

Expand Down

0 comments on commit 2840143

Please sign in to comment.