Commit 39b53e23 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

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

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

Vinod writes:

soundwire updates for 5.13-rc1

Updates for v5.13-rc1 are:

Core:
 - Ability to add quirks for masters
 - static checker cleanup for bus code

Drivers:
 - DMI quirks for Intel controllers
 - static checker cleanup for drivers
 - add auto enumeration support qcom controller

* tag 'soundwire-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire: (45 commits)
  soundwire: intel_init: test link->cdns
  soundwire: qcom: handle return correctly in qcom_swrm_transport_params
  soundwire: qcom: cleanup internal port config indexing
  soundwire: qcom: wait for fifo space to be available before read/write
  soundwire: qcom: add static port map support
  soundwire: qcom: update port map allocation bit mask
  soundwire: add static port mapping support
  soundwire: stream: fix memory leak in stream config error path
  soundwire: qcom: use signed variable for error return
  soundwire: qcom: wait for enumeration to be complete in probe
  soundwire: qcom: add auto enumeration support
  soundwire: export sdw_compare_devid, sdw_extract_slave_id and sdw_slave_add
  soundwire: qcom: add support to new interrupts
  soundwire: qcom: update register read/write routine
  soundwire: qcom: start the clock during initialization
  soundwire: qcom: set continue execution flag for ignored commands
  soundwire: qcom: add support to missing transport params
  dt-bindings: soundwire: qcom: clarify data port bus parameters
  soundwire: cadence: only prepare attached devices on clock stop
  soundwire: generic_allocation: fix confusion between group and packing
  ...
parents 177260a7 14968dd3
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@ board specific bus parameters.
	Value type: <prop-encoded-array>
	Definition: should specify payload transport window offset1 of each
		    data port. Out ports followed by In ports.
		    Value of 0xFF indicates that this option is not implemented
		    or applicable for the respective data port.
		    More info in MIPI Alliance SoundWire 1.0 Specifications.

- qcom,ports-offset2:
@@ -61,6 +63,8 @@ board specific bus parameters.
	Value type: <prop-encoded-array>
	Definition: should specify payload transport window offset2 of each
		    data port. Out ports followed by In ports.
		    Value of 0xFF indicates that this option is not implemented
		    or applicable for the respective data port.
		    More info in MIPI Alliance SoundWire 1.0 Specifications.

- qcom,ports-sinterval-low:
@@ -69,12 +73,16 @@ board specific bus parameters.
	Definition: should be sample interval low of each data port.
		    Out ports followed by In ports. Used for Sample Interval
		    calculation.
		    Value of 0xFF indicates that this option is not implemented
		    or applicable for the respective data port.
		    More info in MIPI Alliance SoundWire 1.0 Specifications.

- qcom,ports-word-length:
	Usage: optional
	Value type: <prop-encoded-array>
	Definition: should be size of payload channel sample.
		    Value of 0xFF indicates that this option is not implemented
		    or applicable for the respective data port.
		    More info in MIPI Alliance SoundWire 1.0 Specifications.

- qcom,ports-block-pack-mode:
@@ -84,6 +92,8 @@ board specific bus parameters.
		    0 to indicate Blocks are per Channel
		    1 to indicate Blocks are per Port.
		    Out ports followed by In ports.
		    Value of 0xFF indicates that this option is not implemented
		    or applicable for the respective data port.
		    More info in MIPI Alliance SoundWire 1.0 Specifications.

- qcom,ports-block-group-count:
@@ -92,6 +102,8 @@ board specific bus parameters.
	Definition: should be in range 1 to 4 to indicate how many sample
		    intervals are combined into a payload.
		    Out ports followed by In ports.
		    Value of 0xFF indicates that this option is not implemented
		    or applicable for the respective data port.
		    More info in MIPI Alliance SoundWire 1.0 Specifications.

- qcom,ports-lane-control:
@@ -100,6 +112,8 @@ board specific bus parameters.
	Definition: should be in range 0 to 7 to identify which	data lane
		    the data port uses.
		    Out ports followed by In ports.
		    Value of 0xFF indicates that this option is not implemented
		    or applicable for the respective data port.
		    More info in MIPI Alliance SoundWire 1.0 Specifications.

- qcom,ports-hstart:
@@ -109,6 +123,8 @@ board specific bus parameters.
		    SoundWire Frame, i.e. left edge of the Transport sub-frame
		    for each port. Values between 0 and 15 are valid.
		    Out ports followed by In ports.
		    Value of 0xFF indicates that this option is not implemented
		    or applicable for the respective data port.
		    More info in MIPI Alliance SoundWire 1.0 Specifications.

