Skip to content

Commit

Permalink
usb: typec: ucsi: return CCI and message from sync_control callback
Browse files Browse the repository at this point in the history
Some of the drivers emulate or handle some of the commands in the
platform-specific way. The code ends up being split between several
callbacks, which complicates emulation.

In preparation to reworking such drivers, move read_cci() and
read_message_in() calls into ucsi_sync_control_common().

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Łukasz Bartosik <ukaszb@chromium.org>
Link: https://lore.kernel.org/r/20250120-ucsi-merge-commands-v2-1-462a1ec22ecc@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Dmitry Baryshkov authored and Greg Kroah-Hartman committed Feb 3, 2025
1 parent 41d5e38 commit 667ecac
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 16 deletions.
5 changes: 3 additions & 2 deletions drivers/usb/typec/ucsi/cros_ec_ucsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,13 @@ static int cros_ucsi_async_control(struct ucsi *ucsi, u64 cmd)
return 0;
}

static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd)
static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd, u32 *cci,
void *data, size_t size)
{
struct cros_ucsi_data *udata = ucsi_get_drvdata(ucsi);
int ret;

ret = ucsi_sync_control_common(ucsi, cmd);
ret = ucsi_sync_control_common(ucsi, cmd, cci, data, size);
switch (ret) {
case -EBUSY:
/* EC may return -EBUSY if CCI.busy is set.
Expand Down
19 changes: 11 additions & 8 deletions drivers/usb/typec/ucsi/ucsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ void ucsi_notify_common(struct ucsi *ucsi, u32 cci)
}
EXPORT_SYMBOL_GPL(ucsi_notify_common);

int ucsi_sync_control_common(struct ucsi *ucsi, u64 command)
int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,
void *data, size_t size)
{
bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI;
int ret;
Expand All @@ -80,6 +81,13 @@ int ucsi_sync_control_common(struct ucsi *ucsi, u64 command)
else
clear_bit(COMMAND_PENDING, &ucsi->flags);

if (!ret && cci)
ret = ucsi->ops->read_cci(ucsi, cci);

if (!ret && data &&
(*cci & UCSI_CCI_COMMAND_COMPLETE))
ret = ucsi->ops->read_message_in(ucsi, data, size);

return ret;
}
EXPORT_SYMBOL_GPL(ucsi_sync_control_common);
Expand All @@ -95,7 +103,7 @@ static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack)
ctrl |= UCSI_ACK_CONNECTOR_CHANGE;
}

return ucsi->ops->sync_control(ucsi, ctrl);
return ucsi->ops->sync_control(ucsi, ctrl, NULL, NULL, 0);
}

static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
Expand All @@ -108,9 +116,7 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
if (size > UCSI_MAX_DATA_LENGTH(ucsi))
return -EINVAL;

ret = ucsi->ops->sync_control(ucsi, command);
if (ucsi->ops->read_cci(ucsi, cci))
return -EIO;
ret = ucsi->ops->sync_control(ucsi, command, cci, data, size);

if (*cci & UCSI_CCI_BUSY)
return ucsi_run_command(ucsi, UCSI_CANCEL, cci, NULL, 0, false) ?: -EBUSY;
Expand All @@ -127,9 +133,6 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
else
err = 0;

if (!err && data && UCSI_CCI_LENGTH(*cci))
err = ucsi->ops->read_message_in(ucsi, data, size);

/*
* Don't ACK connection change if there was an error.
*/
Expand Down
6 changes: 4 additions & 2 deletions drivers/usb/typec/ucsi/ucsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ struct ucsi_operations {
int (*read_version)(struct ucsi *ucsi, u16 *version);
int (*read_cci)(struct ucsi *ucsi, u32 *cci);
int (*read_message_in)(struct ucsi *ucsi, void *val, size_t val_len);
int (*sync_control)(struct ucsi *ucsi, u64 command);
int (*sync_control)(struct ucsi *ucsi, u64 command, u32 *cci,
void *data, size_t size);
int (*async_control)(struct ucsi *ucsi, u64 command);
bool (*update_altmodes)(struct ucsi *ucsi, struct ucsi_altmode *orig,
struct ucsi_altmode *updated);
Expand Down Expand Up @@ -531,7 +532,8 @@ void ucsi_altmode_update_active(struct ucsi_connector *con);
int ucsi_resume(struct ucsi *ucsi);

void ucsi_notify_common(struct ucsi *ucsi, u32 cci);
int ucsi_sync_control_common(struct ucsi *ucsi, u64 command);
int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,
void *data, size_t size);

#if IS_ENABLED(CONFIG_POWER_SUPPLY)
int ucsi_register_port_psy(struct ucsi_connector *con);
Expand Down
5 changes: 3 additions & 2 deletions drivers/usb/typec/ucsi/ucsi_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,13 @@ static int ucsi_gram_read_message_in(struct ucsi *ucsi, void *val, size_t val_le
return ret;
}

static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command)
static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
void *data, size_t size)
{
struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
int ret;

ret = ucsi_sync_control_common(ucsi, command);
ret = ucsi_sync_control_common(ucsi, command, cci, data, size);
if (ret < 0)
return ret;

Expand Down
5 changes: 3 additions & 2 deletions drivers/usb/typec/ucsi/ucsi_ccg.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,8 @@ static int ucsi_ccg_async_control(struct ucsi *ucsi, u64 command)
return ccg_write(uc, reg, (u8 *)&command, sizeof(command));
}

static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command)
static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
void *data, size_t size)
{
struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
struct ucsi_connector *con;
Expand All @@ -652,7 +653,7 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command)
ucsi_ccg_update_set_new_cam_cmd(uc, con, &command);
}

ret = ucsi_sync_control_common(ucsi, command);
ret = ucsi_sync_control_common(ucsi, command, cci, data, size);

err_put:
pm_runtime_put_sync(uc->dev);
Expand Down

0 comments on commit 667ecac

Please sign in to comment.