Add support for updating message out data structure for UCSI ACPI interface for UCSI 2.1 and UCSI 3.0 commands such as Set PDOs and LPM Firmware Update. Reviewed-by: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx> Signed-off-by: Pooja Katiyar <pooja.katiyar@xxxxxxxxx> --- drivers/usb/typec/ucsi/ucsi.c | 14 ++++++++++++++ drivers/usb/typec/ucsi/ucsi.h | 2 ++ drivers/usb/typec/ucsi/ucsi_acpi.c | 16 ++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index c953aa7d5283..02e43687c3f6 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -67,6 +67,20 @@ int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci) reinit_completion(&ucsi->complete); + if (ucsi->message_out_size > 0) { + if (!ucsi->ops->write_message_out) { + ucsi->message_out_size = 0; + ret = -EOPNOTSUPP; + goto out_clear_bit; + } + + ret = ucsi->ops->write_message_out(ucsi, ucsi->message_out, + ucsi->message_out_size); + ucsi->message_out_size = 0; + if (ret) + goto out_clear_bit; + } + ret = ucsi->ops->async_control(ucsi, command); if (ret) goto out_clear_bit; diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index 673f57eb7842..d932fa1a40b9 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -69,6 +69,7 @@ struct dentry; * @read_cci: Read CCI register * @poll_cci: Read CCI register while polling with notifications disabled * @read_message_in: Read message data from UCSI + * @write_message_out: Write message data to UCSI * @sync_control: Blocking control operation * @async_control: Non-blocking control operation * @update_altmodes: Squashes duplicate DP altmodes @@ -84,6 +85,7 @@ struct ucsi_operations { int (*read_cci)(struct ucsi *ucsi, u32 *cci); int (*poll_cci)(struct ucsi *ucsi, u32 *cci); int (*read_message_in)(struct ucsi *ucsi, void *val, size_t val_len); + int (*write_message_out)(struct ucsi *ucsi, void *data, size_t data_len); int (*sync_control)(struct ucsi *ucsi, u64 command, u32 *cci); int (*async_control)(struct ucsi *ucsi, u64 command); bool (*update_altmodes)(struct ucsi *ucsi, u8 recipient, diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c index f1d1f6917b09..f9beeb835238 100644 --- a/drivers/usb/typec/ucsi/ucsi_acpi.c +++ b/drivers/usb/typec/ucsi/ucsi_acpi.c @@ -86,6 +86,21 @@ static int ucsi_acpi_read_message_in(struct ucsi *ucsi, void *val, size_t val_le return 0; } +static int ucsi_acpi_write_message_out(struct ucsi *ucsi, void *data, size_t data_len) +{ + struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); + + if (!data || !data_len) + return -EINVAL; + + if (ucsi->version <= UCSI_VERSION_1_2) + memcpy(ua->base + UCSI_MESSAGE_OUT, data, data_len); + else + memcpy(ua->base + UCSIv2_MESSAGE_OUT, data, data_len); + + return 0; +} + static int ucsi_acpi_async_control(struct ucsi *ucsi, u64 command) { struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); @@ -101,6 +116,7 @@ static const struct ucsi_operations ucsi_acpi_ops = { .read_cci = ucsi_acpi_read_cci, .poll_cci = ucsi_acpi_poll_cci, .read_message_in = ucsi_acpi_read_message_in, + .write_message_out = ucsi_acpi_write_message_out, .sync_control = ucsi_sync_control_common, .async_control = ucsi_acpi_async_control }; -- 2.43.0