Commit 1730a594 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'soundwire-5.14-rc1' of...

Merge tag 'soundwire-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire into char-misc-next

Vinod writes:

soundwire updates for 5.14-rc1

Updates for v5.14-rc1 are:

- Core has odd updates including improving clock stop codes, write api,
  handling ENODATA etc

 - Drivers has Big move of Intel driver to be aux dev and minor updates
   to Intel/cadence driver

* tag 'soundwire-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire:
  soundwire: stream: Fix test for DP prepare complete
  soundwire: bus: Make sdw_nwrite() data pointer argument const
  soundwire: intel: move to auxiliary bus
  soundwire: cadence: remove the repeated declaration
  soundwire: dmi-quirks: remove duplicate initialization
  soundwire: cadence_master: always set CMD_ACCEPT
  soundwire: bus: add missing \n in dynamic debug
  soundwire: bus: handle -ENODATA errors in clock stop/start sequences
  soundwire: add missing kernel-doc description
  soundwire: bus: only use CLOCK_STOP_MODE0 and fix confusions
  soundwire: bandwidth allocation: improve error messages
  soundwire/ASoC: add leading zeroes in peripheral device name
parents 91812dd0 3d3e88e3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ config SOUNDWIRE_INTEL
	tristate "Intel SoundWire Master driver"
	select SOUNDWIRE_CADENCE
	select SOUNDWIRE_GENERIC_ALLOCATION
	select AUXILIARY_BUS
	depends on ACPI && SND_SOC
	help
	  SoundWire Intel Master driver.
+73 −90
Original line number Diff line number Diff line
@@ -394,13 +394,13 @@ sdw_nread_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
}

static int
sdw_nwrite_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
sdw_nwrite_no_pm(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val)
{
	struct sdw_msg msg;
	int ret;

	ret = sdw_fill_msg(&msg, slave, addr, count,
			   slave->dev_num, SDW_MSG_FLAG_WRITE, val);
			   slave->dev_num, SDW_MSG_FLAG_WRITE, (u8 *)val);
	if (ret < 0)
		return ret;

@@ -535,9 +535,9 @@ EXPORT_SYMBOL(sdw_nread);
 * @slave: SDW Slave
 * @addr: Register address
 * @count: length
 * @val: Buffer for values to be read
 * @val: Buffer for values to be written
 */
int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val)
{
	int ret;

@@ -821,26 +821,6 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
	mutex_unlock(&bus->bus_lock);
}

static enum sdw_clk_stop_mode sdw_get_clk_stop_mode(struct sdw_slave *slave)
{
	enum sdw_clk_stop_mode mode;

	/*
	 * Query for clock stop mode if Slave implements
	 * ops->get_clk_stop_mode, else read from property.
	 */
	if (slave->ops && slave->ops->get_clk_stop_mode) {
		mode = slave->ops->get_clk_stop_mode(slave);
	} else {
		if (slave->prop.clk_stop_mode1)
			mode = SDW_CLK_STOP_MODE1;
		else
			mode = SDW_CLK_STOP_MODE0;
	}

	return mode;
}

static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,
				       enum sdw_clk_stop_mode mode,
				       enum sdw_clk_stop_type type)
@@ -849,12 +829,9 @@ static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,

	if (slave->ops && slave->ops->clk_stop) {
		ret = slave->ops->clk_stop(slave, mode, type);
		if (ret < 0) {
			dev_err(&slave->dev,
				"Clk Stop type =%d failed: %d\n", type, ret);
		if (ret < 0)
			return ret;
	}
	}

	return 0;
}
@@ -880,6 +857,7 @@ static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
	} else {
		ret = sdw_read_no_pm(slave, SDW_SCP_SYSTEMCTRL);
		if (ret < 0) {
			if (ret != -ENODATA)
				dev_err(&slave->dev, "SDW_SCP_SYSTEMCTRL read failed:%d\n", ret);
			return ret;
		}
@@ -889,9 +867,8 @@ static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,

	ret = sdw_write_no_pm(slave, SDW_SCP_SYSTEMCTRL, val);

	if (ret < 0)
		dev_err(&slave->dev,
			"Clock Stop prepare failed for slave: %d", ret);
	if (ret < 0 && ret != -ENODATA)
		dev_err(&slave->dev, "SDW_SCP_SYSTEMCTRL write failed:%d\n", ret);

	return ret;
}
@@ -909,7 +886,7 @@ static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num)
		}
		val &= SDW_SCP_STAT_CLK_STP_NF;
		if (!val) {
			dev_dbg(bus->dev, "clock stop prep/de-prep done slave:%d",
			dev_dbg(bus->dev, "clock stop prep/de-prep done slave:%d\n",
				dev_num);
			return 0;
		}
@@ -918,7 +895,7 @@ static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num)
		retry--;
	} while (retry);

	dev_err(bus->dev, "clock stop prep/de-prep failed slave:%d",
	dev_err(bus->dev, "clock stop prep/de-prep failed slave:%d\n",
		dev_num);

	return -ETIMEDOUT;
@@ -933,7 +910,6 @@ static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num)
 */
