Skip to content

Commit 43b0450

Browse files
committed
Merge remote-tracking branch 'soundwire/next' into sound/upstream-20220517
2 parents 9caa7b8 + 74da272 commit 43b0450

6 files changed

Lines changed: 90 additions & 27 deletions

File tree

Documentation/devicetree/bindings/soundwire/qcom,sdw.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,18 @@ board specific bus parameters.
162162
or applicable for the respective data port.
163163
More info in MIPI Alliance SoundWire 1.0 Specifications.
164164

165+
- reset:
166+
Usage: optional
167+
Value type: <prop-encoded-array>
168+
Definition: Should specify the SoundWire audio CSR reset controller interface,
169+
which is required for SoundWire version 1.6.0 and above.
170+
171+
- reset-names:
172+
Usage: optional
173+
Value type: <stringlist>
174+
Definition: should be "swr_audio_cgcr" for SoundWire audio CSR reset
175+
controller interface.
176+
165177
Note:
166178
More Information on detail of encoding of these fields can be
167179
found in MIPI Alliance SoundWire 1.0 Specifications.
@@ -180,6 +192,8 @@ soundwire: soundwire@c85 {
180192
interrupts = <20 IRQ_TYPE_EDGE_RISING>;
181193
clocks = <&wcc>;
182194
clock-names = "iface";
195+
resets = <&lpass_audiocc LPASS_AUDIO_SWR_TX_CGCR>;
196+
reset-names = "swr_audio_cgcr";
183197
#sound-dai-cells = <1>;
184198
qcom,dports-type = <0>;
185199
qcom,dout-ports = <6>;

drivers/soundwire/bus.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -536,11 +536,9 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
536536
{
537537
int ret;
538538

539-
ret = pm_runtime_get_sync(&slave->dev);
540-
if (ret < 0 && ret != -EACCES) {
541-
pm_runtime_put_noidle(&slave->dev);
539+
ret = pm_runtime_resume_and_get(&slave->dev);
540+
if (ret < 0 && ret != -EACCES)
542541
return ret;
543-
}
544542

545543
ret = sdw_nread_no_pm(slave, addr, count, val);
546544

@@ -562,11 +560,9 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val)
562560
{
563561
int ret;
564562

565-
ret = pm_runtime_get_sync(&slave->dev);
566-
if (ret < 0 && ret != -EACCES) {
567-
pm_runtime_put_noidle(&slave->dev);
563+
ret = pm_runtime_resume_and_get(&slave->dev);
564+
if (ret < 0 && ret != -EACCES)
568565
return ret;
569-
}
570566

571567
ret = sdw_nwrite_no_pm(slave, addr, count, val);
572568

@@ -1506,10 +1502,9 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
15061502

15071503
sdw_modify_slave_status(slave, SDW_SLAVE_ALERT);
15081504

1509-
ret = pm_runtime_get_sync(&slave->dev);
1505+
ret = pm_runtime_resume_and_get(&slave->dev);
15101506
if (ret < 0 && ret != -EACCES) {
15111507
dev_err(&slave->dev, "Failed to resume device: %d\n", ret);
1512-
pm_runtime_put_noidle(&slave->dev);
15131508
return ret;
15141509
}
15151510

@@ -1838,6 +1833,18 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
18381833
__func__, slave->dev_num);
18391834

18401835
complete(&slave->initialization_complete);
1836+
1837+
/*
1838+
* If the manager became pm_runtime active, the peripherals will be
1839+
* restarted and attach, but their pm_runtime status may remain
1840+
* suspended. If the 'update_slave_status' callback initiates
1841+
* any sort of deferred processing, this processing would not be
1842+
* cancelled on pm_runtime suspend.
1843+
* To avoid such zombie states, we queue a request to resume.
1844+
* This would be a no-op in case the peripheral was being resumed
1845+
* by e.g. the ALSA/ASoC framework.
1846+
*/
1847+
pm_request_resume(&slave->dev);
18411848
}
18421849
}
18431850

