mirror of
https://github.com/torvalds/linux.git
synced 2026-05-22 06:01:53 +02:00
soundwire updates for 5.20-rc1
- Core: solve the driver bind/unbind problem and remove ops pointer - intel: runtime pm updates - qcom: audio clock gating updates and device status checks -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+vs47OPLdNbVcHzyfBQHDyUjg0cFAmLQ8OEACgkQfBQHDyUj g0efIxAAiU+f6Z75b+NznPvX3/OtBuZoA0kx80f0QUmiZ83GLbSIAJuvaYBBw7+x WkihiBg85VtymAPSe+8BRPhpy5QzQp0J2w1ZcyHfBQrgOen6kBEvGMkGbpDE+/Ym ipwCSqG6XeVcbdjKKHXOP7Pr4yUjm5QoFcbZmorElvMVBrCHFPrEcdbzB4h92eb7 3gQjSM2hyMrszAbY48qlesNNjYeaVpG6U8r0dVgiWg5mr5HrkusIel9KyV+HChho z3cwjqQd4HSNJUgj0A7bVGE+j3tUxFf95w0qIG0VRs6q8baTFxKVfjb9cd6i6/sT hTSpim7/040GU6CabS0WHgMfI7D3besYLlaWbcLjSe1Vam/mJID9zw7S7hO5hRGj uZ2nKeOsHPf9bcdE3e6BXkpMEv9rImuXrwwHbu7OmAeFDSdT9PpSvThxX0qobwL8 wqVfBkoTs9ovnbQ28JSnQkys1r1Q3Nwt2LJ/SYvyEbRmxfAJvIRqgwwq25nGkJIS KasTDvMqamYlaBirH5kBAvsOagyQP8wHq1XFWSLj82sqzeesbQEtxotxiyU1iGcj kO1xdE/XchsHItFy8UADxRGcZ4mmHxdP9nYKk6ZR9h1bnQLZxqQylE8aGuF+C9LG rAgh4tZx0guJwxdcsviuzdI8xxJZLeoVPJNOB4z5AC7UtoC9E8A= =n6b4 -----END PGP SIGNATURE----- Merge tag 'soundwire-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire into char-misc-next Vinod writes: "soundwire updates for 5.20-rc1 - Core: solve the driver bind/unbind problem and remove ops pointer - intel: runtime pm updates - qcom: audio clock gating updates and device status checks" * tag 'soundwire-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire: soundwire: qcom: Enable software clock gating requirement flag soundwire: qcom: Check device status before reading devid soundwire: qcom: Add flag for software clock gating check soundwire: qcom: Add support for controlling audio CGCR from HLOS soundwire: intel: use pm_runtime_resume() on component probe soundwire: peripheral: remove useless ops pointer soundwire: revisit driver bind/unbind and callbacks soundwire: bus_type: fix remove and shutdown support
This commit is contained in:
commit
2306137b13
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/pm_runtime.h>
|
||||
#include <linux/soundwire/sdw_registers.h>
|
||||
#include <linux/soundwire/sdw.h>
|
||||
#include <linux/soundwire/sdw_type.h>
|
||||
#include "bus.h"
|
||||
#include "sysfs_local.h"
|
||||
|
||||
|
|
@ -842,15 +843,21 @@ static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,
|
|||
enum sdw_clk_stop_mode mode,
|
||||
enum sdw_clk_stop_type type)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (slave->ops && slave->ops->clk_stop) {
|
||||
ret = slave->ops->clk_stop(slave, mode, type);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
mutex_lock(&slave->sdw_dev_lock);
|
||||
|
||||
if (slave->probed) {
|
||||
struct device *dev = &slave->dev;
|
||||
struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
|
||||
|
||||
if (drv->ops && drv->ops->clk_stop)
|
||||
ret = drv->ops->clk_stop(slave, mode, type);
|
||||
}
|
||||
|
||||
return 0;
|
||||
mutex_unlock(&slave->sdw_dev_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
|
||||
|
|
@ -1611,14 +1618,24 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
|
|||
}
|
||||
|
||||
/* Update the Slave driver */
|
||||
if (slave_notify && slave->ops &&
|
||||
slave->ops->interrupt_callback) {
|
||||
slave_intr.sdca_cascade = sdca_cascade;
|
||||
slave_intr.control_port = clear;
|
||||
memcpy(slave_intr.port, &port_status,
|
||||
sizeof(slave_intr.port));
|
||||
if (slave_notify) {
|
||||
mutex_lock(&slave->sdw_dev_lock);
|
||||
|
||||
slave->ops->interrupt_callback(slave, &slave_intr);
|
||||
if (slave->probed) {
|
||||
struct device *dev = &slave->dev;
|
||||
struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
|
||||
|
||||
if (drv->ops && drv->ops->interrupt_callback) {
|
||||
slave_intr.sdca_cascade = sdca_cascade;
|
||||
slave_intr.control_port = clear;
|
||||
memcpy(slave_intr.port, &port_status,
|
||||
sizeof(slave_intr.port));
|
||||
|
||||
drv->ops->interrupt_callback(slave, &slave_intr);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&slave->sdw_dev_lock);
|
||||
}
|
||||
|
||||
/* Ack interrupt */
|
||||
|
|
@ -1692,29 +1709,21 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
|
|||
static int sdw_update_slave_status(struct sdw_slave *slave,
|
||||
enum sdw_slave_status status)
|
||||
{
|
||||
unsigned long time;
|
||||
int ret = 0;
|
||||
|
||||
if (!slave->probed) {
|
||||
/*
|
||||
* the slave status update is typically handled in an
|
||||
* interrupt thread, which can race with the driver
|
||||
* probe, e.g. when a module needs to be loaded.
|
||||
*
|
||||
* make sure the probe is complete before updating
|
||||
* status.
|
||||
*/
|
||||
time = wait_for_completion_timeout(&slave->probe_complete,
|
||||
msecs_to_jiffies(DEFAULT_PROBE_TIMEOUT));
|
||||
if (!time) {
|
||||
dev_err(&slave->dev, "Probe not complete, timed out\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
mutex_lock(&slave->sdw_dev_lock);
|
||||
|
||||
if (slave->probed) {
|
||||
struct device *dev = &slave->dev;
|
||||
struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
|
||||
|
||||
if (drv->ops && drv->ops->update_status)
|
||||
ret = drv->ops->update_status(slave, status);
|
||||
}
|
||||
|
||||
if (!slave->ops || !slave->ops->update_status)
|
||||
return 0;
|
||||
mutex_unlock(&slave->sdw_dev_lock);
|
||||
|
||||
return slave->ops->update_status(slave, status);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -98,8 +98,6 @@ static int sdw_drv_probe(struct device *dev)
|
|||
if (!id)
|
||||
return -ENODEV;
|
||||
|
||||
slave->ops = drv->ops;
|
||||
|
||||
/*
|
||||
* attach to power domain but don't turn on (last arg)
|
||||
*/
|
||||
|
|
@ -107,19 +105,23 @@ static int sdw_drv_probe(struct device *dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&slave->sdw_dev_lock);
|
||||
|
||||
ret = drv->probe(slave, id);
|
||||
if (ret) {
|
||||
name = drv->name;
|
||||
if (!name)
|
||||
name = drv->driver.name;
|
||||
mutex_unlock(&slave->sdw_dev_lock);
|
||||
|
||||
dev_err(dev, "Probe of %s failed: %d\n", name, ret);
|
||||
dev_pm_domain_detach(dev, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* device is probed so let's read the properties now */
|
||||
if (slave->ops && slave->ops->read_prop)
|
||||
slave->ops->read_prop(slave);
|
||||
if (drv->ops && drv->ops->read_prop)
|
||||
drv->ops->read_prop(slave);
|
||||
|
||||
/* init the sysfs as we have properties now */
|
||||
ret = sdw_slave_sysfs_init(slave);
|
||||
|
|
@ -139,7 +141,19 @@ static int sdw_drv_probe(struct device *dev)
|
|||
slave->prop.clk_stop_timeout);
|
||||
|
||||
slave->probed = true;
|
||||
complete(&slave->probe_complete);
|
||||
|
||||
/*
|
||||
* if the probe happened after the bus was started, notify the codec driver
|
||||
* of the current hardware status to e.g. start the initialization.
|
||||
* Errors are only logged as warnings to avoid failing the probe.
|
||||
*/
|
||||
if (drv->ops && drv->ops->update_status) {
|
||||
ret = drv->ops->update_status(slave, slave->status);
|
||||
if (ret < 0)
|
||||
dev_warn(dev, "%s: update_status failed with status %d\n", __func__, ret);
|
||||
}
|
||||
|
||||
mutex_unlock(&slave->sdw_dev_lock);
|
||||
|
||||
dev_dbg(dev, "probe complete\n");
|
||||
|
||||
|
|
@ -152,9 +166,15 @@ static int sdw_drv_remove(struct device *dev)
|
|||
struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&slave->sdw_dev_lock);
|
||||
|
||||
slave->probed = false;
|
||||
|
||||
if (drv->remove)
|
||||
ret = drv->remove(slave);
|
||||
|
||||
mutex_unlock(&slave->sdw_dev_lock);
|
||||
|
||||
dev_pm_domain_detach(dev, false);
|
||||
|
||||
return ret;
|
||||
|
|
@ -193,12 +213,8 @@ int __sdw_register_driver(struct sdw_driver *drv, struct module *owner)
|
|||
|
||||
drv->driver.owner = owner;
|
||||
drv->driver.probe = sdw_drv_probe;
|
||||
|
||||
if (drv->remove)
|
||||
drv->driver.remove = sdw_drv_remove;
|
||||
|
||||
if (drv->shutdown)
|
||||
drv->driver.shutdown = sdw_drv_shutdown;
|
||||
drv->driver.remove = sdw_drv_remove;
|
||||
drv->driver.shutdown = sdw_drv_shutdown;
|
||||
|
||||
return driver_register(&drv->driver);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1043,6 +1043,23 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, struct sn
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int intel_component_probe(struct snd_soc_component *component)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* make sure the device is pm_runtime_active before initiating
|
||||
* bus transactions during the card registration.
|
||||
* We use pm_runtime_resume() here, without taking a reference
|
||||
* and releasing it immediately.
|
||||
*/
|
||||
ret = pm_runtime_resume(component->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_component_dais_suspend(struct snd_soc_component *component)
|
||||
{
|
||||
struct snd_soc_dai *dai;
|
||||
|
|
@ -1098,6 +1115,7 @@ static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
|
|||
|
||||
static const struct snd_soc_component_driver dai_component = {
|
||||
.name = "soundwire",
|
||||
.probe = intel_component_probe,
|
||||
.suspend = intel_component_dais_suspend
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/of_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pm_wakeirq.h>
|
||||
#include <linux/slimbus.h>
|
||||
|
|
@ -142,6 +143,7 @@ struct qcom_swrm_ctrl {
|
|||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
void __iomem *mmio;
|
||||
struct reset_control *audio_cgcr;
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *debugfs;
|
||||
#endif
|
||||
|
|
@ -179,6 +181,7 @@ struct qcom_swrm_ctrl {
|
|||
struct qcom_swrm_data {
|
||||
u32 default_cols;
|
||||
u32 default_rows;
|
||||
bool sw_clk_gate_required;
|
||||
};
|
||||
|
||||
static const struct qcom_swrm_data swrm_v1_3_data = {
|
||||
|
|
@ -191,6 +194,12 @@ static const struct qcom_swrm_data swrm_v1_5_data = {
|
|||
.default_cols = 16,
|
||||
};
|
||||
|
||||
static const struct qcom_swrm_data swrm_v1_6_data = {
|
||||
.default_rows = 50,
|
||||
.default_cols = 16,
|
||||
.sw_clk_gate_required = true,
|
||||
};
|
||||
|
||||
#define to_qcom_sdw(b) container_of(b, struct qcom_swrm_ctrl, bus)
|
||||
|
||||
static int qcom_swrm_ahb_reg_read(struct qcom_swrm_ctrl *ctrl, int reg,
|
||||
|
|
@ -471,6 +480,10 @@ static int qcom_swrm_enumerate(struct sdw_bus *bus)
|
|||
char *buf1 = (char *)&val1, *buf2 = (char *)&val2;
|
||||
|
||||
for (i = 1; i <= SDW_MAX_DEVICES; i++) {
|
||||
/* do not continue if the status is Not Present */
|
||||
if (!ctrl->status[i])
|
||||
continue;
|
||||
|
||||
/*SCP_Devid5 - Devid 4*/
|
||||
ctrl->reg_read(ctrl, SWRM_ENUMERATOR_SLAVE_DEV_ID_1(i), &val1);
|
||||
|
||||
|
|
@ -656,6 +669,8 @@ static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
|
|||
val = FIELD_PREP(SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK, ctrl->rows_index);
|
||||
val |= FIELD_PREP(SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK, ctrl->cols_index);
|
||||
|
||||
reset_control_reset(ctrl->audio_cgcr);
|
||||
|
||||
ctrl->reg_write(ctrl, SWRM_MCP_FRAME_CTRL_BANK_ADDR(0), val);
|
||||
|
||||
/* Enable Auto enumeration */
|
||||
|
|
@ -1307,6 +1322,15 @@ static int qcom_swrm_probe(struct platform_device *pdev)
|
|||
return PTR_ERR(ctrl->mmio);
|
||||
}
|
||||
|
||||
if (data->sw_clk_gate_required) {
|
||||
ctrl->audio_cgcr = devm_reset_control_get_exclusive(dev, "swr_audio_cgcr");
|
||||
if (IS_ERR_OR_NULL(ctrl->audio_cgcr)) {
|
||||
dev_err(dev, "Failed to get cgcr reset ctrl required for SW gating\n");
|
||||
ret = PTR_ERR(ctrl->audio_cgcr);
|
||||
goto err_init;
|
||||
}
|
||||
}
|
||||
|
||||
ctrl->irq = of_irq_get(dev->of_node, 0);
|
||||
if (ctrl->irq < 0) {
|
||||
ret = ctrl->irq;
|
||||
|
|
@ -1332,6 +1356,10 @@ static int qcom_swrm_probe(struct platform_device *pdev)
|
|||
ctrl->bus.compute_params = &qcom_swrm_compute_params;
|
||||
ctrl->bus.clk_stop_timeout = 300;
|
||||
|
||||
ctrl->audio_cgcr = devm_reset_control_get_exclusive(dev, "swr_audio_cgcr");
|
||||
if (IS_ERR(ctrl->audio_cgcr))
|
||||
dev_err(dev, "Failed to get audio_cgcr reset required for soundwire-v1.6.0\n");
|
||||
|
||||
ret = qcom_swrm_get_port_config(ctrl);
|
||||
if (ret)
|
||||
goto err_clk;
|
||||
|
|
@ -1485,6 +1513,8 @@ static int __maybe_unused swrm_runtime_resume(struct device *dev)
|
|||
qcom_swrm_get_device_status(ctrl);
|
||||
sdw_handle_slave_status(&ctrl->bus, ctrl->status);
|
||||
} else {
|
||||
reset_control_reset(ctrl->audio_cgcr);
|
||||
|
||||
ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL, SWRM_MCP_BUS_CLK_START);
|
||||
ctrl->reg_write(ctrl, SWRM_INTERRUPT_CLEAR,
|
||||
SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET);
|
||||
|
|
@ -1548,7 +1578,7 @@ static const struct dev_pm_ops swrm_dev_pm_ops = {
|
|||
static const struct of_device_id qcom_swrm_of_match[] = {
|
||||
{ .compatible = "qcom,soundwire-v1.3.0", .data = &swrm_v1_3_data },
|
||||
{ .compatible = "qcom,soundwire-v1.5.1", .data = &swrm_v1_5_data },
|
||||
{ .compatible = "qcom,soundwire-v1.6.0", .data = &swrm_v1_5_data },
|
||||
{ .compatible = "qcom,soundwire-v1.6.0", .data = &swrm_v1_6_data },
|
||||
{/* sentinel */},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ static void sdw_slave_release(struct device *dev)
|
|||
{
|
||||
struct sdw_slave *slave = dev_to_sdw_dev(dev);
|
||||
|
||||
mutex_destroy(&slave->sdw_dev_lock);
|
||||
kfree(slave);
|
||||
}
|
||||
|
||||
|
|
@ -58,9 +59,9 @@ int sdw_slave_add(struct sdw_bus *bus,
|
|||
init_completion(&slave->enumeration_complete);
|
||||
init_completion(&slave->initialization_complete);
|
||||
slave->dev_num = 0;
|
||||
init_completion(&slave->probe_complete);
|
||||
slave->probed = false;
|
||||
slave->first_interrupt_done = false;
|
||||
mutex_init(&slave->sdw_dev_lock);
|
||||
|
||||
for (i = 0; i < SDW_MAX_PORTS; i++)
|
||||
init_completion(&slave->port_ready[i]);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/soundwire/sdw_registers.h>
|
||||
#include <linux/soundwire/sdw.h>
|
||||
#include <linux/soundwire/sdw_type.h>
|
||||
#include <sound/soc.h>
|
||||
#include "bus.h"
|
||||
|
||||
|
|
@ -401,20 +402,26 @@ static int sdw_do_port_prep(struct sdw_slave_runtime *s_rt,
|
|||
struct sdw_prepare_ch prep_ch,
|
||||
enum sdw_port_prep_ops cmd)
|
||||
{
|
||||
const struct sdw_slave_ops *ops = s_rt->slave->ops;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
struct sdw_slave *slave = s_rt->slave;
|
||||
|
||||
if (ops->port_prep) {
|
||||
ret = ops->port_prep(s_rt->slave, &prep_ch, cmd);
|
||||
if (ret < 0) {
|
||||
dev_err(&s_rt->slave->dev,
|
||||
"Slave Port Prep cmd %d failed: %d\n",
|
||||
cmd, ret);
|
||||
return ret;
|
||||
mutex_lock(&slave->sdw_dev_lock);
|
||||
|
||||
if (slave->probed) {
|
||||
struct device *dev = &slave->dev;
|
||||
struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
|
||||
|
||||
if (drv->ops && drv->ops->port_prep) {
|
||||
ret = drv->ops->port_prep(slave, &prep_ch, cmd);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Slave Port Prep cmd %d failed: %d\n",
|
||||
cmd, ret);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
mutex_unlock(&slave->sdw_dev_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
|
||||
|
|
@ -578,7 +585,7 @@ static int sdw_notify_config(struct sdw_master_runtime *m_rt)
|
|||
struct sdw_slave_runtime *s_rt;
|
||||
struct sdw_bus *bus = m_rt->bus;
|
||||
struct sdw_slave *slave;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
if (bus->ops->set_bus_conf) {
|
||||
ret = bus->ops->set_bus_conf(bus, &bus->params);
|
||||
|
|
@ -589,17 +596,27 @@ static int sdw_notify_config(struct sdw_master_runtime *m_rt)
|
|||
list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
|
||||
slave = s_rt->slave;
|
||||
|
||||
if (slave->ops->bus_config) {
|
||||
ret = slave->ops->bus_config(slave, &bus->params);
|
||||
if (ret < 0) {
|
||||
dev_err(bus->dev, "Notify Slave: %d failed\n",
|
||||
slave->dev_num);
|
||||
return ret;
|
||||
mutex_lock(&slave->sdw_dev_lock);
|
||||
|
||||
if (slave->probed) {
|
||||
struct device *dev = &slave->dev;
|
||||
struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
|
||||
|
||||
if (drv->ops && drv->ops->bus_config) {
|
||||
ret = drv->ops->bus_config(slave, &bus->params);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Notify Slave: %d failed\n",
|
||||
slave->dev_num);
|
||||
mutex_unlock(&slave->sdw_dev_lock);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&slave->sdw_dev_lock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -637,7 +637,6 @@ struct sdw_slave_ops {
|
|||
* @dev: Linux device
|
||||
* @status: Status reported by the Slave
|
||||
* @bus: Bus handle
|
||||
* @ops: Slave callback ops
|
||||
* @prop: Slave properties
|
||||
* @debugfs: Slave debugfs
|
||||
* @node: node for bus list
|
||||
|
|
@ -646,9 +645,6 @@ struct sdw_slave_ops {
|
|||
* @dev_num: Current Device Number, values can be 0 or dev_num_sticky
|
||||
* @dev_num_sticky: one-time static Device Number assigned by Bus
|
||||
* @probed: boolean tracking driver state
|
||||
* @probe_complete: completion utility to control potential races
|
||||
* on startup between driver probe/initialization and SoundWire
|
||||
* Slave state changes/implementation-defined interrupts
|
||||
* @enumeration_complete: completion utility to control potential races
|
||||
* on startup between device enumeration and read/write access to the
|
||||
* Slave device
|
||||
|
|
@ -663,13 +659,13 @@ struct sdw_slave_ops {
|
|||
* for a Slave happens for the first time after enumeration
|
||||
* @is_mockup_device: status flag used to squelch errors in the command/control
|
||||
* protocol for SoundWire mockup devices
|
||||
* @sdw_dev_lock: mutex used to protect callbacks/remove races
|
||||
*/
|
||||
struct sdw_slave {
|
||||
struct sdw_slave_id id;
|
||||
struct device dev;
|
||||
enum sdw_slave_status status;
|
||||
struct sdw_bus *bus;
|
||||
const struct sdw_slave_ops *ops;
|
||||
struct sdw_slave_prop prop;
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *debugfs;
|
||||
|
|
@ -680,12 +676,12 @@ struct sdw_slave {
|
|||
u16 dev_num;
|
||||
u16 dev_num_sticky;
|
||||
bool probed;
|
||||
struct completion probe_complete;
|
||||
struct completion enumeration_complete;
|
||||
struct completion initialization_complete;
|
||||
u32 unattach_request;
|
||||
bool first_interrupt_done;
|
||||
bool is_mockup_device;
|
||||
struct mutex sdw_dev_lock; /* protect callbacks/remove races */
|
||||
};
|
||||
|
||||
#define dev_to_sdw_dev(_dev) container_of(_dev, struct sdw_slave, dev)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user