int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
{
	enum sdw_clk_stop_mode slave_mode;
	bool simple_clk_stop = true;
	struct sdw_slave *slave;
	bool is_slave = false;
@@ -943,6 +919,9 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
	 * In order to save on transition time, prepare
	 * each Slave and then wait for all Slave(s) to be
	 * prepared for clock stop.
	 * If one of the Slave devices has lost sync and
	 * replies with Command Ignored/-ENODATA, we continue
	 * the loop
	 */
	list_for_each_entry(slave, &bus->slaves, node) {
		if (!slave->dev_num)
@@ -955,36 +934,45 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
		/* Identify if Slave(s) are available on Bus */
		is_slave = true;

		slave_mode = sdw_get_clk_stop_mode(slave);
		slave->curr_clk_stop_mode = slave_mode;

		ret = sdw_slave_clk_stop_callback(slave, slave_mode,
		ret = sdw_slave_clk_stop_callback(slave,
						  SDW_CLK_STOP_MODE0,
						  SDW_CLK_PRE_PREPARE);
		if (ret < 0) {
			dev_err(&slave->dev,
				"pre-prepare failed:%d", ret);
		if (ret < 0 && ret != -ENODATA) {
			dev_err(&slave->dev, "clock stop pre-prepare cb failed:%d\n", ret);
			return ret;
		}

		/* Only prepare a Slave device if needed */
		if (!slave->prop.simple_clk_stop_capable) {
			simple_clk_stop = false;

			ret = sdw_slave_clk_stop_prepare(slave,
						 slave_mode, true);
		if (ret < 0) {
			dev_err(&slave->dev,
				"pre-prepare failed:%d", ret);
							 SDW_CLK_STOP_MODE0,
							 true);
			if (ret < 0 && ret != -ENODATA) {
				dev_err(&slave->dev, "clock stop prepare failed:%d\n", ret);
				return ret;
			}

		if (slave_mode == SDW_CLK_STOP_MODE1)
			simple_clk_stop = false;
		}
	}

	/* Skip remaining clock stop preparation if no Slave is attached */
	if (!is_slave)
		return ret;
		return 0;

	/*
	 * Don't wait for all Slaves to be ready if they follow the simple
	 * state machine
	 */
	if (!simple_clk_stop) {
		ret = sdw_bus_wait_for_clk_prep_deprep(bus,
						       SDW_BROADCAST_DEV_NUM);
		/*
		 * if there are no Slave devices present and the reply is
		 * Command_Ignored/-ENODATA, we don't need to continue with the
		 * flow and can just return here. The error code is not modified
		 * and its handling left as an exercise for the caller.
		 */
		if (ret < 0)
			return ret;
	}
@@ -998,21 +986,17 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
		    slave->status != SDW_SLAVE_ALERT)
			continue;

		slave_mode = slave->curr_clk_stop_mode;

		if (slave_mode == SDW_CLK_STOP_MODE1) {
		ret = sdw_slave_clk_stop_callback(slave,
							  slave_mode,
						  SDW_CLK_STOP_MODE0,
						  SDW_CLK_POST_PREPARE);

			if (ret < 0) {
				dev_err(&slave->dev,
					"post-prepare failed:%d", ret);
			}
		if (ret < 0 && ret != -ENODATA) {
			dev_err(&slave->dev, "clock stop post-prepare cb failed:%d\n", ret);
			return ret;
		}
	}

	return ret;
	return 0;
}
EXPORT_SYMBOL(sdw_bus_prep_clk_stop);

@@ -1035,12 +1019,8 @@ int sdw_bus_clk_stop(struct sdw_bus *bus)
	ret = sdw_bwrite_no_pm(bus, SDW_BROADCAST_DEV_NUM,
			       SDW_SCP_CTRL, SDW_SCP_CTRL_CLK_STP_NOW);
	if (ret < 0) {
		if (ret == -ENODATA)
			dev_dbg(bus->dev,
				"ClockStopNow Broadcast msg ignored %d", ret);
		else
			dev_err(bus->dev,
				"ClockStopNow Broadcast msg failed %d", ret);
		if (ret != -ENODATA)
			dev_err(bus->dev, "ClockStopNow Broadcast msg failed %d\n", ret);
		return ret;
	}

@@ -1059,7 +1039,6 @@ EXPORT_SYMBOL(sdw_bus_clk_stop);
 */
int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
{
	enum sdw_clk_stop_mode mode;
	bool simple_clk_stop = true;
	struct sdw_slave *slave;
	bool is_slave = false;
@@ -1081,33 +1060,36 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
		/* Identify if Slave(s) are available on Bus */
		is_slave = true;

		mode = slave->curr_clk_stop_mode;

		if (mode == SDW_CLK_STOP_MODE1) {
			simple_clk_stop = false;
			continue;
		}

		ret = sdw_slave_clk_stop_callback(slave, mode,
		ret = sdw_slave_clk_stop_callback(slave, SDW_CLK_STOP_MODE0,
						  SDW_CLK_PRE_DEPREPARE);
		if (ret < 0)
			dev_warn(&slave->dev,
				 "clk stop deprep failed:%d", ret);
			dev_warn(&slave->dev, "clock stop pre-deprepare cb failed:%d\n", ret);

		/* Only de-prepare a Slave device if needed */
		if (!slave->prop.simple_clk_stop_capable) {
			simple_clk_stop = false;

		ret = sdw_slave_clk_stop_prepare(slave, mode,
			ret = sdw_slave_clk_stop_prepare(slave, SDW_CLK_STOP_MODE0,
							 false);

			if (ret < 0)
			dev_warn(&slave->dev,
				 "clk stop deprep failed:%d", ret);
				dev_warn(&slave->dev, "clock stop deprepare failed:%d\n", ret);
		}
	}

	/* Skip remaining clock stop de-preparation if no Slave is attached */
	if (!is_slave)
		return 0;

	if (!simple_clk_stop)
		sdw_bus_wait_for_clk_prep_deprep(bus, SDW_BROADCAST_DEV_NUM);
	/*
	 * Don't wait for all Slaves to be ready if they follow the simple
	 * state machine
	 */
	if (!simple_clk_stop) {
		ret = sdw_bus_wait_for_clk_prep_deprep(bus, SDW_BROADCAST_DEV_NUM);
		if (ret < 0)
			dev_warn(&slave->dev, "clock stop deprepare wait failed:%d\n", ret);
	}

	list_for_each_entry(slave, &bus->slaves, node) {
		if (!slave->dev_num)
@@ -1117,9 +1099,10 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
		    slave->status != SDW_SLAVE_ALERT)
			continue;

		mode = slave->curr_clk_stop_mode;
		sdw_slave_clk_stop_callback(slave, mode,
		ret = sdw_slave_clk_stop_callback(slave, SDW_CLK_STOP_MODE0,
						  SDW_CLK_POST_DEPREPARE);
		if (ret < 0)
			dev_warn(&slave->dev, "clock stop post-deprepare cb failed:%d\n", ret);
	}

	return 0;
+2 −19
Original line number Diff line number Diff line
@@ -1428,20 +1428,6 @@ int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake)
		}
	}

	/*
	 * This CMD_ACCEPT should be used when there are no devices
	 * attached on the link when entering clock stop mode. If this is
	 * not set and there is a broadcast write then the command ignored
	 * will be treated as a failure
	 */
	if (!slave_present)
		cdns_updatel(cdns, CDNS_MCP_CONTROL,
			     CDNS_MCP_CONTROL_CMD_ACCEPT,
			     CDNS_MCP_CONTROL_CMD_ACCEPT);
	else
		cdns_updatel(cdns, CDNS_MCP_CONTROL,
			     CDNS_MCP_CONTROL_CMD_ACCEPT, 0);

	/* commit changes */
	ret = cdns_config_update(cdns);
	if (ret < 0) {
@@ -1508,11 +1494,8 @@ int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset)
	cdns_updatel(cdns, CDNS_MCP_CONTROL,
		     CDNS_MCP_CONTROL_BLOCK_WAKEUP, 0);

	/*
	 * clear CMD_ACCEPT so that the command ignored
	 * will be treated as a failure during a broadcast write
	 */
	cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT, 0);
	cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
		     CDNS_MCP_CONTROL_CMD_ACCEPT);

	if (!bus_reset) {

+0 −3
Original line number Diff line number Diff line
@@ -180,9 +180,6 @@ enum sdw_command_response
cdns_xfer_msg_defer(struct sdw_bus *bus,
		    struct sdw_msg *msg, struct sdw_defer *defer);

enum sdw_command_response
cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num);

int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params);

int cdns_set_sdw_stream(struct snd_soc_dai *dai,
+1 −1
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ u64 sdw_dmi_override_adr(struct sdw_bus *bus, u64 addr)
	/* check if any address remap quirk applies */
	dmi_id = dmi_first_match(adr_remap_quirk_table);
	if (dmi_id) {
		struct adr_remap *map = dmi_id->driver_data;
		struct adr_remap *map;

		for (map = dmi_id->driver_data; map->adr; map++) {
			if (map->adr == addr) {
Loading