drivers/soundwire/cadence_master.c

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,12 +386,11 @@ static int cdns_parity_error_injection(void *data, u64 value)
386386
* Resume Master device. If this results in a bus reset, the
387387
* Slave devices will re-attach and be re-enumerated.
388388
*/
389-
ret = pm_runtime_get_sync(bus->dev);
389+
ret = pm_runtime_resume_and_get(bus->dev);
390390
if (ret < 0 && ret != -EACCES) {
391391
dev_err_ratelimited(cdns->dev,
392-
"pm_runtime_get_sync failed in %s, ret %d\n",
392+
"pm_runtime_resume_and_get failed in %s, ret %d\n",
393393
__func__, ret);
394-
pm_runtime_put_noidle(bus->dev);
395394
return ret;
396395
}
397396

@@ -959,6 +958,8 @@ static void cdns_update_slave_status_work(struct work_struct *work)
959958
container_of(work, struct sdw_cdns, work);
960959
u32 slave0, slave1;
961960
u64 slave_intstat;
961+
u32 device0_status;
962+
int retry_count = 0;
962963

963964
slave0 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0);
964965
slave1 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1);
@@ -968,10 +969,45 @@ static void cdns_update_slave_status_work(struct work_struct *work)
968969

969970
dev_dbg_ratelimited(cdns->dev, "Slave status change: 0x%llx\n", slave_intstat);
970971

972+
update_status:
971973
cdns_update_slave_status(cdns, slave_intstat);
972974
cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave0);
973975
cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave1);
974976

