Commit 667ecac5 authored by Dmitry Baryshkov's avatar Dmitry Baryshkov Committed by Greg Kroah-Hartman
Browse files

usb: typec: ucsi: return CCI and message from sync_control callback



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: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: default avatarŁukasz Bartosik <ukaszb@chromium.org>
Link: https://lore.kernel.org/r/20250120-ucsi-merge-commands-v2-1-462a1ec22ecc@linaro.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 41d5e380
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -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.
+11 −8
Original line number Diff line number Diff line
@@ -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;
@@ -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);
@@ -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,
@@ -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;
@@ -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.
	 */
+4 −2
Original line number Diff line number Diff line
@@ -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);
@@ -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);
+3 −2
Original line number Diff line number Diff line
@@ -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;

+3 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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);