- qcom,ports-hstop:
@@ -118,6 +134,8 @@ board specific bus parameters.
		    SoundWire Frame, i.e. the right edge of the Transport
		    sub-frame for each port. Values between 0 and 15 are valid.
		    Out ports followed by In ports.
		    Value of 0xFF indicates that this option is not implemented
		    or applicable for the respective data port.
		    More info in MIPI Alliance SoundWire 1.0 Specifications.

- qcom,dports-type:
@@ -128,6 +146,8 @@ board specific bus parameters.
		    1 for simple ports
		    2 for full port
		    Out ports followed by In ports.
		    Value of 0xFF indicates that this option is not implemented
		    or applicable for the respective data port.
		    More info in MIPI Alliance SoundWire 1.0 Specifications.

Note:
+1 −1
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ soundwire-cadence-y := cadence_master.o
obj-$(CONFIG_SOUNDWIRE_CADENCE) += soundwire-cadence.o

#Intel driver
soundwire-intel-y :=	intel.o intel_init.o
soundwire-intel-y :=	intel.o intel_init.o dmi-quirks.o
obj-$(CONFIG_SOUNDWIRE_INTEL) += soundwire-intel.o

#Qualcomm driver
+75 −25
Original line number Diff line number Diff line
@@ -44,13 +44,13 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
	}

	ret = sdw_get_id(bus);
	if (ret) {
	if (ret < 0) {
		dev_err(parent, "Failed to get bus id\n");
		return ret;
	}

	ret = sdw_master_device_add(bus, parent, fwnode);
	if (ret) {
	if (ret < 0) {
		dev_err(parent, "Failed to add master device at link %d\n",
			bus->link_id);
		return ret;
@@ -121,7 +121,7 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
	else
		ret = -ENOTSUPP; /* No ACPI/DT so error out */

	if (ret) {
	if (ret < 0) {
		dev_err(bus->dev, "Finding slaves failed:%d\n", ret);
		return ret;
	}
@@ -422,7 +422,7 @@ sdw_bread_no_pm(struct sdw_bus *bus, u16 dev_num, u32 addr)

	ret = sdw_fill_msg(&msg, NULL, addr, 1, dev_num,
			   SDW_MSG_FLAG_READ, &buf);
	if (ret)
	if (ret < 0)
		return ret;

	ret = sdw_transfer(bus, &msg);
@@ -440,7 +440,7 @@ sdw_bwrite_no_pm(struct sdw_bus *bus, u16 dev_num, u32 addr, u8 value)

	ret = sdw_fill_msg(&msg, NULL, addr, 1, dev_num,
			   SDW_MSG_FLAG_WRITE, &value);
	if (ret)
	if (ret < 0)
		return ret;

	return sdw_transfer(bus, &msg);
@@ -454,7 +454,7 @@ int sdw_bread_no_pm_unlocked(struct sdw_bus *bus, u16 dev_num, u32 addr)

	ret = sdw_fill_msg(&msg, NULL, addr, 1, dev_num,
			   SDW_MSG_FLAG_READ, &buf);
	if (ret)
	if (ret < 0)
		return ret;

	ret = sdw_transfer_unlocked(bus, &msg);
@@ -472,7 +472,7 @@ int sdw_bwrite_no_pm_unlocked(struct sdw_bus *bus, u16 dev_num, u32 addr, u8 val

	ret = sdw_fill_msg(&msg, NULL, addr, 1, dev_num,
			   SDW_MSG_FLAG_WRITE, &value);
	if (ret)
	if (ret < 0)
		return ret;

	return sdw_transfer_unlocked(bus, &msg);
@@ -593,7 +593,7 @@ EXPORT_SYMBOL(sdw_write);
/* called with bus_lock held */
static struct sdw_slave *sdw_get_slave(struct sdw_bus *bus, int i)
{
	struct sdw_slave *slave = NULL;
	struct sdw_slave *slave;

	list_for_each_entry(slave, &bus->slaves, node) {
		if (slave->dev_num == i)
@@ -603,7 +603,7 @@ static struct sdw_slave *sdw_get_slave(struct sdw_bus *bus, int i)
	return NULL;
}

static int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id)
int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id)
{
	if (slave->id.mfg_id != id.mfg_id ||
	    slave->id.part_id != id.part_id ||
@@ -614,6 +614,7 @@ static int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id)

	return 0;
}
EXPORT_SYMBOL(sdw_compare_devid);

/* called with bus_lock held */
static int sdw_get_device_num(struct sdw_slave *slave)
@@ -698,6 +699,7 @@ void sdw_extract_slave_id(struct sdw_bus *bus,
		"SDW Slave class_id 0x%02x, mfg_id 0x%04x, part_id 0x%04x, unique_id 0x%x, version 0x%x\n",
		id->class_id, id->mfg_id, id->part_id, id->unique_id, id->sdw_version);
}
EXPORT_SYMBOL(sdw_extract_slave_id);

static int sdw_program_device_num(struct sdw_bus *bus)
{
@@ -705,7 +707,7 @@ static int sdw_program_device_num(struct sdw_bus *bus)
	struct sdw_slave *slave, *_s;
	struct sdw_slave_id id;
	struct sdw_msg msg;
	bool found = false;
	bool found;
	int count = 0, ret;
	u64 addr;

@@ -737,6 +739,7 @@ static int sdw_program_device_num(struct sdw_bus *bus)

		sdw_extract_slave_id(bus, addr, &id);

		found = false;
		/* Now compare with entries */
		list_for_each_entry_safe(slave, _s, &bus->slaves, node) {
			if (sdw_compare_devid(slave, id) == 0) {
@@ -749,7 +752,7 @@ static int sdw_program_device_num(struct sdw_bus *bus)
				 * dev_num
				 */
				ret = sdw_assign_device_num(slave);
				if (ret) {
				if (ret < 0) {
					dev_err(bus->dev,
						"Assign dev_num failed:%d\n",
						ret);
@@ -875,14 +878,18 @@ static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
		if (wake_en)
			val |= SDW_SCP_SYSTEMCTRL_WAKE_UP_EN;
	} else {
		val = sdw_read_no_pm(slave, SDW_SCP_SYSTEMCTRL);

		ret = sdw_read_no_pm(slave, SDW_SCP_SYSTEMCTRL);
		if (ret < 0) {
			dev_err(&slave->dev, "SDW_SCP_SYSTEMCTRL read failed:%d\n", ret);
			return ret;
		}
		val = ret;
		val &= ~(SDW_SCP_SYSTEMCTRL_CLK_STP_PREP);
	}

	ret = sdw_write_no_pm(slave, SDW_SCP_SYSTEMCTRL, val);

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

@@ -895,10 +902,14 @@ static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num)
	int val;

	do {
		val = sdw_bread_no_pm(bus, dev_num, SDW_SCP_STAT) &
			SDW_SCP_STAT_CLK_STP_NF;
		val = sdw_bread_no_pm(bus, dev_num, SDW_SCP_STAT);
		if (val < 0) {
			dev_err(bus->dev, "SDW_SCP_STAT bread failed:%d\n", val);
			return val;
		}
		val &= SDW_SCP_STAT_CLK_STP_NF;
		if (!val) {
			dev_info(bus->dev, "clock stop prep/de-prep done slave:%d",
			dev_dbg(bus->dev, "clock stop prep/de-prep done slave:%d",
				dev_num);
			return 0;
		}
@@ -1253,6 +1264,7 @@ static int sdw_slave_set_frequency(struct sdw_slave *slave)
static int sdw_initialize_slave(struct sdw_slave *slave)
{
	struct sdw_slave_prop *prop = &slave->prop;
	int status;
	int ret;
	u8 val;

@@ -1260,6 +1272,44 @@ static int sdw_initialize_slave(struct sdw_slave *slave)
	if (ret < 0)
		return ret;

	if (slave->bus->prop.quirks & SDW_MASTER_QUIRKS_CLEAR_INITIAL_CLASH) {
		/* Clear bus clash interrupt before enabling interrupt mask */
		status = sdw_read_no_pm(slave, SDW_SCP_INT1);
		if (status < 0) {
			dev_err(&slave->dev,
				"SDW_SCP_INT1 (BUS_CLASH) read failed:%d\n", status);
			return status;
		}
		if (status & SDW_SCP_INT1_BUS_CLASH) {
			dev_warn(&slave->dev, "Bus clash detected before INT mask is enabled\n");
			ret = sdw_write_no_pm(slave, SDW_SCP_INT1, SDW_SCP_INT1_BUS_CLASH);
			if (ret < 0) {
				dev_err(&slave->dev,
					"SDW_SCP_INT1 (BUS_CLASH) write failed:%d\n", ret);
				return ret;
			}
		}
	}
	if ((slave->bus->prop.quirks & SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY) &&
	    !(slave->prop.quirks & SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY)) {
		/* Clear parity interrupt before enabling interrupt mask */
		status = sdw_read_no_pm(slave, SDW_SCP_INT1);
		if (status < 0) {
			dev_err(&slave->dev,
				"SDW_SCP_INT1 (PARITY) read failed:%d\n", status);
			return status;
		}
		if (status & SDW_SCP_INT1_PARITY) {
			dev_warn(&slave->dev, "PARITY error detected before INT mask is enabled\n");
			ret = sdw_write_no_pm(slave, SDW_SCP_INT1, SDW_SCP_INT1_PARITY);
			if (ret < 0) {
				dev_err(&slave->dev,
					"SDW_SCP_INT1 (PARITY) write failed:%d\n", ret);
				return ret;
			}
		}
	}

	/*
	 * Set SCP_INT1_MASK register, typically bus clash and
	 * implementation-defined interrupt mask. The Parity detection
@@ -1589,7 +1639,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
		ret = sdw_read_no_pm(slave, SDW_SCP_INT1);
		if (ret < 0) {
			dev_err(&slave->dev,
				"SDW_SCP_INT1 read failed:%d\n", ret);
				"SDW_SCP_INT1 recheck read failed:%d\n", ret);
			goto io_err;
		}
		_buf = ret;
@@ -1597,7 +1647,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
		ret = sdw_nread_no_pm(slave, SDW_SCP_INTSTAT2, 2, _buf2);
		if (ret < 0) {
			dev_err(&slave->dev,
				"SDW_SCP_INT2/3 read failed:%d\n", ret);
				"SDW_SCP_INT2/3 recheck read failed:%d\n", ret);
			goto io_err;
		}

@@ -1605,7 +1655,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
			ret = sdw_read_no_pm(slave, SDW_DP0_INT);
			if (ret < 0) {
				dev_err(&slave->dev,
					"SDW_DP0_INT read failed:%d\n", ret);
					"SDW_DP0_INT recheck read failed:%d\n", ret);
				goto io_err;
			}
			sdca_cascade = ret & SDW_DP0_SDCA_CASCADE;
@@ -1701,7 +1751,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
	if (status[0] == SDW_SLAVE_ATTACHED) {
		dev_dbg(bus->dev, "Slave attached, programming device number\n");
		ret = sdw_program_device_num(bus);
		if (ret)
		if (ret < 0)
			dev_err(bus->dev, "Slave attach failed: %d\n", ret);
		/*
		 * programming a device number will have side effects,
@@ -1735,7 +1785,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,

		case SDW_SLAVE_ALERT:
			ret = sdw_handle_slave_alerts(slave);
			if (ret)
			if (ret < 0)
				dev_err(&slave->dev,
					"Slave %d alert handling failed: %d\n",
					i, ret);
@@ -1754,7 +1804,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
			attached_initializing = true;

			ret = sdw_initialize_slave(slave);
			if (ret)
			if (ret < 0)
				dev_err(&slave->dev,
					"Slave %d initialization failed: %d\n",
					i, ret);
@@ -1768,7 +1818,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
		}

		ret = sdw_update_slave_status(slave, status[i]);
		if (ret)
		if (ret < 0)
			dev_err(&slave->dev,
				"Update Slave status failed:%d\n", ret);
		if (attached_initializing) {
+2 −0
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@
#define DEFAULT_BANK_SWITCH_TIMEOUT 3000
#define DEFAULT_PROBE_TIMEOUT       2000

u64 sdw_dmi_override_adr(struct sdw_bus *bus, u64 addr);

#if IS_ENABLED(CONFIG_ACPI)
int sdw_acpi_find_slaves(struct sdw_bus *bus);
#else
+12 −3
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ static int sdw_drv_probe(struct device *dev)
	struct sdw_slave *slave = dev_to_sdw_dev(dev);
	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
	const struct sdw_device_id *id;
	const char *name;
	int ret;

	/*
@@ -108,7 +109,10 @@ static int sdw_drv_probe(struct device *dev)

	ret = drv->probe(slave, id);
	if (ret) {
		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
		name = drv->name;
		if (!name)
			name = drv->driver.name;
		dev_err(dev, "Probe of %s failed: %d\n", name, ret);
		dev_pm_domain_detach(dev, false);
		return ret;
	}
@@ -174,11 +178,16 @@ static void sdw_drv_shutdown(struct device *dev)
 */
int __sdw_register_driver(struct sdw_driver *drv, struct module *owner)
{
	const char *name;

	drv->driver.bus = &sdw_bus_type;

	if (!drv->probe) {
		pr_err("driver %s didn't provide SDW probe routine\n",
		       drv->name);
		name = drv->name;
		if (!name)
			name = drv->driver.name;

		pr_err("driver %s didn't provide SDW probe routine\n", name);
		return -EINVAL;
	}

Loading