The firmware does not provide any information for capture streams via the
shared pipeline registers.
To avoid reporting invalid delay value for capture streams to user space
we need to disable it.
Fixes: af74dbd0dbcf ("ASoC: SOF: ipc4-pcm: allocate time info for pcm delay feature")
Cc: stable(a)vger.kernel.org
Signed-off-by: Peter Ujfalusi <peter.ujfalusi(a)linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao(a)linux.intel.com>
Reviewed-by: Liam Girdwood <liam.r.girdwood(a)intel.com>
---
sound/soc/sof/ipc4-pcm.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c
index 52903503cf3b..8eee3e1aadf9 100644
--- a/sound/soc/sof/ipc4-pcm.c
+++ b/sound/soc/sof/ipc4-pcm.c
@@ -799,7 +799,8 @@ static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm
spcm->stream[stream].private = stream_priv;
- if (!support_info)
+ /* Delay reporting is only supported on playback */
+ if (!support_info || stream == SNDRV_PCM_STREAM_CAPTURE)
continue;
time_info = kzalloc(sizeof(*time_info), GFP_KERNEL);
--
2.49.0
The header.numid is set to scontrol->comp_id in bytes_ext_get and it is
ignored during bytes_ext_put.
The use of comp_id is not quite great as it is kernel internal
identification number.
Set the header.numid to SOF_CTRL_CMD_BINARY during get and validate the
numid during put to provide consistent and compatible identification
number as IPC3.
For IPC4 existing tooling also ignored the numid but with the use of
SOF_CTRL_CMD_BINARY the different handling of the blobs can be dropped,
providing better user experience.
Reported-by: Seppo Ingalsuo <seppo.ingalsuo(a)linux.intel.com>
Closes: https://github.com/thesofproject/linux/issues/5282
Fixes: a062c8899fed ("ASoC: SOF: ipc4-control: Add support for bytes control get and put")
Cc: stable(a)vger.kernel.org
Signed-off-by: Peter Ujfalusi <peter.ujfalusi(a)linux.intel.com>
Reviewed-by: Seppo Ingalsuo <seppo.ingalsuo(a)linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan(a)linux.intel.com>
Reviewed-by: Liam Girdwood <liam.r.girdwood(a)intel.com>
---
sound/soc/sof/ipc4-control.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/sound/soc/sof/ipc4-control.c b/sound/soc/sof/ipc4-control.c
index 576f407cd456..976a4794d610 100644
--- a/sound/soc/sof/ipc4-control.c
+++ b/sound/soc/sof/ipc4-control.c
@@ -531,6 +531,14 @@ static int sof_ipc4_bytes_ext_put(struct snd_sof_control *scontrol,
return -EINVAL;
}
+ /* Check header id */
+ if (header.numid != SOF_CTRL_CMD_BINARY) {
+ dev_err_ratelimited(scomp->dev,
+ "Incorrect numid for bytes put %d\n",
+ header.numid);
+ return -EINVAL;
+ }
+
/* Verify the ABI header first */
if (copy_from_user(&abi_hdr, tlvd->tlv, sizeof(abi_hdr)))
return -EFAULT;
@@ -613,7 +621,8 @@ static int _sof_ipc4_bytes_ext_get(struct snd_sof_control *scontrol,
if (data_size > size)
return -ENOSPC;
- header.numid = scontrol->comp_id;
+ /* Set header id and length */
+ header.numid = SOF_CTRL_CMD_BINARY;
header.length = data_size;
if (copy_to_user(tlvd, &header, sizeof(struct snd_ctl_tlv)))
--
2.49.0
From: Kai Vehmanen <kai.vehmanen(a)linux.intel.com>
The partial matching of DAI widget to link names, can cause problems if
one of the widget names is a substring of another. E.g. with names
"Foo1" and Foo10", it's not possible to correctly link up "Foo1".
Modify the logic so that if multiple DAI links match the widget stream
name, prioritize a full match if one is found.
Fixes: fe88788779fc ("ASoC: SOF: topology: Use partial match for connecting DAI link and DAI widget")
Link: https://github.com/thesofproject/linux/issues/5308
Signed-off-by: Kai Vehmanen <kai.vehmanen(a)linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi(a)linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan(a)linux.intel.com>
Cc: stable(a)vger.kernel.org
Signed-off-by: Peter Ujfalusi <peter.ujfalusi(a)linux.intel.com>
---
sound/soc/sof/topology.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index 2d4e660b19d5..d612d693efc3 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -1071,7 +1071,7 @@ static int sof_connect_dai_widget(struct snd_soc_component *scomp,
struct snd_sof_dai *dai)
{
struct snd_soc_card *card = scomp->card;
- struct snd_soc_pcm_runtime *rtd;
+ struct snd_soc_pcm_runtime *rtd, *full, *partial;
struct snd_soc_dai *cpu_dai;
int stream;
int i;
@@ -1088,12 +1088,22 @@ static int sof_connect_dai_widget(struct snd_soc_component *scomp,
else
goto end;
+ full = NULL;
+ partial = NULL;
list_for_each_entry(rtd, &card->rtd_list, list) {
/* does stream match DAI link ? */
- if (!rtd->dai_link->stream_name ||
- !strstr(rtd->dai_link->stream_name, w->sname))
- continue;
+ if (rtd->dai_link->stream_name) {
+ if (!strcmp(rtd->dai_link->stream_name, w->sname)) {
+ full = rtd;
+ break;
+ } else if (strstr(rtd->dai_link->stream_name, w->sname)) {
+ partial = rtd;
+ }
+ }
+ }
+ rtd = full ? full : partial;
+ if (rtd) {
for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
/*
* Please create DAI widget in the right order
--
2.49.0
This is the start of the stable review cycle for the 5.15.182 release.
There are 55 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Sat, 10 May 2025 11:25:42 +0000.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.182-r…
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Linux 5.15.182-rc2
Tudor Ambarus <tudor.ambarus(a)linaro.org>
dm: fix copying after src array boundaries
Nicolin Chen <nicolinc(a)nvidia.com>
iommu/arm-smmu-v3: Fix iommu_device_probe bug due to duplicated stream ids
Jason Gunthorpe <jgg(a)ziepe.ca>
iommu/arm-smmu-v3: Use the new rb tree helpers
Björn Töpel <bjorn(a)rivosinc.com>
riscv: uprobes: Add missing fence.i after building the XOL buffer
Suzuki K Poulose <suzuki.poulose(a)arm.com>
irqchip/gic-v2m: Prevent use after free of gicv2m_get_fwnode()
Thomas Gleixner <tglx(a)linutronix.de>
irqchip/gic-v2m: Mark a few functions __init
Xiang wangx <wangxiang(a)cdjrlc.com>
irqchip/gic-v2m: Add const to of_device_id
Christian Hewitt <christianshewitt(a)gmail.com>
Revert "drm/meson: vclk: fix calculation of 59.94 fractional rates"
Fiona Klute <fiona.klute(a)gmx.de>
net: phy: microchip: force IRQ polling mode for lan88xx
Sébastien Szymanski <sebastien.szymanski(a)armadeus.com>
ARM: dts: opos6ul: add ksz8081 phy properties
Cristian Marussi <cristian.marussi(a)arm.com>
firmware: arm_scmi: Balance device refcount when destroying devices
Yonglong Liu <liuyonglong(a)huawei.com>
net: hns3: fix deadlock issue when externel_lb and reset are executed together
Sergey Shtylyov <s.shtylyov(a)omp.ru>
of: module: add buffer overflow check in of_modalias()
Richard Zhu <hongxing.zhu(a)nxp.com>
PCI: imx6: Skip controller_id generation logic for i.MX7D
Jian Shen <shenjian15(a)huawei.com>
net: hns3: defer calling ptp_clock_register()
Hao Lan <lanhao(a)huawei.com>
net: hns3: fixed debugfs tm_qset size
Yonglong Liu <liuyonglong(a)huawei.com>
net: hns3: fix an interrupt residual problem
Yonglong Liu <liuyonglong(a)huawei.com>
net: hns3: add support for external loopback test
Jian Shen <shenjian15(a)huawei.com>
net: hns3: store rx VLAN tag offload state for VF
Mattias Barthel <mattias.barthel(a)atlascopco.com>
net: fec: ERR007885 Workaround for conventional TX
Thangaraj Samynathan <thangaraj.s(a)microchip.com>
net: lan743x: Fix memleak issue when GSO enabled
Michael Liang <mliang(a)purestorage.com>
nvme-tcp: fix premature queue removal and I/O failover
Michael Chan <michael.chan(a)broadcom.com>
bnxt_en: Fix ethtool -d byte order for 32-bit values
Shruti Parab <shruti.parab(a)broadcom.com>
bnxt_en: Fix out-of-bound memcpy() during ethtool -w
Shruti Parab <shruti.parab(a)broadcom.com>
bnxt_en: Fix coredump logic to free allocated buffer
Felix Fietkau <nbd(a)nbd.name>
net: ipv6: fix UDPv6 GSO segmentation with NAT
Simon Horman <horms(a)kernel.org>
net: dlink: Correct endianness handling of led_mode
Xuanqiang Luo <luoxuanqiang(a)kylinos.cn>
ice: Check VF VSI Pointer Value in ice_vc_add_fdir_fltr()
Brett Creeley <brett.creeley(a)intel.com>
ice: Refactor promiscuous functions
Victor Nogueira <victor(a)mojatatu.com>
net_sched: qfq: Fix double list add in class with netem as child qdisc
Victor Nogueira <victor(a)mojatatu.com>
net_sched: ets: Fix double list add in class with netem as child qdisc
Victor Nogueira <victor(a)mojatatu.com>
net_sched: hfsc: Fix a UAF vulnerability in class with netem as child qdisc
Victor Nogueira <victor(a)mojatatu.com>
net_sched: drr: Fix double list add in class with netem as child qdisc
Louis-Alexis Eyraud <louisalexis.eyraud(a)collabora.com>
net: ethernet: mtk-star-emac: rearm interrupts in rx_poll only when advised
Louis-Alexis Eyraud <louisalexis.eyraud(a)collabora.com>
net: ethernet: mtk-star-emac: fix spinlock recursion issues on rx/tx poll
Biao Huang <biao.huang(a)mediatek.com>
net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs
Chris Mi <cmi(a)nvidia.com>
net/mlx5: E-switch, Fix error handling for enabling roce
Maor Gottlieb <maorg(a)nvidia.com>
net/mlx5: E-Switch, Initialize MAC Address for Default GID
Jakub Kicinski <kuba(a)kernel.org>
net/sched: act_mirred: don't override retval if we already lost the skb
Sean Christopherson <seanjc(a)google.com>
KVM: x86: Load DR6 with guest value only before entering .vcpu_run() loop
Jeongjun Park <aha310510(a)gmail.com>
tracing: Fix oob write in trace_seq_to_buffer()
Mingcong Bai <jeffbai(a)aosc.io>
iommu/vt-d: Apply quirk_iommu_igfx for 8086:0044 (QM57/QS57)
Pavel Paklov <Pavel.Paklov(a)cyberprotect.ru>
iommu/amd: Fix potential buffer overflow in parse_ivrs_acpihid
Benjamin Marzinski <bmarzins(a)redhat.com>
dm: always update the array size in realloc_argv on success
Mikulas Patocka <mpatocka(a)redhat.com>
dm-integrity: fix a warning on invalid table line
Wentao Liang <vulab(a)iscas.ac.cn>
wifi: brcm80211: fmac: Add error handling for brcmf_usb_dl_writeimage()
Ruslan Piasetskyi <ruslan.piasetskyi(a)gmail.com>
mmc: renesas_sdhi: Fix error handling in renesas_sdhi_probe
Vishal Badole <Vishal.Badole(a)amd.com>
amd-xgbe: Fix to ensure dependent features are toggled with RX checksum offload
Helge Deller <deller(a)gmx.de>
parisc: Fix double SIGFPE crash
Will Deacon <will(a)kernel.org>
arm64: errata: Add missing sentinels to Spectre-BHB MIDR arrays
Clark Wang <xiaoning.wang(a)nxp.com>
i2c: imx-lpi2c: Fix clock count when probe defers
Niravkumar L Rabara <niravkumar.l.rabara(a)altera.com>
EDAC/altera: Set DDR and SDMMC interrupt mask before registration
Niravkumar L Rabara <niravkumar.l.rabara(a)altera.com>
EDAC/altera: Test the correct error reg offset
Philipp Stanner <phasta(a)kernel.org>
drm/nouveau: Fix WARN_ON in nouveau_fence_context_kill()
Joachim Priesner <joachim.priesner(a)web.de>
ALSA: usb-audio: Add second USB ID for Jabra Evolve 65 headset
-------------
Diffstat:
Makefile | 4 +-
arch/arm/boot/dts/imx6ul-imx6ull-opos6ul.dtsi | 3 +
arch/arm64/kernel/proton-pack.c | 2 +
arch/parisc/math-emu/driver.c | 16 +-
arch/riscv/kernel/probes/uprobes.c | 10 +-
arch/x86/include/asm/kvm-x86-ops.h | 1 +
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/svm/svm.c | 13 +-
arch/x86/kvm/vmx/vmx.c | 11 +-
arch/x86/kvm/x86.c | 3 +
drivers/edac/altera_edac.c | 9 +-
drivers/edac/altera_edac.h | 2 +
drivers/firmware/arm_scmi/bus.c | 3 +
drivers/gpu/drm/meson/meson_vclk.c | 6 +-
drivers/gpu/drm/nouveau/nouveau_fence.c | 2 +-
drivers/i2c/busses/i2c-imx-lpi2c.c | 4 +-
drivers/iommu/amd/init.c | 8 +
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 79 ++---
drivers/iommu/intel/iommu.c | 4 +-
drivers/irqchip/irq-gic-v2m.c | 8 +-
drivers/md/dm-integrity.c | 2 +-
drivers/md/dm-table.c | 5 +-
drivers/mmc/host/renesas_sdhi_core.c | 10 +-
drivers/net/ethernet/amd/xgbe/xgbe-desc.c | 9 +-
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 24 +-
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 11 +-
drivers/net/ethernet/amd/xgbe/xgbe.h | 4 +
drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c | 30 +-
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 36 ++-
drivers/net/ethernet/dlink/dl2k.c | 2 +-
drivers/net/ethernet/dlink/dl2k.h | 2 +-
drivers/net/ethernet/freescale/fec_main.c | 7 +-
drivers/net/ethernet/hisilicon/hns3/hnae3.h | 2 +
drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 2 +-
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 119 ++++++--
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 3 +
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 61 ++--
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 26 +-
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | 13 +-
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 25 +-
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 1 +
drivers/net/ethernet/intel/ice/ice_fltr.c | 58 ++++
drivers/net/ethernet/intel/ice/ice_fltr.h | 12 +
drivers/net/ethernet/intel/ice/ice_main.c | 49 +--
drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c | 5 +
drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | 139 ++++-----
drivers/net/ethernet/mediatek/mtk_star_emac.c | 339 ++++++++++++---------
.../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 5 +-
drivers/net/ethernet/mellanox/mlx5/core/rdma.c | 11 +-
drivers/net/ethernet/mellanox/mlx5/core/rdma.h | 4 +-
drivers/net/ethernet/microchip/lan743x_main.c | 8 +-
drivers/net/ethernet/microchip/lan743x_main.h | 1 +
drivers/net/phy/microchip.c | 46 +--
.../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 6 +-
drivers/nvme/host/tcp.c | 31 +-
drivers/of/device.c | 7 +-
drivers/pci/controller/dwc/pci-imx6.c | 5 +-
kernel/trace/trace.c | 5 +-
net/ipv4/udp_offload.c | 61 +++-
net/sched/act_mirred.c | 22 +-
net/sched/sch_drr.c | 9 +-
net/sched/sch_ets.c | 9 +-
net/sched/sch_hfsc.c | 2 +-
net/sched/sch_qfq.c | 11 +-
sound/usb/format.c | 3 +-
65 files changed, 926 insertions(+), 505 deletions(-)
The PMIC GLINK driver is currently generating DisplayPort hotplug
notifications whenever something is connected to (or disconnected from)
a port regardless of the type of notification sent by the firmware.
These notifications are forwarded to user space by the DRM subsystem as
connector "change" uevents:
KERNEL[1556.223776] change /devices/platform/soc(a)0/ae00000.display-subsystem/ae01000.display-controller/drm/card0 (drm)
ACTION=change
DEVPATH=/devices/platform/soc(a)0/ae00000.display-subsystem/ae01000.display-controller/drm/card0
SUBSYSTEM=drm
HOTPLUG=1
CONNECTOR=36
DEVNAME=/dev/dri/card0
DEVTYPE=drm_minor
SEQNUM=4176
MAJOR=226
MINOR=0
On the Lenovo ThinkPad X13s and T14s, the PMIC GLINK firmware sends two
identical notifications with orientation information when connecting a
charger, each generating a bogus DRM hotplug event. On the X13s, two
such notification are also sent every 90 seconds while a charger remains
connected, which again are forwarded to user space:
port = 1, svid = ff00, mode = 255, hpd_state = 0
payload = 01 00 00 00 00 00 00 ff 00 00 00 00 00 00 00 00
Note that the firmware only sends on of these when connecting an
ethernet adapter.
Fix the spurious hotplug events by only forwarding hotplug notifications
for the Type-C DisplayPort service id. This also reduces the number of
uevents from four to two when an actual DisplayPort altmode device is
connected:
port = 0, svid = ff01, mode = 2, hpd_state = 0
payload = 00 01 02 00 f2 0c 01 ff 03 00 00 00 00 00 00 00
port = 0, svid = ff01, mode = 2, hpd_state = 1
payload = 00 01 02 00 f2 0c 01 ff 43 00 00 00 00 00 00 00
Fixes: 080b4e24852b ("soc: qcom: pmic_glink: Introduce altmode support")
Cc: stable(a)vger.kernel.org # 6.3
Cc: Bjorn Andersson <andersson(a)kernel.org>
Reported-by: Clayton Craft <clayton(a)craftyguy.net>
Signed-off-by: Johan Hovold <johan+linaro(a)kernel.org>
---
Clayton reported seeing display flickering with recent RC kernels, which
may possibly be related to these spurious events being generated with
even greater frequency.
That still remains to be fully understood, but the spurious events, that
on the X13s are generated every 90 seconds, should be fixed either way.
Johan
drivers/soc/qcom/pmic_glink_altmode.c | 30 +++++++++++++++++----------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c
index bd06ce161804..7f11acd33323 100644
--- a/drivers/soc/qcom/pmic_glink_altmode.c
+++ b/drivers/soc/qcom/pmic_glink_altmode.c
@@ -218,21 +218,29 @@ static void pmic_glink_altmode_worker(struct work_struct *work)
{
struct pmic_glink_altmode_port *alt_port = work_to_altmode_port(work);
struct pmic_glink_altmode *altmode = alt_port->altmode;
+ enum drm_connector_status conn_status;
typec_switch_set(alt_port->typec_switch, alt_port->orientation);
- if (alt_port->svid == USB_TYPEC_DP_SID && alt_port->mode == 0xff)
- pmic_glink_altmode_safe(altmode, alt_port);
- else if (alt_port->svid == USB_TYPEC_DP_SID)
- pmic_glink_altmode_enable_dp(altmode, alt_port, alt_port->mode,
- alt_port->hpd_state, alt_port->hpd_irq);
- else
- pmic_glink_altmode_enable_usb(altmode, alt_port);
+ if (alt_port->svid == USB_TYPEC_DP_SID) {
+ if (alt_port->mode == 0xff) {
+ pmic_glink_altmode_safe(altmode, alt_port);
+ } else {
+ pmic_glink_altmode_enable_dp(altmode, alt_port,
+ alt_port->mode,
+ alt_port->hpd_state,
+ alt_port->hpd_irq);
+ }
- drm_aux_hpd_bridge_notify(&alt_port->bridge->dev,
- alt_port->hpd_state ?
- connector_status_connected :
- connector_status_disconnected);
+ if (alt_port->hpd_state)
+ conn_status = connector_status_connected;
+ else
+ conn_status = connector_status_disconnected;
+
+ drm_aux_hpd_bridge_notify(&alt_port->bridge->dev, conn_status);
+ } else {
+ pmic_glink_altmode_enable_usb(altmode, alt_port);
+ }
pmic_glink_altmode_request(altmode, ALTMODE_PAN_ACK, alt_port->index);
}
--
2.48.1
[Why]
Notice AUX request format of I2C-over-AUX with
Write_Status_Update_Request flag set is incorrect. It should
be address only request without length and data like:
"SYNC->COM3:0 (= 0110)|0000-> 0000|0000->
0|7-bit I2C address (the same as the last)-> STOP->".
[How]
Refer to DP v2.1 Table 2-178, correct the
Write_Status_Update_Request to be address only request.
Note that we might receive 0 returned by aux->transfer() when
receive reply I2C_ACK|AUX_ACK of Write_Status_Update_Request
transaction. Which indicating all data bytes get written.
We should avoid to return 0 bytes get transferred under this
case.
V2:
- Add checking condition before restoring msg->buffer and
msg->size. (Limonciello Mario)
- Revise unclear comment to appropriately describe the idea.
(Jani Nikula)
Fixes: 68ec2a2a2481 ("drm/dp: Use I2C_WRITE_STATUS_UPDATE to drain partial I2C_WRITE requests")
Cc: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
Cc: Jani Nikula <jani.nikula(a)intel.com>
Cc: Mario Limonciello <mario.limonciello(a)amd.com>
Cc: Harry Wentland <harry.wentland(a)amd.com>
Cc: stable(a)vger.kernel.org
Signed-off-by: Wayne Lin <Wayne.Lin(a)amd.com>
---
drivers/gpu/drm/display/drm_dp_helper.c | 54 +++++++++++++++++++++----
1 file changed, 47 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
index 57828f2b7b5a..c71a1395a2d6 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -1857,6 +1857,12 @@ static u32 drm_dp_i2c_functionality(struct i2c_adapter *adapter)
I2C_FUNC_10BIT_ADDR;
}
+static inline bool
+drm_dp_i2c_msg_is_write_status_update(struct drm_dp_aux_msg *msg)
+{
+ return ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE_STATUS_UPDATE);
+}
+
static void drm_dp_i2c_msg_write_status_update(struct drm_dp_aux_msg *msg)
{
/*
@@ -1965,6 +1971,7 @@ MODULE_PARM_DESC(dp_aux_i2c_speed_khz,
static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
{
unsigned int retry, defer_i2c;
+ struct drm_dp_aux_msg orig_msg = *msg;
int ret;
/*
* DP1.2 sections 2.7.7.1.5.6.1 and 2.7.7.1.6.6.1: A DP Source device
@@ -1976,6 +1983,12 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
int max_retries = max(7, drm_dp_i2c_retry_count(msg, dp_aux_i2c_speed_khz));
for (retry = 0, defer_i2c = 0; retry < (max_retries + defer_i2c); retry++) {
+ if (drm_dp_i2c_msg_is_write_status_update(msg)) {
+ /* Address only transaction */
+ msg->buffer = NULL;
+ msg->size = 0;
+ }
+
ret = aux->transfer(aux, msg);
if (ret < 0) {
if (ret == -EBUSY)
@@ -1993,7 +2006,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
else
drm_dbg_kms(aux->drm_dev, "%s: transaction failed: %d\n",
aux->name, ret);
- return ret;
+ goto out;
}
@@ -2008,7 +2021,8 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
case DP_AUX_NATIVE_REPLY_NACK:
drm_dbg_kms(aux->drm_dev, "%s: native nack (result=%d, size=%zu)\n",
aux->name, ret, msg->size);
- return -EREMOTEIO;
+ ret = -EREMOTEIO;
+ goto out;
case DP_AUX_NATIVE_REPLY_DEFER:
drm_dbg_kms(aux->drm_dev, "%s: native defer\n", aux->name);
@@ -2027,24 +2041,41 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
default:
drm_err(aux->drm_dev, "%s: invalid native reply %#04x\n",
aux->name, msg->reply);
- return -EREMOTEIO;
+ ret = -EREMOTEIO;
+ goto out;
}
switch (msg->reply & DP_AUX_I2C_REPLY_MASK) {
case DP_AUX_I2C_REPLY_ACK:
+ /*
+ * When DPTx sets Write_Status_Update_Request flag to
+ * ask DPRx for the write status, the AUX reply from
+ * DPRx will be I2C_ACK|AUX_ACK if I2C write request
+ * completes successfully. Such AUX transaction is for
+ * status checking only, so no new data is written by
+ * aux->transfer(). In this case, here we have to
+ * report all original data get written. Otherwise,
+ * drm_dp_i2c_drain_msg() takes returned value 0 as
+ * an error.
+ */
+ if (drm_dp_i2c_msg_is_write_status_update(msg) && ret == 0)
+ ret = orig_msg.size;
+
/*
* Both native ACK and I2C ACK replies received. We
* can assume the transfer was successful.
*/
if (ret != msg->size)
drm_dp_i2c_msg_write_status_update(msg);
- return ret;
+
+ goto out;
case DP_AUX_I2C_REPLY_NACK:
drm_dbg_kms(aux->drm_dev, "%s: I2C nack (result=%d, size=%zu)\n",
aux->name, ret, msg->size);
aux->i2c_nack_count++;
- return -EREMOTEIO;
+ ret = -EREMOTEIO;
+ goto out;
case DP_AUX_I2C_REPLY_DEFER:
drm_dbg_kms(aux->drm_dev, "%s: I2C defer\n", aux->name);
@@ -2063,12 +2094,21 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
default:
drm_err(aux->drm_dev, "%s: invalid I2C reply %#04x\n",
aux->name, msg->reply);
- return -EREMOTEIO;
+ ret = -EREMOTEIO;
+ goto out;
}
}
drm_dbg_kms(aux->drm_dev, "%s: Too many retries, giving up\n", aux->name);
- return -EREMOTEIO;
+ ret = -EREMOTEIO;
+out:
+ /* In case we change original msg by Write_Status_Update case*/
+ if (drm_dp_i2c_msg_is_write_status_update(msg)) {
+ msg->buffer = orig_msg.buffer;
+ msg->size = orig_msg.size;
+ }
+
+ return ret;
}
static void drm_dp_i2c_msg_set_request(struct drm_dp_aux_msg *msg,
--
2.43.0