977+
/*
978+
* When there is more than one peripheral per link, it's
979+
* possible that a deviceB becomes attached after we deal with
980+
* the attachment of deviceA. Since the hardware does a
981+
* logical AND, the attachment of the second device does not
982+
* change the status seen by the driver.
983+
*
984+
* In that case, clearing the registers above would result in
985+
* the deviceB never being detected - until a change of status
986+
* is observed on the bus.
987+
*
988+
* To avoid this race condition, re-check if any device0 needs
989+
* attention with PING commands. There is no need to check for
990+
* ALERTS since they are not allowed until a non-zero
991+
* device_number is assigned.
992+
*/
993+
994+
device0_status = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
995+
device0_status &= 3;
996+
997+
if (device0_status == SDW_SLAVE_ATTACHED) {
998+
if (retry_count++ < SDW_MAX_DEVICES) {
999+
dev_dbg_ratelimited(cdns->dev,
1000+
"Device0 detected after clearing status, iteration %d\n",
1001+
retry_count);
1002+
slave_intstat = CDNS_MCP_SLAVE_INTSTAT_ATTACHED;
1003+
goto update_status;
1004+
} else {
1005+
dev_err_ratelimited(cdns->dev,
1006+
"Device0 detected after %d iterations\n",
1007+
retry_count);
1008+
}
1009+
}
1010+
9751011
/* clear and unmask Slave interrupt now */
9761012
cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_SLAVE_MASK);
9771013
cdns_updatel(cdns, CDNS_MCP_INTMASK,

drivers/soundwire/intel.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -799,12 +799,11 @@ static int intel_startup(struct snd_pcm_substream *substream,
799799
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
800800
int ret;
801801

802-
ret = pm_runtime_get_sync(cdns->dev);
802+
ret = pm_runtime_resume_and_get(cdns->dev);
803803
if (ret < 0 && ret != -EACCES) {
804804
dev_err_ratelimited(cdns->dev,
805-
"pm_runtime_get_sync failed in %s, ret %d\n",
805+
"pm_runtime_resume_and_get failed in %s, ret %d\n",
806806
__func__, ret);
807-
pm_runtime_put_noidle(cdns->dev);
808807
return ret;
809808
}
810809
return 0;
@@ -1293,6 +1292,9 @@ static int intel_link_probe(struct auxiliary_device *auxdev,
12931292
/* use generic bandwidth allocation algorithm */
12941293
sdw->cdns.bus.compute_params = sdw_compute_params;
12951294

1295+
/* avoid resuming from pm_runtime suspend if it's not required */
1296+
dev_pm_set_driver_flags(dev, DPM_FLAG_SMART_SUSPEND);
1297+
12961298
ret = sdw_bus_master_add(bus, dev, dev->fwnode);
12971299
if (ret) {
12981300
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)
18281830
return 0;
18291831
}
18301832

1833+
/* unconditionally disable WAKEEN interrupt */
1834+
intel_shim_wake(sdw, false);
1835+
18311836
link_flags = md_flags >> (bus->link_id * 8);
18321837
multi_link = !(link_flags & SDW_INTEL_MASTER_DISABLE_MULTI_LINK);
18331838

drivers/soundwire/qcom.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105

106106
#define SWRM_SPECIAL_CMD_ID 0xF
107107
#define MAX_FREQ_NUM 1
108-
#define TIMEOUT_MS (2 * HZ)
108+
#define TIMEOUT_MS 100
109109
#define QCOM_SWRM_MAX_RD_LEN 0x1
110110
#define QCOM_SDW_MAX_PORTS 14
111111
#define DEFAULT_CLK_FREQ 9600000
@@ -510,12 +510,12 @@ static irqreturn_t qcom_swrm_wake_irq_handler(int irq, void *dev_id)
510510
struct qcom_swrm_ctrl *swrm = dev_id;
511511
int ret;
512512

513-
ret = pm_runtime_get_sync(swrm->dev);
513+
ret = pm_runtime_resume_and_get(swrm->dev);
514514
if (ret < 0 && ret != -EACCES) {
515515
dev_err_ratelimited(swrm->dev,
516-
"pm_runtime_get_sync failed in %s, ret %d\n",
516+
"pm_runtime_resume_and_get failed in %s, ret %d\n",
517517
__func__, ret);
518-
pm_runtime_put_noidle(swrm->dev);
518+
return ret;
519519
}
520520

521521
if (swrm->wake_irq > 0) {
@@ -1058,12 +1058,11 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
10581058
struct snd_soc_dai *codec_dai;
10591059
int ret, i;
10601060

1061-
ret = pm_runtime_get_sync(ctrl->dev);
1061+
ret = pm_runtime_resume_and_get(ctrl->dev);
10621062
if (ret < 0 && ret != -EACCES) {
10631063
dev_err_ratelimited(ctrl->dev,
1064-
"pm_runtime_get_sync failed in %s, ret %d\n",
1064+
"pm_runtime_resume_and_get failed in %s, ret %d\n",
10651065
__func__, ret);
1066-
pm_runtime_put_noidle(ctrl->dev);
10671066
return ret;
10681067
}
10691068

@@ -1252,12 +1251,12 @@ static int swrm_reg_show(struct seq_file *s_file, void *data)
12521251
struct qcom_swrm_ctrl *swrm = s_file->private;
12531252
int reg, reg_val, ret;
12541253

1255-
ret = pm_runtime_get_sync(swrm->dev);
1254+
ret = pm_runtime_resume_and_get(swrm->dev);
12561255
if (ret < 0 && ret != -EACCES) {
12571256
dev_err_ratelimited(swrm->dev,
1258-
"pm_runtime_get_sync failed in %s, ret %d\n",
1257+
"pm_runtime_resume_and_get failed in %s, ret %d\n",
12591258
__func__, ret);
1260-
pm_runtime_put_noidle(swrm->dev);
1259+
return ret;
12611260
}
12621261

12631262
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)
14521451
} while (retry--);
14531452

14541453
dev_err(swrm->dev, "%s: link status not %s\n", __func__,
1455-
comp_sts && SWRM_FRM_GEN_ENABLED ? "connected" : "disconnected");
1454+
comp_sts & SWRM_FRM_GEN_ENABLED ? "connected" : "disconnected");
14561455

14571456
return false;
14581457
}
@@ -1549,6 +1548,7 @@ static const struct dev_pm_ops swrm_dev_pm_ops = {
15491548
static const struct of_device_id qcom_swrm_of_match[] = {
15501549
{ .compatible = "qcom,soundwire-v1.3.0", .data = &swrm_v1_3_data },
15511550
{ .compatible = "qcom,soundwire-v1.5.1", .data = &swrm_v1_5_data },
1551+
{ .compatible = "qcom,soundwire-v1.6.0", .data = &swrm_v1_5_data },
15521552
{/* sentinel */},
15531553
};
15541554

drivers/soundwire/stream.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,7 @@ static int do_bank_switch(struct sdw_stream_runtime *stream)
822822
} else if (multi_link) {
823823
dev_err(bus->dev,
824824
"Post bank switch ops not implemented\n");
825+
ret = -EINVAL;
825826
goto error;
826827
}
827828

0 commit comments

Comments
 (0)