mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-29 23:24:11 +08:00
ASoC/soundwire: log actual PING status on resume issues
Merge series from Bard Liao <yung-chuan.liao@linux.intel.com>: we've been stuck with problems in the dual-amplifier configurations where one of the two devices seems to become UNATTACHED and never regains sync, see https://github.com/thesofproject/linux/issues/3638. This is a rather infrequent issue that may happen once or twice per month, but still it remains a concern. One possibility is that the device does lose sync but somehow our hardware detection fails to see it resync. This series just adds a basic read directly from the PING frames to help confirm if yes/no the device regain sync.
This commit is contained in:
commit
1decead8d7
@ -297,6 +297,38 @@ int sdw_transfer(struct sdw_bus *bus, struct sdw_msg *msg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdw_show_ping_status() - Direct report of PING status, to be used by Peripheral drivers
|
||||
* @bus: SDW bus
|
||||
* @sync_delay: Delay before reading status
|
||||
*/
|
||||
void sdw_show_ping_status(struct sdw_bus *bus, bool sync_delay)
|
||||
{
|
||||
u32 status;
|
||||
|
||||
if (!bus->ops->read_ping_status)
|
||||
return;
|
||||
|
||||
/*
|
||||
* wait for peripheral to sync if desired. 10-15ms should be more than
|
||||
* enough in most cases.
|
||||
*/
|
||||
if (sync_delay)
|
||||
usleep_range(10000, 15000);
|
||||
|
||||
mutex_lock(&bus->msg_lock);
|
||||
|
||||
status = bus->ops->read_ping_status(bus);
|
||||
|
||||
mutex_unlock(&bus->msg_lock);
|
||||
|
||||
if (!status)
|
||||
dev_warn(bus->dev, "%s: no peripherals attached\n", __func__);
|
||||
else
|
||||
dev_dbg(bus->dev, "PING status: %#x\n", status);
|
||||
}
|
||||
EXPORT_SYMBOL(sdw_show_ping_status);
|
||||
|
||||
/**
|
||||
* sdw_transfer_defer() - Asynchronously transfer message to a SDW Slave device
|
||||
* @bus: SDW bus
|
||||
|
@ -756,6 +756,14 @@ cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num)
|
||||
}
|
||||
EXPORT_SYMBOL(cdns_reset_page_addr);
|
||||
|
||||
u32 cdns_read_ping_status(struct sdw_bus *bus)
|
||||
{
|
||||
struct sdw_cdns *cdns = bus_to_cdns(bus);
|
||||
|
||||
return cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
|
||||
}
|
||||
EXPORT_SYMBOL(cdns_read_ping_status);
|
||||
|
||||
/*
|
||||
* IRQ handling
|
||||
*/
|
||||
|
@ -177,6 +177,8 @@ enum sdw_command_response
|
||||
cdns_xfer_msg_defer(struct sdw_bus *bus,
|
||||
struct sdw_msg *msg, struct sdw_defer *defer);
|
||||
|
||||
u32 cdns_read_ping_status(struct sdw_bus *bus);
|
||||
|
||||
int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params);
|
||||
|
||||
int cdns_set_sdw_stream(struct snd_soc_dai *dai,
|
||||
|
@ -1262,6 +1262,7 @@ static struct sdw_master_ops sdw_intel_ops = {
|
||||
.set_bus_conf = cdns_bus_conf,
|
||||
.pre_bank_switch = intel_pre_bank_switch,
|
||||
.post_bank_switch = intel_post_bank_switch,
|
||||
.read_ping_status = cdns_read_ping_status,
|
||||
};
|
||||
|
||||
static int intel_init(struct sdw_intel *sdw)
|
||||
|
@ -839,6 +839,8 @@ struct sdw_defer {
|
||||
* @set_bus_conf: Set the bus configuration
|
||||
* @pre_bank_switch: Callback for pre bank switch
|
||||
* @post_bank_switch: Callback for post bank switch
|
||||
* @read_ping_status: Read status from PING frames, reported with two bits per Device.
|
||||
* Bits 31:24 are reserved.
|
||||
*/
|
||||
struct sdw_master_ops {
|
||||
int (*read_prop)(struct sdw_bus *bus);
|
||||
@ -855,6 +857,7 @@ struct sdw_master_ops {
|
||||
struct sdw_bus_params *params);
|
||||
int (*pre_bank_switch)(struct sdw_bus *bus);
|
||||
int (*post_bank_switch)(struct sdw_bus *bus);
|
||||
u32 (*read_ping_status)(struct sdw_bus *bus);
|
||||
|
||||
};
|
||||
|
||||
@ -919,6 +922,8 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
|
||||
struct fwnode_handle *fwnode);
|
||||
void sdw_bus_master_delete(struct sdw_bus *bus);
|
||||
|
||||
void sdw_show_ping_status(struct sdw_bus *bus, bool sync_delay);
|
||||
|
||||
/**
|
||||
* sdw_port_config: Master or Slave Port configuration
|
||||
*
|
||||
|
@ -281,6 +281,8 @@ static __maybe_unused int max98373_resume(struct device *dev)
|
||||
msecs_to_jiffies(MAX98373_PROBE_TIMEOUT));
|
||||
if (!time) {
|
||||
dev_err(dev, "Initialization not complete, timed out\n");
|
||||
sdw_show_ping_status(slave->bus, true);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -749,6 +749,8 @@ static int __maybe_unused rt1308_dev_resume(struct device *dev)
|
||||
msecs_to_jiffies(RT1308_PROBE_TIMEOUT));
|
||||
if (!time) {
|
||||
dev_err(&slave->dev, "Initialization not complete, timed out\n");
|
||||
sdw_show_ping_status(slave->bus, true);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -734,6 +734,8 @@ static int __maybe_unused rt1316_dev_resume(struct device *dev)
|
||||
msecs_to_jiffies(RT1316_PROBE_TIMEOUT));
|
||||
if (!time) {
|
||||
dev_err(&slave->dev, "Initialization not complete, timed out\n");
|
||||
sdw_show_ping_status(slave->bus, true);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -793,6 +793,8 @@ static int __maybe_unused rt5682_dev_resume(struct device *dev)
|
||||
msecs_to_jiffies(RT5682_PROBE_TIMEOUT));
|
||||
if (!time) {
|
||||
dev_err(&slave->dev, "Initialization not complete, timed out\n");
|
||||
sdw_show_ping_status(slave->bus, true);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -542,6 +542,8 @@ static int __maybe_unused rt700_dev_resume(struct device *dev)
|
||||
msecs_to_jiffies(RT700_PROBE_TIMEOUT));
|
||||
if (!time) {
|
||||
dev_err(&slave->dev, "Initialization not complete, timed out\n");
|
||||
sdw_show_ping_status(slave->bus, true);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -449,6 +449,8 @@ static int __maybe_unused rt711_sdca_dev_resume(struct device *dev)
|
||||
msecs_to_jiffies(RT711_PROBE_TIMEOUT));
|
||||
if (!time) {
|
||||
dev_err(&slave->dev, "Initialization not complete, timed out\n");
|
||||
sdw_show_ping_status(slave->bus, true);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -244,6 +244,8 @@ static int __maybe_unused rt715_dev_resume(struct device *dev)
|
||||
msecs_to_jiffies(RT715_PROBE_TIMEOUT));
|
||||
if (!time) {
|
||||
dev_err(&slave->dev, "Enumeration not complete, timed out\n");
|
||||
sdw_show_ping_status(slave->bus, true);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -562,6 +562,8 @@ static int __maybe_unused rt715_dev_resume(struct device *dev)
|
||||
msecs_to_jiffies(RT715_PROBE_TIMEOUT));
|
||||
if (!time) {
|
||||
dev_err(&slave->dev, "Initialization not complete, timed out\n");
|
||||
sdw_show_ping_status(slave->bus, true);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user