soundwire updates for 5.19-rc1
- Support for v1.6.0 Qualcomm controllers - Bunch of pm updates by Intel for peripheral attachment and system pm etc -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+vs47OPLdNbVcHzyfBQHDyUjg0cFAmJ8/LIACgkQfBQHDyUj g0cg/BAAhpuUHSE+4Xzhgbb93o6AAKVLFnGXuDCUYHGTJ/TyFarq8msHrEF8oAqu l7SPJjfpga1KNG6BVla0fTIVepdEZegdf2EF7xjYeszg9TwLX7Ek8kaGk8HJ9pKO euuRfy1xdouGobrk/gfywKNCLZWM2sCFow7FkdOhlvrofkeqj89rvYPkGY/c1cbM Pmnjg22aYR+cqXJcuLZ8SpO2QljVo0UGkgrn3Uoo7Qjgk/xq7NaW0TyS23w5O4nz VrDnGoP/kpOVMdXkp6y4mKhAfCWMj655Kr6Ag9+gIysk/qL0QVCkVwZ38u6XVK9z duUmwIIYemGIh5qP1sbjhUJ6cmcSDLR9+u4QliFMJqpKko1njLx3omOUm2/GN+fJ Jm75BQ16D7yruYD4nQPUl7KIqh/PyQRe4ofCY29qrrmUnAZFBrkf+HMRG+6roKyf z9fyQl4QdabVFOsMFdMXsMFTkCw5OIWjpPy/qdozHiCkAQH0C/P3EQSVKQfan2eb blLVOdr7pMHsks6IoXjqLHBX7lYGlmp8S1Qmh+GiENv7Zpl2vQBLOc9K0/jdHcBU wVuHOd320HN5MoZx3kuyHI6uoEL43kSHv4itaHc41wijetdu/I41X+ns5onukk5O 2NXmowoZAoCtriJT7EGhJNczFymu63VyQu3wFI0g2zg8i6S4bCk= =ZFFY -----END PGP SIGNATURE----- Merge tag 'soundwire-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire into char-misc-next Vinod writes: soundwire updates for 5.19-rc1 - Support for v1.6.0 Qualcomm controllers - Bunch of pm updates by Intel for peripheral attachment and system pm etc * tag 'soundwire-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire: soundwire: qcom: adjust autoenumeration timeout soundwire: qcom: use pm_runtime_resume_and_get() soundwire: intel: use pm_runtime_resume_and_get() soundwire: cadence: use pm_runtime_resume_and_get() soundwire: bus: use pm_runtime_resume_and_get() soundwire: qcom: return error when pm_runtime_get_sync fails soundwire: bus: pm_runtime_request_resume on peripheral attachment soundwire: intel: disable WAKEEN in pm_runtime resume soundwire: intel: prevent pm_runtime resume prior to system suspend soundwire: cadence: recheck device0 attachment after status change dt-bindings: soundwire: qcom: Add bindings for audio clock reset control property soundwire: qcom: Add compatible name for v1.6.0 soundwire: stream: Fix error return code in do_bank_switch() soundwire: qcom: fix an error message in swrm_wait_for_frame_gen_enabled()
This commit is contained in:
commit
fa5602c625
|
@ -162,6 +162,18 @@ board specific bus parameters.
|
|||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
|
||||
- reset:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Should specify the SoundWire audio CSR reset controller interface,
|
||||
which is required for SoundWire version 1.6.0 and above.
|
||||
|
||||
- reset-names:
|
||||
Usage: optional
|
||||
Value type: <stringlist>
|
||||
Definition: should be "swr_audio_cgcr" for SoundWire audio CSR reset
|
||||
controller interface.
|
||||
|
||||
Note:
|
||||
More Information on detail of encoding of these fields can be
|
||||
found in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
|
@ -180,6 +192,8 @@ soundwire: soundwire@c85 {
|
|||
interrupts = <20 IRQ_TYPE_EDGE_RISING>;
|
||||
clocks = <&wcc>;
|
||||
clock-names = "iface";
|
||||
resets = <&lpass_audiocc LPASS_AUDIO_SWR_TX_CGCR>;
|
||||
reset-names = "swr_audio_cgcr";
|
||||
#sound-dai-cells = <1>;
|
||||
qcom,dports-type = <0>;
|
||||
qcom,dout-ports = <6>;
|
||||
|
|
|
@ -536,11 +536,9 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(&slave->dev);
|
||||
if (ret < 0 && ret != -EACCES) {
|
||||
pm_runtime_put_noidle(&slave->dev);
|
||||
ret = pm_runtime_resume_and_get(&slave->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sdw_nread_no_pm(slave, addr, count, val);
|
||||
|
||||
|
@ -562,11 +560,9 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(&slave->dev);
|
||||
if (ret < 0 && ret != -EACCES) {
|
||||
pm_runtime_put_noidle(&slave->dev);
|
||||
ret = pm_runtime_resume_and_get(&slave->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sdw_nwrite_no_pm(slave, addr, count, val);
|
||||
|
||||
|
@ -1506,10 +1502,9 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
|
|||
|
||||
sdw_modify_slave_status(slave, SDW_SLAVE_ALERT);
|
||||
|
||||
ret = pm_runtime_get_sync(&slave->dev);
|
||||
ret = pm_runtime_resume_and_get(&slave->dev);
|
||||
if (ret < 0 && ret != -EACCES) {
|
||||
dev_err(&slave->dev, "Failed to resume device: %d\n", ret);
|
||||
pm_runtime_put_noidle(&slave->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1838,6 +1833,18 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
|
|||
__func__, slave->dev_num);
|
||||
|
||||
complete(&slave->initialization_complete);
|
||||
|
||||
/*
|
||||
* If the manager became pm_runtime active, the peripherals will be
|
||||
* restarted and attach, but their pm_runtime status may remain
|
||||
* suspended. If the 'update_slave_status' callback initiates
|
||||
* any sort of deferred processing, this processing would not be
|
||||
* cancelled on pm_runtime suspend.
|
||||
* To avoid such zombie states, we queue a request to resume.
|
||||
* This would be a no-op in case the peripheral was being resumed
|
||||
* by e.g. the ALSA/ASoC framework.
|
||||
*/
|
||||
pm_request_resume(&slave->dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -386,12 +386,11 @@ static int cdns_parity_error_injection(void *data, u64 value)
|
|||
* Resume Master device. If this results in a bus reset, the
|
||||
* Slave devices will re-attach and be re-enumerated.
|
||||
*/
|
||||
ret = pm_runtime_get_sync(bus->dev);
|
||||
ret = pm_runtime_resume_and_get(bus->dev);
|
||||
if (ret < 0 && ret != -EACCES) {
|
||||
dev_err_ratelimited(cdns->dev,
|
||||
"pm_runtime_get_sync failed in %s, ret %d\n",
|
||||
"pm_runtime_resume_and_get failed in %s, ret %d\n",
|
||||
__func__, ret);
|
||||
pm_runtime_put_noidle(bus->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -959,6 +958,8 @@ static void cdns_update_slave_status_work(struct work_struct *work)
|
|||
container_of(work, struct sdw_cdns, work);
|
||||
u32 slave0, slave1;
|
||||
u64 slave_intstat;
|
||||
u32 device0_status;
|
||||
int retry_count = 0;
|
||||
|
||||
slave0 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0);
|
||||
slave1 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1);
|
||||
|
@ -968,10 +969,45 @@ static void cdns_update_slave_status_work(struct work_struct *work)
|
|||
|
||||
dev_dbg_ratelimited(cdns->dev, "Slave status change: 0x%llx\n", slave_intstat);
|
||||
|
||||
update_status:
|
||||
cdns_update_slave_status(cdns, slave_intstat);
|
||||
cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave0);
|
||||
cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave1);
|
||||
|
||||
/*
|
||||
* When there is more than one peripheral per link, it's
|
||||
* possible that a deviceB becomes attached after we deal with
|
||||
* the attachment of deviceA. Since the hardware does a
|
||||
* logical AND, the attachment of the second device does not
|
||||
* change the status seen by the driver.
|
||||
*
|
||||
* In that case, clearing the registers above would result in
|
||||
* the deviceB never being detected - until a change of status
|
||||
* is observed on the bus.
|
||||
*
|
||||
* To avoid this race condition, re-check if any device0 needs
|
||||
* attention with PING commands. There is no need to check for
|
||||
* ALERTS since they are not allowed until a non-zero
|
||||
* device_number is assigned.
|
||||
*/
|
||||
|
||||
device0_status = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
|
||||
device0_status &= 3;
|
||||
|
||||
if (device0_status == SDW_SLAVE_ATTACHED) {
|
||||
if (retry_count++ < SDW_MAX_DEVICES) {
|
||||
dev_dbg_ratelimited(cdns->dev,
|
||||
"Device0 detected after clearing status, iteration %d\n",
|
||||
retry_count);
|
||||
slave_intstat = CDNS_MCP_SLAVE_INTSTAT_ATTACHED;
|
||||
goto update_status;
|
||||
} else {
|
||||
dev_err_ratelimited(cdns->dev,
|
||||
"Device0 detected after %d iterations\n",
|
||||
retry_count);
|
||||
}
|
||||
}
|
||||
|
||||
/* clear and unmask Slave interrupt now */
|
||||
cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_SLAVE_MASK);
|
||||
cdns_updatel(cdns, CDNS_MCP_INTMASK,
|
||||
|
|
|
@ -799,12 +799,11 @@ static int intel_startup(struct snd_pcm_substream *substream,
|
|||
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(cdns->dev);
|
||||
ret = pm_runtime_resume_and_get(cdns->dev);
|
||||
if (ret < 0 && ret != -EACCES) {
|
||||
dev_err_ratelimited(cdns->dev,
|
||||
"pm_runtime_get_sync failed in %s, ret %d\n",
|
||||
"pm_runtime_resume_and_get failed in %s, ret %d\n",
|
||||
__func__, ret);
|
||||
pm_runtime_put_noidle(cdns->dev);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
|
@ -1293,6 +1292,9 @@ static int intel_link_probe(struct auxiliary_device *auxdev,
|
|||
/* use generic bandwidth allocation algorithm */
|
||||
sdw->cdns.bus.compute_params = sdw_compute_params;
|
||||
|
||||
/* avoid resuming from pm_runtime suspend if it's not required */
|
||||
dev_pm_set_driver_flags(dev, DPM_FLAG_SMART_SUSPEND);
|
||||
|
||||
ret = sdw_bus_master_add(bus, dev, dev->fwnode);
|
||||
if (ret) {
|
||||
dev_err(dev, "sdw_bus_master_add fail: %d\n", ret);
|
||||
|
@ -1828,6 +1830,9 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* unconditionally disable WAKEEN interrupt */
|
||||
intel_shim_wake(sdw, false);
|
||||
|
||||
link_flags = md_flags >> (bus->link_id * 8);
|
||||
multi_link = !(link_flags & SDW_INTEL_MASTER_DISABLE_MULTI_LINK);
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
|
||||
#define SWRM_SPECIAL_CMD_ID 0xF
|
||||
#define MAX_FREQ_NUM 1
|
||||
#define TIMEOUT_MS (2 * HZ)
|
||||
#define TIMEOUT_MS 100
|
||||
#define QCOM_SWRM_MAX_RD_LEN 0x1
|
||||
#define QCOM_SDW_MAX_PORTS 14
|
||||
#define DEFAULT_CLK_FREQ 9600000
|
||||
|
@ -510,12 +510,12 @@ static irqreturn_t qcom_swrm_wake_irq_handler(int irq, void *dev_id)
|
|||
struct qcom_swrm_ctrl *swrm = dev_id;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(swrm->dev);
|
||||
ret = pm_runtime_resume_and_get(swrm->dev);
|
||||
if (ret < 0 && ret != -EACCES) {
|
||||
dev_err_ratelimited(swrm->dev,
|
||||
"pm_runtime_get_sync failed in %s, ret %d\n",
|
||||
"pm_runtime_resume_and_get failed in %s, ret %d\n",
|
||||
__func__, ret);
|
||||
pm_runtime_put_noidle(swrm->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (swrm->wake_irq > 0) {
|
||||
|
@ -1058,12 +1058,11 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *codec_dai;
|
||||
int ret, i;
|
||||
|
||||
ret = pm_runtime_get_sync(ctrl->dev);
|
||||
ret = pm_runtime_resume_and_get(ctrl->dev);
|
||||
if (ret < 0 && ret != -EACCES) {
|
||||
dev_err_ratelimited(ctrl->dev,
|
||||
"pm_runtime_get_sync failed in %s, ret %d\n",
|
||||
"pm_runtime_resume_and_get failed in %s, ret %d\n",
|
||||
__func__, ret);
|
||||
pm_runtime_put_noidle(ctrl->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1252,12 +1251,12 @@ static int swrm_reg_show(struct seq_file *s_file, void *data)
|
|||
struct qcom_swrm_ctrl *swrm = s_file->private;
|
||||
int reg, reg_val, ret;
|
||||
|
||||
ret = pm_runtime_get_sync(swrm->dev);
|
||||
ret = pm_runtime_resume_and_get(swrm->dev);
|
||||
if (ret < 0 && ret != -EACCES) {
|
||||
dev_err_ratelimited(swrm->dev,
|
||||
"pm_runtime_get_sync failed in %s, ret %d\n",
|
||||
"pm_runtime_resume_and_get failed in %s, ret %d\n",
|
||||
__func__, ret);
|
||||
pm_runtime_put_noidle(swrm->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (reg = 0; reg <= SWR_MSTR_MAX_REG_ADDR; reg += 4) {
|
||||
|
@ -1452,7 +1451,7 @@ static bool swrm_wait_for_frame_gen_enabled(struct qcom_swrm_ctrl *swrm)
|
|||
} while (retry--);
|
||||
|
||||
dev_err(swrm->dev, "%s: link status not %s\n", __func__,
|
||||
comp_sts && SWRM_FRM_GEN_ENABLED ? "connected" : "disconnected");
|
||||
comp_sts & SWRM_FRM_GEN_ENABLED ? "connected" : "disconnected");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1549,6 +1548,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 },
|
||||
{/* sentinel */},
|
||||
};
|
||||
|
||||
|
|
|
@ -822,6 +822,7 @@ static int do_bank_switch(struct sdw_stream_runtime *stream)
|
|||
} else if (multi_link) {
|
||||
dev_err(bus->dev,
|
||||
"Post bank switch ops not implemented\n");
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue