From 7b5162080174ae50e8288574379d339b0fcd1760 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sat, 24 Jun 2023 18:52:32 +0200 Subject: [PATCH 001/272] ASoC: hdmi-codec: fix channel info for compressed formats According to CTA 861 the channel/speaker allocation info in the audio infoframe only applies to uncompressed (PCM) audio streams. The channel count info should indicate the number of channels in the transmitted audio, which usually won't match the number of channels used to transmit the compressed bitstream. Some devices (eg some Sony TVs) will refuse to decode compressed audio if these values are not set correctly. To fix this we can simply set the channel count to 0 (which means "refer to stream header") and set the channel/speaker allocation to 0 as well (which would mean stereo FL/FR for PCM, a safe value all sinks will support) when transmitting compressed audio. Signed-off-by: Matthias Reichl Link: https://lore.kernel.org/r/20230624165232.5751-1-hias@horus.com Signed-off-by: Mark Brown --- sound/soc/codecs/hdmi-codec.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 6d980fbc4207..d21f69f05342 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -495,31 +495,43 @@ static int hdmi_codec_fill_codec_params(struct snd_soc_dai *dai, struct hdmi_codec_params *hp) { struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); - int idx; + int idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; + u8 ca_id = 0; + bool pcm_audio = !(hcp->iec_status[0] & IEC958_AES0_NONAUDIO); - /* Select a channel allocation that matches with ELD and pcm channels */ - idx = hdmi_codec_get_ch_alloc_table_idx(hcp, channels); - if (idx < 0) { - dev_err(dai->dev, "Not able to map channels to speakers (%d)\n", - idx); - hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; - return idx; + if (pcm_audio) { + /* Select a channel allocation that matches with ELD and pcm channels */ + idx = hdmi_codec_get_ch_alloc_table_idx(hcp, channels); + + if (idx < 0) { + dev_err(dai->dev, "Not able to map channels to speakers (%d)\n", + idx); + hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; + return idx; + } + + ca_id = hdmi_codec_channel_alloc[idx].ca_id; } memset(hp, 0, sizeof(*hp)); hdmi_audio_infoframe_init(&hp->cea); - hp->cea.channels = channels; + + if (pcm_audio) + hp->cea.channels = channels; + else + hp->cea.channels = 0; + hp->cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; hp->cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; hp->cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; - hp->cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id; + hp->cea.channel_allocation = ca_id; hp->sample_width = sample_width; hp->sample_rate = sample_rate; hp->channels = channels; - hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id; + hcp->chmap_idx = idx; return 0; } From 7beda6a256ed10e74dc00fcd0fc8da0ad8fea78d Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Mon, 26 Jun 2023 16:23:49 +0530 Subject: [PATCH 002/272] ASoC: amd: ps: add comments for DMA irq bits mapping Add comments for DMA stream id and IRQ bit mapping in ACP_EXTERNAL_CNTL & ACP_EXTERNAL_CNTL1 registers for SDW0 and SDW1 manager instances. Signed-off-by: Vijendar Mukunda Link: https://lore.kernel.org/r/20230626105356.2580125-1-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index e96e6dc9d90f..733a16e23d32 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -116,8 +116,28 @@ #define ACP63_SDW0_DMA_MAX_STREAMS 6 #define ACP63_SDW1_DMA_MAX_STREAMS 2 #define ACP_P1_AUDIO_TX_THRESHOLD 6 + +/* + * Below entries describes SDW0 instance DMA stream id and DMA irq bit mapping + * in ACP_EXTENAL_INTR_CNTL register. + * Stream id IRQ Bit + * 0 (SDW0_AUDIO0_TX) 28 + * 1 (SDW0_AUDIO1_TX) 26 + * 2 (SDW0_AUDIO2_TX) 24 + * 3 (SDW0_AUDIO0_RX) 27 + * 4 (SDW0_AUDIO1_RX) 25 + * 5 (SDW0_AUDIO2_RX) 23 + */ #define SDW0_DMA_TX_IRQ_MASK(i) (ACP_AUDIO0_TX_THRESHOLD - (2 * (i))) #define SDW0_DMA_RX_IRQ_MASK(i) (ACP_AUDIO0_RX_THRESHOLD - (2 * (i))) + +/* + * Below entries describes SDW1 instance DMA stream id and DMA irq bit mapping + * in ACP_EXTENAL_INTR_CNTL1 register. + * Stream id IRQ Bit + * 0 (SDW1_AUDIO1_TX) 6 + * 1 (SDW1_AUDIO1_RX) 5 + */ #define SDW1_DMA_IRQ_MASK(i) (ACP_P1_AUDIO_TX_THRESHOLD - (i)) #define ACP_DELAY_US 5 From 322a163ea6a38f63555d824c5b66c7df5a595c2d Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Mon, 26 Jun 2023 16:23:50 +0530 Subject: [PATCH 003/272] ASoC: amd: ps: add fix for dma irq mask for rx streams for SDW0 instance Correct the DMA irq mask macro to program DMA irq bits correctly for SDW0 instance rx streams. Fixes: 298d4f7b1765 ("ASoC: amd: ps: add support for SoundWire DMA interrupts") Signed-off-by: Vijendar Mukunda Link: https://lore.kernel.org/r/20230626105356.2580125-2-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 733a16e23d32..8b853b8d0219 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -129,7 +129,7 @@ * 5 (SDW0_AUDIO2_RX) 23 */ #define SDW0_DMA_TX_IRQ_MASK(i) (ACP_AUDIO0_TX_THRESHOLD - (2 * (i))) -#define SDW0_DMA_RX_IRQ_MASK(i) (ACP_AUDIO0_RX_THRESHOLD - (2 * (i))) +#define SDW0_DMA_RX_IRQ_MASK(i) (ACP_AUDIO0_RX_THRESHOLD - (2 * ((i) - 3))) /* * Below entries describes SDW1 instance DMA stream id and DMA irq bit mapping From f15f6b294dde506bd4902db3262e9b4ab7e9e5a9 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Mon, 26 Jun 2023 16:23:51 +0530 Subject: [PATCH 004/272] ASoC: amd: ps: fix for position register set for AUDIO0 RX stream For AUDIO0 RX stream, AUDIO0_RX position registers should be used. DMA error is reported due to referring wrong position register set for AUDIO0 RX stream. Correct the position register set for AUDIO0 RX stream. Fixes: f722917350ee ("ASoC: amd: ps: add SoundWire dma driver dma ops") Signed-off-by: Vijendar Mukunda Link: https://lore.kernel.org/r/20230626105356.2580125-3-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/ps-sdw-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index ade130a8062a..3ab41bd1fce2 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -30,7 +30,7 @@ static struct sdw_dma_ring_buf_reg sdw0_dma_ring_buf_reg[ACP63_SDW0_DMA_MAX_STRE ACP_AUDIO2_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_TX_LINEARPOSITIONCNTR_HIGH}, {ACP_AUDIO0_RX_DMA_SIZE, ACP_AUDIO0_RX_FIFOADDR, ACP_AUDIO0_RX_FIFOSIZE, ACP_AUDIO0_RX_RINGBUFSIZE, ACP_AUDIO0_RX_RINGBUFADDR, ACP_AUDIO0_RX_INTR_WATERMARK_SIZE, - ACP_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH}, + ACP_AUDIO0_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_RX_LINEARPOSITIONCNTR_HIGH}, {ACP_AUDIO1_RX_DMA_SIZE, ACP_AUDIO1_RX_FIFOADDR, ACP_AUDIO1_RX_FIFOSIZE, ACP_AUDIO1_RX_RINGBUFSIZE, ACP_AUDIO1_RX_RINGBUFADDR, ACP_AUDIO1_RX_INTR_WATERMARK_SIZE, ACP_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH}, From 46b50e514b191ae15789cccabace5b6040c9278e Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Mon, 26 Jun 2023 16:23:52 +0530 Subject: [PATCH 005/272] ASoC: amd: ps: add comments for DMA register mapping Add comments for DMA register mapping for both the SoundWire manager instances. Signed-off-by: Vijendar Mukunda Link: https://lore.kernel.org/r/20230626105356.2580125-4-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/ps-sdw-dma.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 3ab41bd1fce2..000ab5d96815 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -39,6 +39,11 @@ static struct sdw_dma_ring_buf_reg sdw0_dma_ring_buf_reg[ACP63_SDW0_DMA_MAX_STRE ACP_AUDIO2_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_RX_LINEARPOSITIONCNTR_HIGH} }; +/* + * SDW1 instance supports one TX stream and one RX stream. + * For TX/RX streams DMA registers programming for SDW1 instance, it uses ACP_P1_AUDIO1 register + * set as per hardware register documentation + */ static struct sdw_dma_ring_buf_reg sdw1_dma_ring_buf_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { {ACP_P1_AUDIO1_TX_DMA_SIZE, ACP_P1_AUDIO1_TX_FIFOADDR, ACP_P1_AUDIO1_TX_FIFOSIZE, ACP_P1_AUDIO1_TX_RINGBUFSIZE, ACP_P1_AUDIO1_TX_RINGBUFADDR, @@ -59,6 +64,12 @@ static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = { ACP_SW0_AUDIO2_RX_EN, }; +/* + * SDW1 instance supports one TX stream and one RX stream. + * For TX/RX streams DMA enable register programming for SDW1 instance, + * it uses ACP_SW1_AUDIO1_TX_EN and ACP_SW1_AUDIO1_RX_EN registers + * as per hardware register documentation. + */ static u32 sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { ACP_SW1_AUDIO1_TX_EN, ACP_SW1_AUDIO1_RX_EN, From 68a653ab864ccf7874fe622f3af20fe7345c39be Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Mon, 26 Jun 2023 16:23:53 +0530 Subject: [PATCH 006/272] ASoC: amd: ps: fix byte count return value for invalid SoundWire manager instance acp_get_byte_count() function should return zero bytes instead of -EINVAL for invalid SoundWire manager instance. Fixes: f722917350ee ("ASoC: amd: ps: add SoundWire dma driver dma ops") Signed-off-by: Vijendar Mukunda Link: https://lore.kernel.org/r/20230626105356.2580125-5-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/ps-sdw-dma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 000ab5d96815..324c80fca672 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -318,12 +318,13 @@ static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __io pos_high_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_high_reg; break; default: - return -EINVAL; + goto POINTER_RETURN_BYTES; } if (pos_low_reg) { byte_count.bcount.high = readl(acp_base + pos_high_reg); byte_count.bcount.low = readl(acp_base + pos_low_reg); } +POINTER_RETURN_BYTES: return byte_count.bytescount; } From 85aeab362201cf52c34cd429e4f6c75a0b42f9a3 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Mon, 26 Jun 2023 16:23:54 +0530 Subject: [PATCH 007/272] ASoC: amd: acp: fix for invalid dai id handling in acp_get_byte_count() For invalid dai id, instead of returning -EINVAL return bytes count as zero in acp_get_byte_count() function. Fixes: 623621a9f9e1 ("ASoC: amd: Add common framework to support I2S on ACP SOC") Signed-off-by: Vijendar Mukunda Link: https://lore.kernel.org/r/20230626105356.2580125-6-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/amd.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 5f2119f42271..12a176a50fd6 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -173,7 +173,7 @@ int snd_amd_acp_find_config(struct pci_dev *pci); static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction) { - u64 byte_count, low = 0, high = 0; + u64 byte_count = 0, low = 0, high = 0; if (direction == SNDRV_PCM_STREAM_PLAYBACK) { switch (dai_id) { @@ -191,7 +191,7 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int break; default: dev_err(adata->dev, "Invalid dai id %x\n", dai_id); - return -EINVAL; + goto POINTER_RETURN_BYTES; } } else { switch (dai_id) { @@ -213,12 +213,13 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int break; default: dev_err(adata->dev, "Invalid dai id %x\n", dai_id); - return -EINVAL; + goto POINTER_RETURN_BYTES; } } /* Get 64 bit value from two 32 bit registers */ byte_count = (high << 32) | low; +POINTER_RETURN_BYTES: return byte_count; } From 49bd7b08149417a30aa7d92c8c85b3518de44a76 Mon Sep 17 00:00:00 2001 From: Sheetal Date: Thu, 29 Jun 2023 10:42:13 +0530 Subject: [PATCH 008/272] ASoC: tegra: Fix AMX byte map Byte mask for channel-1 of stream-1 is not getting enabled and this causes failures during AMX use cases. This happens because the byte map value 0 matches the byte map array and put() callback returns without enabling the corresponding bits in the byte mask. AMX supports 4 input streams and each stream can take a maximum of 16 channels. Each byte in the output frame is uniquely mapped to a byte in one of these 4 inputs. This mapping is done with the help of byte map array via user space control setting. The byte map array size in the driver is 16 and each array element is of size 4 bytes. This corresponds to 64 byte map values. Each byte in the byte map array can have any value between 0 to 255 to enable the corresponding bits in the byte mask. The value 256 is used as a way to disable the byte map. However the byte map array element cannot store this value. The put() callback disables the byte mask for 256 value and byte map value is reset to 0 for this case. This causes problems during subsequent runs since put() callback, for value of 0, just returns without enabling the byte mask. In short, the problem is coming because 0 and 256 control values are stored as 0 in the byte map array. Right now fix the put() callback by actually looking at the byte mask array state to identify if any change is needed and update the fields accordingly. The get() callback needs an update as well to return the correct control value that user has set before. Note that when user sets 256, the value is stored as 0 and byte mask is disabled. So byte mask state is used to either return 256 or the value from byte map array. Given above, this looks bit complicated and all this happens because the byte map array is tightly packed and cannot actually store the 256 value. Right now the priority is to fix the existing failure and a TODO item is put to improve this logic. Fixes: 8db78ace1ba8 ("ASoC: tegra: Fix kcontrol put callback in AMX") Cc: stable@vger.kernel.org Signed-off-by: Sheetal Reviewed-by: Mohan Kumar D Reviewed-by: Sameer Pujar Link: https://lore.kernel.org/r/1688015537-31682-2-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_amx.c | 40 +++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/sound/soc/tegra/tegra210_amx.c b/sound/soc/tegra/tegra210_amx.c index 782a141b65c0..179876949b30 100644 --- a/sound/soc/tegra/tegra210_amx.c +++ b/sound/soc/tegra/tegra210_amx.c @@ -2,7 +2,7 @@ // // tegra210_amx.c - Tegra210 AMX driver // -// Copyright (c) 2021 NVIDIA CORPORATION. All rights reserved. +// Copyright (c) 2021-2023 NVIDIA CORPORATION. All rights reserved. #include #include @@ -203,10 +203,20 @@ static int tegra210_amx_get_byte_map(struct snd_kcontrol *kcontrol, else enabled = amx->byte_mask[0] & (1 << reg); + /* + * TODO: Simplify this logic to just return from bytes_map[] + * + * Presently below is required since bytes_map[] is + * tightly packed and cannot store the control value of 256. + * Byte mask state is used to know if 256 needs to be returned. + * Note that for control value of 256, the put() call stores 0 + * in the bytes_map[] and disables the corresponding bit in + * byte_mask[]. + */ if (enabled) ucontrol->value.integer.value[0] = bytes_map[reg]; else - ucontrol->value.integer.value[0] = 0; + ucontrol->value.integer.value[0] = 256; return 0; } @@ -221,25 +231,19 @@ static int tegra210_amx_put_byte_map(struct snd_kcontrol *kcontrol, unsigned char *bytes_map = (unsigned char *)&amx->map; int reg = mc->reg; int value = ucontrol->value.integer.value[0]; + unsigned int mask_val = amx->byte_mask[reg / 32]; - if (value == bytes_map[reg]) + if (value >= 0 && value <= 255) + mask_val |= (1 << (reg % 32)); + else + mask_val &= ~(1 << (reg % 32)); + + if (mask_val == amx->byte_mask[reg / 32]) return 0; - if (value >= 0 && value <= 255) { - /* Update byte map and enable slot */ - bytes_map[reg] = value; - if (reg > 31) - amx->byte_mask[1] |= (1 << (reg - 32)); - else - amx->byte_mask[0] |= (1 << reg); - } else { - /* Reset byte map and disable slot */ - bytes_map[reg] = 0; - if (reg > 31) - amx->byte_mask[1] &= ~(1 << (reg - 32)); - else - amx->byte_mask[0] &= ~(1 << reg); - } + /* Update byte map and slot */ + bytes_map[reg] = value % 256; + amx->byte_mask[reg / 32] = mask_val; return 1; } From 6dfe70be0b0dec0f9297811501bec26c05fd96ad Mon Sep 17 00:00:00 2001 From: Sheetal Date: Thu, 29 Jun 2023 10:42:14 +0530 Subject: [PATCH 009/272] ASoC: tegra: Fix ADX byte map Byte mask for channel-1 of stream-1 is not getting enabled and this causes failures during ADX use cases. This happens because the byte map value 0 matches the byte map array and put() callback returns without enabling the corresponding bits in the byte mask. ADX supports 4 output streams and each stream can have a maximum of 16 channels. Each byte in the input frame is uniquely mapped to a byte in one of these 4 outputs. This mapping is done with the help of byte map array via user space control setting. The byte map array size in the driver is 16 and each array element is of size 4 bytes. This corresponds to 64 byte map values. Each byte in the byte map array can have any value between 0 to 255 to enable the corresponding bits in the byte mask. The value 256 is used as a way to disable the byte map. However the byte map array element cannot store this value. The put() callback disables the byte mask for 256 value and byte map value is reset to 0 for this case. This causes problems during subsequent runs since put() callback, for value of 0, just returns without enabling the byte mask. In short, the problem is coming because 0 and 256 control values are stored as 0 in the byte map array. Right now fix the put() callback by actually looking at the byte mask array state to identify if any change is needed and update the fields accordingly. The get() callback needs an update as well to return the correct control value that user has set before. Note that when user set 256, the value is stored as 0 and byte mask is disabled. So byte mask state is used to either return 256 or the value from byte map array. Given above, this looks bit complicated and all this happens because the byte map array is tightly packed and cannot actually store the 256 value. Right now the priority is to fix the existing failure and a TODO item is put to improve this logic. Fixes: 3c97881b8c8a ("ASoC: tegra: Fix kcontrol put callback in ADX") Cc: stable@vger.kernel.org Signed-off-by: Sheetal Reviewed-by: Mohan Kumar D Reviewed-by: Sameer Pujar Link: https://lore.kernel.org/r/1688015537-31682-3-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_adx.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/sound/soc/tegra/tegra210_adx.c b/sound/soc/tegra/tegra210_adx.c index bd0b10c70c4c..7d003f0c8d0f 100644 --- a/sound/soc/tegra/tegra210_adx.c +++ b/sound/soc/tegra/tegra210_adx.c @@ -2,7 +2,7 @@ // // tegra210_adx.c - Tegra210 ADX driver // -// Copyright (c) 2021 NVIDIA CORPORATION. All rights reserved. +// Copyright (c) 2021-2023 NVIDIA CORPORATION. All rights reserved. #include #include @@ -175,10 +175,20 @@ static int tegra210_adx_get_byte_map(struct snd_kcontrol *kcontrol, mc = (struct soc_mixer_control *)kcontrol->private_value; enabled = adx->byte_mask[mc->reg / 32] & (1 << (mc->reg % 32)); + /* + * TODO: Simplify this logic to just return from bytes_map[] + * + * Presently below is required since bytes_map[] is + * tightly packed and cannot store the control value of 256. + * Byte mask state is used to know if 256 needs to be returned. + * Note that for control value of 256, the put() call stores 0 + * in the bytes_map[] and disables the corresponding bit in + * byte_mask[]. + */ if (enabled) ucontrol->value.integer.value[0] = bytes_map[mc->reg]; else - ucontrol->value.integer.value[0] = 0; + ucontrol->value.integer.value[0] = 256; return 0; } @@ -192,19 +202,19 @@ static int tegra210_adx_put_byte_map(struct snd_kcontrol *kcontrol, int value = ucontrol->value.integer.value[0]; struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; + unsigned int mask_val = adx->byte_mask[mc->reg / 32]; - if (value == bytes_map[mc->reg]) + if (value >= 0 && value <= 255) + mask_val |= (1 << (mc->reg % 32)); + else + mask_val &= ~(1 << (mc->reg % 32)); + + if (mask_val == adx->byte_mask[mc->reg / 32]) return 0; - if (value >= 0 && value <= 255) { - /* update byte map and enable slot */ - bytes_map[mc->reg] = value; - adx->byte_mask[mc->reg / 32] |= (1 << (mc->reg % 32)); - } else { - /* reset byte map and disable slot */ - bytes_map[mc->reg] = 0; - adx->byte_mask[mc->reg / 32] &= ~(1 << (mc->reg % 32)); - } + /* Update byte map and slot */ + bytes_map[mc->reg] = value % 256; + adx->byte_mask[mc->reg / 32] = mask_val; return 1; } From 70a6404ff610aa4889d98977da131c37f9ff9d1f Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Thu, 29 Jun 2023 10:42:15 +0530 Subject: [PATCH 010/272] ASoC: rt5640: Fix sleep in atomic context Following prints are observed while testing audio on Jetson AGX Orin which has onboard RT5640 audio codec: BUG: sleeping function called from invalid context at kernel/workqueue.c:3027 in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 0, name: swapper/0 preempt_count: 10001, expected: 0 RCU nest depth: 0, expected: 0 ------------[ cut here ]------------ WARNING: CPU: 0 PID: 0 at kernel/irq/handle.c:159 __handle_irq_event_percpu+0x1e0/0x270 ---[ end trace ad1c64905aac14a6 ]- The IRQ handler rt5640_irq() runs in interrupt context and can sleep during cancel_delayed_work_sync(). Fix this by running IRQ handler, rt5640_irq(), in thread context. Hence replace request_irq() calls with devm_request_threaded_irq(). Fixes: 051dade34695 ("ASoC: rt5640: Fix the wrong state of JD1 and JD2") Cc: stable@vger.kernel.org Cc: Oder Chiou Signed-off-by: Sameer Pujar Link: https://lore.kernel.org/r/1688015537-31682-4-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 0ed4fa261abf..e24ed754ac56 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -2567,9 +2567,10 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component, if (jack_data && jack_data->use_platform_clock) rt5640->use_platform_clock = jack_data->use_platform_clock; - ret = request_irq(rt5640->irq, rt5640_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "rt5640", rt5640); + ret = devm_request_threaded_irq(component->dev, rt5640->irq, + NULL, rt5640_irq, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "rt5640", rt5640); if (ret) { dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret); rt5640_disable_jack_detect(component); @@ -2622,8 +2623,9 @@ static void rt5640_enable_hda_jack_detect( rt5640->jack = jack; - ret = request_irq(rt5640->irq, rt5640_irq, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, "rt5640", rt5640); + ret = devm_request_threaded_irq(component->dev, rt5640->irq, + NULL, rt5640_irq, IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "rt5640", rt5640); if (ret) { dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret); rt5640->irq = -ENXIO; From b1db244c716fe300e36428aeb0874913d2e0a91d Mon Sep 17 00:00:00 2001 From: Mastan Katragadda Date: Fri, 30 Jun 2023 12:35:42 +0530 Subject: [PATCH 011/272] ASoC: SOF: amd: add revision check for sending sha dma completion command ACP driver should send SHA DMA completion command to PSP module for RN platform only. Add a revision check for RN platform. Signed-off-by: Mastan Katragadda Link: https://lore.kernel.org/r/20230630070544.2167421-1-Mastan.Katragadda@amd.com Signed-off-by: Mark Brown --- sound/soc/sof/amd/acp.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c index 2ae76bcd3590..afb505461ea1 100644 --- a/sound/soc/sof/amd/acp.c +++ b/sound/soc/sof/amd/acp.c @@ -217,6 +217,7 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr, unsigned int image_length) { struct snd_sof_dev *sdev = adata->dev; + const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata); unsigned int tx_count, fw_qualifier, val; int ret; @@ -251,9 +252,12 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr, return ret; } - ret = psp_send_cmd(adata, MBOX_ACP_SHA_DMA_COMMAND); - if (ret) - return ret; + /* psp_send_cmd only required for renoir platform (rev - 3) */ + if (desc->rev == 3) { + ret = psp_send_cmd(adata, MBOX_ACP_SHA_DMA_COMMAND); + if (ret) + return ret; + } ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_SHA_DSP_FW_QUALIFIER, fw_qualifier, fw_qualifier & DSP_FW_RUN_ENABLE, From 85a61b1ce461a3f62f1019e5e6423c393c542bff Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 30 Jun 2023 14:03:18 +0200 Subject: [PATCH 012/272] ASoC: codecs: wcd938x: fix codec initialisation race Make sure to resume the codec and soundwire device before trying to read the codec variant and configure the device during component probe. This specifically avoids interpreting (a masked and shifted) -EBUSY errno as the variant: wcd938x_codec audio-codec: ASoC: error at soc_component_read_no_lock on audio-codec for register: [0x000034b0] -16 when the soundwire device happens to be suspended, which in turn prevents some headphone controls from being registered. Fixes: 8d78602aa87a ("ASoC: codecs: wcd938x: add basic driver") Cc: stable@vger.kernel.org # 5.14 Cc: Srinivas Kandagatla Reported-by: Steev Klimaszewski Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20230630120318.6571-1-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd938x.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index e7d6a02cdec0..e3ae4fb2c4db 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -3085,6 +3085,10 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) snd_soc_component_init_regmap(component, wcd938x->regmap); + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) + return ret; + wcd938x->variant = snd_soc_component_read_field(component, WCD938X_DIGITAL_EFUSE_REG_0, WCD938X_ID_MASK); @@ -3098,6 +3102,8 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) (WCD938X_DIGITAL_INTR_LEVEL_0 + i), 0); } + pm_runtime_put(dev); + wcd938x->hphr_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip, WCD938X_IRQ_HPHR_PDM_WD_INT); wcd938x->hphl_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip, From ac192c1a54f9562efe6bac910e6e7aae7b5fbea3 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 28 Jun 2023 10:24:04 +0100 Subject: [PATCH 013/272] ASoC: qdsp6: q6apm: use dai link pcm id as pcm device number For some reason we ended up with a setup without this flag. This resulted in inconsistent sound card devices numbers which are also not starting as expected at dai_link->id. (Ex: MultiMedia1 pcm ended up with device number 4 instead of 0) With this patch patch now the MultiMedia1 PCM ends up with device number 0 as expected. [This is causing unstable numbering in userspace as other changes go in, which in turn gets noticed by some userspace. There's been multiple values so we can't simply pick one and revert to it. Do not backport since it will introduce a change. -- broonie] Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230628092404.13927-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6apm-dai.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c index 5eb0b864c740..c90db6daabbd 100644 --- a/sound/soc/qcom/qdsp6/q6apm-dai.c +++ b/sound/soc/qcom/qdsp6/q6apm-dai.c @@ -840,6 +840,7 @@ static const struct snd_soc_component_driver q6apm_fe_dai_component = { .pointer = q6apm_dai_pointer, .trigger = q6apm_dai_trigger, .compress_ops = &q6apm_dai_compress_ops, + .use_dai_pcm_id = true, }; static int q6apm_dai_probe(struct platform_device *pdev) From e5ce198bd5c6923b6a51e1493b1401f84c24b26d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 30 Jun 2023 16:27:13 +0200 Subject: [PATCH 014/272] ASoC: codecs: wcd938x: fix mbhc impedance loglevel Demote the MBHC impedance measurement printk, which is not an error message, from error to debug level. While at it, fix the capitalisation of "ohm" and add the missing space before the opening parenthesis. Fixes: bcee7ed09b8e ("ASoC: codecs: wcd938x: add Multi Button Headset Control support") Signed-off-by: Johan Hovold Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230630142717.5314-2-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd938x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index e7d6a02cdec0..81d865276c9c 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -2165,8 +2165,8 @@ static inline void wcd938x_mbhc_get_result_params(struct wcd938x_priv *wcd938x, else if (x1 < minCode_param[noff]) *zdet = WCD938X_ZDET_FLOATING_IMPEDANCE; - pr_err("%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n", - __func__, d1, c1, x1, *zdet); + pr_debug("%s: d1=%d, c1=%d, x1=0x%x, z_val=%d (milliohm)\n", + __func__, d1, c1, x1, *zdet); ramp_down: i = 0; while (x1) { From 5db9fe9562aaefca3c972401a9e3d6454707b1d5 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 30 Jun 2023 16:27:14 +0200 Subject: [PATCH 015/272] ASoC: codecs: wcd938x: drop inline keywords The compiler is generally better at deciding what functions should be inlined than driver authors are. Drop the bogus inline keyword from two functions that were neither very small or used in a single place. Signed-off-by: Johan Hovold Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230630142717.5314-3-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd938x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index 81d865276c9c..63756f0a6a53 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -2124,7 +2124,7 @@ static int wcd938x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *compon return wcd938x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2); } -static inline void wcd938x_mbhc_get_result_params(struct wcd938x_priv *wcd938x, +static void wcd938x_mbhc_get_result_params(struct wcd938x_priv *wcd938x, s16 *d1_a, u16 noff, int32_t *zdet) { @@ -2231,8 +2231,8 @@ z_right: *zr = zdet; } -static inline void wcd938x_wcd_mbhc_qfuse_cal(struct snd_soc_component *component, - int32_t *z_val, int flag_l_r) +static void wcd938x_wcd_mbhc_qfuse_cal(struct snd_soc_component *component, + int32_t *z_val, int flag_l_r) { s16 q1; int q1_cal; From 17d59d9ed832742f9572fe5e77ed3a66f5ae404d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 30 Jun 2023 16:27:15 +0200 Subject: [PATCH 016/272] ASoC: codecs: wcd938x: use dev_printk() for impedance logging Pass the component structure also to the wcd938x_mbhc_get_result_params() helper so that the component device can be used for logging consistently. Signed-off-by: Johan Hovold Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230630142717.5314-4-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd938x.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index 63756f0a6a53..373e86f31b48 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -2124,10 +2124,11 @@ static int wcd938x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *compon return wcd938x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2); } -static void wcd938x_mbhc_get_result_params(struct wcd938x_priv *wcd938x, +static void wcd938x_mbhc_get_result_params(struct snd_soc_component *component, s16 *d1_a, u16 noff, int32_t *zdet) { + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); int i; int val, val1; s16 c1; @@ -2154,8 +2155,8 @@ static void wcd938x_mbhc_get_result_params(struct wcd938x_priv *wcd938x, usleep_range(5000, 5050); if (!c1 || !x1) { - pr_err("%s: Impedance detect ramp error, c1=%d, x1=0x%x\n", - __func__, c1, x1); + dev_err(component->dev, "Impedance detect ramp error, c1=%d, x1=0x%x\n", + c1, x1); goto ramp_down; } d1 = d1_a[c1]; @@ -2165,8 +2166,8 @@ static void wcd938x_mbhc_get_result_params(struct wcd938x_priv *wcd938x, else if (x1 < minCode_param[noff]) *zdet = WCD938X_ZDET_FLOATING_IMPEDANCE; - pr_debug("%s: d1=%d, c1=%d, x1=0x%x, z_val=%d (milliohm)\n", - __func__, d1, c1, x1, *zdet); + dev_dbg(component->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d (milliohm)\n", + __func__, d1, c1, x1, *zdet); ramp_down: i = 0; while (x1) { @@ -2210,7 +2211,7 @@ static void wcd938x_mbhc_zdet_ramp(struct snd_soc_component *component, WCD938X_ANA_MBHC_ZDET, 0x80, 0x80); dev_dbg(component->dev, "%s: ramp for HPH_L, noff = %d\n", __func__, zdet_param->noff); - wcd938x_mbhc_get_result_params(wcd938x, d1_a, zdet_param->noff, &zdet); + wcd938x_mbhc_get_result_params(component, d1_a, zdet_param->noff, &zdet); regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x80, 0x00); @@ -2224,7 +2225,7 @@ z_right: WCD938X_ANA_MBHC_ZDET, 0x40, 0x40); dev_dbg(component->dev, "%s: ramp for HPH_R, noff = %d\n", __func__, zdet_param->noff); - wcd938x_mbhc_get_result_params(wcd938x, d1_a, zdet_param->noff, &zdet); + wcd938x_mbhc_get_result_params(component, d1_a, zdet_param->noff, &zdet); regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x40, 0x00); From cb7d60ab98cfe12fdd6052142176d42682f78540 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 30 Jun 2023 16:27:16 +0200 Subject: [PATCH 017/272] ASoC: codecs: wcd934x: demote impedance printk Demote the MBHC impedance measurement printk, which is only needed for development and debugging, to debug level. While at it, fix the capitalisation of "ohm" and add the missing space before the opening parenthesis. Signed-off-by: Johan Hovold Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230630142717.5314-5-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd934x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c index c0d1fa36d841..9d724b5710f7 100644 --- a/sound/soc/codecs/wcd934x.c +++ b/sound/soc/codecs/wcd934x.c @@ -2683,7 +2683,7 @@ static inline void wcd934x_mbhc_get_result_params(struct wcd934x_codec *wcd934x, else if (x1 < minCode_param[noff]) *zdet = WCD934X_ZDET_FLOATING_IMPEDANCE; - dev_info(wcd934x->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n", + dev_dbg(wcd934x->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%di (milliohm)\n", __func__, d1, c1, x1, *zdet); ramp_down: i = 0; From c93723ada378a63929b3135b4f30483383e88e05 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 30 Jun 2023 16:27:17 +0200 Subject: [PATCH 018/272] ASoC: codecs: wcd934x: drop inline keywords The compiler is generally better at deciding what functions should be inlined than driver authors are. Drop the bogus inline keyword from two functions that were neither very small or used in a single place. Signed-off-by: Johan Hovold Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230630142717.5314-6-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd934x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c index 9d724b5710f7..a17cd75b969b 100644 --- a/sound/soc/codecs/wcd934x.c +++ b/sound/soc/codecs/wcd934x.c @@ -2642,7 +2642,7 @@ static int wcd934x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *compon return rc; } -static inline void wcd934x_mbhc_get_result_params(struct wcd934x_codec *wcd934x, +static void wcd934x_mbhc_get_result_params(struct wcd934x_codec *wcd934x, s16 *d1_a, u16 noff, int32_t *zdet) { @@ -2740,8 +2740,8 @@ z_right: *zr = zdet; } -static inline void wcd934x_wcd_mbhc_qfuse_cal(struct snd_soc_component *component, - int32_t *z_val, int flag_l_r) +static void wcd934x_wcd_mbhc_qfuse_cal(struct snd_soc_component *component, + int32_t *z_val, int flag_l_r) { s16 q1; int q1_cal; From 6f49256897083848ce9a59651f6b53fc80462397 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sat, 1 Jul 2023 11:47:23 +0200 Subject: [PATCH 019/272] ASoC: codecs: wcd938x: fix soundwire initialisation race Make sure that the soundwire device used for register accesses has been enumerated and initialised before trying to read the codec variant during component probe. This specifically avoids interpreting (a masked and shifted) -EBUSY errno as the variant: wcd938x_codec audio-codec: ASoC: error at soc_component_read_no_lock on audio-codec for register: [0x000034b0] -16 in case the soundwire device has not yet been initialised, which in turn prevents some headphone controls from being registered. Fixes: 8d78602aa87a ("ASoC: codecs: wcd938x: add basic driver") Cc: stable@vger.kernel.org # 5.14 Cc: Srinivas Kandagatla Reported-by: Steev Klimaszewski Signed-off-by: Johan Hovold Tested-by: Steev Klimaszewski Link: https://lore.kernel.org/r/20230701094723.29379-1-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd938x.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index ddefe4af0b1e..1595df2bf0e9 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -3081,9 +3081,18 @@ static int wcd938x_irq_init(struct wcd938x_priv *wcd, struct device *dev) static int wcd938x_soc_codec_probe(struct snd_soc_component *component) { struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + struct sdw_slave *tx_sdw_dev = wcd938x->tx_sdw_dev; struct device *dev = component->dev; + unsigned long time_left; int ret, i; + time_left = wait_for_completion_timeout(&tx_sdw_dev->initialization_complete, + msecs_to_jiffies(2000)); + if (!time_left) { + dev_err(dev, "soundwire device init timeout\n"); + return -ETIMEDOUT; + } + snd_soc_component_init_regmap(component, wcd938x->regmap); ret = pm_runtime_resume_and_get(dev); From 7dfae2631bfbdebecd35fe7b472ab3cc95c9ed66 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 3 Jul 2023 14:47:01 +0200 Subject: [PATCH 020/272] ASoC: codecs: wcd938x: fix missing mbhc init error handling MBHC initialisation can fail so add the missing error handling to avoid dereferencing an error pointer when later configuring the jack: Unable to handle kernel paging request at virtual address fffffffffffffff8 pc : wcd_mbhc_start+0x28/0x380 [snd_soc_wcd_mbhc] lr : wcd938x_codec_set_jack+0x28/0x48 [snd_soc_wcd938x] Call trace: wcd_mbhc_start+0x28/0x380 [snd_soc_wcd_mbhc] wcd938x_codec_set_jack+0x28/0x48 [snd_soc_wcd938x] snd_soc_component_set_jack+0x28/0x8c [snd_soc_core] qcom_snd_wcd_jack_setup+0x7c/0x19c [snd_soc_qcom_common] sc8280xp_snd_init+0x20/0x2c [snd_soc_sc8280xp] snd_soc_link_init+0x28/0x90 [snd_soc_core] snd_soc_bind_card+0x628/0xbfc [snd_soc_core] snd_soc_register_card+0xec/0x104 [snd_soc_core] devm_snd_soc_register_card+0x4c/0xa4 [snd_soc_core] sc8280xp_platform_probe+0xf0/0x108 [snd_soc_sc8280xp] Fixes: bcee7ed09b8e ("ASoC: codecs: wcd938x: add Multi Button Headset Control support") Cc: stable@vger.kernel.org # 5.15 Cc: Srinivas Kandagatla Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20230703124701.11734-1-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd938x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index 1595df2bf0e9..faa15a5ed2c8 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -2626,6 +2626,8 @@ static int wcd938x_mbhc_init(struct snd_soc_component *component) WCD938X_IRQ_HPHR_OCP_INT); wcd938x->wcd_mbhc = wcd_mbhc_init(component, &mbhc_cb, intr_ids, wcd_mbhc_fields, true); + if (IS_ERR(wcd938x->wcd_mbhc)) + return PTR_ERR(wcd938x->wcd_mbhc); snd_soc_add_component_controls(component, impedance_detect_controls, ARRAY_SIZE(impedance_detect_controls)); From d9ba2975e98a4bec0a9f8d4be4c1de8883fccb71 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 3 Jul 2023 14:43:15 -0700 Subject: [PATCH 021/272] ASoC: cs35l45: Select REGMAP_IRQ After commit 6085f9e6dc19 ("ASoC: cs35l45: IRQ support"), without any other configuration that selects CONFIG_REGMAP_IRQ, modpost errors out with: ERROR: modpost: "regmap_irq_get_virq" [sound/soc/codecs/snd-soc-cs35l45.ko] undefined! ERROR: modpost: "devm_regmap_add_irq_chip" [sound/soc/codecs/snd-soc-cs35l45.ko] undefined! Add the Kconfig selection to ensure these functions get built and included, which resolves the build failure. Cc: stable@vger.kernel.org Fixes: 6085f9e6dc19 ("ASoC: cs35l45: IRQ support") Reported-by: Marcus Seyfarth Closes: https://github.com/ClangBuiltLinux/linux/issues/1882 Signed-off-by: Nathan Chancellor Link: https://lore.kernel.org/r/20230703-cs35l45-select-regmap_irq-v1-1-37d7e838b614@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 0cd107fa112f..76ddd3ffc496 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -715,6 +715,7 @@ config SND_SOC_CS35L41_I2C config SND_SOC_CS35L45 tristate + select REGMAP_IRQ config SND_SOC_CS35L45_SPI tristate "Cirrus Logic CS35L45 CODEC (SPI)" From bf62eec5cdecbe7eeab02407da98f36cd7b1dea7 Mon Sep 17 00:00:00 2001 From: Shuming Fan Date: Wed, 5 Jul 2023 12:29:14 +0800 Subject: [PATCH 022/272] ASoC: rt5645: check return value after reading device id If the I2C controller encounters some problems like timed-out, the codec driver will report the error code for the first read. Signed-off-by: Shuming Fan Link: https://lore.kernel.org/r/20230705042915.24932-1-shumingf@realtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5645.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index acc7fb1581b2..a506d940a2ea 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3950,7 +3950,11 @@ static int rt5645_i2c_probe(struct i2c_client *i2c) * read and power On. */ msleep(TIME_TO_POWER_MS); - regmap_read(regmap, RT5645_VENDOR_ID2, &val); + ret = regmap_read(regmap, RT5645_VENDOR_ID2, &val); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read: 0x%02X\n, ret = %d", RT5645_VENDOR_ID2, ret); + goto err_enable; + } switch (val) { case RT5645_DEVICE_ID: From 4f3fcf5f6dc8ab561e152c8747fd7e502b32266c Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 5 Jul 2023 13:48:50 +0100 Subject: [PATCH 023/272] ASoC: qcom: q6afe-dai: fix Display Port Playback stream name With recent changes to add more display ports did not change the Stream name in q6afe-dai. This results in below error "ASoC: Failed to add route DISPLAY_PORT_RX -> Display Port Playback(*)" and sound card fails to probe. Fix this by adding correct stream name. Fixes: 90848a2557fe ("ASoC: qcom: q6dsp: add support to more display ports") Reported-by: Amit Pundir Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230705124850.40069-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6afe-dai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/qcom/qdsp6/q6afe-dai.c b/sound/soc/qcom/qdsp6/q6afe-dai.c index 31e0bad71e95..dbff55a97162 100644 --- a/sound/soc/qcom/qdsp6/q6afe-dai.c +++ b/sound/soc/qcom/qdsp6/q6afe-dai.c @@ -476,7 +476,7 @@ static int q6afe_mi2s_set_sysclk(struct snd_soc_dai *dai, static const struct snd_soc_dapm_route q6afe_dapm_routes[] = { {"HDMI Playback", NULL, "HDMI_RX"}, - {"Display Port Playback", NULL, "DISPLAY_PORT_RX"}, + {"DISPLAY_PORT_RX_0 Playback", NULL, "DISPLAY_PORT_RX"}, {"Slimbus Playback", NULL, "SLIMBUS_0_RX"}, {"Slimbus1 Playback", NULL, "SLIMBUS_1_RX"}, {"Slimbus2 Playback", NULL, "SLIMBUS_2_RX"}, From c03226ba15fe3c42d13907ec7d8536396602557b Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 5 Jul 2023 13:57:23 +0100 Subject: [PATCH 024/272] ASoC: codecs: wcd938x: fix dB range for HPHL and HPHR dB range for HPHL and HPHR gains are from +6dB to -30dB in steps of 1.5dB with register values range from 0 to 24. Current code maps these dB ranges incorrectly, fix them to allow proper volume setting. Fixes: e8ba1e05bdc0 ("ASoC: codecs: wcd938x: add basic controls") Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230705125723.40464-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd938x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index faa15a5ed2c8..3a3360711f8f 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -210,7 +210,7 @@ struct wcd938x_priv { }; static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800); -static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(line_gain, 600, -3000); +static const DECLARE_TLV_DB_SCALE(line_gain, -3000, 150, -3000); static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(analog_gain, 0, 3000); struct wcd938x_mbhc_zdet_param { @@ -2655,8 +2655,8 @@ static const struct snd_kcontrol_new wcd938x_snd_controls[] = { wcd938x_get_swr_port, wcd938x_set_swr_port), SOC_SINGLE_EXT("DSD_R Switch", WCD938X_DSD_R, 0, 1, 0, wcd938x_get_swr_port, wcd938x_set_swr_port), - SOC_SINGLE_TLV("HPHL Volume", WCD938X_HPH_L_EN, 0, 0x18, 0, line_gain), - SOC_SINGLE_TLV("HPHR Volume", WCD938X_HPH_R_EN, 0, 0x18, 0, line_gain), + SOC_SINGLE_TLV("HPHL Volume", WCD938X_HPH_L_EN, 0, 0x18, 1, line_gain), + SOC_SINGLE_TLV("HPHR Volume", WCD938X_HPH_R_EN, 0, 0x18, 1, line_gain), WCD938X_EAR_PA_GAIN_TLV("EAR_PA Volume", WCD938X_ANA_EAR_COMPANDER_CTL, 2, 0x10, 0, ear_pa_gain), SOC_SINGLE_EXT("ADC1 Switch", WCD938X_ADC1, 1, 1, 0, From 46ec420573cefa1fc98025e7e6841bdafd6f1e20 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 5 Jul 2023 14:30:12 +0200 Subject: [PATCH 025/272] ASoC: qdsp6: audioreach: fix topology probe deferral Propagate errors when failing to load the topology component so that probe deferrals can be handled. Fixes: 36ad9bf1d93d ("ASoC: qdsp6: audioreach: add topology support") Cc: stable@vger.kernel.org # 5.17 Cc: Srinivas Kandagatla Signed-off-by: Johan Hovold Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230705123018.30903-3-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/topology.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/qcom/qdsp6/topology.c b/sound/soc/qcom/qdsp6/topology.c index cccc59b570b9..130b22a34fb3 100644 --- a/sound/soc/qcom/qdsp6/topology.c +++ b/sound/soc/qcom/qdsp6/topology.c @@ -1277,8 +1277,8 @@ int audioreach_tplg_init(struct snd_soc_component *component) ret = snd_soc_tplg_component_load(component, &audioreach_tplg_ops, fw); if (ret < 0) { - dev_err(dev, "tplg component load failed%d\n", ret); - ret = -EINVAL; + if (ret != -EPROBE_DEFER) + dev_err(dev, "tplg component load failed: %d\n", ret); } release_firmware(fw); From ed0dd9205bf69593edb495cb4b086dbae96a3f05 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 5 Jul 2023 14:30:13 +0200 Subject: [PATCH 026/272] ASoC: codecs: wcd938x: fix missing clsh ctrl error handling Allocation of the clash control structure may fail so add the missing error handling to avoid dereferencing an error pointer. Fixes: 8d78602aa87a ("ASoC: codecs: wcd938x: add basic driver") Cc: stable@vger.kernel.org # 5.14 Cc: Srinivas Kandagatla Signed-off-by: Johan Hovold Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230705123018.30903-4-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd938x.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index 3a3360711f8f..a8aed48e76ee 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -3106,6 +3106,10 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) WCD938X_ID_MASK); wcd938x->clsh_info = wcd_clsh_ctrl_alloc(component, WCD938X); + if (IS_ERR(wcd938x->clsh_info)) { + pm_runtime_put(dev); + return PTR_ERR(wcd938x->clsh_info); + } wcd938x_io_init(wcd938x); /* Set all interrupts as edge triggered */ From a3406f87775fee986876e03f93a84385f54d5999 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 5 Jul 2023 14:30:14 +0200 Subject: [PATCH 027/272] ASoC: codecs: wcd938x: fix resource leaks on component remove Make sure to release allocated resources on component probe failure and on remove. This is specifically needed to allow probe deferrals of the sound card which otherwise fails when reprobing the codec component: snd-sc8280xp sound: ASoC: failed to instantiate card -517 genirq: Flags mismatch irq 289. 00002001 (HPHR PDM WD INT) vs. 00002001 (HPHR PDM WD INT) wcd938x_codec audio-codec: Failed to request HPHR WD interrupt (-16) genirq: Flags mismatch irq 290. 00002001 (HPHL PDM WD INT) vs. 00002001 (HPHL PDM WD INT) wcd938x_codec audio-codec: Failed to request HPHL WD interrupt (-16) genirq: Flags mismatch irq 291. 00002001 (AUX PDM WD INT) vs. 00002001 (AUX PDM WD INT) wcd938x_codec audio-codec: Failed to request Aux WD interrupt (-16) genirq: Flags mismatch irq 292. 00002001 (mbhc sw intr) vs. 00002001 (mbhc sw intr) wcd938x_codec audio-codec: Failed to request mbhc interrupts -16 Fixes: 8d78602aa87a ("ASoC: codecs: wcd938x: add basic driver") Cc: stable@vger.kernel.org # 5.14 Cc: Srinivas Kandagatla Signed-off-by: Johan Hovold Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230705123018.30903-5-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd938x.c | 55 +++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index a8aed48e76ee..a3c680661377 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -2636,6 +2636,14 @@ static int wcd938x_mbhc_init(struct snd_soc_component *component) return 0; } + +static void wcd938x_mbhc_deinit(struct snd_soc_component *component) +{ + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + wcd_mbhc_deinit(wcd938x->wcd_mbhc); +} + /* END MBHC */ static const struct snd_kcontrol_new wcd938x_snd_controls[] = { @@ -3131,20 +3139,26 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) ret = request_threaded_irq(wcd938x->hphr_pdm_wd_int, NULL, wcd938x_wd_handle_irq, IRQF_ONESHOT | IRQF_TRIGGER_RISING, "HPHR PDM WD INT", wcd938x); - if (ret) + if (ret) { dev_err(dev, "Failed to request HPHR WD interrupt (%d)\n", ret); + goto err_free_clsh_ctrl; + } ret = request_threaded_irq(wcd938x->hphl_pdm_wd_int, NULL, wcd938x_wd_handle_irq, IRQF_ONESHOT | IRQF_TRIGGER_RISING, "HPHL PDM WD INT", wcd938x); - if (ret) + if (ret) { dev_err(dev, "Failed to request HPHL WD interrupt (%d)\n", ret); + goto err_free_hphr_pdm_wd_int; + } ret = request_threaded_irq(wcd938x->aux_pdm_wd_int, NULL, wcd938x_wd_handle_irq, IRQF_ONESHOT | IRQF_TRIGGER_RISING, "AUX PDM WD INT", wcd938x); - if (ret) + if (ret) { dev_err(dev, "Failed to request Aux WD interrupt (%d)\n", ret); + goto err_free_hphl_pdm_wd_int; + } /* Disable watchdog interrupt for HPH and AUX */ disable_irq_nosync(wcd938x->hphr_pdm_wd_int); @@ -3159,7 +3173,7 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) dev_err(component->dev, "%s: Failed to add snd ctrls for variant: %d\n", __func__, wcd938x->variant); - goto err; + goto err_free_aux_pdm_wd_int; } break; case WCD9385: @@ -3169,7 +3183,7 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) dev_err(component->dev, "%s: Failed to add snd ctrls for variant: %d\n", __func__, wcd938x->variant); - goto err; + goto err_free_aux_pdm_wd_int; } break; default: @@ -3177,12 +3191,38 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) } ret = wcd938x_mbhc_init(component); - if (ret) + if (ret) { dev_err(component->dev, "mbhc initialization failed\n"); -err: + goto err_free_aux_pdm_wd_int; + } + + return 0; + +err_free_aux_pdm_wd_int: + free_irq(wcd938x->aux_pdm_wd_int, wcd938x); +err_free_hphl_pdm_wd_int: + free_irq(wcd938x->hphl_pdm_wd_int, wcd938x); +err_free_hphr_pdm_wd_int: + free_irq(wcd938x->hphr_pdm_wd_int, wcd938x); +err_free_clsh_ctrl: + wcd_clsh_ctrl_free(wcd938x->clsh_info); + return ret; } +static void wcd938x_soc_codec_remove(struct snd_soc_component *component) +{ + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + wcd938x_mbhc_deinit(component); + + free_irq(wcd938x->aux_pdm_wd_int, wcd938x); + free_irq(wcd938x->hphl_pdm_wd_int, wcd938x); + free_irq(wcd938x->hphr_pdm_wd_int, wcd938x); + + wcd_clsh_ctrl_free(wcd938x->clsh_info); +} + static int wcd938x_codec_set_jack(struct snd_soc_component *comp, struct snd_soc_jack *jack, void *data) { @@ -3199,6 +3239,7 @@ static int wcd938x_codec_set_jack(struct snd_soc_component *comp, static const struct snd_soc_component_driver soc_codec_dev_wcd938x = { .name = "wcd938x_codec", .probe = wcd938x_soc_codec_probe, + .remove = wcd938x_soc_codec_remove, .controls = wcd938x_snd_controls, .num_controls = ARRAY_SIZE(wcd938x_snd_controls), .dapm_widgets = wcd938x_dapm_widgets, From 798590cc7d3c2b5f3a7548d96dd4d8a081c1bc39 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 5 Jul 2023 14:30:15 +0200 Subject: [PATCH 028/272] ASoC: codecs: wcd934x: fix resource leaks on component remove Make sure to release allocated MBHC resources also on component remove. This is specifically needed to allow probe deferrals of the sound card which otherwise fails when reprobing the codec component. Fixes: 9fb9b1690f0b ("ASoC: codecs: wcd934x: add mbhc support") Cc: stable@vger.kernel.org # 5.14 Cc: Srinivas Kandagatla Signed-off-by: Johan Hovold Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230705123018.30903-6-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd934x.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c index a17cd75b969b..1b6e376f3833 100644 --- a/sound/soc/codecs/wcd934x.c +++ b/sound/soc/codecs/wcd934x.c @@ -3044,6 +3044,17 @@ static int wcd934x_mbhc_init(struct snd_soc_component *component) return 0; } + +static void wcd934x_mbhc_deinit(struct snd_soc_component *component) +{ + struct wcd934x_codec *wcd = snd_soc_component_get_drvdata(component); + + if (!wcd->mbhc) + return; + + wcd_mbhc_deinit(wcd->mbhc); +} + static int wcd934x_comp_probe(struct snd_soc_component *component) { struct wcd934x_codec *wcd = dev_get_drvdata(component->dev); @@ -3077,6 +3088,7 @@ static void wcd934x_comp_remove(struct snd_soc_component *comp) { struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev); + wcd934x_mbhc_deinit(comp); wcd_clsh_ctrl_free(wcd->clsh_ctrl); } From a5475829adcc600bc69ee9ff7c9e3e43fb4f8d30 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 5 Jul 2023 14:30:16 +0200 Subject: [PATCH 029/272] ASoC: codecs: wcd-mbhc-v2: fix resource leaks on component remove The MBHC resources must be released on component probe failure and removal so can not be tied to the lifetime of the component device. This is specifically needed to allow probe deferrals of the sound card which otherwise fails when reprobing the codec component: snd-sc8280xp sound: ASoC: failed to instantiate card -517 genirq: Flags mismatch irq 299. 00002001 (mbhc sw intr) vs. 00002001 (mbhc sw intr) wcd938x_codec audio-codec: Failed to request mbhc interrupts -16 wcd938x_codec audio-codec: mbhc initialization failed wcd938x_codec audio-codec: ASoC: error at snd_soc_component_probe on audio-codec: -16 snd-sc8280xp sound: ASoC: failed to instantiate card -16 Fixes: 0e5c9e7ff899 ("ASoC: codecs: wcd: add multi button Headset detection support") Cc: stable@vger.kernel.org # 5.14 Cc: Srinivas Kandagatla Signed-off-by: Johan Hovold Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230705123018.30903-7-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd-mbhc-v2.c | 57 ++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index 1911750f7445..5da1934527f3 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -1454,7 +1454,7 @@ struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component, return ERR_PTR(-EINVAL); } - mbhc = devm_kzalloc(dev, sizeof(*mbhc), GFP_KERNEL); + mbhc = kzalloc(sizeof(*mbhc), GFP_KERNEL); if (!mbhc) return ERR_PTR(-ENOMEM); @@ -1474,61 +1474,76 @@ struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component, INIT_WORK(&mbhc->correct_plug_swch, wcd_correct_swch_plug); - ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_sw_intr, NULL, + ret = request_threaded_irq(mbhc->intr_ids->mbhc_sw_intr, NULL, wcd_mbhc_mech_plug_detect_irq, IRQF_ONESHOT | IRQF_TRIGGER_RISING, "mbhc sw intr", mbhc); if (ret) - goto err; + goto err_free_mbhc; - ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_btn_press_intr, NULL, + ret = request_threaded_irq(mbhc->intr_ids->mbhc_btn_press_intr, NULL, wcd_mbhc_btn_press_handler, IRQF_ONESHOT | IRQF_TRIGGER_RISING, "Button Press detect", mbhc); if (ret) - goto err; + goto err_free_sw_intr; - ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_btn_release_intr, NULL, + ret = request_threaded_irq(mbhc->intr_ids->mbhc_btn_release_intr, NULL, wcd_mbhc_btn_release_handler, IRQF_ONESHOT | IRQF_TRIGGER_RISING, "Button Release detect", mbhc); if (ret) - goto err; + goto err_free_btn_press_intr; - ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_hs_ins_intr, NULL, + ret = request_threaded_irq(mbhc->intr_ids->mbhc_hs_ins_intr, NULL, wcd_mbhc_adc_hs_ins_irq, IRQF_ONESHOT | IRQF_TRIGGER_RISING, "Elect Insert", mbhc); if (ret) - goto err; + goto err_free_btn_release_intr; disable_irq_nosync(mbhc->intr_ids->mbhc_hs_ins_intr); - ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_hs_rem_intr, NULL, + ret = request_threaded_irq(mbhc->intr_ids->mbhc_hs_rem_intr, NULL, wcd_mbhc_adc_hs_rem_irq, IRQF_ONESHOT | IRQF_TRIGGER_RISING, "Elect Remove", mbhc); if (ret) - goto err; + goto err_free_hs_ins_intr; disable_irq_nosync(mbhc->intr_ids->mbhc_hs_rem_intr); - ret = devm_request_threaded_irq(dev, mbhc->intr_ids->hph_left_ocp, NULL, + ret = request_threaded_irq(mbhc->intr_ids->hph_left_ocp, NULL, wcd_mbhc_hphl_ocp_irq, IRQF_ONESHOT | IRQF_TRIGGER_RISING, "HPH_L OCP detect", mbhc); if (ret) - goto err; + goto err_free_hs_rem_intr; - ret = devm_request_threaded_irq(dev, mbhc->intr_ids->hph_right_ocp, NULL, + ret = request_threaded_irq(mbhc->intr_ids->hph_right_ocp, NULL, wcd_mbhc_hphr_ocp_irq, IRQF_ONESHOT | IRQF_TRIGGER_RISING, "HPH_R OCP detect", mbhc); if (ret) - goto err; + goto err_free_hph_left_ocp; return mbhc; -err: + +err_free_hph_left_ocp: + free_irq(mbhc->intr_ids->hph_left_ocp, mbhc); +err_free_hs_rem_intr: + free_irq(mbhc->intr_ids->mbhc_hs_rem_intr, mbhc); +err_free_hs_ins_intr: + free_irq(mbhc->intr_ids->mbhc_hs_ins_intr, mbhc); +err_free_btn_release_intr: + free_irq(mbhc->intr_ids->mbhc_btn_release_intr, mbhc); +err_free_btn_press_intr: + free_irq(mbhc->intr_ids->mbhc_btn_press_intr, mbhc); +err_free_sw_intr: + free_irq(mbhc->intr_ids->mbhc_sw_intr, mbhc); +err_free_mbhc: + kfree(mbhc); + dev_err(dev, "Failed to request mbhc interrupts %d\n", ret); return ERR_PTR(ret); @@ -1537,9 +1552,19 @@ EXPORT_SYMBOL(wcd_mbhc_init); void wcd_mbhc_deinit(struct wcd_mbhc *mbhc) { + free_irq(mbhc->intr_ids->hph_right_ocp, mbhc); + free_irq(mbhc->intr_ids->hph_left_ocp, mbhc); + free_irq(mbhc->intr_ids->mbhc_hs_rem_intr, mbhc); + free_irq(mbhc->intr_ids->mbhc_hs_ins_intr, mbhc); + free_irq(mbhc->intr_ids->mbhc_btn_release_intr, mbhc); + free_irq(mbhc->intr_ids->mbhc_btn_press_intr, mbhc); + free_irq(mbhc->intr_ids->mbhc_sw_intr, mbhc); + mutex_lock(&mbhc->lock); wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); mutex_unlock(&mbhc->lock); + + kfree(mbhc); } EXPORT_SYMBOL(wcd_mbhc_deinit); From b6c3bdda3a7e43acfcec711ce20e7cfe44744740 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 5 Jul 2023 14:30:17 +0200 Subject: [PATCH 030/272] ASoC: topology: suppress probe deferral errors Suppress probe deferral error messages when loading topologies and creating frontend links to avoid spamming the logs when a component has not yet been registered: snd-sc8280xp sound: ASoC: adding FE link failed snd-sc8280xp sound: ASoC: topology: could not load header: -517 Note that dev_err_probe() is not used as the topology component can be probed and removed while the underlying platform device remains bound to its driver. Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20230705123018.30903-8-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/soc-topology.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 8add361e87c6..ad08d4f75a7b 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -1732,7 +1732,8 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg, ret = snd_soc_add_pcm_runtimes(tplg->comp->card, link, 1); if (ret < 0) { - dev_err(tplg->dev, "ASoC: adding FE link failed\n"); + if (ret != -EPROBE_DEFER) + dev_err(tplg->dev, "ASoC: adding FE link failed\n"); goto err; } @@ -2492,8 +2493,11 @@ static int soc_tplg_process_headers(struct soc_tplg *tplg) /* load the header object */ ret = soc_tplg_load_header(tplg, hdr); if (ret < 0) { - dev_err(tplg->dev, - "ASoC: topology: could not load header: %d\n", ret); + if (ret != -EPROBE_DEFER) { + dev_err(tplg->dev, + "ASoC: topology: could not load header: %d\n", + ret); + } return ret; } From f09b6e96796056633453cb0d07b720d09f1efc68 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 5 Jul 2023 14:30:18 +0200 Subject: [PATCH 031/272] ASoC: core: suppress probe deferral errors Suppress probe deferral error messages when probing link components to avoid spamming the logs, for example, if a required component has not yet been registered: snd-sc8280xp sound: ASoC: failed to instantiate card -517 Note that dev_err_probe() is not used as the card can be unbound and rebound while the underlying platform device remains bound to its driver. Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20230705123018.30903-9-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 11bc5250ffd0..1a0bde23f5e6 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1988,8 +1988,10 @@ static int snd_soc_bind_card(struct snd_soc_card *card) /* probe all components used by DAI links on this card */ ret = soc_probe_link_components(card); if (ret < 0) { - dev_err(card->dev, - "ASoC: failed to instantiate card %d\n", ret); + if (ret != -EPROBE_DEFER) { + dev_err(card->dev, + "ASoC: failed to instantiate card %d\n", ret); + } goto probe_end; } From c1be62923d4d86e7c06b1224626e27eb8d9ab32e Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 5 Jul 2023 14:18:42 +0100 Subject: [PATCH 032/272] ASoC: qcom: q6apm: do not close GPR port before closing graph Closing GPR port before graph close can result in un handled notifications from DSP, this results in spam of errors from GPR driver as there is no one to handle these notification at that point in time. Fix this by closing GPR port after graph close is finished. Fixes: 5477518b8a0e ("ASoC: qdsp6: audioreach: add q6apm support") Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230705131842.41584-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6apm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c index 7bfac9492ab5..5d44d07acd69 100644 --- a/sound/soc/qcom/qdsp6/q6apm.c +++ b/sound/soc/qcom/qdsp6/q6apm.c @@ -511,6 +511,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op) switch (hdr->opcode) { case DATA_CMD_RSP_WR_SH_MEM_EP_DATA_BUFFER_DONE_V2: + if (!graph->ar_graph) + break; client_event = APM_CLIENT_EVENT_DATA_WRITE_DONE; mutex_lock(&graph->lock); token = hdr->token & APM_WRITE_TOKEN_MASK; @@ -544,6 +546,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op) wake_up(&graph->cmd_wait); break; case DATA_CMD_RSP_RD_SH_MEM_EP_DATA_BUFFER_V2: + if (!graph->ar_graph) + break; client_event = APM_CLIENT_EVENT_DATA_READ_DONE; mutex_lock(&graph->lock); rd_done = data->payload; @@ -649,8 +653,9 @@ int q6apm_graph_close(struct q6apm_graph *graph) { struct audioreach_graph *ar_graph = graph->ar_graph; - gpr_free_port(graph->port); + graph->ar_graph = NULL; kref_put(&ar_graph->refcount, q6apm_put_audioreach_graph); + gpr_free_port(graph->port); kfree(graph); return 0; From e231cd833f6463e9a1d54acae9614b513c74d45e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 6 Jul 2023 13:42:04 +0200 Subject: [PATCH 033/272] ASoC: codecs: SND_SOC_WCD934X should select REGMAP_IRQ If CONFIG_SND_SOC_WCD934X=y, CONFIG_COMPILE_TEST=y, CONFIG_MFD_WCD934X=n, CONFIG_REGMAP_IRQ=n: aarch64-linux-gnu-ld: sound/soc/codecs/wcd934x.o: in function `wcd934x_codec_probe': wcd934x.c:(.text+0x33cc): undefined reference to `regmap_irq_get_virq' aarch64-linux-gnu-ld: sound/soc/codecs/wcd934x.o: in function `wcd934x_comp_probe': wcd934x.c:(.text+0x4cb0): undefined reference to `regmap_irq_get_virq' aarch64-linux-gnu-ld: wcd934x.c:(.text+0x4cc0): undefined reference to `regmap_irq_get_virq' aarch64-linux-gnu-ld: wcd934x.c:(.text+0x4cd0): undefined reference to `regmap_irq_get_virq' aarch64-linux-gnu-ld: wcd934x.c:(.text+0x4ce0): undefined reference to `regmap_irq_get_virq' aarch64-linux-gnu-ld: sound/soc/codecs/wcd934x.o:wcd934x.c:(.text+0x4cf0): more undefined references to `regmap_irq_get_virq' follow Fix this by making SND_SOC_WCD934X select REGMAP_IRQ. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/cafd878747e7951914a7d9fea33788a4a230d1f0.1688643442.git.geert@linux-m68k.org Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 76ddd3ffc496..d379a670a46d 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1943,6 +1943,7 @@ config SND_SOC_WCD934X tristate "WCD9340/WCD9341 Codec" depends on COMMON_CLK depends on SLIMBUS + select REGMAP_IRQ select REGMAP_SLIMBUS select SND_SOC_WCD_MBHC depends on MFD_WCD934X || COMPILE_TEST From 86867aca7330e4fbcfa2a117e20b48bbb6c758a9 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 6 Jul 2023 19:18:27 -0300 Subject: [PATCH 034/272] ASoC: fsl_sai: Revert "ASoC: fsl_sai: Enable MCTL_MCLK_EN bit for master mode" This reverts commit ff87d619ac180444db297f043962a5c325ded47b. Andreas reports that on an i.MX8MP-based system where MCLK needs to be used as an input, the MCLK pin is actually an output, despite not having the 'fsl,sai-mclk-direction-output' property present in the devicetree. This is caused by commit ff87d619ac18 ("ASoC: fsl_sai: Enable MCTL_MCLK_EN bit for master mode") that sets FSL_SAI_MCTL_MCLK_EN unconditionally for imx8mm/8mn/8mp/93, causing the MCLK to always be configured as output. FSL_SAI_MCTL_MCLK_EN corresponds to the MOE (MCLK Output Enable) bit of register MCR and the drivers sets it when the 'fsl,sai-mclk-direction-output' devicetree property is present. Revert the commit to allow SAI to use MCLK as input as well. Cc: stable@vger.kernel.org Fixes: ff87d619ac18 ("ASoC: fsl_sai: Enable MCTL_MCLK_EN bit for master mode") Reported-by: Andreas Henriksson Signed-off-by: Fabio Estevam Acked-by: Shengjiu Wang Link: https://lore.kernel.org/r/20230706221827.1938990-1-festevam@gmail.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 5e09f634c61b..54b4bf3744c6 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -507,12 +507,6 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) savediv / 2 - 1); } - if (sai->soc_data->max_register >= FSL_SAI_MCTL) { - /* SAI is in master mode at this point, so enable MCLK */ - regmap_update_bits(sai->regmap, FSL_SAI_MCTL, - FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN); - } - return 0; } From cd710900ed2b96b1fbc26d711d562581afc385e2 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 7 Jul 2023 21:52:08 -0500 Subject: [PATCH 035/272] ASoC: amd: ps: Fix extraneous error messages On Pink Sardine machines that don't have SdW controllers in use, the property `mipi-sdw-manager-list` won't exist. There is no point in showing an error to a user when this situation is encountered. Furthermore if the machine doesn't have a DMIC connected to the ACP, there may be no platform devices created either. Downgrade the associated message to debug. Fixes: d1351c30ac8a6 ("ASoC: amd: ps: create platform devices based on acp config") Signed-off-by: Mario Limonciello Link: https://lore.kernel.org/r/20230708025208.54272-1-mario.limonciello@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/pci-ps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 5b46dc8573f8..4af3c3665387 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -257,7 +257,7 @@ static int sdw_amd_scan_controller(struct device *dev) &sdw_manager_bitmap, 1); if (ret) { - dev_err(dev, "Failed to read mipi-sdw-manager-list: %d\n", ret); + dev_dbg(dev, "Failed to read mipi-sdw-manager-list: %d\n", ret); return -EINVAL; } count = hweight32(sdw_manager_bitmap); @@ -641,7 +641,7 @@ static int snd_acp63_probe(struct pci_dev *pci, ret = get_acp63_device_config(val, pci, adata); /* ACP PCI driver probe should be continued even PDM or SoundWire Devices are not found */ if (ret) { - dev_err(&pci->dev, "get acp device config failed:%d\n", ret); + dev_dbg(&pci->dev, "get acp device config failed:%d\n", ret); goto skip_pdev_creation; } ret = create_acp63_platform_devs(pci, adata, addr); From a1ff5802da3806e916de100130a7850b3f80c377 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Fri, 7 Jul 2023 13:13:36 +0530 Subject: [PATCH 036/272] ASoC: dt-bindings: Update maintainer email id Updated my mail id to latest quicinc id. Acked-by: Krzysztof Kozlowski Signed-off-by: Rohit kumar Link: https://lore.kernel.org/r/20230707074337.3120530-1-quic_rohkumar@quicinc.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/google,sc7180-trogdor.yaml | 2 +- Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml b/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml index 666a95ac22c8..ba5b7728cf33 100644 --- a/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml +++ b/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Google SC7180-Trogdor ASoC sound card driver maintainers: - - Rohit kumar + - Rohit kumar - Cheng-Yi Chiang description: diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml index 6cc8f86c7531..3a559bd07a79 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml @@ -8,7 +8,7 @@ title: Qualcomm Technologies Inc. LPASS CPU dai driver maintainers: - Srinivas Kandagatla - - Rohit kumar + - Rohit kumar description: | Qualcomm Technologies Inc. SOC Low-Power Audio SubSystem (LPASS) that consist From c65b21f8aeac86768d387a86dfcbec5980480b6a Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 7 Jul 2023 16:17:25 -0600 Subject: [PATCH 037/272] ASoC: dt-bindings: audio-graph-card2: Drop incomplete example The example in audio-graph-card2 binding is incomplete, uses undocumented compatibles strings, and doesn't follow typical .dts formatting. Rather than try to fix with what would probably be a lengthy example, just drop the example. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20230707221725.1071292-1-robh@kernel.org Signed-off-by: Mark Brown --- .../bindings/sound/audio-graph-card2.yaml | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml b/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml index 3de7b36829da..d3ce4de449d5 100644 --- a/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml +++ b/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml @@ -39,22 +39,4 @@ required: additionalProperties: false -examples: - - | - sound { - compatible = "audio-graph-card2"; - - links = <&cpu_port>; - }; - - cpu { - compatible = "cpu-driver"; - - cpu_port: port { cpu_ep: endpoint { remote-endpoint = <&codec_ep>; }; }; - }; - - codec { - compatible = "codec-driver"; - - port { codec_ep: endpoint { remote-endpoint = <&cpu_ep>; }; }; - }; +... From cb2bffdea267efad8d03eb680890e5fa2e93411c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 7 Jul 2023 09:50:57 +0200 Subject: [PATCH 038/272] ALSA: pcmtest: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new() which already returns void. Eventually after all drivers are converted, .remove_new() is renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Signed-off-by: Uwe Kleine-König Acked-by: Ivan Orlov Link: https://lore.kernel.org/r/20230707075058.3402832-1-u.kleine-koenig@pengutronix.de Signed-off-by: Takashi Iwai --- sound/drivers/pcmtest.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/drivers/pcmtest.c b/sound/drivers/pcmtest.c index 2ae912a64d16..1fff85feaf82 100644 --- a/sound/drivers/pcmtest.c +++ b/sound/drivers/pcmtest.c @@ -576,10 +576,9 @@ static int pcmtst_probe(struct platform_device *pdev) return 0; } -static int pdev_remove(struct platform_device *dev) +static void pdev_remove(struct platform_device *dev) { snd_pcmtst_free(pcmtst); - return 0; } static struct platform_device pcmtst_pdev = { @@ -589,7 +588,7 @@ static struct platform_device pcmtst_pdev = { static struct platform_driver pcmtst_pdrv = { .probe = pcmtst_probe, - .remove = pdev_remove, + .remove_new = pdev_remove, .driver = { .name = "pcmtest", }, From 35bc3efb3157cc5a9c3b5853591c4dcef40f6029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 7 Jul 2023 09:50:58 +0200 Subject: [PATCH 039/272] ALSA: pcmtest: Don't use static storage to track per device data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While there is probably only ever a single instance of such a pcmtst device, it's still bad style to use a static variable to store per device data. Make use of platform_get_drvdata() and platform_set_drvdata() which fixes a data corruption if there should be two or more such devices (or this driver is used as a template for another driver). Signed-off-by: Uwe Kleine-König Acked-by: Ivan Orlov Link: https://lore.kernel.org/r/20230707075058.3402832-2-u.kleine-koenig@pengutronix.de Signed-off-by: Takashi Iwai --- sound/drivers/pcmtest.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sound/drivers/pcmtest.c b/sound/drivers/pcmtest.c index 1fff85feaf82..291e7fe47893 100644 --- a/sound/drivers/pcmtest.c +++ b/sound/drivers/pcmtest.c @@ -110,8 +110,6 @@ struct pcmtst_buf_iter { struct timer_list timer_instance; }; -static struct pcmtst *pcmtst; - static struct snd_pcm_hardware snd_pcmtst_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -552,6 +550,7 @@ _err_free_chip: static int pcmtst_probe(struct platform_device *pdev) { struct snd_card *card; + struct pcmtst *pcmtst; int err; err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); @@ -573,11 +572,15 @@ static int pcmtst_probe(struct platform_device *pdev) if (err < 0) return err; + platform_set_drvdata(pdev, pcmtst); + return 0; } -static void pdev_remove(struct platform_device *dev) +static void pdev_remove(struct platform_device *pdev) { + struct pcmtst *pcmtst = platform_get_drvdata(pdev); + snd_pcmtst_free(pcmtst); } From 7e08baf6a89c8758050a3593aedc949f44fe3413 Mon Sep 17 00:00:00 2001 From: Baoquan He Date: Fri, 7 Jul 2023 21:58:52 +0800 Subject: [PATCH 040/272] of: make OF_EARLY_FLATTREE depend on HAS_IOMEM On s390 systems (aka mainframes), it has classic channel devices for networking and permanent storage that are currently even more common than PCI devices. Hence it could have a fully functional s390 kernel with CONFIG_PCI=n, then the relevant iomem mapping functions [including ioremap(), devm_ioremap(), etc.] are not available. In LKP error report at below on s390: ------ ld: kernel/dma/coherent.o: in function `dma_init_coherent_memory': coherent.c:(.text+0x102): undefined reference to `memremap' ld: coherent.c:(.text+0x226): undefined reference to `memunmap' ld: kernel/dma/coherent.o: in function `dma_declare_coherent_memory': coherent.c:(.text+0x8b8): undefined reference to `memunmap' ld: kernel/dma/coherent.o: in function `dma_release_coherent_memory': coherent.c:(.text+0x9aa): undefined reference to `memunmap' ------ In the config file, several Kconfig options are: ------ '# CONFIG_PCI is not set' CONFIG_OF_EARLY_FLATTREE=y CONFIG_DMA_DECLARE_COHERENT=y ------ So, enabling OF_EARLY_FLATTREE will select DMA_DECLARE_COHERENT and cause above building errors even though they are not needed because CONFIG_PCI is disabled. Here let OF_EARLY_FLATTREE depend on HAS_IOMEM so that it won't be built to cause compiling error if PCI is unset. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202306211329.ticOJCSv-lkp@intel.com/ Signed-off-by: Baoquan He Cc: Rob Herring Cc: Frank Rowand Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20230707135852.24292-9-bhe@redhat.com Signed-off-by: Rob Herring --- drivers/of/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index e40f10bf2ba4..da9826accb1b 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -55,7 +55,7 @@ config OF_FLATTREE config OF_EARLY_FLATTREE bool - select DMA_DECLARE_COHERENT if HAS_DMA + select DMA_DECLARE_COHERENT if HAS_DMA && HAS_IOMEM select OF_FLATTREE config OF_PROMTREE From c2d6fd9d6f35079f1669f0100f05b46708c74b7f Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Tue, 6 Jun 2023 21:59:23 +0800 Subject: [PATCH 041/272] jbd2: recheck chechpointing non-dirty buffer There is a long-standing metadata corruption issue that happens from time to time, but it's very difficult to reproduce and analyse, benefit from the JBD2_CYCLE_RECORD option, we found out that the problem is the checkpointing process miss to write out some buffers which are raced by another do_get_write_access(). Looks below for detail. jbd2_log_do_checkpoint() //transaction X //buffer A is dirty and not belones to any transaction __buffer_relink_io() //move it to the IO list __flush_batch() write_dirty_buffer() do_get_write_access() clear_buffer_dirty __jbd2_journal_file_buffer() //add buffer A to a new transaction Y lock_buffer(bh) //doesn't write out __jbd2_journal_remove_checkpoint() //finish checkpoint except buffer A //filesystem corrupt if the new transaction Y isn't fully write out. Due to the t_checkpoint_list walking loop in jbd2_log_do_checkpoint() have already handles waiting for buffers under IO and re-added new transaction to complete commit, and it also removing cleaned buffers, this makes sure the list will eventually get empty. So it's fine to leave buffers on the t_checkpoint_list while flushing out and completely stop using the t_checkpoint_io_list. Cc: stable@vger.kernel.org Suggested-by: Jan Kara Signed-off-by: Zhang Yi Tested-by: Zhihao Cheng Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230606135928.434610-2-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o --- fs/jbd2/checkpoint.c | 102 ++++++++++++------------------------------- 1 file changed, 29 insertions(+), 73 deletions(-) diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 51bd38da21cd..25e3c20eb19f 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -57,28 +57,6 @@ static inline void __buffer_unlink(struct journal_head *jh) } } -/* - * Move a buffer from the checkpoint list to the checkpoint io list - * - * Called with j_list_lock held - */ -static inline void __buffer_relink_io(struct journal_head *jh) -{ - transaction_t *transaction = jh->b_cp_transaction; - - __buffer_unlink_first(jh); - - if (!transaction->t_checkpoint_io_list) { - jh->b_cpnext = jh->b_cpprev = jh; - } else { - jh->b_cpnext = transaction->t_checkpoint_io_list; - jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev; - jh->b_cpprev->b_cpnext = jh; - jh->b_cpnext->b_cpprev = jh; - } - transaction->t_checkpoint_io_list = jh; -} - /* * Check a checkpoint buffer could be release or not. * @@ -183,6 +161,7 @@ __flush_batch(journal_t *journal, int *batch_count) struct buffer_head *bh = journal->j_chkpt_bhs[i]; BUFFER_TRACE(bh, "brelse"); __brelse(bh); + journal->j_chkpt_bhs[i] = NULL; } *batch_count = 0; } @@ -242,6 +221,11 @@ restart: jh = transaction->t_checkpoint_list; bh = jh2bh(jh); + /* + * The buffer may be writing back, or flushing out in the + * last couple of cycles, or re-adding into a new transaction, + * need to check it again until it's unlocked. + */ if (buffer_locked(bh)) { get_bh(bh); spin_unlock(&journal->j_list_lock); @@ -287,28 +271,32 @@ restart: } if (!buffer_dirty(bh)) { BUFFER_TRACE(bh, "remove from checkpoint"); - if (__jbd2_journal_remove_checkpoint(jh)) - /* The transaction was released; we're done */ + /* + * If the transaction was released or the checkpoint + * list was empty, we're done. + */ + if (__jbd2_journal_remove_checkpoint(jh) || + !transaction->t_checkpoint_list) goto out; - continue; + } else { + /* + * We are about to write the buffer, it could be + * raced by some other transaction shrink or buffer + * re-log logic once we release the j_list_lock, + * leave it on the checkpoint list and check status + * again to make sure it's clean. + */ + BUFFER_TRACE(bh, "queue"); + get_bh(bh); + J_ASSERT_BH(bh, !buffer_jwrite(bh)); + journal->j_chkpt_bhs[batch_count++] = bh; + transaction->t_chp_stats.cs_written++; + transaction->t_checkpoint_list = jh->b_cpnext; } - /* - * Important: we are about to write the buffer, and - * possibly block, while still holding the journal - * lock. We cannot afford to let the transaction - * logic start messing around with this buffer before - * we write it to disk, as that would break - * recoverability. - */ - BUFFER_TRACE(bh, "queue"); - get_bh(bh); - J_ASSERT_BH(bh, !buffer_jwrite(bh)); - journal->j_chkpt_bhs[batch_count++] = bh; - __buffer_relink_io(jh); - transaction->t_chp_stats.cs_written++; + if ((batch_count == JBD2_NR_BATCH) || - need_resched() || - spin_needbreak(&journal->j_list_lock)) + need_resched() || spin_needbreak(&journal->j_list_lock) || + jh2bh(transaction->t_checkpoint_list) == journal->j_chkpt_bhs[0]) goto unlock_and_flush; } @@ -322,38 +310,6 @@ restart: goto restart; } - /* - * Now we issued all of the transaction's buffers, let's deal - * with the buffers that are out for I/O. - */ -restart2: - /* Did somebody clean up the transaction in the meanwhile? */ - if (journal->j_checkpoint_transactions != transaction || - transaction->t_tid != this_tid) - goto out; - - while (transaction->t_checkpoint_io_list) { - jh = transaction->t_checkpoint_io_list; - bh = jh2bh(jh); - if (buffer_locked(bh)) { - get_bh(bh); - spin_unlock(&journal->j_list_lock); - wait_on_buffer(bh); - /* the journal_head may have gone by now */ - BUFFER_TRACE(bh, "brelse"); - __brelse(bh); - spin_lock(&journal->j_list_lock); - goto restart2; - } - - /* - * Now in whatever state the buffer currently is, we - * know that it has been written out and so we can - * drop it from the list - */ - if (__jbd2_journal_remove_checkpoint(jh)) - break; - } out: spin_unlock(&journal->j_list_lock); result = jbd2_cleanup_journal_tail(journal); From be22255360f80d3af789daad00025171a65424a5 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Tue, 6 Jun 2023 21:59:24 +0800 Subject: [PATCH 042/272] jbd2: remove t_checkpoint_io_list Since t_checkpoint_io_list was stop using in jbd2_log_do_checkpoint() now, it's time to remove the whole t_checkpoint_io_list logic. Signed-off-by: Zhang Yi Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230606135928.434610-3-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o --- fs/jbd2/checkpoint.c | 42 ++---------------------------------------- fs/jbd2/commit.c | 3 +-- include/linux/jbd2.h | 6 ------ 3 files changed, 3 insertions(+), 48 deletions(-) diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 25e3c20eb19f..55d6efdbea64 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -27,7 +27,7 @@ * * Called with j_list_lock held. */ -static inline void __buffer_unlink_first(struct journal_head *jh) +static inline void __buffer_unlink(struct journal_head *jh) { transaction_t *transaction = jh->b_cp_transaction; @@ -40,23 +40,6 @@ static inline void __buffer_unlink_first(struct journal_head *jh) } } -/* - * Unlink a buffer from a transaction checkpoint(io) list. - * - * Called with j_list_lock held. - */ -static inline void __buffer_unlink(struct journal_head *jh) -{ - transaction_t *transaction = jh->b_cp_transaction; - - __buffer_unlink_first(jh); - if (transaction->t_checkpoint_io_list == jh) { - transaction->t_checkpoint_io_list = jh->b_cpnext; - if (transaction->t_checkpoint_io_list == jh) - transaction->t_checkpoint_io_list = NULL; - } -} - /* * Check a checkpoint buffer could be release or not. * @@ -503,15 +486,6 @@ again: break; if (need_resched() || spin_needbreak(&journal->j_list_lock)) break; - if (released) - continue; - - nr_freed += journal_shrink_one_cp_list(transaction->t_checkpoint_io_list, - nr_to_scan, &released); - if (*nr_to_scan == 0) - break; - if (need_resched() || spin_needbreak(&journal->j_list_lock)) - break; } while (transaction != last_transaction); if (transaction != last_transaction) { @@ -566,17 +540,6 @@ void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy) */ if (need_resched()) return; - if (ret) - continue; - /* - * It is essential that we are as careful as in the case of - * t_checkpoint_list with removing the buffer from the list as - * we can possibly see not yet submitted buffers on io_list - */ - ret = journal_clean_one_cp_list(transaction-> - t_checkpoint_io_list, destroy); - if (need_resched()) - return; /* * Stop scanning if we couldn't free the transaction. This * avoids pointless scanning of transactions which still @@ -661,7 +624,7 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh) jbd2_journal_put_journal_head(jh); /* Is this transaction empty? */ - if (transaction->t_checkpoint_list || transaction->t_checkpoint_io_list) + if (transaction->t_checkpoint_list) return 0; /* @@ -753,7 +716,6 @@ void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transact J_ASSERT(transaction->t_forget == NULL); J_ASSERT(transaction->t_shadow_list == NULL); J_ASSERT(transaction->t_checkpoint_list == NULL); - J_ASSERT(transaction->t_checkpoint_io_list == NULL); J_ASSERT(atomic_read(&transaction->t_updates) == 0); J_ASSERT(journal->j_committing_transaction != transaction); J_ASSERT(journal->j_running_transaction != transaction); diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index b33155dd7001..1073259902a6 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -1141,8 +1141,7 @@ restart_loop: spin_lock(&journal->j_list_lock); commit_transaction->t_state = T_FINISHED; /* Check if the transaction can be dropped now that we are finished */ - if (commit_transaction->t_checkpoint_list == NULL && - commit_transaction->t_checkpoint_io_list == NULL) { + if (commit_transaction->t_checkpoint_list == NULL) { __jbd2_journal_drop_transaction(journal, commit_transaction); jbd2_journal_free_transaction(commit_transaction); } diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index d860499e15e4..bd660aac8e07 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -613,12 +613,6 @@ struct transaction_s */ struct journal_head *t_checkpoint_list; - /* - * Doubly-linked circular list of all buffers submitted for IO while - * checkpointing. [j_list_lock] - */ - struct journal_head *t_checkpoint_io_list; - /* * Doubly-linked circular list of metadata buffers being * shadowed by log IO. The IO buffers on the iobuf list and From b98dba273a0e47dbfade89c9af73c5b012a4eabb Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Tue, 6 Jun 2023 21:59:25 +0800 Subject: [PATCH 043/272] jbd2: remove journal_clean_one_cp_list() journal_clean_one_cp_list() and journal_shrink_one_cp_list() are almost the same, so merge them into journal_shrink_one_cp_list(), remove the nr_to_scan parameter, always scan and try to free the whole checkpoint list. Signed-off-by: Zhang Yi Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230606135928.434610-4-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o --- fs/jbd2/checkpoint.c | 85 ++++++++++--------------------------- include/trace/events/jbd2.h | 12 ++---- 2 files changed, 26 insertions(+), 71 deletions(-) diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 55d6efdbea64..b94f847960c2 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -348,19 +348,24 @@ int jbd2_cleanup_journal_tail(journal_t *journal) /* Checkpoint list management */ /* - * journal_clean_one_cp_list + * journal_shrink_one_cp_list * - * Find all the written-back checkpoint buffers in the given list and - * release them. If 'destroy' is set, clean all buffers unconditionally. + * Find all the written-back checkpoint buffers in the given list + * and try to release them. If the whole transaction is released, set + * the 'released' parameter. Return the number of released checkpointed + * buffers. * * Called with j_list_lock held. - * Returns 1 if we freed the transaction, 0 otherwise. */ -static int journal_clean_one_cp_list(struct journal_head *jh, bool destroy) +static unsigned long journal_shrink_one_cp_list(struct journal_head *jh, + bool destroy, bool *released) { struct journal_head *last_jh; struct journal_head *next_jh = jh; + unsigned long nr_freed = 0; + int ret; + *released = false; if (!jh) return 0; @@ -370,52 +375,6 @@ static int journal_clean_one_cp_list(struct journal_head *jh, bool destroy) next_jh = jh->b_cpnext; if (!destroy && __cp_buffer_busy(jh)) - return 0; - - if (__jbd2_journal_remove_checkpoint(jh)) - return 1; - /* - * This function only frees up some memory - * if possible so we dont have an obligation - * to finish processing. Bail out if preemption - * requested: - */ - if (need_resched()) - return 0; - } while (jh != last_jh); - - return 0; -} - -/* - * journal_shrink_one_cp_list - * - * Find 'nr_to_scan' written-back checkpoint buffers in the given list - * and try to release them. If the whole transaction is released, set - * the 'released' parameter. Return the number of released checkpointed - * buffers. - * - * Called with j_list_lock held. - */ -static unsigned long journal_shrink_one_cp_list(struct journal_head *jh, - unsigned long *nr_to_scan, - bool *released) -{ - struct journal_head *last_jh; - struct journal_head *next_jh = jh; - unsigned long nr_freed = 0; - int ret; - - if (!jh || *nr_to_scan == 0) - return 0; - - last_jh = jh->b_cpprev; - do { - jh = next_jh; - next_jh = jh->b_cpnext; - - (*nr_to_scan)--; - if (__cp_buffer_busy(jh)) continue; nr_freed++; @@ -427,7 +386,7 @@ static unsigned long journal_shrink_one_cp_list(struct journal_head *jh, if (need_resched()) break; - } while (jh != last_jh && *nr_to_scan); + } while (jh != last_jh); return nr_freed; } @@ -445,11 +404,11 @@ unsigned long jbd2_journal_shrink_checkpoint_list(journal_t *journal, unsigned long *nr_to_scan) { transaction_t *transaction, *last_transaction, *next_transaction; - bool released; + bool __maybe_unused released; tid_t first_tid = 0, last_tid = 0, next_tid = 0; tid_t tid = 0; unsigned long nr_freed = 0; - unsigned long nr_scanned = *nr_to_scan; + unsigned long freed; again: spin_lock(&journal->j_list_lock); @@ -478,10 +437,11 @@ again: transaction = next_transaction; next_transaction = transaction->t_cpnext; tid = transaction->t_tid; - released = false; - nr_freed += journal_shrink_one_cp_list(transaction->t_checkpoint_list, - nr_to_scan, &released); + freed = journal_shrink_one_cp_list(transaction->t_checkpoint_list, + false, &released); + nr_freed += freed; + (*nr_to_scan) -= min(*nr_to_scan, freed); if (*nr_to_scan == 0) break; if (need_resched() || spin_needbreak(&journal->j_list_lock)) @@ -502,9 +462,8 @@ again: if (*nr_to_scan && next_tid) goto again; out: - nr_scanned -= *nr_to_scan; trace_jbd2_shrink_checkpoint_list(journal, first_tid, tid, last_tid, - nr_freed, nr_scanned, next_tid); + nr_freed, next_tid); return nr_freed; } @@ -520,7 +479,7 @@ out: void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy) { transaction_t *transaction, *last_transaction, *next_transaction; - int ret; + bool released; transaction = journal->j_checkpoint_transactions; if (!transaction) @@ -531,8 +490,8 @@ void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy) do { transaction = next_transaction; next_transaction = transaction->t_cpnext; - ret = journal_clean_one_cp_list(transaction->t_checkpoint_list, - destroy); + journal_shrink_one_cp_list(transaction->t_checkpoint_list, + destroy, &released); /* * This function only frees up some memory if possible so we * dont have an obligation to finish processing. Bail out if @@ -545,7 +504,7 @@ void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy) * avoids pointless scanning of transactions which still * weren't checkpointed. */ - if (!ret) + if (!released) return; } while (transaction != last_transaction); } diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h index 8f5ee380d309..5646ae15a957 100644 --- a/include/trace/events/jbd2.h +++ b/include/trace/events/jbd2.h @@ -462,11 +462,9 @@ TRACE_EVENT(jbd2_shrink_scan_exit, TRACE_EVENT(jbd2_shrink_checkpoint_list, TP_PROTO(journal_t *journal, tid_t first_tid, tid_t tid, tid_t last_tid, - unsigned long nr_freed, unsigned long nr_scanned, - tid_t next_tid), + unsigned long nr_freed, tid_t next_tid), - TP_ARGS(journal, first_tid, tid, last_tid, nr_freed, - nr_scanned, next_tid), + TP_ARGS(journal, first_tid, tid, last_tid, nr_freed, next_tid), TP_STRUCT__entry( __field(dev_t, dev) @@ -474,7 +472,6 @@ TRACE_EVENT(jbd2_shrink_checkpoint_list, __field(tid_t, tid) __field(tid_t, last_tid) __field(unsigned long, nr_freed) - __field(unsigned long, nr_scanned) __field(tid_t, next_tid) ), @@ -484,15 +481,14 @@ TRACE_EVENT(jbd2_shrink_checkpoint_list, __entry->tid = tid; __entry->last_tid = last_tid; __entry->nr_freed = nr_freed; - __entry->nr_scanned = nr_scanned; __entry->next_tid = next_tid; ), TP_printk("dev %d,%d shrink transaction %u-%u(%u) freed %lu " - "scanned %lu next transaction %u", + "next transaction %u", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->first_tid, __entry->tid, __entry->last_tid, - __entry->nr_freed, __entry->nr_scanned, __entry->next_tid) + __entry->nr_freed, __entry->next_tid) ); #endif /* _TRACE_JBD2_H */ From e34c8dd238d0c9368b746480f313055f5bab5040 Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Tue, 6 Jun 2023 21:59:26 +0800 Subject: [PATCH 044/272] jbd2: Fix wrongly judgement for buffer head removing while doing checkpoint Following process, jbd2_journal_commit_transaction // there are several dirty buffer heads in transaction->t_checkpoint_list P1 wb_workfn jbd2_log_do_checkpoint if (buffer_locked(bh)) // false __block_write_full_page trylock_buffer(bh) test_clear_buffer_dirty(bh) if (!buffer_dirty(bh)) __jbd2_journal_remove_checkpoint(jh) if (buffer_write_io_error(bh)) // false >> bh IO error occurs << jbd2_cleanup_journal_tail __jbd2_update_log_tail jbd2_write_superblock // The bh won't be replayed in next mount. , which could corrupt the ext4 image, fetch a reproducer in [Link]. Since writeback process clears buffer dirty after locking buffer head, we can fix it by try locking buffer and check dirtiness while buffer is locked, the buffer head can be removed if it is neither dirty nor locked. Link: https://bugzilla.kernel.org/show_bug.cgi?id=217490 Fixes: 470decc613ab ("[PATCH] jbd2: initial copy of files from jbd") Signed-off-by: Zhihao Cheng Signed-off-by: Zhang Yi Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230606135928.434610-5-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o --- fs/jbd2/checkpoint.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index b94f847960c2..42b34cab64fb 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -204,20 +204,6 @@ restart: jh = transaction->t_checkpoint_list; bh = jh2bh(jh); - /* - * The buffer may be writing back, or flushing out in the - * last couple of cycles, or re-adding into a new transaction, - * need to check it again until it's unlocked. - */ - if (buffer_locked(bh)) { - get_bh(bh); - spin_unlock(&journal->j_list_lock); - wait_on_buffer(bh); - /* the journal_head may have gone by now */ - BUFFER_TRACE(bh, "brelse"); - __brelse(bh); - goto retry; - } if (jh->b_transaction != NULL) { transaction_t *t = jh->b_transaction; tid_t tid = t->t_tid; @@ -252,7 +238,22 @@ restart: spin_lock(&journal->j_list_lock); goto restart; } - if (!buffer_dirty(bh)) { + if (!trylock_buffer(bh)) { + /* + * The buffer is locked, it may be writing back, or + * flushing out in the last couple of cycles, or + * re-adding into a new transaction, need to check + * it again until it's unlocked. + */ + get_bh(bh); + spin_unlock(&journal->j_list_lock); + wait_on_buffer(bh); + /* the journal_head may have gone by now */ + BUFFER_TRACE(bh, "brelse"); + __brelse(bh); + goto retry; + } else if (!buffer_dirty(bh)) { + unlock_buffer(bh); BUFFER_TRACE(bh, "remove from checkpoint"); /* * If the transaction was released or the checkpoint @@ -262,6 +263,7 @@ restart: !transaction->t_checkpoint_list) goto out; } else { + unlock_buffer(bh); /* * We are about to write the buffer, it could be * raced by some other transaction shrink or buffer From 46f881b5b1758dc4a35fba4a643c10717d0cf427 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Tue, 6 Jun 2023 21:59:27 +0800 Subject: [PATCH 045/272] jbd2: fix a race when checking checkpoint buffer busy Before removing checkpoint buffer from the t_checkpoint_list, we have to check both BH_Dirty and BH_Lock bits together to distinguish buffers have not been or were being written back. But __cp_buffer_busy() checks them separately, it first check lock state and then check dirty, the window between these two checks could be raced by writing back procedure, which locks buffer and clears buffer dirty before I/O completes. So it cannot guarantee checkpointing buffers been written back to disk if some error happens later. Finally, it may clean checkpoint transactions and lead to inconsistent filesystem. jbd2_journal_forget() and __journal_try_to_free_buffer() also have the same problem (journal_unmap_buffer() escape from this issue since it's running under the buffer lock), so fix them through introducing a new helper to try holding the buffer lock and remove really clean buffer. Link: https://bugzilla.kernel.org/show_bug.cgi?id=217490 Cc: stable@vger.kernel.org Suggested-by: Jan Kara Signed-off-by: Zhang Yi Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230606135928.434610-6-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o --- fs/jbd2/checkpoint.c | 38 +++++++++++++++++++++++++++++++++++--- fs/jbd2/transaction.c | 17 +++++------------ include/linux/jbd2.h | 1 + 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 42b34cab64fb..9ec91017a7f3 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -376,11 +376,15 @@ static unsigned long journal_shrink_one_cp_list(struct journal_head *jh, jh = next_jh; next_jh = jh->b_cpnext; - if (!destroy && __cp_buffer_busy(jh)) - continue; + if (destroy) { + ret = __jbd2_journal_remove_checkpoint(jh); + } else { + ret = jbd2_journal_try_remove_checkpoint(jh); + if (ret < 0) + continue; + } nr_freed++; - ret = __jbd2_journal_remove_checkpoint(jh); if (ret) { *released = true; break; @@ -616,6 +620,34 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh) return 1; } +/* + * Check the checkpoint buffer and try to remove it from the checkpoint + * list if it's clean. Returns -EBUSY if it is not clean, returns 1 if + * it frees the transaction, 0 otherwise. + * + * This function is called with j_list_lock held. + */ +int jbd2_journal_try_remove_checkpoint(struct journal_head *jh) +{ + struct buffer_head *bh = jh2bh(jh); + + if (!trylock_buffer(bh)) + return -EBUSY; + if (buffer_dirty(bh)) { + unlock_buffer(bh); + return -EBUSY; + } + unlock_buffer(bh); + + /* + * Buffer is clean and the IO has finished (we held the buffer + * lock) so the checkpoint is done. We can safely remove the + * buffer from this transaction. + */ + JBUFFER_TRACE(jh, "remove from checkpoint list"); + return __jbd2_journal_remove_checkpoint(jh); +} + /* * journal_insert_checkpoint: put a committed buffer onto a checkpoint * list so that we know when it is safe to clean the transaction out of diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 18611241f451..6ef5022949c4 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -1784,8 +1784,7 @@ int jbd2_journal_forget(handle_t *handle, struct buffer_head *bh) * Otherwise, if the buffer has been written to disk, * it is safe to remove the checkpoint and drop it. */ - if (!buffer_dirty(bh)) { - __jbd2_journal_remove_checkpoint(jh); + if (jbd2_journal_try_remove_checkpoint(jh) >= 0) { spin_unlock(&journal->j_list_lock); goto drop; } @@ -2112,20 +2111,14 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) jh = bh2jh(bh); - if (buffer_locked(bh) || buffer_dirty(bh)) - goto out; - if (jh->b_next_transaction != NULL || jh->b_transaction != NULL) - goto out; + return; spin_lock(&journal->j_list_lock); - if (jh->b_cp_transaction != NULL) { - /* written-back checkpointed metadata buffer */ - JBUFFER_TRACE(jh, "remove from checkpoint list"); - __jbd2_journal_remove_checkpoint(jh); - } + /* Remove written-back checkpointed metadata buffer */ + if (jh->b_cp_transaction != NULL) + jbd2_journal_try_remove_checkpoint(jh); spin_unlock(&journal->j_list_lock); -out: return; } diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index bd660aac8e07..44c298aa58d4 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -1443,6 +1443,7 @@ extern void jbd2_journal_commit_transaction(journal_t *); void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy); unsigned long jbd2_journal_shrink_checkpoint_list(journal_t *journal, unsigned long *nr_to_scan); int __jbd2_journal_remove_checkpoint(struct journal_head *); +int jbd2_journal_try_remove_checkpoint(struct journal_head *jh); void jbd2_journal_destroy_checkpoint(journal_t *journal); void __jbd2_journal_insert_checkpoint(struct journal_head *, transaction_t *); From 3c55097c553c49deab60ac62c83ef17565004a97 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Tue, 6 Jun 2023 21:59:28 +0800 Subject: [PATCH 046/272] jbd2: remove __journal_try_to_free_buffer() __journal_try_to_free_buffer() has only one caller and it's logic is much simple now, so just remove it and open code in jbd2_journal_try_to_free_buffers(). Signed-off-by: Zhang Yi Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230606135928.434610-7-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o --- fs/jbd2/transaction.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 6ef5022949c4..4d1fda1f7143 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -2099,29 +2099,6 @@ void jbd2_journal_unfile_buffer(journal_t *journal, struct journal_head *jh) __brelse(bh); } -/* - * Called from jbd2_journal_try_to_free_buffers(). - * - * Called under jh->b_state_lock - */ -static void -__journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) -{ - struct journal_head *jh; - - jh = bh2jh(bh); - - if (jh->b_next_transaction != NULL || jh->b_transaction != NULL) - return; - - spin_lock(&journal->j_list_lock); - /* Remove written-back checkpointed metadata buffer */ - if (jh->b_cp_transaction != NULL) - jbd2_journal_try_remove_checkpoint(jh); - spin_unlock(&journal->j_list_lock); - return; -} - /** * jbd2_journal_try_to_free_buffers() - try to free page buffers. * @journal: journal for operation @@ -2179,7 +2156,13 @@ bool jbd2_journal_try_to_free_buffers(journal_t *journal, struct folio *folio) continue; spin_lock(&jh->b_state_lock); - __journal_try_to_free_buffer(journal, bh); + if (!jh->b_transaction && !jh->b_next_transaction) { + spin_lock(&journal->j_list_lock); + /* Remove written-back checkpointed metadata buffer */ + if (jh->b_cp_transaction != NULL) + jbd2_journal_try_remove_checkpoint(jh); + spin_unlock(&journal->j_list_lock); + } spin_unlock(&jh->b_state_lock); jbd2_journal_put_journal_head(jh); if (buffer_jbd(bh)) From 4e47382fbca916d7db95cbf9e2d7ca2e9d1ca3fe Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Wed, 28 Jun 2023 15:24:37 +0200 Subject: [PATCH 047/272] fbdev: imxfb: warn about invalid left/right margin Warn about invalid var->left_margin or var->right_margin. Their values are read from the device tree. We store var->left_margin-3 and var->right_margin-1 in register fields. These fields should be >= 0. Fixes: 7e8549bcee00 ("imxfb: Fix margin settings") Signed-off-by: Martin Kaiser Signed-off-by: Helge Deller --- drivers/video/fbdev/imxfb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c index adf36690c342..5fbcb78a9cae 100644 --- a/drivers/video/fbdev/imxfb.c +++ b/drivers/video/fbdev/imxfb.c @@ -613,10 +613,10 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf if (var->hsync_len < 1 || var->hsync_len > 64) printk(KERN_ERR "%s: invalid hsync_len %d\n", info->fix.id, var->hsync_len); - if (var->left_margin > 255) + if (var->left_margin < 3 || var->left_margin > 255) printk(KERN_ERR "%s: invalid left_margin %d\n", info->fix.id, var->left_margin); - if (var->right_margin > 255) + if (var->right_margin < 1 || var->right_margin > 255) printk(KERN_ERR "%s: invalid right_margin %d\n", info->fix.id, var->right_margin); if (var->yres < 1 || var->yres > ymax_mask) From 86a101023e7d4413f89d0a0a77693af952529260 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Wed, 28 Jun 2023 15:26:52 +0200 Subject: [PATCH 048/272] fbdev: imxfb: switch to DEFINE_SIMPLE_DEV_PM_OPS SIMPLE_DEV_PM_OPS is deprecated, replace it with DEFINE_SIMPLE_DEV_PM_OPS and use pm_sleep_ptr for setting the driver's pm routines. We can now remove the __maybe_unused qualifier in the suspend and resume functions. Signed-off-by: Martin Kaiser Signed-off-by: Helge Deller --- drivers/video/fbdev/imxfb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c index 5fbcb78a9cae..04f3bf30a529 100644 --- a/drivers/video/fbdev/imxfb.c +++ b/drivers/video/fbdev/imxfb.c @@ -1066,7 +1066,7 @@ static void imxfb_remove(struct platform_device *pdev) framebuffer_release(info); } -static int __maybe_unused imxfb_suspend(struct device *dev) +static int imxfb_suspend(struct device *dev) { struct fb_info *info = dev_get_drvdata(dev); struct imxfb_info *fbi = info->par; @@ -1076,7 +1076,7 @@ static int __maybe_unused imxfb_suspend(struct device *dev) return 0; } -static int __maybe_unused imxfb_resume(struct device *dev) +static int imxfb_resume(struct device *dev) { struct fb_info *info = dev_get_drvdata(dev); struct imxfb_info *fbi = info->par; @@ -1086,13 +1086,13 @@ static int __maybe_unused imxfb_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(imxfb_pm_ops, imxfb_suspend, imxfb_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(imxfb_pm_ops, imxfb_suspend, imxfb_resume); static struct platform_driver imxfb_driver = { .driver = { .name = DRIVER_NAME, .of_match_table = imxfb_of_dev_id, - .pm = &imxfb_pm_ops, + .pm = pm_sleep_ptr(&imxfb_pm_ops), }, .probe = imxfb_probe, .remove_new = imxfb_remove, From 45fcc058a75bf5d65cf4c32da44a252fbe873cd4 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Mon, 10 Jul 2023 21:19:58 +0800 Subject: [PATCH 049/272] fbdev: imxfb: Removed unneeded release_mem_region Remove unnecessary release_mem_region from the error path to prevent mem region from being released twice, which could avoid resource leak or other unexpected issues. Fixes: b083c22d5114 ("video: fbdev: imxfb: Convert request_mem_region + ioremap to devm_ioremap_resource") Signed-off-by: Yangtao Li Signed-off-by: Helge Deller --- drivers/video/fbdev/imxfb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c index 04f3bf30a529..385c4715c7b7 100644 --- a/drivers/video/fbdev/imxfb.c +++ b/drivers/video/fbdev/imxfb.c @@ -1043,7 +1043,6 @@ failed_cmap: failed_map: failed_ioremap: failed_getclock: - release_mem_region(res->start, resource_size(res)); failed_of_parse: kfree(info->pseudo_palette); failed_init: From 55dd7378ba94afe389e7edec23510bad80d344ca Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Mon, 10 Jul 2023 21:19:59 +0800 Subject: [PATCH 050/272] fbdev: imxfb: Convert to devm_kmalloc_array() No need for manual kfree in the error path and the remove function. Signed-off-by: Yangtao Li Signed-off-by: Helge Deller --- drivers/video/fbdev/imxfb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c index 385c4715c7b7..7020b5f6434d 100644 --- a/drivers/video/fbdev/imxfb.c +++ b/drivers/video/fbdev/imxfb.c @@ -673,7 +673,8 @@ static int imxfb_init_fbinfo(struct platform_device *pdev) pr_debug("%s\n",__func__); - info->pseudo_palette = kmalloc_array(16, sizeof(u32), GFP_KERNEL); + info->pseudo_palette = devm_kmalloc_array(&pdev->dev, 16, + sizeof(u32), GFP_KERNEL); if (!info->pseudo_palette) return -ENOMEM; @@ -1044,7 +1045,6 @@ failed_map: failed_ioremap: failed_getclock: failed_of_parse: - kfree(info->pseudo_palette); failed_init: framebuffer_release(info); return ret; @@ -1061,7 +1061,6 @@ static void imxfb_remove(struct platform_device *pdev) fb_dealloc_cmap(&info->cmap); dma_free_wc(&pdev->dev, fbi->map_size, info->screen_buffer, fbi->map_dma); - kfree(info->pseudo_palette); framebuffer_release(info); } From 78dd4f415567a94fa134214f82b7966cbefde05c Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Mon, 10 Jul 2023 21:20:00 +0800 Subject: [PATCH 051/272] fbdev: imxfb: Convert to devm_platform_ioremap_resource() Use devm_platform_ioremap_resource() to simplify code. Signed-off-by: Yangtao Li Signed-off-by: Helge Deller --- drivers/video/fbdev/imxfb.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c index 7020b5f6434d..4582ea801121 100644 --- a/drivers/video/fbdev/imxfb.c +++ b/drivers/video/fbdev/imxfb.c @@ -869,7 +869,6 @@ static int imxfb_probe(struct platform_device *pdev) struct imxfb_info *fbi; struct lcd_device *lcd; struct fb_info *info; - struct resource *res; struct imx_fb_videomode *m; const struct of_device_id *of_id; struct device_node *display_np; @@ -886,10 +885,6 @@ static int imxfb_probe(struct platform_device *pdev) if (of_id) pdev->id_entry = of_id->data; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev); if (!info) return -ENOMEM; @@ -971,7 +966,7 @@ static int imxfb_probe(struct platform_device *pdev) goto failed_getclock; } - fbi->regs = devm_ioremap_resource(&pdev->dev, res); + fbi->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(fbi->regs)) { ret = PTR_ERR(fbi->regs); goto failed_ioremap; From 53a90ae81a33437ff6ae907c75fd8a9902df2480 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Mon, 10 Jul 2023 21:20:01 +0800 Subject: [PATCH 052/272] fbdev: imxfb: remove unneeded labels These labels are now redundant and don't do anything, let's remove them. Signed-off-by: Yangtao Li Signed-off-by: Helge Deller --- drivers/video/fbdev/imxfb.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c index 4582ea801121..77dedd2c05fd 100644 --- a/drivers/video/fbdev/imxfb.c +++ b/drivers/video/fbdev/imxfb.c @@ -903,7 +903,7 @@ static int imxfb_probe(struct platform_device *pdev) if (!display_np) { dev_err(&pdev->dev, "No display defined in devicetree\n"); ret = -EINVAL; - goto failed_of_parse; + goto failed_init; } /* @@ -917,13 +917,13 @@ static int imxfb_probe(struct platform_device *pdev) if (!fbi->mode) { ret = -ENOMEM; of_node_put(display_np); - goto failed_of_parse; + goto failed_init; } ret = imxfb_of_read_mode(&pdev->dev, display_np, fbi->mode); of_node_put(display_np); if (ret) - goto failed_of_parse; + goto failed_init; /* Calculate maximum bytes used per pixel. In most cases this should * be the same as m->bpp/8 */ @@ -936,7 +936,7 @@ static int imxfb_probe(struct platform_device *pdev) fbi->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); if (IS_ERR(fbi->clk_ipg)) { ret = PTR_ERR(fbi->clk_ipg); - goto failed_getclock; + goto failed_init; } /* @@ -951,25 +951,25 @@ static int imxfb_probe(struct platform_device *pdev) */ ret = clk_prepare_enable(fbi->clk_ipg); if (ret) - goto failed_getclock; + goto failed_init; clk_disable_unprepare(fbi->clk_ipg); fbi->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); if (IS_ERR(fbi->clk_ahb)) { ret = PTR_ERR(fbi->clk_ahb); - goto failed_getclock; + goto failed_init; } fbi->clk_per = devm_clk_get(&pdev->dev, "per"); if (IS_ERR(fbi->clk_per)) { ret = PTR_ERR(fbi->clk_per); - goto failed_getclock; + goto failed_init; } fbi->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(fbi->regs)) { ret = PTR_ERR(fbi->regs); - goto failed_ioremap; + goto failed_init; } fbi->map_size = PAGE_ALIGN(info->fix.smem_len); @@ -978,7 +978,7 @@ static int imxfb_probe(struct platform_device *pdev) if (!info->screen_buffer) { dev_err(&pdev->dev, "Failed to allocate video RAM\n"); ret = -ENOMEM; - goto failed_map; + goto failed_init; } info->fix.smem_start = fbi->map_dma; @@ -1030,16 +1030,11 @@ static int imxfb_probe(struct platform_device *pdev) failed_lcd: unregister_framebuffer(info); - failed_register: fb_dealloc_cmap(&info->cmap); failed_cmap: dma_free_wc(&pdev->dev, fbi->map_size, info->screen_buffer, fbi->map_dma); -failed_map: -failed_ioremap: -failed_getclock: -failed_of_parse: failed_init: framebuffer_release(info); return ret; From fe769e6c1f80f542d6f4e7f7c8c6bf20c1307f99 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 27 Jun 2023 15:05:57 +0100 Subject: [PATCH 053/272] KVM: arm64: timers: Use CNTHCTL_EL2 when setting non-CNTKCTL_EL1 bits It recently appeared that, when running VHE, there is a notable difference between using CNTKCTL_EL1 and CNTHCTL_EL2, despite what the architecture documents: - When accessed from EL2, bits [19:18] and [16:10] of CNTKCTL_EL1 have the same assignment as CNTHCTL_EL2 - When accessed from EL1, bits [19:18] and [16:10] are RES0 It is all OK, until you factor in NV, where the EL2 guest runs at EL1. In this configuration, CNTKCTL_EL11 doesn't trap, nor ends up in the VNCR page. This means that any write from the guest affecting CNTHCTL_EL2 using CNTKCTL_EL1 ends up losing some state. Not good. The fix it obvious: don't use CNTKCTL_EL1 if you want to change bits that are not part of the EL1 definition of CNTKCTL_EL1, and use CNTHCTL_EL2 instead. This doesn't change anything for a bare-metal OS, and fixes it when running under NV. The NV hypervisor will itself have to work harder to merge the two accessors. Note that there is a pending update to the architecture to address this issue by making the affected bits UNKNOWN when CNTKCTL_EL1 is used from EL2 with VHE enabled. Fixes: c605ee245097 ("KVM: arm64: timers: Allow physical offset without CNTPOFF_EL2") Signed-off-by: Marc Zyngier Cc: stable@vger.kernel.org # v6.4 Reviewed-by: Eric Auger Link: https://lore.kernel.org/r/20230627140557.544885-1-maz@kernel.org Signed-off-by: Oliver Upton --- arch/arm64/kvm/arch_timer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 0696732fa38c..6dcdae4d38cb 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -827,8 +827,8 @@ static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map) assign_clear_set_bit(tpt, CNTHCTL_EL1PCEN << 10, set, clr); assign_clear_set_bit(tpc, CNTHCTL_EL1PCTEN << 10, set, clr); - /* This only happens on VHE, so use the CNTKCTL_EL1 accessor */ - sysreg_clear_set(cntkctl_el1, clr, set); + /* This only happens on VHE, so use the CNTHCTL_EL2 accessor. */ + sysreg_clear_set(cnthctl_el2, clr, set); } void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu) @@ -1563,7 +1563,7 @@ no_vgic: void kvm_timer_init_vhe(void) { if (cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF)) - sysreg_clear_set(cntkctl_el1, 0, CNTHCTL_ECV); + sysreg_clear_set(cnthctl_el2, 0, CNTHCTL_ECV); } int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) From fa729bc7c9c8c17a2481358c841ef8ca920485d3 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 4 Jul 2023 20:32:43 +0100 Subject: [PATCH 054/272] KVM: arm64: Handle kvm_arm_init failure correctly in finalize_pkvm Currently there is no synchronisation between finalize_pkvm() and kvm_arm_init() initcalls. The finalize_pkvm() proceeds happily even if kvm_arm_init() fails resulting in the following warning on all the CPUs and eventually a HYP panic: | kvm [1]: IPA Size Limit: 48 bits | kvm [1]: Failed to init hyp memory protection | kvm [1]: error initializing Hyp mode: -22 | | | | WARNING: CPU: 0 PID: 0 at arch/arm64/kvm/pkvm.c:226 _kvm_host_prot_finalize+0x30/0x50 | Modules linked in: | CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.4.0 #237 | Hardware name: FVP Base RevC (DT) | pstate: 634020c5 (nZCv daIF +PAN -UAO +TCO +DIT -SSBS BTYPE=--) | pc : _kvm_host_prot_finalize+0x30/0x50 | lr : __flush_smp_call_function_queue+0xd8/0x230 | | Call trace: | _kvm_host_prot_finalize+0x3c/0x50 | on_each_cpu_cond_mask+0x3c/0x6c | pkvm_drop_host_privileges+0x4c/0x78 | finalize_pkvm+0x3c/0x5c | do_one_initcall+0xcc/0x240 | do_initcall_level+0x8c/0xac | do_initcalls+0x54/0x94 | do_basic_setup+0x1c/0x28 | kernel_init_freeable+0x100/0x16c | kernel_init+0x20/0x1a0 | ret_from_fork+0x10/0x20 | Failed to finalize Hyp protection: -22 | dtb=fvp-base-revc.dtb | kvm [95]: nVHE hyp BUG at: arch/arm64/kvm/hyp/nvhe/mem_protect.c:540! | kvm [95]: nVHE call trace: | kvm [95]: [] __kvm_nvhe_hyp_panic+0xac/0xf8 | kvm [95]: [] __kvm_nvhe_handle_host_mem_abort+0x1a0/0x2ac | kvm [95]: [] __kvm_nvhe_handle_trap+0x4c/0x160 | kvm [95]: [] __kvm_nvhe___skip_pauth_save+0x4/0x4 | kvm [95]: ---[ end nVHE call trace ]--- | kvm [95]: Hyp Offset: 0xfffe8db00ffa0000 | Kernel panic - not syncing: HYP panic: | PS:a34023c9 PC:0000f250710b973c ESR:00000000f2000800 | FAR:ffff000800cb00d0 HPFAR:000000000880cb00 PAR:0000000000000000 | VCPU:0000000000000000 | CPU: 3 PID: 95 Comm: kworker/u16:2 Tainted: G W 6.4.0 #237 | Hardware name: FVP Base RevC (DT) | Workqueue: rpciod rpc_async_schedule | Call trace: | dump_backtrace+0xec/0x108 | show_stack+0x18/0x2c | dump_stack_lvl+0x50/0x68 | dump_stack+0x18/0x24 | panic+0x138/0x33c | nvhe_hyp_panic_handler+0x100/0x184 | new_slab+0x23c/0x54c | ___slab_alloc+0x3e4/0x770 | kmem_cache_alloc_node+0x1f0/0x278 | __alloc_skb+0xdc/0x294 | tcp_stream_alloc_skb+0x2c/0xf0 | tcp_sendmsg_locked+0x3d0/0xda4 | tcp_sendmsg+0x38/0x5c | inet_sendmsg+0x44/0x60 | sock_sendmsg+0x1c/0x34 | xprt_sock_sendmsg+0xdc/0x274 | xs_tcp_send_request+0x1ac/0x28c | xprt_transmit+0xcc/0x300 | call_transmit+0x78/0x90 | __rpc_execute+0x114/0x3d8 | rpc_async_schedule+0x28/0x48 | process_one_work+0x1d8/0x314 | worker_thread+0x248/0x474 | kthread+0xfc/0x184 | ret_from_fork+0x10/0x20 | SMP: stopping secondary CPUs | Kernel Offset: 0x57c5cb460000 from 0xffff800080000000 | PHYS_OFFSET: 0x80000000 | CPU features: 0x00000000,1035b7a3,ccfe773f | Memory Limit: none | ---[ end Kernel panic - not syncing: HYP panic: | PS:a34023c9 PC:0000f250710b973c ESR:00000000f2000800 | FAR:ffff000800cb00d0 HPFAR:000000000880cb00 PAR:0000000000000000 | VCPU:0000000000000000 ]--- Fix it by checking for the successfull initialisation of kvm_arm_init() in finalize_pkvm() before proceeding any futher. Fixes: 87727ba2bb05 ("KVM: arm64: Ensure CPU PMU probes before pKVM host de-privilege") Cc: Will Deacon Cc: Marc Zyngier Cc: Oliver Upton Cc: James Morse Cc: Suzuki K Poulose Cc: Zenghui Yu Signed-off-by: Sudeep Holla Acked-by: Marc Zyngier Link: https://lore.kernel.org/r/20230704193243.3300506-1-sudeep.holla@arm.com Signed-off-by: Oliver Upton --- arch/arm64/include/asm/virt.h | 1 + arch/arm64/kvm/arm.c | 9 ++++++++- arch/arm64/kvm/pkvm.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h index 5227db7640c8..261d6e9df2e1 100644 --- a/arch/arm64/include/asm/virt.h +++ b/arch/arm64/include/asm/virt.h @@ -78,6 +78,7 @@ extern u32 __boot_cpu_mode[2]; void __hyp_set_vectors(phys_addr_t phys_vector_base); void __hyp_reset_vectors(void); +bool is_kvm_arm_initialised(void); DECLARE_STATIC_KEY_FALSE(kvm_protected_mode_initialized); diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index c2c14059f6a8..0a564d2f30ad 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -53,11 +53,16 @@ DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params); DECLARE_KVM_NVHE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt); -static bool vgic_present; +static bool vgic_present, kvm_arm_initialised; static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled); DEFINE_STATIC_KEY_FALSE(userspace_irqchip_in_use); +bool is_kvm_arm_initialised(void) +{ + return kvm_arm_initialised; +} + int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) { return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE; @@ -2482,6 +2487,8 @@ static __init int kvm_arm_init(void) if (err) goto out_subs; + kvm_arm_initialised = true; + return 0; out_subs: diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index 994a494703c3..6ff3ec18c925 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -244,7 +244,7 @@ static int __init finalize_pkvm(void) { int ret; - if (!is_protected_kvm_enabled()) + if (!is_protected_kvm_enabled() || !is_kvm_arm_initialised()) return 0; /* From 970dee09b230895fe2230d2b32ad05a2826818c6 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 3 Jul 2023 17:35:48 +0100 Subject: [PATCH 055/272] KVM: arm64: Disable preemption in kvm_arch_hardware_enable() Since 0bf50497f03b ("KVM: Drop kvm_count_lock and instead protect kvm_usage_count with kvm_lock"), hotplugging back a CPU whilst a guest is running results in a number of ugly splats as most of this code expects to run with preemption disabled, which isn't the case anymore. While the context is preemptable, it isn't migratable, which should be enough. But we have plenty of preemptible() checks all over the place, and our per-CPU accessors also disable preemption. Since this affects released versions, let's do the easy fix first, disabling preemption in kvm_arch_hardware_enable(). We can always revisit this with a more invasive fix in the future. Fixes: 0bf50497f03b ("KVM: Drop kvm_count_lock and instead protect kvm_usage_count with kvm_lock") Reported-by: Kristina Martsenko Tested-by: Kristina Martsenko Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/aeab7562-2d39-e78e-93b1-4711f8cc3fa5@arm.com Cc: stable@vger.kernel.org # v6.3, v6.4 Link: https://lore.kernel.org/r/20230703163548.1498943-1-maz@kernel.org Signed-off-by: Oliver Upton --- arch/arm64/kvm/arm.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 0a564d2f30ad..a402ea5511f3 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1872,8 +1872,17 @@ static void _kvm_arch_hardware_enable(void *discard) int kvm_arch_hardware_enable(void) { - int was_enabled = __this_cpu_read(kvm_arm_hardware_enabled); + int was_enabled; + /* + * Most calls to this function are made with migration + * disabled, but not with preemption disabled. The former is + * enough to ensure correctness, but most of the helpers + * expect the later and will throw a tantrum otherwise. + */ + preempt_disable(); + + was_enabled = __this_cpu_read(kvm_arm_hardware_enabled); _kvm_arch_hardware_enable(NULL); if (!was_enabled) { @@ -1881,6 +1890,8 @@ int kvm_arch_hardware_enable(void) kvm_timer_cpu_up(); } + preempt_enable(); + return 0; } From 0bb8f49cd2cc8cb32ac51189ff9fcbe7ec3d9d65 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 10 Jul 2023 11:40:07 -0600 Subject: [PATCH 056/272] of: Preserve "of-display" device name for compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 241d2fb56a18 ("of: Make OF framebuffer device names unique"), as spotted by Frédéric Bonnard, the historical "of-display" device is gone: the updated logic creates "of-display.0" instead, then as many "of-display.N" as required. This means that offb no longer finds the expected device, which prevents the Debian Installer from setting up its interface, at least on ppc64el. Fix this by keeping "of-display" for the first device and "of-display.N" for subsequent devices. Link: https://bugzilla.kernel.org/show_bug.cgi?id=217328 Link: https://bugs.debian.org/1033058 Fixes: 241d2fb56a18 ("of: Make OF framebuffer device names unique") Cc: stable@vger.kernel.org Cc: Cyril Brulebois Cc: Thomas Zimmermann Cc: Helge Deller Acked-by: Helge Deller Acked-by: Thomas Zimmermann Reviewed-by: Michal Suchánek Link: https://lore.kernel.org/r/20230710174007.2291013-1-robh@kernel.org Signed-off-by: Rob Herring --- drivers/of/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 051e29b7ad2b..0c3475e7d2ff 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -552,7 +552,7 @@ static int __init of_platform_default_populate_init(void) if (!of_get_property(node, "linux,opened", NULL) || !of_get_property(node, "linux,boot-display", NULL)) continue; - dev = of_platform_device_create(node, "of-display.0", NULL); + dev = of_platform_device_create(node, "of-display", NULL); of_node_put(node); if (WARN_ON(!dev)) return -ENOMEM; From 0266a2f791294e0b4ba36f4a1d89b8615ea3cac0 Mon Sep 17 00:00:00 2001 From: Wang Ming Date: Tue, 4 Jul 2023 15:40:47 +0800 Subject: [PATCH 057/272] ksmbd: Fix unsigned expression compared with zero The return value of the ksmbd_vfs_getcasexattr() is signed. However, the return value is being assigned to an unsigned variable and subsequently recasted, causing warnings. Use a signed type. Signed-off-by: Wang Ming Acked-by: Tom Talpey Acked-by: Namjae Jeon Signed-off-by: Steve French --- fs/smb/server/vfs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index e35914457350..e605ee96b0d0 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -412,7 +412,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, { char *stream_buf = NULL, *wbuf; struct mnt_idmap *idmap = file_mnt_idmap(fp->filp); - size_t size, v_len; + size_t size; + ssize_t v_len; int err = 0; ksmbd_debug(VFS, "write stream data pos : %llu, count : %zd\n", @@ -429,9 +430,9 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, fp->stream.name, fp->stream.size, &stream_buf); - if ((int)v_len < 0) { + if (v_len < 0) { pr_err("not found stream in xattr : %zd\n", v_len); - err = (int)v_len; + err = v_len; goto out; } From 390ef8c0a37751434d084a8226a1ad9c90ae5772 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 10 Jul 2023 21:28:59 -0700 Subject: [PATCH 058/272] kconfig: gconfig: drop the Show Debug Info help text The Show Debug Info option was removed eons ago. Now finish the job by removing the help text for it also. Fixes: 7b5d87215b38 ("gconfig: remove show_debug option") Signed-off-by: Randy Dunlap Signed-off-by: Masahiro Yamada --- scripts/kconfig/gconf.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 17adabfd6e6b..f2f01945b3dc 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -647,10 +647,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) "Although there is no cross reference yet to help you figure out\n" "what other options must be enabled to support the option you\n" "are interested in, you can still view the help of a grayed-out\n" - "option.\n" - "\n" - "Toggling Show Debug Info under the Options menu will show \n" - "the dependencies, which you can then match by examining other options."; + "option."; dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), GTK_DIALOG_DESTROY_WITH_PARENT, From 30ebf2ce70888d8fdd1986e8e6d509dd2d227985 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 10 Jul 2023 21:29:13 -0700 Subject: [PATCH 059/272] kconfig: gconfig: correct program name in help text Change "gkc" to "gconfig" in 3 places since it is called "gconfig" and not "gkc". Add a period at the end of one sentence. Signed-off-by: Randy Dunlap Signed-off-by: Masahiro Yamada --- scripts/kconfig/gconf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index f2f01945b3dc..9709aca3a30f 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -636,7 +636,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *dialog; const gchar *intro_text = - "Welcome to gkc, the GTK+ graphical configuration tool\n" + "Welcome to gconfig, the GTK+ graphical configuration tool.\n" "For each option, a blank box indicates the feature is disabled, a\n" "check indicates it is enabled, and a dot indicates that it is to\n" "be compiled as a module. Clicking on the box will cycle through the three states.\n" @@ -664,7 +664,7 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *dialog; const gchar *about_text = - "gkc is copyright (c) 2002 Romain Lievin .\n" + "gconfig is copyright (c) 2002 Romain Lievin .\n" "Based on the source code from Roman Zippel.\n"; dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), @@ -682,7 +682,7 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *dialog; const gchar *license_text = - "gkc is released under the terms of the GNU GPL v2.\n" + "gconfig is released under the terms of the GNU GPL v2.\n" "For more information, please see the source code or\n" "visit http://www.fsf.org/licenses/licenses.html\n"; From 5782017cc4d0c8f3425d55b893675bb8a20c33e9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 11 Jul 2023 09:13:25 +0300 Subject: [PATCH 060/272] phy: phy-mtk-dp: Fix an error code in probe() Negative -EINVAL was intended instead of positive EINVAL. Fixes: 6a23afad443a ("phy: phy-mtk-dp: Add driver for DP phy") Signed-off-by: Dan Carpenter Reviewed-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/3c699e00-2883-40d9-92c3-0da1dc38fdd4@moroto.mountain Signed-off-by: Vinod Koul --- drivers/phy/mediatek/phy-mtk-dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/mediatek/phy-mtk-dp.c b/drivers/phy/mediatek/phy-mtk-dp.c index 232fd3f1ff1b..d7024a144335 100644 --- a/drivers/phy/mediatek/phy-mtk-dp.c +++ b/drivers/phy/mediatek/phy-mtk-dp.c @@ -169,7 +169,7 @@ static int mtk_dp_phy_probe(struct platform_device *pdev) regs = *(struct regmap **)dev->platform_data; if (!regs) - return dev_err_probe(dev, EINVAL, + return dev_err_probe(dev, -EINVAL, "No data passed, requires struct regmap**\n"); dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL); From 95bd315f0a5ed7d7afe771776272c5b3cdb29bc8 Mon Sep 17 00:00:00 2001 From: Guillaume Ranquet Date: Tue, 30 May 2023 10:43:07 +0200 Subject: [PATCH 061/272] phy: mediatek: hdmi: mt8195: fix prediv bad upper limit test The pll prediv calculus searchs for the smallest prediv that gets the ns_hdmipll_ck in the range of 5 GHz to 12 GHz. A typo in the upper bound test was testing for 5Ghz to 1Ghz Fixes: 45810d486bb44 ("phy: mediatek: add support for phy-mtk-hdmi-mt8195") Signed-off-by: Guillaume Ranquet Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20230529-hdmi_phy_fix-v1-1-bf65f53af533@baylibre.com Signed-off-by: Vinod Koul --- drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c index 8aa7251de4a9..bbfe11d6a69d 100644 --- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c @@ -253,7 +253,7 @@ static int mtk_hdmi_pll_calc(struct mtk_hdmi_phy *hdmi_phy, struct clk_hw *hw, for (i = 0; i < ARRAY_SIZE(txpredivs); i++) { ns_hdmipll_ck = 5 * tmds_clk * txposdiv * txpredivs[i]; if (ns_hdmipll_ck >= 5 * GIGA && - ns_hdmipll_ck <= 1 * GIGA) + ns_hdmipll_ck <= 12 * GIGA) break; } if (i == (ARRAY_SIZE(txpredivs) - 1) && From 45d89a344eb46db9dce851c28e14f5e3c635c251 Mon Sep 17 00:00:00 2001 From: Adrien Thierry Date: Thu, 29 Jun 2023 10:45:38 -0400 Subject: [PATCH 062/272] phy: qcom-snps-femto-v2: keep cfg_ahb_clk enabled during runtime suspend In the dwc3 core, both system and runtime suspend end up calling dwc3_suspend_common(). From there, what happens for the PHYs depends on the USB mode and whether the controller is entering system or runtime suspend. HOST mode: (1) system suspend on a non-wakeup-capable controller The [1] if branch is taken. dwc3_core_exit() is called, which ends up calling phy_power_off() and phy_exit(). Those two functions decrease the PM runtime count at some point, so they will trigger the PHY runtime sleep (assuming the count is right). (2) runtime suspend / system suspend on a wakeup-capable controller The [1] branch is not taken. dwc3_suspend_common() calls phy_pm_runtime_put_sync(). Assuming the ref count is right, the PHY runtime suspend op is called. DEVICE mode: dwc3_core_exit() is called on both runtime and system sleep unless the controller is already runtime suspended. OTG mode: (1) system suspend : dwc3_core_exit() is called (2) runtime suspend : do nothing In host mode, the code seems to make a distinction between 1) runtime sleep / system sleep for wakeup-capable controller, and 2) system sleep for non-wakeup-capable controller, where phy_power_off() and phy_exit() are only called for the latter. This suggests the PHY is not supposed to be in a fully powered-off state for runtime sleep and system sleep for wakeup-capable controller. Moreover, downstream, cfg_ahb_clk only gets disabled for system suspend. The clocks are disabled by phy->set_suspend() [2] which is only called in the system sleep path through dwc3_core_exit() [3]. With that in mind, don't disable the clocks during the femto PHY runtime suspend callback. The clocks will only be disabled during system suspend for non-wakeup-capable controllers, through dwc3_core_exit(). [1] https://elixir.bootlin.com/linux/v6.4/source/drivers/usb/dwc3/core.c#L1988 [2] https://git.codelinaro.org/clo/la/kernel/msm-5.4/-/blob/LV.AU.1.2.1.r2-05300-gen3meta.0/drivers/usb/phy/phy-msm-snps-hs.c#L524 [3] https://git.codelinaro.org/clo/la/kernel/msm-5.4/-/blob/LV.AU.1.2.1.r2-05300-gen3meta.0/drivers/usb/dwc3/core.c#L1915 Signed-off-by: Adrien Thierry Link: https://lore.kernel.org/r/20230629144542.14906-2-athierry@redhat.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c index 6c237f3cc66d..3335480fc395 100644 --- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c +++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c @@ -165,22 +165,13 @@ static int qcom_snps_hsphy_suspend(struct qcom_snps_hsphy *hsphy) 0, USB2_AUTO_RESUME); } - clk_disable_unprepare(hsphy->cfg_ahb_clk); return 0; } static int qcom_snps_hsphy_resume(struct qcom_snps_hsphy *hsphy) { - int ret; - dev_dbg(&hsphy->phy->dev, "Resume QCOM SNPS PHY, mode\n"); - ret = clk_prepare_enable(hsphy->cfg_ahb_clk); - if (ret) { - dev_err(&hsphy->phy->dev, "failed to enable cfg ahb clock\n"); - return ret; - } - return 0; } From 8a0eb8f9b9a002291a3934acfd913660b905249e Mon Sep 17 00:00:00 2001 From: Adrien Thierry Date: Thu, 29 Jun 2023 10:45:39 -0400 Subject: [PATCH 063/272] phy: qcom-snps-femto-v2: properly enable ref clock The driver is not enabling the ref clock, which thus gets disabled by the clk_disable_unused() initcall. This leads to the dwc3 controller failing to initialize if probed after clk_disable_unused() is called, for instance when the driver is built as a module. To fix this, switch to the clk_bulk API to handle both cfg_ahb and ref clocks at the proper places. Note that the cfg_ahb clock is currently not used by any device tree instantiation of the PHY. Work needs to be done separately to fix this. Link: https://lore.kernel.org/linux-arm-msm/ZEqvy+khHeTkC2hf@fedora/ Fixes: 51e8114f80d0 ("phy: qcom-snps: Add SNPS USB PHY driver for QCOM based SOCs") Signed-off-by: Adrien Thierry Link: https://lore.kernel.org/r/20230629144542.14906-3-athierry@redhat.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 63 ++++++++++++++----- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c index 3335480fc395..6170f8fd118e 100644 --- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c +++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c @@ -110,11 +110,13 @@ struct phy_override_seq { /** * struct qcom_snps_hsphy - snps hs phy attributes * + * @dev: device structure + * * @phy: generic phy * @base: iomapped memory space for snps hs phy * - * @cfg_ahb_clk: AHB2PHY interface clock - * @ref_clk: phy reference clock + * @num_clks: number of clocks + * @clks: array of clocks * @phy_reset: phy reset control * @vregs: regulator supplies bulk data * @phy_initialized: if PHY has been initialized correctly @@ -122,11 +124,13 @@ struct phy_override_seq { * @update_seq_cfg: tuning parameters for phy init */ struct qcom_snps_hsphy { + struct device *dev; + struct phy *phy; void __iomem *base; - struct clk *cfg_ahb_clk; - struct clk *ref_clk; + int num_clks; + struct clk_bulk_data *clks; struct reset_control *phy_reset; struct regulator_bulk_data vregs[SNPS_HS_NUM_VREGS]; @@ -135,6 +139,34 @@ struct qcom_snps_hsphy { struct phy_override_seq update_seq_cfg[NUM_HSPHY_TUNING_PARAMS]; }; +static int qcom_snps_hsphy_clk_init(struct qcom_snps_hsphy *hsphy) +{ + struct device *dev = hsphy->dev; + + hsphy->num_clks = 2; + hsphy->clks = devm_kcalloc(dev, hsphy->num_clks, sizeof(*hsphy->clks), GFP_KERNEL); + if (!hsphy->clks) + return -ENOMEM; + + /* + * TODO: Currently no device tree instantiation of the PHY is using the clock. + * This needs to be fixed in order for this code to be able to use devm_clk_bulk_get(). + */ + hsphy->clks[0].id = "cfg_ahb"; + hsphy->clks[0].clk = devm_clk_get_optional(dev, "cfg_ahb"); + if (IS_ERR(hsphy->clks[0].clk)) + return dev_err_probe(dev, PTR_ERR(hsphy->clks[0].clk), + "failed to get cfg_ahb clk\n"); + + hsphy->clks[1].id = "ref"; + hsphy->clks[1].clk = devm_clk_get(dev, "ref"); + if (IS_ERR(hsphy->clks[1].clk)) + return dev_err_probe(dev, PTR_ERR(hsphy->clks[1].clk), + "failed to get ref clk\n"); + + return 0; +} + static inline void qcom_snps_hsphy_write_mask(void __iomem *base, u32 offset, u32 mask, u32 val) { @@ -365,16 +397,16 @@ static int qcom_snps_hsphy_init(struct phy *phy) if (ret) return ret; - ret = clk_prepare_enable(hsphy->cfg_ahb_clk); + ret = clk_bulk_prepare_enable(hsphy->num_clks, hsphy->clks); if (ret) { - dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret); + dev_err(&phy->dev, "failed to enable clocks, %d\n", ret); goto poweroff_phy; } ret = reset_control_assert(hsphy->phy_reset); if (ret) { dev_err(&phy->dev, "failed to assert phy_reset, %d\n", ret); - goto disable_ahb_clk; + goto disable_clks; } usleep_range(100, 150); @@ -382,7 +414,7 @@ static int qcom_snps_hsphy_init(struct phy *phy) ret = reset_control_deassert(hsphy->phy_reset); if (ret) { dev_err(&phy->dev, "failed to de-assert phy_reset, %d\n", ret); - goto disable_ahb_clk; + goto disable_clks; } qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_CFG0, @@ -439,8 +471,8 @@ static int qcom_snps_hsphy_init(struct phy *phy) return 0; -disable_ahb_clk: - clk_disable_unprepare(hsphy->cfg_ahb_clk); +disable_clks: + clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks); poweroff_phy: regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs); @@ -452,7 +484,7 @@ static int qcom_snps_hsphy_exit(struct phy *phy) struct qcom_snps_hsphy *hsphy = phy_get_drvdata(phy); reset_control_assert(hsphy->phy_reset); - clk_disable_unprepare(hsphy->cfg_ahb_clk); + clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks); regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs); hsphy->phy_initialized = false; @@ -545,14 +577,15 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev) if (!hsphy) return -ENOMEM; + hsphy->dev = dev; + hsphy->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(hsphy->base)) return PTR_ERR(hsphy->base); - hsphy->ref_clk = devm_clk_get(dev, "ref"); - if (IS_ERR(hsphy->ref_clk)) - return dev_err_probe(dev, PTR_ERR(hsphy->ref_clk), - "failed to get ref clk\n"); + ret = qcom_snps_hsphy_clk_init(hsphy); + if (ret) + return dev_err_probe(dev, ret, "failed to initialize clocks\n"); hsphy->phy_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (IS_ERR(hsphy->phy_reset)) { From 8932089b566c24ea19b57e37704c492678de1420 Mon Sep 17 00:00:00 2001 From: Adrien Thierry Date: Thu, 29 Jun 2023 10:45:40 -0400 Subject: [PATCH 064/272] phy: qcom-snps-femto-v2: use qcom_snps_hsphy_suspend/resume error code The return value from qcom_snps_hsphy_suspend/resume is not used. Make sure qcom_snps_hsphy_runtime_suspend/resume return this value as well. Signed-off-by: Adrien Thierry Link: https://lore.kernel.org/r/20230629144542.14906-4-athierry@redhat.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c index 6170f8fd118e..d0319bee01c0 100644 --- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c +++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c @@ -214,8 +214,7 @@ static int __maybe_unused qcom_snps_hsphy_runtime_suspend(struct device *dev) if (!hsphy->phy_initialized) return 0; - qcom_snps_hsphy_suspend(hsphy); - return 0; + return qcom_snps_hsphy_suspend(hsphy); } static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev) @@ -225,8 +224,7 @@ static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev) if (!hsphy->phy_initialized) return 0; - qcom_snps_hsphy_resume(hsphy); - return 0; + return qcom_snps_hsphy_resume(hsphy); } static int qcom_snps_hsphy_set_mode(struct phy *phy, enum phy_mode mode, From c40d6b3249b11d60e09d81530588f56233d9aa44 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 5 Jul 2023 14:30:11 +0200 Subject: [PATCH 065/272] soundwire: fix enumeration completion The soundwire subsystem uses two completion structures that allow drivers to wait for soundwire device to become enumerated on the bus and initialised by their drivers, respectively. The code implementing the signalling is currently broken as it does not signal all current and future waiters and also uses the wrong reinitialisation function, which can potentially lead to memory corruption if there are still waiters on the queue. Not signalling future waiters specifically breaks sound card probe deferrals as codec drivers can not tell that the soundwire device is already attached when being reprobed. Some codec runtime PM implementations suffer from similar problems as waiting for enumeration during resume can also timeout despite the device already having been enumerated. Fixes: fb9469e54fa7 ("soundwire: bus: fix race condition with enumeration_complete signaling") Fixes: a90def068127 ("soundwire: bus: fix race condition with initialization_complete signaling") Cc: stable@vger.kernel.org # 5.7 Cc: Pierre-Louis Bossart Cc: Rander Wang Signed-off-by: Johan Hovold Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230705123018.30903-2-johan+linaro@kernel.org Signed-off-by: Vinod Koul --- drivers/soundwire/bus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c index dba920ec88f6..cf78839b3f74 100644 --- a/drivers/soundwire/bus.c +++ b/drivers/soundwire/bus.c @@ -922,8 +922,8 @@ static void sdw_modify_slave_status(struct sdw_slave *slave, "initializing enumeration and init completion for Slave %d\n", slave->dev_num); - init_completion(&slave->enumeration_complete); - init_completion(&slave->initialization_complete); + reinit_completion(&slave->enumeration_complete); + reinit_completion(&slave->initialization_complete); } else if ((status == SDW_SLAVE_ATTACHED) && (slave->status == SDW_SLAVE_UNATTACHED)) { @@ -931,7 +931,7 @@ static void sdw_modify_slave_status(struct sdw_slave *slave, "signaling enumeration completion for Slave %d\n", slave->dev_num); - complete(&slave->enumeration_complete); + complete_all(&slave->enumeration_complete); } slave->status = status; mutex_unlock(&bus->bus_lock); @@ -1951,7 +1951,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus, "signaling initialization completion for Slave %d\n", slave->dev_num); - complete(&slave->initialization_complete); + complete_all(&slave->initialization_complete); /* * If the manager became pm_runtime active, the peripherals will be From f84d41b2a083b990cbdf70f3b24b6b108b9678ad Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 25 May 2023 14:38:09 +0100 Subject: [PATCH 066/272] soundwire: qcom: update status correctly with mask SoundWire device status can be incorrectly updated without proper mask, fix this by adding a mask before updating the status. Fixes: c7d49c76d1d5 ("soundwire: qcom: add support to new interrupts") Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230525133812.30841-2-srinivas.kandagatla@linaro.org Signed-off-by: Vinod Koul --- drivers/soundwire/qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c index 7970fdb27ba0..c029e4d53573 100644 --- a/drivers/soundwire/qcom.c +++ b/drivers/soundwire/qcom.c @@ -540,7 +540,7 @@ static int qcom_swrm_get_alert_slave_dev_num(struct qcom_swrm_ctrl *ctrl) status = (val >> (dev_num * SWRM_MCP_SLV_STATUS_SZ)); if ((status & SWRM_MCP_SLV_STATUS_MASK) == SDW_SLAVE_ALERT) { - ctrl->status[dev_num] = status; + ctrl->status[dev_num] = status & SWRM_MCP_SLV_STATUS_MASK; return dev_num; } } From df6556adf27b7372cfcd97e1c0afb0d516c8279f Mon Sep 17 00:00:00 2001 From: Oliver Upton Date: Tue, 27 Jun 2023 23:54:05 +0000 Subject: [PATCH 067/272] KVM: arm64: Correctly handle page aging notifiers for unaligned memslot Userspace is allowed to select any PAGE_SIZE aligned hva to back guest memory. This is even the case with hugepages, although it is a rather suboptimal configuration as PTE level mappings are used at stage-2. The arm64 page aging handlers have an assumption that the specified range is exactly one page/block of memory, which in the aforementioned case is not necessarily true. All together this leads to the WARN() in kvm_age_gfn() firing. However, the WARN is only part of the issue as the table walkers visit at most a single leaf PTE. For hugepage-backed memory in a memslot that isn't hugepage-aligned, page aging entirely misses accesses to the hugepage beyond the first page in the memslot. Add a new walker dedicated to handling page aging MMU notifiers capable of walking a range of PTEs. Convert kvm(_test)_age_gfn() over to the new walker and drop the WARN that caught the issue in the first place. The implementation of this walker was inspired by the test_clear_young() implementation by Yu Zhao [*], but repurposed to address a bug in the existing aging implementation. Cc: stable@vger.kernel.org # v5.15 Fixes: 056aad67f836 ("kvm: arm/arm64: Rework gpa callback handlers") Link: https://lore.kernel.org/kvmarm/20230526234435.662652-6-yuzhao@google.com/ Co-developed-by: Yu Zhao Signed-off-by: Yu Zhao Reported-by: Reiji Watanabe Reviewed-by: Marc Zyngier Reviewed-by: Shaoqin Huang Link: https://lore.kernel.org/r/20230627235405.4069823-1-oliver.upton@linux.dev Signed-off-by: Oliver Upton --- arch/arm64/include/asm/kvm_pgtable.h | 26 ++++++--------- arch/arm64/kvm/hyp/pgtable.c | 47 ++++++++++++++++++++++------ arch/arm64/kvm/mmu.c | 18 +++++------ 3 files changed, 55 insertions(+), 36 deletions(-) diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h index 8294a9a7e566..929d355eae0a 100644 --- a/arch/arm64/include/asm/kvm_pgtable.h +++ b/arch/arm64/include/asm/kvm_pgtable.h @@ -608,22 +608,26 @@ int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size); kvm_pte_t kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr); /** - * kvm_pgtable_stage2_mkold() - Clear the access flag in a page-table entry. + * kvm_pgtable_stage2_test_clear_young() - Test and optionally clear the access + * flag in a page-table entry. * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*(). * @addr: Intermediate physical address to identify the page-table entry. + * @size: Size of the address range to visit. + * @mkold: True if the access flag should be cleared. * * The offset of @addr within a page is ignored. * - * If there is a valid, leaf page-table entry used to translate @addr, then - * clear the access flag in that entry. + * Tests and conditionally clears the access flag for every valid, leaf + * page-table entry used to translate the range [@addr, @addr + @size). * * Note that it is the caller's responsibility to invalidate the TLB after * calling this function to ensure that the updated permissions are visible * to the CPUs. * - * Return: The old page-table entry prior to clearing the flag, 0 on failure. + * Return: True if any of the visited PTEs had the access flag set. */ -kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr); +bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr, + u64 size, bool mkold); /** * kvm_pgtable_stage2_relax_perms() - Relax the permissions enforced by a @@ -645,18 +649,6 @@ kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr); int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot); -/** - * kvm_pgtable_stage2_is_young() - Test whether a page-table entry has the - * access flag set. - * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*(). - * @addr: Intermediate physical address to identify the page-table entry. - * - * The offset of @addr within a page is ignored. - * - * Return: True if the page-table entry has the access flag set, false otherwise. - */ -bool kvm_pgtable_stage2_is_young(struct kvm_pgtable *pgt, u64 addr); - /** * kvm_pgtable_stage2_flush_range() - Clean and invalidate data cache to Point * of Coherency for guest stage-2 address diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index aa740a974e02..f7a93ef29250 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -1195,25 +1195,54 @@ kvm_pte_t kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr) return pte; } -kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr) +struct stage2_age_data { + bool mkold; + bool young; +}; + +static int stage2_age_walker(const struct kvm_pgtable_visit_ctx *ctx, + enum kvm_pgtable_walk_flags visit) { - kvm_pte_t pte = 0; - stage2_update_leaf_attrs(pgt, addr, 1, 0, KVM_PTE_LEAF_ATTR_LO_S2_AF, - &pte, NULL, 0); + kvm_pte_t new = ctx->old & ~KVM_PTE_LEAF_ATTR_LO_S2_AF; + struct stage2_age_data *data = ctx->arg; + + if (!kvm_pte_valid(ctx->old) || new == ctx->old) + return 0; + + data->young = true; + + /* + * stage2_age_walker() is always called while holding the MMU lock for + * write, so this will always succeed. Nonetheless, this deliberately + * follows the race detection pattern of the other stage-2 walkers in + * case the locking mechanics of the MMU notifiers is ever changed. + */ + if (data->mkold && !stage2_try_set_pte(ctx, new)) + return -EAGAIN; + /* * "But where's the TLBI?!", you scream. * "Over in the core code", I sigh. * * See the '->clear_flush_young()' callback on the KVM mmu notifier. */ - return pte; + return 0; } -bool kvm_pgtable_stage2_is_young(struct kvm_pgtable *pgt, u64 addr) +bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr, + u64 size, bool mkold) { - kvm_pte_t pte = 0; - stage2_update_leaf_attrs(pgt, addr, 1, 0, 0, &pte, NULL, 0); - return pte & KVM_PTE_LEAF_ATTR_LO_S2_AF; + struct stage2_age_data data = { + .mkold = mkold, + }; + struct kvm_pgtable_walker walker = { + .cb = stage2_age_walker, + .arg = &data, + .flags = KVM_PGTABLE_WALK_LEAF, + }; + + WARN_ON(kvm_pgtable_walk(pgt, addr, size, &walker)); + return data.young; } int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 6db9ef288ec3..d3b4feed460c 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1756,27 +1756,25 @@ bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range) bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range) { u64 size = (range->end - range->start) << PAGE_SHIFT; - kvm_pte_t kpte; - pte_t pte; if (!kvm->arch.mmu.pgt) return false; - WARN_ON(size != PAGE_SIZE && size != PMD_SIZE && size != PUD_SIZE); - - kpte = kvm_pgtable_stage2_mkold(kvm->arch.mmu.pgt, - range->start << PAGE_SHIFT); - pte = __pte(kpte); - return pte_valid(pte) && pte_young(pte); + return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt, + range->start << PAGE_SHIFT, + size, true); } bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range) { + u64 size = (range->end - range->start) << PAGE_SHIFT; + if (!kvm->arch.mmu.pgt) return false; - return kvm_pgtable_stage2_is_young(kvm->arch.mmu.pgt, - range->start << PAGE_SHIFT); + return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt, + range->start << PAGE_SHIFT, + size, false); } phys_addr_t kvm_mmu_get_httbr(void) From dcf89d111199562fa5f31a1bb76f17bc4831f6da Mon Sep 17 00:00:00 2001 From: Mostafa Saleh Date: Thu, 6 Jul 2023 15:22:40 +0000 Subject: [PATCH 068/272] KVM: arm64: Add missing BTI instructions Some bti instructions were missing from commit b53d4a272349 ("KVM: arm64: Use BTI for nvhe") 1) kvm_host_psci_cpu_entry kvm_host_psci_cpu_entry is called from __kvm_hyp_init_cpu through "br" instruction as __kvm_hyp_init_cpu resides in idmap section while kvm_host_psci_cpu_entry is in hyp .text so the offset is larger than 128MB range covered by "b". Which means that this function should start with "bti j" instruction. LLVM which is the only compiler supporting BTI for Linux, adds "bti j" for jump tables or by when taking the address of the block [1]. Same behaviour is observed with GCC. As kvm_host_psci_cpu_entry is a C function, this must be done in assembly. Another solution is to use X16/X17 with "br", as according to ARM ARM DDI0487I.a RLJHCL/IGMGRS, PACIASP has an implicit branch target identification instruction that is compatible with PSTATE.BTYPE 0b01 which includes "br X16/X17" And the kvm_host_psci_cpu_entry has PACIASP as it is an external function. Although, using explicit "bti" makes it more clear than relying on which register is used. A third solution is to clear SCTLR_EL2.BT, which would make PACIASP compatible PSTATE.BTYPE 0b11 ("br" to other registers). However this deviates from the kernel behaviour (in bti_enable()). 2) Spectre vector table "br" instructions are generated at runtime for the vector table (__bp_harden_hyp_vecs). These branches would land on vectors in __kvm_hyp_vector at offset 8. As all the macros are defined with valid_vect/invalid_vect, it is sufficient to add "bti j" at the correct offset. [1] https://reviews.llvm.org/D52867 Fixes: b53d4a272349 ("KVM: arm64: Use BTI for nvhe") Signed-off-by: Mostafa Saleh Reported-by: Sudeep Holla Acked-by: Marc Zyngier Tested-by: Sudeep Holla Link: https://lore.kernel.org/r/20230706152240.685684-1-smostafa@google.com Signed-off-by: Oliver Upton --- arch/arm64/kvm/hyp/hyp-entry.S | 8 ++++++++ arch/arm64/kvm/hyp/nvhe/host.S | 10 ++++++++++ arch/arm64/kvm/hyp/nvhe/psci-relay.c | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S index 8f3f93fa119e..03f97d71984c 100644 --- a/arch/arm64/kvm/hyp/hyp-entry.S +++ b/arch/arm64/kvm/hyp/hyp-entry.S @@ -154,6 +154,12 @@ SYM_CODE_END(\label) esb stp x0, x1, [sp, #-16]! 662: + /* + * spectre vectors __bp_harden_hyp_vecs generate br instructions at runtime + * that jump at offset 8 at __kvm_hyp_vector. + * As hyp .text is guarded section, it needs bti j. + */ + bti j b \target check_preamble_length 661b, 662b @@ -165,6 +171,8 @@ check_preamble_length 661b, 662b nop stp x0, x1, [sp, #-16]! 662: + /* Check valid_vect */ + bti j b \target check_preamble_length 661b, 662b diff --git a/arch/arm64/kvm/hyp/nvhe/host.S b/arch/arm64/kvm/hyp/nvhe/host.S index c87c63133e10..7693a6757cd7 100644 --- a/arch/arm64/kvm/hyp/nvhe/host.S +++ b/arch/arm64/kvm/hyp/nvhe/host.S @@ -297,3 +297,13 @@ SYM_CODE_START(__kvm_hyp_host_forward_smc) ret SYM_CODE_END(__kvm_hyp_host_forward_smc) + +/* + * kvm_host_psci_cpu_entry is called through br instruction, which requires + * bti j instruction as compilers (gcc and llvm) doesn't insert bti j for external + * functions, but bti c instead. + */ +SYM_CODE_START(kvm_host_psci_cpu_entry) + bti j + b __kvm_host_psci_cpu_entry +SYM_CODE_END(kvm_host_psci_cpu_entry) diff --git a/arch/arm64/kvm/hyp/nvhe/psci-relay.c b/arch/arm64/kvm/hyp/nvhe/psci-relay.c index 08508783ec3d..24543d2a3490 100644 --- a/arch/arm64/kvm/hyp/nvhe/psci-relay.c +++ b/arch/arm64/kvm/hyp/nvhe/psci-relay.c @@ -200,7 +200,7 @@ static int psci_system_suspend(u64 func_id, struct kvm_cpu_context *host_ctxt) __hyp_pa(init_params), 0); } -asmlinkage void __noreturn kvm_host_psci_cpu_entry(bool is_cpu_on) +asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bool is_cpu_on) { struct psci_boot_args *boot_args; struct kvm_cpu_context *host_ctxt; From 7891d0a5ce6f627132d3068ba925cf86f29008b1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 27 Jun 2023 08:42:10 +0300 Subject: [PATCH 069/272] soundwire: amd: Fix a check for errors in probe() This code has two problems: 1) The devm_ioremap() function returns NULL, not error pointers. 2) It's checking the wrong variable. ->mmio instead of ->acp_mmio. Fixes: d8f48fbdfd9a ("soundwire: amd: Add support for AMD Manager driver") Suggested-by: "Mukunda,Vijendar" Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/9863b2bf-0de2-4bf8-8f09-fe24dc5c63ff@moroto.mountain Signed-off-by: Vinod Koul --- drivers/soundwire/amd_manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c index 08aeb7ed00e1..3a99f6dcdfaf 100644 --- a/drivers/soundwire/amd_manager.c +++ b/drivers/soundwire/amd_manager.c @@ -910,9 +910,9 @@ static int amd_sdw_manager_probe(struct platform_device *pdev) return -ENOMEM; amd_manager->acp_mmio = devm_ioremap(dev, res->start, resource_size(res)); - if (IS_ERR(amd_manager->mmio)) { + if (!amd_manager->acp_mmio) { dev_err(dev, "mmio not found\n"); - return PTR_ERR(amd_manager->mmio); + return -ENOMEM; } amd_manager->instance = pdata->instance; amd_manager->mmio = amd_manager->acp_mmio + From 645e583d2689a1dd2163da28a7789b4d9febf316 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 12 Jul 2023 15:01:22 +0100 Subject: [PATCH 070/272] selftests: ALSA: Fix fclose on an already fclosed file pointer In the case where a sysfs file cannot be opened the error return path fcloses file pointer fpl, however, fpl has already been closed in the previous stanza. Fix the double fclose by removing it. Fixes: 10b98a4db11a ("selftests: ALSA: Add test for the 'pcmtest' driver") Signed-off-by: Colin Ian King Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20230712140122.457206-1-colin.i.king@gmail.com Signed-off-by: Takashi Iwai --- tools/testing/selftests/alsa/test-pcmtest-driver.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/testing/selftests/alsa/test-pcmtest-driver.c b/tools/testing/selftests/alsa/test-pcmtest-driver.c index 71931b240a83..357adc722cba 100644 --- a/tools/testing/selftests/alsa/test-pcmtest-driver.c +++ b/tools/testing/selftests/alsa/test-pcmtest-driver.c @@ -47,10 +47,8 @@ static int read_patterns(void) sprintf(pf, "/sys/kernel/debug/pcmtest/fill_pattern%d", i); fp = fopen(pf, "r"); - if (!fp) { - fclose(fpl); + if (!fp) return -1; - } fread(patterns[i].buf, 1, patterns[i].len, fp); fclose(fp); } From 55b87b74996383230586f4f9f801ae304c70e649 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 3 Jul 2023 14:04:16 +0100 Subject: [PATCH 071/272] arm64: Fix HFGxTR_EL2 field naming The HFGxTR_EL2 fields do not always follow the naming described in the spec, nor do they match the name of the register they trap in the rest of the kernel. It is a bit sad that they were written by hand despite the availability of a machine readable version... Fixes: cc077e7facbe ("arm64/sysreg: Convert HFG[RW]TR_EL2 to automatic generation") Signed-off-by: Marc Zyngier Cc: Mark Brown Cc: Will Deacon Cc: Catalin Marinas Cc: Mark Rutland Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20230703130416.1495307-1-maz@kernel.org Signed-off-by: Will Deacon --- arch/arm64/tools/sysreg | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 1ea4a3dc68f8..65866bf819c3 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -2017,7 +2017,7 @@ Field 0 SM EndSysreg SysregFields HFGxTR_EL2 -Field 63 nAMIAIR2_EL1 +Field 63 nAMAIR2_EL1 Field 62 nMAIR2_EL1 Field 61 nS2POR_EL1 Field 60 nPOR_EL1 @@ -2032,9 +2032,9 @@ Field 52 nGCS_EL0 Res0 51 Field 50 nACCDATA_EL1 Field 49 ERXADDR_EL1 -Field 48 EXRPFGCDN_EL1 -Field 47 EXPFGCTL_EL1 -Field 46 EXPFGF_EL1 +Field 48 ERXPFGCDN_EL1 +Field 47 ERXPFGCTL_EL1 +Field 46 ERXPFGF_EL1 Field 45 ERXMISCn_EL1 Field 44 ERXSTATUS_EL1 Field 43 ERXCTLR_EL1 @@ -2049,8 +2049,8 @@ Field 35 TPIDR_EL0 Field 34 TPIDRRO_EL0 Field 33 TPIDR_EL1 Field 32 TCR_EL1 -Field 31 SCTXNUM_EL0 -Field 30 SCTXNUM_EL1 +Field 31 SCXTNUM_EL0 +Field 30 SCXTNUM_EL1 Field 29 SCTLR_EL1 Field 28 REVIDR_EL1 Field 27 PAR_EL1 From c2a88e8bdf5f6239948d75283d0ae7e0c7945b03 Mon Sep 17 00:00:00 2001 From: Jocelyn Falempe Date: Tue, 11 Jul 2023 11:20:43 +0200 Subject: [PATCH 072/272] drm/client: Fix memory leak in drm_client_target_cloned dmt_mode is allocated and never freed in this function. It was found with the ast driver, but most drivers using generic fbdev setup are probably affected. This fixes the following kmemleak report: backtrace: [<00000000b391296d>] drm_mode_duplicate+0x45/0x220 [drm] [<00000000e45bb5b3>] drm_client_target_cloned.constprop.0+0x27b/0x480 [drm] [<00000000ed2d3a37>] drm_client_modeset_probe+0x6bd/0xf50 [drm] [<0000000010e5cc9d>] __drm_fb_helper_initial_config_and_unlock+0xb4/0x2c0 [drm_kms_helper] [<00000000909f82ca>] drm_fbdev_client_hotplug+0x2bc/0x4d0 [drm_kms_helper] [<00000000063a69aa>] drm_client_register+0x169/0x240 [drm] [<00000000a8c61525>] ast_pci_probe+0x142/0x190 [ast] [<00000000987f19bb>] local_pci_probe+0xdc/0x180 [<000000004fca231b>] work_for_cpu_fn+0x4e/0xa0 [<0000000000b85301>] process_one_work+0x8b7/0x1540 [<000000003375b17c>] worker_thread+0x70a/0xed0 [<00000000b0d43cd9>] kthread+0x29f/0x340 [<000000008d770833>] ret_from_fork+0x1f/0x30 unreferenced object 0xff11000333089a00 (size 128): cc: Fixes: 1d42bbc8f7f9 ("drm/fbdev: fix cloning on fbcon") Reported-by: Zhang Yi Signed-off-by: Jocelyn Falempe Reviewed-by: Javier Martinez Canillas Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20230711092203.68157-2-jfalempe@redhat.com --- drivers/gpu/drm/drm_client_modeset.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index 1b12a3c201a3..a4a62aa99984 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -311,6 +311,9 @@ static bool drm_client_target_cloned(struct drm_device *dev, can_clone = true; dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false); + if (!dmt_mode) + goto fail; + for (i = 0; i < connector_count; i++) { if (!enabled[i]) continue; @@ -326,11 +329,13 @@ static bool drm_client_target_cloned(struct drm_device *dev, if (!modes[i]) can_clone = false; } + kfree(dmt_mode); if (can_clone) { DRM_DEBUG_KMS("can clone using 1024x768\n"); return true; } +fail: DRM_INFO("kms: can't enable cloning when we probably wanted to.\n"); return false; } From 2329cc7a101af1a844fbf706c0724c0baea38365 Mon Sep 17 00:00:00 2001 From: Jocelyn Falempe Date: Tue, 11 Jul 2023 11:20:44 +0200 Subject: [PATCH 073/272] drm/client: Fix memory leak in drm_client_modeset_probe When a new mode is set to modeset->mode, the previous mode should be freed. This fixes the following kmemleak report: drm_mode_duplicate+0x45/0x220 [drm] drm_client_modeset_probe+0x944/0xf50 [drm] __drm_fb_helper_initial_config_and_unlock+0xb4/0x2c0 [drm_kms_helper] drm_fbdev_client_hotplug+0x2bc/0x4d0 [drm_kms_helper] drm_client_register+0x169/0x240 [drm] ast_pci_probe+0x142/0x190 [ast] local_pci_probe+0xdc/0x180 work_for_cpu_fn+0x4e/0xa0 process_one_work+0x8b7/0x1540 worker_thread+0x70a/0xed0 kthread+0x29f/0x340 ret_from_fork+0x1f/0x30 cc: Reported-by: Zhang Yi Signed-off-by: Jocelyn Falempe Reviewed-by: Javier Martinez Canillas Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20230711092203.68157-3-jfalempe@redhat.com --- drivers/gpu/drm/drm_client_modeset.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index a4a62aa99984..871e4e2129d6 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -867,6 +867,7 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, break; } + kfree(modeset->mode); modeset->mode = drm_mode_duplicate(dev, mode); drm_connector_get(connector); modeset->connectors[modeset->num_connectors++] = connector; From b321c31c9b7b309dcde5e8854b741c8e6a9a05f0 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 13 Jul 2023 08:06:57 +0100 Subject: [PATCH 074/272] KVM: arm64: vgic-v4: Make the doorbell request robust w.r.t preemption Xiang reports that VMs occasionally fail to boot on GICv4.1 systems when running a preemptible kernel, as it is possible that a vCPU is blocked without requesting a doorbell interrupt. The issue is that any preemption that occurs between vgic_v4_put() and schedule() on the block path will mark the vPE as nonresident and *not* request a doorbell irq. This occurs because when the vcpu thread is resumed on its way to block, vcpu_load() will make the vPE resident again. Once the vcpu actually blocks, we don't request a doorbell anymore, and the vcpu won't be woken up on interrupt delivery. Fix it by tracking that we're entering WFI, and key the doorbell request on that flag. This allows us not to make the vPE resident when going through a preempt/schedule cycle, meaning we don't lose any state. Cc: stable@vger.kernel.org Fixes: 8e01d9a396e6 ("KVM: arm64: vgic-v4: Move the GICv4 residency flow to be driven by vcpu_load/put") Reported-by: Xiang Chen Suggested-by: Zenghui Yu Tested-by: Xiang Chen Co-developed-by: Oliver Upton Signed-off-by: Marc Zyngier Acked-by: Zenghui Yu Link: https://lore.kernel.org/r/20230713070657.3873244-1-maz@kernel.org Signed-off-by: Oliver Upton --- arch/arm64/include/asm/kvm_host.h | 2 ++ arch/arm64/kvm/arm.c | 6 ++++-- arch/arm64/kvm/vgic/vgic-v3.c | 2 +- arch/arm64/kvm/vgic/vgic-v4.c | 7 +++++-- include/kvm/arm_vgic.h | 2 +- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 8b6096753740..d3dd05bbfe23 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -727,6 +727,8 @@ struct kvm_vcpu_arch { #define DBG_SS_ACTIVE_PENDING __vcpu_single_flag(sflags, BIT(5)) /* PMUSERENR for the guest EL0 is on physical CPU */ #define PMUSERENR_ON_CPU __vcpu_single_flag(sflags, BIT(6)) +/* WFI instruction trapped */ +#define IN_WFI __vcpu_single_flag(sflags, BIT(7)) /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */ diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index a402ea5511f3..72dc53a75d1c 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -718,13 +718,15 @@ void kvm_vcpu_wfi(struct kvm_vcpu *vcpu) */ preempt_disable(); kvm_vgic_vmcr_sync(vcpu); - vgic_v4_put(vcpu, true); + vcpu_set_flag(vcpu, IN_WFI); + vgic_v4_put(vcpu); preempt_enable(); kvm_vcpu_halt(vcpu); vcpu_clear_flag(vcpu, IN_WFIT); preempt_disable(); + vcpu_clear_flag(vcpu, IN_WFI); vgic_v4_load(vcpu); preempt_enable(); } @@ -792,7 +794,7 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu) if (kvm_check_request(KVM_REQ_RELOAD_GICv4, vcpu)) { /* The distributor enable bits were changed */ preempt_disable(); - vgic_v4_put(vcpu, false); + vgic_v4_put(vcpu); vgic_v4_load(vcpu); preempt_enable(); } diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index c3b8e132d599..3dfc8b84e03e 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -749,7 +749,7 @@ void vgic_v3_put(struct kvm_vcpu *vcpu) { struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; - WARN_ON(vgic_v4_put(vcpu, false)); + WARN_ON(vgic_v4_put(vcpu)); vgic_v3_vmcr_sync(vcpu); diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c index c1c28fe680ba..339a55194b2c 100644 --- a/arch/arm64/kvm/vgic/vgic-v4.c +++ b/arch/arm64/kvm/vgic/vgic-v4.c @@ -336,14 +336,14 @@ void vgic_v4_teardown(struct kvm *kvm) its_vm->vpes = NULL; } -int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db) +int vgic_v4_put(struct kvm_vcpu *vcpu) { struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe; if (!vgic_supports_direct_msis(vcpu->kvm) || !vpe->resident) return 0; - return its_make_vpe_non_resident(vpe, need_db); + return its_make_vpe_non_resident(vpe, !!vcpu_get_flag(vcpu, IN_WFI)); } int vgic_v4_load(struct kvm_vcpu *vcpu) @@ -354,6 +354,9 @@ int vgic_v4_load(struct kvm_vcpu *vcpu) if (!vgic_supports_direct_msis(vcpu->kvm) || vpe->resident) return 0; + if (vcpu_get_flag(vcpu, IN_WFI)) + return 0; + /* * Before making the VPE resident, make sure the redistributor * corresponding to our current CPU expects us here. See the diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 402b545959af..5b27f94d4fad 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -431,7 +431,7 @@ int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int irq, int vgic_v4_load(struct kvm_vcpu *vcpu); void vgic_v4_commit(struct kvm_vcpu *vcpu); -int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db); +int vgic_v4_put(struct kvm_vcpu *vcpu); /* CPU HP callbacks */ void kvm_vgic_cpu_up(void); From 69ea4c9d02b7947cdd612335a61cc1a02e544ccd Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Thu, 13 Jul 2023 15:57:13 +0800 Subject: [PATCH 075/272] ALSA: hda/realtek - remove 3k pull low procedure This was the ALC283 depop procedure. Maybe this procedure wasn't suitable with new codec. So, let us remove it. But HP 15z-fc000 must do 3k pull low. If it reboot with plugged headset, it will have errors show don't find codec error messages. Run 3k pull low will solve issues. So, let AMD chipset will run this for workarround. Fixes: 5aec98913095 ("ALSA: hda/realtek - ALC236 headset MIC recording issue") Signed-off-by: Kailang Yang Cc: Reported-by: Joseph C. Sible Closes: https://lore.kernel.org/r/CABpewhE4REgn9RJZduuEU6Z_ijXNeQWnrxO1tg70Gkw=F8qNYg@mail.gmail.com/ Link: https://lore.kernel.org/r/4678992299664babac4403d9978e7ba7@realtek.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e2f8b608de82..afb4d82475b4 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -122,6 +122,7 @@ struct alc_spec { unsigned int ultra_low_power:1; unsigned int has_hs_key:1; unsigned int no_internal_mic_pin:1; + unsigned int en_3kpull_low:1; /* for PLL fix */ hda_nid_t pll_nid; @@ -3622,6 +3623,7 @@ static void alc256_shutup(struct hda_codec *codec) if (!hp_pin) hp_pin = 0x21; + alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); if (hp_pin_sense) @@ -3638,8 +3640,7 @@ static void alc256_shutup(struct hda_codec *codec) /* If disable 3k pulldown control for alc257, the Mic detection will not work correctly * when booting with headset plugged. So skip setting it for the codec alc257 */ - if (codec->core.vendor_id != 0x10ec0236 && - codec->core.vendor_id != 0x10ec0257) + if (spec->en_3kpull_low) alc_update_coef_idx(codec, 0x46, 0, 3 << 12); if (!spec->no_shutup_pins) @@ -10682,6 +10683,8 @@ static int patch_alc269(struct hda_codec *codec) spec->shutup = alc256_shutup; spec->init_hook = alc256_init; spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */ + if (codec->bus->pci->vendor == PCI_VENDOR_ID_AMD) + spec->en_3kpull_low = true; break; case 0x10ec0257: spec->codec_variant = ALC269_TYPE_ALC257; From 9c2dcfc2cf0f2e4e0a0db33bc1a626e35928c475 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 30 May 2023 12:16:39 +0200 Subject: [PATCH 076/272] media: tc358746: Address compiler warnings Address these compiler warnings by initialising the m_best and p_best values to 0 and 1 respectively (as latter is used as a divisor): drivers/media/i2c/tc358746.c: In function 'tc358746_find_pll_settings': >> drivers/media/i2c/tc358746.c:817:13: warning: 'p_best' is used uninitialized [-Wuninitialized] 817 | u16 p_best, p; | ^~~~~~ >> drivers/media/i2c/tc358746.c:816:13: warning: 'm_best' is used uninitialized [-Wuninitialized] 816 | u16 m_best, mul; | ^~~~~~ The warnings may well be a false positive but it is difficult for a compiler to find out whether that truly is the case. Closes: https://lore.kernel.org/oe-kbuild-all/202305301627.fLT3Bkds-lkp@intel.com/ Reported-by: kernel test robot Fixes: 80a21da3605 ("media: tc358746: add Toshiba TC358746 Parallel to CSI-2 bridge driver") Signed-off-by: Sakari Ailus Reviewed-by: Marco Felsch Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tc358746.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/tc358746.c b/drivers/media/i2c/tc358746.c index e9b2d906c177..3f7e147ef594 100644 --- a/drivers/media/i2c/tc358746.c +++ b/drivers/media/i2c/tc358746.c @@ -813,8 +813,8 @@ static unsigned long tc358746_find_pll_settings(struct tc358746 *tc358746, u32 min_delta = 0xffffffff; u16 prediv_max = 17; u16 prediv_min = 1; - u16 m_best, mul; - u16 p_best, p; + u16 m_best = 0, mul; + u16 p_best = 1, p; u8 postdiv; if (fout > 1000 * HZ_PER_MHZ) { From bf4c985707d3168ebb7d87d15830de66949d979c Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 13 Jun 2023 18:47:53 +0200 Subject: [PATCH 077/272] media: staging: atomisp: select V4L2_FWNODE Select V4L2_FWNODE as the driver depends on it. Reported-by: Andy Shevchenko Fixes: aa31f6514047 ("media: atomisp: allow building the driver again") Signed-off-by: Sakari Ailus Tested-by: Andy Shevchenko Reviewed-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/media/atomisp/Kconfig b/drivers/staging/media/atomisp/Kconfig index c9bff98e5309..e9b168ba97bf 100644 --- a/drivers/staging/media/atomisp/Kconfig +++ b/drivers/staging/media/atomisp/Kconfig @@ -13,6 +13,7 @@ config VIDEO_ATOMISP tristate "Intel Atom Image Signal Processor Driver" depends on VIDEO_DEV && INTEL_ATOMISP depends on PMIC_OPREGION + select V4L2_FWNODE select IOSF_MBI select VIDEOBUF2_VMALLOC select VIDEO_V4L2_SUBDEV_API From 517f088385e1b8015606143e6212cb30f8714070 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Tue, 31 Jan 2023 11:32:44 +0100 Subject: [PATCH 078/272] media: amphion: use dev_err_probe This simplifies the code and silences -517 error messages. Also the reason is listed in /sys/kernel/debug/devices_deferred. Signed-off-by: Alexander Stein Reviewed-by: ming_qian Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/amphion/vpu_mbox.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/amphion/vpu_mbox.c b/drivers/media/platform/amphion/vpu_mbox.c index bf759eb2fd46..b6d5b4844f67 100644 --- a/drivers/media/platform/amphion/vpu_mbox.c +++ b/drivers/media/platform/amphion/vpu_mbox.c @@ -46,11 +46,10 @@ static int vpu_mbox_request_channel(struct device *dev, struct vpu_mbox *mbox) cl->rx_callback = vpu_mbox_rx_callback; ch = mbox_request_channel_byname(cl, mbox->name); - if (IS_ERR(ch)) { - dev_err(dev, "Failed to request mbox chan %s, ret : %ld\n", - mbox->name, PTR_ERR(ch)); - return PTR_ERR(ch); - } + if (IS_ERR(ch)) + return dev_err_probe(dev, PTR_ERR(ch), + "Failed to request mbox chan %s\n", + mbox->name); mbox->ch = ch; return 0; From dcff0b56f661b6b42e828012b464d22cc2068c38 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Thu, 25 May 2023 22:10:15 +0200 Subject: [PATCH 079/272] media: amphion: Fix firmware path to match linux-firmware The path did not match the one it was submitted into linux-firmware which prevented generic distribution from having working CODEC. Fixes: 9f599f351e86 ("media: amphion: add vpu core driver") Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/amphion/vpu_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c index 43d85a54268b..7863b7b53494 100644 --- a/drivers/media/platform/amphion/vpu_core.c +++ b/drivers/media/platform/amphion/vpu_core.c @@ -826,7 +826,7 @@ static const struct dev_pm_ops vpu_core_pm_ops = { static struct vpu_core_resources imx8q_enc = { .type = VPU_CORE_TYPE_ENC, - .fwname = "vpu/vpu_fw_imx8_enc.bin", + .fwname = "amphion/vpu/vpu_fw_imx8_enc.bin", .stride = 16, .max_width = 1920, .max_height = 1920, @@ -841,7 +841,7 @@ static struct vpu_core_resources imx8q_enc = { static struct vpu_core_resources imx8q_dec = { .type = VPU_CORE_TYPE_DEC, - .fwname = "vpu/vpu_fw_imx8_dec.bin", + .fwname = "amphion/vpu/vpu_fw_imx8_dec.bin", .stride = 256, .max_width = 8188, .max_height = 8188, From 53ebeea50599c1ed05277d7a57e331a34e6d6a82 Mon Sep 17 00:00:00 2001 From: Ming Qian Date: Tue, 30 May 2023 09:16:30 +0200 Subject: [PATCH 080/272] media: imx-jpeg: Support to assign slot for encoder/decoder imx jpeg encoder and decoder support 4 slots each, aim to support some virtualization scenarios. driver should only enable one slot one time. but due to some hardware issue, only slot 0 can be enabled in imx8q platform, and they may be fixed in imx9 platform. Signed-off-by: Ming Qian Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h | 1 - .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 135 +++++++++--------- .../media/platform/nxp/imx-jpeg/mxc-jpeg.h | 5 +- 3 files changed, 68 insertions(+), 73 deletions(-) diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h index ed15ea348f97..a2b4fb9e29e7 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h @@ -58,7 +58,6 @@ #define CAST_OFBSIZE_LO CAST_STATUS18 #define CAST_OFBSIZE_HI CAST_STATUS19 -#define MXC_MAX_SLOTS 1 /* TODO use all 4 slots*/ /* JPEG-Decoder Wrapper Slot Registers 0..3 */ #define SLOT_BASE 0x10000 #define SLOT_STATUS 0x0 diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index c0e49be42450..9512c0a61966 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -745,87 +745,77 @@ static void notify_src_chg(struct mxc_jpeg_ctx *ctx) v4l2_event_queue_fh(&ctx->fh, &ev); } -static int mxc_get_free_slot(struct mxc_jpeg_slot_data slot_data[], int n) +static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data) { - int free_slot = 0; - - while (slot_data[free_slot].used && free_slot < n) - free_slot++; - - return free_slot; /* >=n when there are no more free slots */ + if (!slot_data->used) + return slot_data->slot; + return -1; } -static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg, - unsigned int slot) +static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg) { struct mxc_jpeg_desc *desc; struct mxc_jpeg_desc *cfg_desc; void *cfg_stm; - if (jpeg->slot_data[slot].desc) + if (jpeg->slot_data.desc) goto skip_alloc; /* already allocated, reuse it */ /* allocate descriptor for decoding/encoding phase */ desc = dma_alloc_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), - &jpeg->slot_data[slot].desc_handle, + &jpeg->slot_data.desc_handle, GFP_ATOMIC); if (!desc) goto err; - jpeg->slot_data[slot].desc = desc; + jpeg->slot_data.desc = desc; /* allocate descriptor for configuration phase (encoder only) */ cfg_desc = dma_alloc_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), - &jpeg->slot_data[slot].cfg_desc_handle, + &jpeg->slot_data.cfg_desc_handle, GFP_ATOMIC); if (!cfg_desc) goto err; - jpeg->slot_data[slot].cfg_desc = cfg_desc; + jpeg->slot_data.cfg_desc = cfg_desc; /* allocate configuration stream */ cfg_stm = dma_alloc_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM, - &jpeg->slot_data[slot].cfg_stream_handle, + &jpeg->slot_data.cfg_stream_handle, GFP_ATOMIC); if (!cfg_stm) goto err; - jpeg->slot_data[slot].cfg_stream_vaddr = cfg_stm; + jpeg->slot_data.cfg_stream_vaddr = cfg_stm; skip_alloc: - jpeg->slot_data[slot].used = true; + jpeg->slot_data.used = true; return true; err: - dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", slot); + dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot); return false; } -static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg, - unsigned int slot) +static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg) { - if (slot >= MXC_MAX_SLOTS) { - dev_err(jpeg->dev, "Invalid slot %d, nothing to free.", slot); - return; - } - /* free descriptor for decoding/encoding phase */ dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), - jpeg->slot_data[slot].desc, - jpeg->slot_data[slot].desc_handle); + jpeg->slot_data.desc, + jpeg->slot_data.desc_handle); /* free descriptor for encoder configuration phase / decoder DHT */ dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), - jpeg->slot_data[slot].cfg_desc, - jpeg->slot_data[slot].cfg_desc_handle); + jpeg->slot_data.cfg_desc, + jpeg->slot_data.cfg_desc_handle); /* free configuration stream */ dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM, - jpeg->slot_data[slot].cfg_stream_vaddr, - jpeg->slot_data[slot].cfg_stream_handle); + jpeg->slot_data.cfg_stream_vaddr, + jpeg->slot_data.cfg_stream_handle); - jpeg->slot_data[slot].used = false; + jpeg->slot_data.used = false; } static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx, @@ -855,7 +845,7 @@ static void mxc_jpeg_job_finish(struct mxc_jpeg_ctx *ctx, enum vb2_buffer_state v4l2_m2m_buf_done(dst_buf, state); mxc_jpeg_disable_irq(reg, ctx->slot); - ctx->mxc_jpeg->slot_data[ctx->slot].used = false; + jpeg->slot_data.used = false; if (reset) mxc_jpeg_sw_reset(reg); } @@ -919,7 +909,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) goto job_unlock; } - if (!jpeg->slot_data[slot].used) + if (!jpeg->slot_data.used) goto job_unlock; dec_ret = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS)); @@ -1179,13 +1169,13 @@ static void mxc_jpeg_config_dec_desc(struct vb2_buffer *out_buf, struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; void __iomem *reg = jpeg->base_reg; unsigned int slot = ctx->slot; - struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc; - struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc; - dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle; - dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle; - dma_addr_t cfg_stream_handle = jpeg->slot_data[slot].cfg_stream_handle; - unsigned int *cfg_size = &jpeg->slot_data[slot].cfg_stream_size; - void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr; + struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; + struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; + dma_addr_t desc_handle = jpeg->slot_data.desc_handle; + dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; + dma_addr_t cfg_stream_handle = jpeg->slot_data.cfg_stream_handle; + unsigned int *cfg_size = &jpeg->slot_data.cfg_stream_size; + void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; struct mxc_jpeg_src_buf *jpeg_src_buf; jpeg_src_buf = vb2_to_mxc_buf(src_buf); @@ -1245,18 +1235,18 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf, struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; void __iomem *reg = jpeg->base_reg; unsigned int slot = ctx->slot; - struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc; - struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc; - dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle; - dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle; - void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr; + struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; + struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; + dma_addr_t desc_handle = jpeg->slot_data.desc_handle; + dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; + void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; struct mxc_jpeg_q_data *q_data; enum mxc_jpeg_image_format img_fmt; int w, h; q_data = mxc_jpeg_get_q_data(ctx, src_buf->vb2_queue->type); - jpeg->slot_data[slot].cfg_stream_size = + jpeg->slot_data.cfg_stream_size = mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr, q_data->fmt->fourcc, q_data->crop.width, @@ -1265,7 +1255,7 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf, /* chain the config descriptor with the encoding descriptor */ cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN; - cfg_desc->buf_base0 = jpeg->slot_data[slot].cfg_stream_handle; + cfg_desc->buf_base0 = jpeg->slot_data.cfg_stream_handle; cfg_desc->buf_base1 = 0; cfg_desc->line_pitch = 0; cfg_desc->stm_bufbase = 0; /* no output expected */ @@ -1408,7 +1398,7 @@ static void mxc_jpeg_device_run_timeout(struct work_struct *work) unsigned long flags; spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); - if (ctx->slot < MXC_MAX_SLOTS && ctx->mxc_jpeg->slot_data[ctx->slot].used) { + if (ctx->mxc_jpeg->slot_data.used) { dev_warn(jpeg->dev, "%s timeout, cancel it\n", ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? "decode" : "encode"); mxc_jpeg_job_finish(ctx, VB2_BUF_STATE_ERROR, true); @@ -1476,12 +1466,12 @@ static void mxc_jpeg_device_run(void *priv) mxc_jpeg_enable(reg); mxc_jpeg_set_l_endian(reg, 1); - ctx->slot = mxc_get_free_slot(jpeg->slot_data, MXC_MAX_SLOTS); - if (ctx->slot >= MXC_MAX_SLOTS) { + ctx->slot = mxc_get_free_slot(&jpeg->slot_data); + if (ctx->slot < 0) { dev_err(dev, "No more free slots\n"); goto end; } - if (!mxc_jpeg_alloc_slot_data(jpeg, ctx->slot)) { + if (!mxc_jpeg_alloc_slot_data(jpeg)) { dev_err(dev, "Cannot allocate slot data\n"); goto end; } @@ -2101,7 +2091,7 @@ static int mxc_jpeg_open(struct file *file) } ctx->fh.ctrl_handler = &ctx->ctrl_handler; mxc_jpeg_set_default_params(ctx); - ctx->slot = MXC_MAX_SLOTS; /* slot not allocated yet */ + ctx->slot = -1; /* slot not allocated yet */ INIT_DELAYED_WORK(&ctx->task_timer, mxc_jpeg_device_run_timeout); if (mxc_jpeg->mode == MXC_JPEG_DECODE) @@ -2677,6 +2667,11 @@ static int mxc_jpeg_attach_pm_domains(struct mxc_jpeg_dev *jpeg) dev_err(dev, "No power domains defined for jpeg node\n"); return jpeg->num_domains; } + if (jpeg->num_domains == 1) { + /* genpd_dev_pm_attach() attach automatically if power domains count is 1 */ + jpeg->num_domains = 0; + return 0; + } jpeg->pd_dev = devm_kmalloc_array(dev, jpeg->num_domains, sizeof(*jpeg->pd_dev), GFP_KERNEL); @@ -2718,7 +2713,6 @@ static int mxc_jpeg_probe(struct platform_device *pdev) int ret; int mode; const struct of_device_id *of_id; - unsigned int slot; of_id = of_match_node(mxc_jpeg_match, dev->of_node); if (!of_id) @@ -2742,19 +2736,22 @@ static int mxc_jpeg_probe(struct platform_device *pdev) if (IS_ERR(jpeg->base_reg)) return PTR_ERR(jpeg->base_reg); - for (slot = 0; slot < MXC_MAX_SLOTS; slot++) { - dec_irq = platform_get_irq(pdev, slot); - if (dec_irq < 0) { - ret = dec_irq; - goto err_irq; - } - ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq, - 0, pdev->name, jpeg); - if (ret) { - dev_err(&pdev->dev, "Failed to request irq %d (%d)\n", - dec_irq, ret); - goto err_irq; - } + ret = of_property_read_u32_index(pdev->dev.of_node, "slot", 0, &jpeg->slot_data.slot); + if (ret) + jpeg->slot_data.slot = 0; + dev_info(&pdev->dev, "choose slot %d\n", jpeg->slot_data.slot); + dec_irq = platform_get_irq(pdev, 0); + if (dec_irq < 0) { + dev_err(&pdev->dev, "Failed to get irq %d\n", dec_irq); + ret = dec_irq; + goto err_irq; + } + ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq, + 0, pdev->name, jpeg); + if (ret) { + dev_err(&pdev->dev, "Failed to request irq %d (%d)\n", + dec_irq, ret); + goto err_irq; } jpeg->pdev = pdev; @@ -2914,11 +2911,9 @@ static const struct dev_pm_ops mxc_jpeg_pm_ops = { static void mxc_jpeg_remove(struct platform_device *pdev) { - unsigned int slot; struct mxc_jpeg_dev *jpeg = platform_get_drvdata(pdev); - for (slot = 0; slot < MXC_MAX_SLOTS; slot++) - mxc_jpeg_free_slot_data(jpeg, slot); + mxc_jpeg_free_slot_data(jpeg); pm_runtime_disable(&pdev->dev); video_unregister_device(jpeg->dec_vdev); diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h index 87157db78082..d80e94cc9d99 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h @@ -97,7 +97,7 @@ struct mxc_jpeg_ctx { struct mxc_jpeg_q_data cap_q; struct v4l2_fh fh; enum mxc_jpeg_enc_state enc_state; - unsigned int slot; + int slot; unsigned int source_change; bool header_parsed; struct v4l2_ctrl_handler ctrl_handler; @@ -106,6 +106,7 @@ struct mxc_jpeg_ctx { }; struct mxc_jpeg_slot_data { + int slot; bool used; struct mxc_jpeg_desc *desc; // enc/dec descriptor struct mxc_jpeg_desc *cfg_desc; // configuration descriptor @@ -128,7 +129,7 @@ struct mxc_jpeg_dev { struct v4l2_device v4l2_dev; struct v4l2_m2m_dev *m2m_dev; struct video_device *dec_vdev; - struct mxc_jpeg_slot_data slot_data[MXC_MAX_SLOTS]; + struct mxc_jpeg_slot_data slot_data; int num_domains; struct device **pd_dev; struct device_link **pd_link; From 20de9fdaf4883deffb0138eef28e9cbbead32cfd Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 1 Jun 2023 23:37:22 +0200 Subject: [PATCH 081/272] media: mtk_jpeg_core: avoid unused-variable warning The mtk8195_jpegenc_drvdata object was added outside of an #ifdef causing a harmless build warning. drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:1879:32: error: 'mtk8195_jpegenc_drvdata' defined but not used [-Werror=unused-variable] 1879 | static struct mtk_jpeg_variant mtk8195_jpegenc_drvdata = { | ^~~~~~~~~~~~~~~~~~~~~~~ A follow-up patch moved it inside of an #ifdef, which caused more warnings, and a third patch ended up adding even more #ifdefs. These were all bogus, since the actual problem here is the incorrect use of of_ptr(). Since the driver (like any other modern platform driver) only works in combination with CONFIG_OF, there is no point in hiding the reference, so just remove that along with all the pointless #ifdef checks in the driver. This improves build coverage and avoids running into the same problem again when another part of the driver gets changed that relies on the #ifdef blocks to be completely matched. Fixes: 934e8bccac95 ("mtk-jpegenc: support jpegenc multi-hardware") Fixes: 4ae47770d57b ("media: mtk-jpegenc: Fix a compilation issue") Fixes: da4ede4b7fd6 ("media: mtk-jpeg: move data/code inside CONFIG_OF blocks") Signed-off-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 6 +----- drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 4 +--- drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 4 +--- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index 4768156181c9..40cb3cb87ba1 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -28,7 +28,6 @@ #include "mtk_jpeg_core.h" #include "mtk_jpeg_dec_parse.h" -#if defined(CONFIG_OF) static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = { { .fourcc = V4L2_PIX_FMT_JPEG, @@ -102,7 +101,6 @@ static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = { .flags = MTK_JPEG_FMT_FLAG_CAPTURE, }, }; -#endif #define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats) #define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats) @@ -1455,7 +1453,6 @@ static const struct dev_pm_ops mtk_jpeg_pm_ops = { SET_RUNTIME_PM_OPS(mtk_jpeg_pm_suspend, mtk_jpeg_pm_resume, NULL) }; -#if defined(CONFIG_OF) static int mtk_jpegenc_get_hw(struct mtk_jpeg_ctx *ctx) { struct mtk_jpegenc_comp_dev *comp_jpeg; @@ -1951,14 +1948,13 @@ static const struct of_device_id mtk_jpeg_match[] = { }; MODULE_DEVICE_TABLE(of, mtk_jpeg_match); -#endif static struct platform_driver mtk_jpeg_driver = { .probe = mtk_jpeg_probe, .remove_new = mtk_jpeg_remove, .driver = { .name = MTK_JPEG_NAME, - .of_match_table = of_match_ptr(mtk_jpeg_match), + .of_match_table = mtk_jpeg_match, .pm = &mtk_jpeg_pm_ops, }, }; diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c index 869068fac5e2..baa7be58ce69 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c @@ -39,7 +39,6 @@ enum mtk_jpeg_color { MTK_JPEG_COLOR_400 = 0x00110000 }; -#if defined(CONFIG_OF) static const struct of_device_id mtk_jpegdec_hw_ids[] = { { .compatible = "mediatek,mt8195-jpgdec-hw", @@ -47,7 +46,6 @@ static const struct of_device_id mtk_jpegdec_hw_ids[] = { {}, }; MODULE_DEVICE_TABLE(of, mtk_jpegdec_hw_ids); -#endif static inline int mtk_jpeg_verify_align(u32 val, int align, u32 reg) { @@ -653,7 +651,7 @@ static struct platform_driver mtk_jpegdec_hw_driver = { .probe = mtk_jpegdec_hw_probe, .driver = { .name = "mtk-jpegdec-hw", - .of_match_table = of_match_ptr(mtk_jpegdec_hw_ids), + .of_match_table = mtk_jpegdec_hw_ids, }, }; diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c index 71e85b4bbf12..244018365b6f 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c @@ -46,7 +46,6 @@ static const struct mtk_jpeg_enc_qlt mtk_jpeg_enc_quality[] = { {.quality_param = 97, .hardware_value = JPEG_ENC_QUALITY_Q97}, }; -#if defined(CONFIG_OF) static const struct of_device_id mtk_jpegenc_drv_ids[] = { { .compatible = "mediatek,mt8195-jpgenc-hw", @@ -54,7 +53,6 @@ static const struct of_device_id mtk_jpegenc_drv_ids[] = { {}, }; MODULE_DEVICE_TABLE(of, mtk_jpegenc_drv_ids); -#endif void mtk_jpeg_enc_reset(void __iomem *base) { @@ -377,7 +375,7 @@ static struct platform_driver mtk_jpegenc_hw_driver = { .probe = mtk_jpegenc_hw_probe, .driver = { .name = "mtk-jpegenc-hw", - .of_match_table = of_match_ptr(mtk_jpegenc_drv_ids), + .of_match_table = mtk_jpegenc_drv_ids, }, }; From 92cbf865ea2e0f2997ff97815c6db182eb23df1b Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 6 Jun 2023 06:38:15 +0200 Subject: [PATCH 082/272] media: pulse8-cec: handle possible ping error Handle (and warn about) possible error waiting for MSGCODE_PING result. Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Dmitry Antipov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/usb/pulse8/pulse8-cec.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/cec/usb/pulse8/pulse8-cec.c b/drivers/media/cec/usb/pulse8/pulse8-cec.c index 04b13cdc38d2..ba67587bd43e 100644 --- a/drivers/media/cec/usb/pulse8/pulse8-cec.c +++ b/drivers/media/cec/usb/pulse8/pulse8-cec.c @@ -809,8 +809,11 @@ static void pulse8_ping_eeprom_work_handler(struct work_struct *work) mutex_lock(&pulse8->lock); cmd = MSGCODE_PING; - pulse8_send_and_wait(pulse8, &cmd, 1, - MSGCODE_COMMAND_ACCEPTED, 0); + if (pulse8_send_and_wait(pulse8, &cmd, 1, + MSGCODE_COMMAND_ACCEPTED, 0)) { + dev_warn(pulse8->dev, "failed to ping EEPROM\n"); + goto unlock; + } if (pulse8->vers < 2) goto unlock; From 4aaa96b59df5fac41ba891969df6b092061ea9d7 Mon Sep 17 00:00:00 2001 From: Nikolay Burykin Date: Tue, 10 Jan 2023 10:09:00 +0100 Subject: [PATCH 083/272] media: pci: cx23885: fix error handling for cx23885 ATSC boards After having been assigned to NULL value at cx23885-dvb.c:1202, pointer '0' is dereferenced at cx23885-dvb.c:2469. Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Nikolay Burykin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-dvb.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 8fd5b6ef2428..7551ca4a322a 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -2459,16 +2459,10 @@ static int dvb_register(struct cx23885_tsport *port) request_module("%s", info.type); client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info); if (!i2c_client_has_driver(client_tuner)) { - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } if (!try_module_get(client_tuner->dev.driver->owner)) { i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } port->i2c_client_tuner = client_tuner; @@ -2505,16 +2499,10 @@ static int dvb_register(struct cx23885_tsport *port) request_module("%s", info.type); client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info); if (!i2c_client_has_driver(client_tuner)) { - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } if (!try_module_get(client_tuner->dev.driver->owner)) { i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } port->i2c_client_tuner = client_tuner; From d05dea76d4a813eb959ba0a150c45246d54e7148 Mon Sep 17 00:00:00 2001 From: Yunfei Dong Date: Mon, 12 Jun 2023 05:15:57 +0200 Subject: [PATCH 084/272] media: mediatek: vcodec: fix cancel_work_sync fail with fluster test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Will cause below warning then reboot when exercising the decoder with fluster on mt8192-asurada-spherion. This deinit function is called on the v4l2 release callback, even though the work might not have been initialized as that only happens if/when the codec specific 'decode' callback is called (as a result of device_run m2m callback). CPU: 5 PID: 2338 Comm: gst-launch-1.0 Tainted: G W 6.4.0-rc5-next-20230607+ #475 Hardware name: Google Spherion (rev0 - 3) (DT) pstate: 00400009 (nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __flush_work.isra.0+0x23c/0x258 lr : __cancel_work_timer+0x14c/0x1c8 sp : ffff8000896e3b00 x29: ffff8000896e3b00 x28: ffff57c3d4079f80 x27: 0000000000000000 x26: ffff57c3d4079f80 x25: ffffb76395b59dc8 x24: 0000000000000001 x23: ffffb763928daab8 x22: ffff57c3d4079f80 x21: 0000000000000000 x20: ffffb763955f6778 x19: ffff57c3cf06f4a0 x18: 0000000000000000 x17: 000000040044ffff x16: 005000f2b5503510 x15: 0000000000000000 x14: ffff57c3c03a1f80 x13: ffffa0616a2fc000 x12: 000000003464d91d x11: 0000000000000000 x10: 0000000000001b10 x9 : ffffb763928de61c x8 : ffff57c3d407baf0 x7 : 0000000000000000 x6 : ffff57c3d4079f80 x5 : ffff57c3d4079f80 x4 : 0000000000000000 x3 : 0000000000000000 x2 : ffff8000896e3bf0 x1 : 0000000000000011 x0 : 0000000000000000 Call trace: __flush_work.isra.0+0x23c/0x258 __cancel_work_timer+0x14c/0x1c8 cancel_work_sync+0x1c/0x30 vdec_msg_queue_deinit+0xac/0xc8 vdec_h264_slice_deinit+0x64/0xb8 vdec_if_deinit+0x3c/0x68 mtk_vcodec_dec_release+0x20/0x40 fops_vcodec_release+0x50/0xd8 v4l2_release+0x7c/0x100 __fput+0x80/0x270 ____fput+0x18/0x30 task_work_run+0x78/0xe0 do_notify_resume+0x29c/0x7f8 el0_svc+0xa4/0xb8 el0t_64_sync_handler+0xc0/0xc8 el0t_64_sync+0x1a8/0x1b0 ---[ end trace 0000000000000000 ]--- Fixes: 297160d411e3 ("media: mediatek: vcodec: move core context from device to each instance") Reported-by: Nícolas F. R. A. Prado Signed-off-by: Yunfei Dong Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c index f555341ae708..04e6dc6cfa1d 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c +++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c @@ -233,7 +233,8 @@ void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue, kfree(lat_buf->private_data); } - cancel_work_sync(&msg_queue->core_work); + if (msg_queue->wdma_addr.size) + cancel_work_sync(&msg_queue->core_work); } static void vdec_msg_queue_core_work(struct work_struct *work) From 7ee8acd1b803502878992acd6f99e61f1e8c7a25 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 16 Jun 2023 16:48:47 +0200 Subject: [PATCH 085/272] media: verisilicon: fix excessive stack usage In some configurations, gcc decides not to inline the register accessor functions, which in turn leads to lots of temporary hantro_reg structures on the stack that cannot be eliminated because they escape into an uninlined function: drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c:1022:1: warning: the frame size of 1112 bytes is larger than 1024 bytes [-Wframe-larger-than=] Mark all of these as __always_inline so the compiler is able to completely eliminate the temporary structures instead, which brings the stack usage back down to just the normal local variables. Closes: https://lore.kernel.org/oe-kbuild-all/202306151506.goHEegOd-lkp@intel.com/ [hverkuil: fix function prototype alignment, wrap commit log] Reported-by: kernel test robot Fixes: 727a400686a2 ("media: verisilicon: Add Rockchip AV1 decoder") Signed-off-by: Arnd Bergmann Reviewed-by: Nicolas Dufresne Tested-by: Nathan Chancellor Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/verisilicon/hantro.h | 42 ++++++++++----------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h index 6523ffb74881..1afec3df8c73 100644 --- a/drivers/media/platform/verisilicon/hantro.h +++ b/drivers/media/platform/verisilicon/hantro.h @@ -370,26 +370,26 @@ extern int hantro_debug; pr_err("%s:%d: " fmt, __func__, __LINE__, ##args) /* Structure access helpers. */ -static inline struct hantro_ctx *fh_to_ctx(struct v4l2_fh *fh) +static __always_inline struct hantro_ctx *fh_to_ctx(struct v4l2_fh *fh) { return container_of(fh, struct hantro_ctx, fh); } /* Register accessors. */ -static inline void vepu_write_relaxed(struct hantro_dev *vpu, - u32 val, u32 reg) +static __always_inline void vepu_write_relaxed(struct hantro_dev *vpu, + u32 val, u32 reg) { vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); writel_relaxed(val, vpu->enc_base + reg); } -static inline void vepu_write(struct hantro_dev *vpu, u32 val, u32 reg) +static __always_inline void vepu_write(struct hantro_dev *vpu, u32 val, u32 reg) { vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); writel(val, vpu->enc_base + reg); } -static inline u32 vepu_read(struct hantro_dev *vpu, u32 reg) +static __always_inline u32 vepu_read(struct hantro_dev *vpu, u32 reg) { u32 val = readl(vpu->enc_base + reg); @@ -397,27 +397,27 @@ static inline u32 vepu_read(struct hantro_dev *vpu, u32 reg) return val; } -static inline void vdpu_write_relaxed(struct hantro_dev *vpu, - u32 val, u32 reg) +static __always_inline void vdpu_write_relaxed(struct hantro_dev *vpu, + u32 val, u32 reg) { vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); writel_relaxed(val, vpu->dec_base + reg); } -static inline void vdpu_write(struct hantro_dev *vpu, u32 val, u32 reg) +static __always_inline void vdpu_write(struct hantro_dev *vpu, u32 val, u32 reg) { vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); writel(val, vpu->dec_base + reg); } -static inline void hantro_write_addr(struct hantro_dev *vpu, - unsigned long offset, - dma_addr_t addr) +static __always_inline void hantro_write_addr(struct hantro_dev *vpu, + unsigned long offset, + dma_addr_t addr) { vdpu_write(vpu, addr & 0xffffffff, offset); } -static inline u32 vdpu_read(struct hantro_dev *vpu, u32 reg) +static __always_inline u32 vdpu_read(struct hantro_dev *vpu, u32 reg) { u32 val = readl(vpu->dec_base + reg); @@ -425,9 +425,9 @@ static inline u32 vdpu_read(struct hantro_dev *vpu, u32 reg) return val; } -static inline u32 vdpu_read_mask(struct hantro_dev *vpu, - const struct hantro_reg *reg, - u32 val) +static __always_inline u32 vdpu_read_mask(struct hantro_dev *vpu, + const struct hantro_reg *reg, + u32 val) { u32 v; @@ -437,16 +437,16 @@ static inline u32 vdpu_read_mask(struct hantro_dev *vpu, return v; } -static inline void hantro_reg_write(struct hantro_dev *vpu, - const struct hantro_reg *reg, - u32 val) +static __always_inline void hantro_reg_write(struct hantro_dev *vpu, + const struct hantro_reg *reg, + u32 val) { vdpu_write_relaxed(vpu, vdpu_read_mask(vpu, reg, val), reg->base); } -static inline void hantro_reg_write_s(struct hantro_dev *vpu, - const struct hantro_reg *reg, - u32 val) +static __always_inline void hantro_reg_write_s(struct hantro_dev *vpu, + const struct hantro_reg *reg, + u32 val) { vdpu_write(vpu, vdpu_read_mask(vpu, reg, val), reg->base); } From 0cb1d9c845110ce638a43a1417c7df5968d1daa3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 16 Jun 2023 16:48:48 +0200 Subject: [PATCH 086/272] media: verisilicon: change confusingly named relaxed register access The register abstraction has wrappers around both the normal writel() and its writel_relaxed() counterpart, but this has led to a lot of users ending up with the relaxed version. There is sometimes a need to intentionally pick the relaxed accessor for performance critical functions, but I noticed that each hantro_reg_write() call also contains a non-relaxed readl(), which is typically much more expensive than a writel, so there is little benefit here but an added risk of missing a serialization against DMA. To make this behave like other interfaces, use the normal accessor by default and only provide the relaxed version as an alternative for performance critical code. hantro_postproc.c is the only place that used both the relaxed and normal writel, but this does not seem cricital either, so change it all to the normal ones. [hverkuil: fix function prototype alignment] Signed-off-by: Arnd Bergmann Tested-by: Benjamin Gaignard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/verisilicon/hantro.h | 10 +++++----- drivers/media/platform/verisilicon/hantro_postproc.c | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h index 1afec3df8c73..77aee9489516 100644 --- a/drivers/media/platform/verisilicon/hantro.h +++ b/drivers/media/platform/verisilicon/hantro.h @@ -441,14 +441,14 @@ static __always_inline void hantro_reg_write(struct hantro_dev *vpu, const struct hantro_reg *reg, u32 val) { - vdpu_write_relaxed(vpu, vdpu_read_mask(vpu, reg, val), reg->base); + vdpu_write(vpu, vdpu_read_mask(vpu, reg, val), reg->base); } -static __always_inline void hantro_reg_write_s(struct hantro_dev *vpu, - const struct hantro_reg *reg, - u32 val) +static __always_inline void hantro_reg_write_relaxed(struct hantro_dev *vpu, + const struct hantro_reg *reg, + u32 val) { - vdpu_write(vpu, vdpu_read_mask(vpu, reg, val), reg->base); + vdpu_write_relaxed(vpu, vdpu_read_mask(vpu, reg, val), reg->base); } void *hantro_get_ctrl(struct hantro_ctx *ctx, u32 id); diff --git a/drivers/media/platform/verisilicon/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c index c977d64105b1..0224ff68ab3f 100644 --- a/drivers/media/platform/verisilicon/hantro_postproc.c +++ b/drivers/media/platform/verisilicon/hantro_postproc.c @@ -21,11 +21,11 @@ val); \ } -#define HANTRO_PP_REG_WRITE_S(vpu, reg_name, val) \ +#define HANTRO_PP_REG_WRITE_RELAXED(vpu, reg_name, val) \ { \ - hantro_reg_write_s(vpu, \ - &hantro_g1_postproc_regs.reg_name, \ - val); \ + hantro_reg_write_relaxed(vpu, \ + &hantro_g1_postproc_regs.reg_name, \ + val); \ } #define VPU_PP_IN_YUYV 0x0 @@ -72,7 +72,7 @@ static void hantro_postproc_g1_enable(struct hantro_ctx *ctx) dma_addr_t dst_dma; /* Turn on pipeline mode. Must be done first. */ - HANTRO_PP_REG_WRITE_S(vpu, pipeline_en, 0x1); + HANTRO_PP_REG_WRITE(vpu, pipeline_en, 0x1); src_pp_fmt = VPU_PP_IN_NV12; @@ -242,7 +242,7 @@ static void hantro_postproc_g1_disable(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; - HANTRO_PP_REG_WRITE_S(vpu, pipeline_en, 0x0); + HANTRO_PP_REG_WRITE(vpu, pipeline_en, 0x0); } static void hantro_postproc_g2_disable(struct hantro_ctx *ctx) From cc8ff2dfcb948f16267335ba5440a42abb41aee2 Mon Sep 17 00:00:00 2001 From: Derek Fang Date: Wed, 12 Jul 2023 14:25:53 +0800 Subject: [PATCH 087/272] ASoC: rt5640: Fix the issue of speaker noise Remove the class-D internal register setting during initialization to be compatible with most speaker designs to avoid noise. Signed-off-by: Derek Fang Link: https://lore.kernel.org/r/20230712062553.31066-1-derek.fang@realtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index e24ed754ac56..eceed8209787 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -53,7 +53,6 @@ static const struct reg_sequence init_list[] = { {RT5640_PR_BASE + 0x3d, 0x3600}, {RT5640_PR_BASE + 0x12, 0x0aa8}, {RT5640_PR_BASE + 0x14, 0x0aaa}, - {RT5640_PR_BASE + 0x20, 0x6110}, {RT5640_PR_BASE + 0x21, 0xe0e0}, {RT5640_PR_BASE + 0x23, 0x1804}, }; From 8b58f757cd1c712b5f081e4c26b13611298dfb07 Mon Sep 17 00:00:00 2001 From: Thomas GENTY Date: Fri, 14 Jul 2023 12:51:17 +0200 Subject: [PATCH 088/272] platform/x86: touchscreen_dmi.c: small changes for Archos 101 Cesium Educ tablet Fix the axes and add home button support as suggested by Hans de Goede. Signed-off-by: Thomas GENTY Link: https://lore.kernel.org/r/20230714105117.192938-1-tomlohave@gmail.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/touchscreen_dmi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c index a5b687eed8f3..f9301a9382e7 100644 --- a/drivers/platform/x86/touchscreen_dmi.c +++ b/drivers/platform/x86/touchscreen_dmi.c @@ -27,11 +27,12 @@ struct ts_dmi_data { /* NOTE: Please keep all entries sorted alphabetically */ static const struct property_entry archos_101_cesium_educ_props[] = { - PROPERTY_ENTRY_U32("touchscreen-size-x", 1280), - PROPERTY_ENTRY_U32("touchscreen-size-y", 1850), - PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"), + PROPERTY_ENTRY_U32("touchscreen-size-x", 1850), + PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), + PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_U32("silead,max-fingers", 10), + PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-archos-101-cesium-educ.fw"), { } }; From f2ae72541d52a0bf50366840fe2238aaf111f7ae Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 11 Jul 2023 11:59:20 +0200 Subject: [PATCH 089/272] platform/x86/amd: pmc: Use release_mem_region() to undo request_mem_region_muxed() Muxed (mem) regions will wait in request_mem_region_muxed() if the region is busy (in use by another consumer) during the call. In order to wake-up possibly waiting other consumers of the region, it must be released by a release_mem_region() call, which will actually wake up any waiters. release_mem_region() also frees the resource created by request_mem_region_muxed(), avoiding the need for the unmatched kfree(). Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko Reviewed-by: Mario Limonciello Link: https://lore.kernel.org/r/20230711095920.264308-1-hdegoede@redhat.com --- drivers/platform/x86/amd/pmc-quirks.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/platform/x86/amd/pmc-quirks.c b/drivers/platform/x86/amd/pmc-quirks.c index 362e7c0097d7..ad702463a65d 100644 --- a/drivers/platform/x86/amd/pmc-quirks.c +++ b/drivers/platform/x86/amd/pmc-quirks.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "pmc.h" @@ -135,12 +134,10 @@ static const struct dmi_system_id fwbug_list[] = { */ static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio) { - struct resource *res; void __iomem *addr; u8 val; - res = request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80"); - if (!res) + if (!request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80")) return; addr = ioremap(s2idle_bug_mmio, 1); @@ -152,8 +149,7 @@ static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio) iounmap(addr); cleanup_resource: - release_resource(res); - kfree(res); + release_mem_region(s2idle_bug_mmio, 1); } void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev) From ea33cb6fc2788f9fe248d49e1c0b2553a58436ef Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 11 Jul 2023 11:20:44 +0300 Subject: [PATCH 090/272] accel/qaic: tighten bounds checking in encode_message() There are several issues in this code. The check at the start of the loop: if (user_len >= user_msg->len) { This check does not ensure that we have enough space for the trans_hdr (8 bytes). Instead the check needs to be: if (user_len > user_msg->len - sizeof(*trans_hdr)) { That subtraction is done as an unsigned long we want to avoid negatives. Add a lower bound to the start of the function. if (user_msg->len < sizeof(*trans_hdr)) There is a second integer underflow which can happen if trans_hdr->len is zero inside the encode_passthrough() function. memcpy(out_trans->data, in_trans->data, in_trans->hdr.len - sizeof(in_trans->hdr)); Instead of adding a check to encode_passthrough() it's better to check in this central place. Add that check: if (trans_hdr->len < sizeof(trans_hdr) The final concern is that the "user_len + trans_hdr->len" might have an integer overflow bug. Use size_add() to prevent that. - if (user_len + trans_hdr->len > user_msg->len) { + if (size_add(user_len, trans_hdr->len) > user_msg->len) { Fixes: 129776ac2e38 ("accel/qaic: Add control path") Signed-off-by: Dan Carpenter Reviewed-by: Pranjal Ramajor Asha Kanojiya Reviewed-by: Jeffrey Hugo Cc: stable@vger.kernel.org # 6.4.x Signed-off-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/9a0cb0c1-a974-4f10-bc8d-94437983639a@moroto.mountain --- drivers/accel/qaic/qaic_control.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/accel/qaic/qaic_control.c b/drivers/accel/qaic/qaic_control.c index 5c57f7b4494e..2fdd5959c52f 100644 --- a/drivers/accel/qaic/qaic_control.c +++ b/drivers/accel/qaic/qaic_control.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -748,7 +749,8 @@ static int encode_message(struct qaic_device *qdev, struct manage_msg *user_msg, int ret; int i; - if (!user_msg->count) { + if (!user_msg->count || + user_msg->len < sizeof(*trans_hdr)) { ret = -EINVAL; goto out; } @@ -765,12 +767,13 @@ static int encode_message(struct qaic_device *qdev, struct manage_msg *user_msg, } for (i = 0; i < user_msg->count; ++i) { - if (user_len >= user_msg->len) { + if (user_len > user_msg->len - sizeof(*trans_hdr)) { ret = -EINVAL; break; } trans_hdr = (struct qaic_manage_trans_hdr *)(user_msg->data + user_len); - if (user_len + trans_hdr->len > user_msg->len) { + if (trans_hdr->len < sizeof(trans_hdr) || + size_add(user_len, trans_hdr->len) > user_msg->len) { ret = -EINVAL; break; } From 51b56382ed2a2b03347372272362b3baa623ed1e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 11 Jul 2023 11:20:54 +0300 Subject: [PATCH 091/272] accel/qaic: tighten bounds checking in decode_message() Copy the bounds checking from encode_message() to decode_message(). This patch addresses the following concerns. Ensure that there is enough space for at least one header so that we don't have a negative size later. if (msg_hdr_len < sizeof(*trans_hdr)) Ensure that we have enough space to read the next header from the msg->data. if (msg_len > msg_hdr_len - sizeof(*trans_hdr)) return -EINVAL; Check that the trans_hdr->len is not below the minimum size: if (hdr_len < sizeof(*trans_hdr)) This minimum check ensures that we don't corrupt memory in decode_passthrough() when we do. memcpy(out_trans->data, in_trans->data, len - sizeof(in_trans->hdr)); And finally, use size_add() to prevent an integer overflow: if (size_add(msg_len, hdr_len) > msg_hdr_len) Fixes: 129776ac2e38 ("accel/qaic: Add control path") Signed-off-by: Dan Carpenter Reviewed-by: Pranjal Ramajor Asha Kanojiya Reviewed-by: Jeffrey Hugo Cc: stable@vger.kernel.org # 6.4.x Signed-off-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/ZK0Q5nbLyDO7kJa+@moroto --- drivers/accel/qaic/qaic_control.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/accel/qaic/qaic_control.c b/drivers/accel/qaic/qaic_control.c index 2fdd5959c52f..752b67aff777 100644 --- a/drivers/accel/qaic/qaic_control.c +++ b/drivers/accel/qaic/qaic_control.c @@ -956,15 +956,23 @@ static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg, int ret; int i; - if (msg_hdr_len > QAIC_MANAGE_MAX_MSG_LENGTH) + if (msg_hdr_len < sizeof(*trans_hdr) || + msg_hdr_len > QAIC_MANAGE_MAX_MSG_LENGTH) return -EINVAL; user_msg->len = 0; user_msg->count = le32_to_cpu(msg->hdr.count); for (i = 0; i < user_msg->count; ++i) { + u32 hdr_len; + + if (msg_len > msg_hdr_len - sizeof(*trans_hdr)) + return -EINVAL; + trans_hdr = (struct wire_trans_hdr *)(msg->data + msg_len); - if (msg_len + le32_to_cpu(trans_hdr->len) > msg_hdr_len) + hdr_len = le32_to_cpu(trans_hdr->len); + if (hdr_len < sizeof(*trans_hdr) || + size_add(msg_len, hdr_len) > msg_hdr_len) return -EINVAL; switch (le32_to_cpu(trans_hdr->type)) { From 47d87f71d00b7091b43a56f608f7151b33e5772e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 11 Jul 2023 11:21:00 +0300 Subject: [PATCH 092/272] accel/qaic: Add consistent integer overflow checks The encode_dma() function has integer overflow checks. The encode_passthrough(), encode_activate() and encode_status() functions did not. I added integer overflow checking everywhere. I also updated the integer overflow checking in encode_dma() to use size_add() so everything is consistent. Fixes: 129776ac2e38 ("accel/qaic: Add control path") Signed-off-by: Dan Carpenter Reviewed-by: Pranjal Ramajor Asha Kanojiya Reviewed-by: Jeffrey Hugo Cc: stable@vger.kernel.org # 6.4.x [jhugo: tweak if in encode_dma() to match existing style] Signed-off-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/ZK0Q7IsPkj6WSCcL@moroto --- drivers/accel/qaic/qaic_control.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/accel/qaic/qaic_control.c b/drivers/accel/qaic/qaic_control.c index 752b67aff777..2c336a86e0fd 100644 --- a/drivers/accel/qaic/qaic_control.c +++ b/drivers/accel/qaic/qaic_control.c @@ -367,7 +367,7 @@ static int encode_passthrough(struct qaic_device *qdev, void *trans, struct wrap if (in_trans->hdr.len % 8 != 0) return -EINVAL; - if (msg_hdr_len + in_trans->hdr.len > QAIC_MANAGE_EXT_MSG_LENGTH) + if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_EXT_MSG_LENGTH) return -ENOSPC; trans_wrapper = add_wrapper(wrappers, @@ -558,11 +558,8 @@ static int encode_dma(struct qaic_device *qdev, void *trans, struct wrapper_list msg = &wrapper->msg; msg_hdr_len = le32_to_cpu(msg->hdr.len); - if (msg_hdr_len > (UINT_MAX - QAIC_MANAGE_EXT_MSG_LENGTH)) - return -EINVAL; - /* There should be enough space to hold at least one ASP entry. */ - if (msg_hdr_len + sizeof(*out_trans) + sizeof(struct wire_addr_size_pair) > + if (size_add(msg_hdr_len, sizeof(*out_trans) + sizeof(struct wire_addr_size_pair)) > QAIC_MANAGE_EXT_MSG_LENGTH) return -ENOMEM; @@ -635,7 +632,7 @@ static int encode_activate(struct qaic_device *qdev, void *trans, struct wrapper msg = &wrapper->msg; msg_hdr_len = le32_to_cpu(msg->hdr.len); - if (msg_hdr_len + sizeof(*out_trans) > QAIC_MANAGE_MAX_MSG_LENGTH) + if (size_add(msg_hdr_len, sizeof(*out_trans)) > QAIC_MANAGE_MAX_MSG_LENGTH) return -ENOSPC; if (!in_trans->queue_size) @@ -719,7 +716,7 @@ static int encode_status(struct qaic_device *qdev, void *trans, struct wrapper_l msg = &wrapper->msg; msg_hdr_len = le32_to_cpu(msg->hdr.len); - if (msg_hdr_len + in_trans->hdr.len > QAIC_MANAGE_MAX_MSG_LENGTH) + if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_MAX_MSG_LENGTH) return -ENOSPC; trans_wrapper = add_wrapper(wrappers, sizeof(*trans_wrapper)); From 73274c33d961f4aa0f968f763e2c9f4210b4f4a3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 11 Jul 2023 11:21:13 +0300 Subject: [PATCH 093/272] accel/qaic: Fix a leak in map_user_pages() If get_user_pages_fast() allocates some pages but not as many as we wanted, then the current code leaks those pages. Call put_page() on the pages before returning. Fixes: 129776ac2e38 ("accel/qaic: Add control path") Signed-off-by: Dan Carpenter Reviewed-by: Pranjal Ramajor Asha Kanojiya Reviewed-by: Jeffrey Hugo Reviewed-by: Dafna Hirschfeld Cc: stable@vger.kernel.org # 6.4.x Signed-off-by: Jeffrey Hugo Link: https://patchwork.freedesktop.org/patch/msgid/ZK0Q+ZuONTsBG+1T@moroto --- drivers/accel/qaic/qaic_control.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/accel/qaic/qaic_control.c b/drivers/accel/qaic/qaic_control.c index 2c336a86e0fd..cfbc92da426f 100644 --- a/drivers/accel/qaic/qaic_control.c +++ b/drivers/accel/qaic/qaic_control.c @@ -419,9 +419,12 @@ static int find_and_map_user_pages(struct qaic_device *qdev, } ret = get_user_pages_fast(xfer_start_addr, nr_pages, 0, page_list); - if (ret < 0 || ret != nr_pages) { - ret = -EFAULT; + if (ret < 0) goto free_page_list; + if (ret != nr_pages) { + nr_pages = ret; + ret = -EFAULT; + goto put_pages; } sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); From 676b7c5ecab36274442887ceadd6dee8248a244f Mon Sep 17 00:00:00 2001 From: David Xu Date: Thu, 13 Jul 2023 21:35:28 +0800 Subject: [PATCH 094/272] platform/x86: serial-multi-instantiate: Auto detect IRQ resource for CSC3551 The current code assumes that the CSC3551(multiple cs35l41) always have its interrupt pin connected to GPIO thus the IRQ can be acquired with acpi_dev_gpio_irq_get. However on some newer laptop models this is no longer the case as they have the CSC3551's interrupt pin connected to APIC. This causes smi_i2c_probe to fail on these machines. To support these machines, a new macro IRQ_RESOURCE_AUTO was introduced for cs35l41 smi_node, and smi_get_irq function was modified so it tries to get GPIO irq resource first and if failed, tries to get APIC irq resource for cs35l41. This patch affects only the cs35l41's probing and brings no negative influence on machines that indeed have the cs35l41's interrupt pin connected to GPIO. Signed-off-by: David Xu Link: https://lore.kernel.org/r/SY4P282MB18350CD8288687B87FFD2243E037A@SY4P282MB1835.AUSP282.PROD.OUTLOOK.COM Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- .../platform/x86/serial-multi-instantiate.c | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/serial-multi-instantiate.c b/drivers/platform/x86/serial-multi-instantiate.c index f3dcbdd72fec..2c2abf69f049 100644 --- a/drivers/platform/x86/serial-multi-instantiate.c +++ b/drivers/platform/x86/serial-multi-instantiate.c @@ -21,6 +21,7 @@ #define IRQ_RESOURCE_NONE 0 #define IRQ_RESOURCE_GPIO 1 #define IRQ_RESOURCE_APIC 2 +#define IRQ_RESOURCE_AUTO 3 enum smi_bus_type { SMI_I2C, @@ -52,6 +53,18 @@ static int smi_get_irq(struct platform_device *pdev, struct acpi_device *adev, int ret; switch (inst->flags & IRQ_RESOURCE_TYPE) { + case IRQ_RESOURCE_AUTO: + ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx); + if (ret > 0) { + dev_dbg(&pdev->dev, "Using gpio irq\n"); + break; + } + ret = platform_get_irq(pdev, inst->irq_idx); + if (ret > 0) { + dev_dbg(&pdev->dev, "Using platform irq\n"); + break; + } + break; case IRQ_RESOURCE_GPIO: ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx); break; @@ -307,10 +320,10 @@ static const struct smi_node int3515_data = { static const struct smi_node cs35l41_hda = { .instances = { - { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, - { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, - { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, - { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, {} }, .bus_type = SMI_AUTO_DETECT, From 70904263512a74a3b8941dd9e6e515ca6fc57821 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Fri, 14 Jul 2023 11:11:06 +0100 Subject: [PATCH 095/272] blk-mq: Fix stall due to recursive flush plug We have seen rare IO stalls as follows: * blk_mq_plug_issue_direct() is entered with an mq_list containing two requests. * For the first request, it sets last == false and enters the driver's queue_rq callback. * The driver queue_rq callback indirectly calls schedule() which calls blk_flush_plug(). This may happen if the driver has the BLK_MQ_F_BLOCKING flag set and is allowed to sleep in ->queue_rq. * blk_flush_plug() handles the remaining request in the mq_list. mq_list is now empty. * The original call to queue_rq resumes (with last == false). * The loop in blk_mq_plug_issue_direct() terminates because there are no remaining requests in mq_list. The IO is now stalled because the last request submitted to the driver had last == false and there was no subsequent call to commit_rqs(). Fix this by returning early in blk_mq_flush_plug_list() if rq_count is 0 which it will be in the recursive case, rather than checking if the mq_list is empty. At the same time, adjust one of the callers to skip the mq_list empty check as it is not necessary. Fixes: dc5fc361d891 ("block: attempt direct issue of plug list") Signed-off-by: Ross Lagerwall Reviewed-by: Bart Van Assche Link: https://lore.kernel.org/r/20230714101106.3635611-1-ross.lagerwall@citrix.com Signed-off-by: Jens Axboe --- block/blk-core.c | 3 +-- block/blk-mq.c | 9 ++++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 99d8b9812b18..90de50082146 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1144,8 +1144,7 @@ void __blk_flush_plug(struct blk_plug *plug, bool from_schedule) { if (!list_empty(&plug->cb_list)) flush_plug_callbacks(plug, from_schedule); - if (!rq_list_empty(plug->mq_list)) - blk_mq_flush_plug_list(plug, from_schedule); + blk_mq_flush_plug_list(plug, from_schedule); /* * Unconditionally flush out cached requests, even if the unplug * event came from schedule. Since we know hold references to the diff --git a/block/blk-mq.c b/block/blk-mq.c index d50b1d62a3d9..b04ff6f56926 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -2754,7 +2754,14 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule) { struct request *rq; - if (rq_list_empty(plug->mq_list)) + /* + * We may have been called recursively midway through handling + * plug->mq_list via a schedule() in the driver's queue_rq() callback. + * To avoid mq_list changing under our feet, clear rq_count early and + * bail out specifically if rq_count is 0 rather than checking + * whether the mq_list is empty. + */ + if (plug->rq_count == 0) return; plug->rq_count = 0; From 030d2a0ce5dc621e5c6b2f5f65a77a4bb1620adb Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 12 Jul 2023 10:11:24 +0200 Subject: [PATCH 096/272] dt-bindings: hwmon: moortec,mr75203: fix multipleOf for coefficients Few coefficients use default values multiple of 100, not 1000 (in the example DTS and in the Linux driver): moortec,mr75203.example.dtb: pvt@e0680000: moortec,ts-coeff-g:0:0: 61400 is not a multiple of 1000 Fixes: bf1fdafdbc61 ("dt-bindings: hwmon: (mr75203) add coefficient properties for the thermal equation") Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230712081124.110345-1-krzysztof.kozlowski@linaro.org Signed-off-by: Rob Herring --- .../devicetree/bindings/hwmon/moortec,mr75203.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/hwmon/moortec,mr75203.yaml b/Documentation/devicetree/bindings/hwmon/moortec,mr75203.yaml index ae4f68d4e696..bd67cfee6d19 100644 --- a/Documentation/devicetree/bindings/hwmon/moortec,mr75203.yaml +++ b/Documentation/devicetree/bindings/hwmon/moortec,mr75203.yaml @@ -105,7 +105,7 @@ properties: G coefficient for temperature equation. Default for series 5 = 60000 Default for series 6 = 57400 - multipleOf: 1000 + multipleOf: 100 minimum: 1000 $ref: /schemas/types.yaml#/definitions/uint32 @@ -114,7 +114,7 @@ properties: H coefficient for temperature equation. Default for series 5 = 200000 Default for series 6 = 249400 - multipleOf: 1000 + multipleOf: 100 minimum: 1000 $ref: /schemas/types.yaml#/definitions/uint32 @@ -131,7 +131,7 @@ properties: J coefficient for temperature equation. Default for series 5 = -100 Default for series 6 = 0 - multipleOf: 1000 + multipleOf: 100 maximum: 0 $ref: /schemas/types.yaml#/definitions/int32 From 6d4f9236cd678e0bf0c09fd0e1fa20435bb2e5a2 Mon Sep 17 00:00:00 2001 From: Oliver Upton Date: Thu, 13 Jul 2023 22:16:49 +0000 Subject: [PATCH 097/272] KVM: arm64: Correctly handle RES0 bits PMEVTYPER_EL0.evtCount The PMU event ID varies from 10 to 16 bits, depending on the PMU version. If the PMU only supports 10 bits of event ID, bits [15:10] of the evtCount field behave as RES0. While the actual PMU emulation code gets this right (i.e. RES0 bits are masked out when programming the perf event), the sysreg emulation writes an unmasked value to the in-memory cpu context. The net effect is that guest reads and writes of PMEVTYPER_EL0 will see non-RES0 behavior in the reserved bits of the field. As it so happens, kvm_pmu_set_counter_event_type() already writes a masked value to the in-memory context that gets overwritten by access_pmu_evtyper(). Fix the issue by removing the unnecessary (and incorrect) register write in access_pmu_evtyper(). Reviewed-by: Marc Zyngier Reviewed-by: Reiji Watanabe Link: https://lore.kernel.org/r/20230713221649.3889210-1-oliver.upton@linux.dev Signed-off-by: Oliver Upton --- arch/arm64/kvm/sys_regs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index bd3431823ec5..fa7597882ed8 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -986,7 +986,6 @@ static bool access_pmu_evtyper(struct kvm_vcpu *vcpu, struct sys_reg_params *p, if (p->is_write) { kvm_pmu_set_counter_event_type(vcpu, p->regval, idx); - __vcpu_sys_reg(vcpu, reg) = p->regval & ARMV8_PMU_EVTYPE_MASK; kvm_vcpu_pmu_restore_guest(vcpu); } else { p->regval = __vcpu_sys_reg(vcpu, reg) & ARMV8_PMU_EVTYPE_MASK; From 9d2a55b403eea26cab7c831d8e1c00ef1e6a6850 Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Fri, 14 Jul 2023 11:38:40 +0800 Subject: [PATCH 098/272] KVM: arm64: Fix the name of sys_reg_desc related to PMU For those PMU system registers defined in sys_reg_descs[], use macro PMU_SYS_REG() / PMU_PMEVCNTR_EL0 / PMU_PMEVTYPER_EL0 to define them, and later two macros call macro PMU_SYS_REG() actually. Currently the input parameter of PMU_SYS_REG() is another macro which is calculation formula of the value of system registers, so for example, if we want to "SYS_PMINTENSET_EL1" as the name of sys register, actually the name we get is as following: (((3) << 19) | ((0) << 16) | ((9) << 12) | ((14) << 8) | ((1) << 5)) The name of system register is used in some tracepoints such as trace_kvm_sys_access(), if not set correctly, we need to analyze the inaccurate name to get the exact name (which also is inconsistent with other system registers), and also the inaccurate name occupies more space. To fix the issue, use the name as a input parameter of PMU_SYS_REG like MTE_REG or EL2_REG. Signed-off-by: Xiang Chen Acked-by: Marc Zyngier Link: https://lore.kernel.org/r/1689305920-170523-1-git-send-email-chenxiang66@hisilicon.com Signed-off-by: Oliver Upton --- arch/arm64/kvm/sys_regs.c | 41 ++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index fa7597882ed8..2ca2973abe66 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1114,18 +1114,19 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, { SYS_DESC(SYS_DBGWCRn_EL1(n)), \ trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr } -#define PMU_SYS_REG(r) \ - SYS_DESC(r), .reset = reset_pmu_reg, .visibility = pmu_visibility +#define PMU_SYS_REG(name) \ + SYS_DESC(SYS_##name), .reset = reset_pmu_reg, \ + .visibility = pmu_visibility /* Macro to expand the PMEVCNTRn_EL0 register */ #define PMU_PMEVCNTR_EL0(n) \ - { PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)), \ + { PMU_SYS_REG(PMEVCNTRn_EL0(n)), \ .reset = reset_pmevcntr, .get_user = get_pmu_evcntr, \ .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), } /* Macro to expand the PMEVTYPERn_EL0 register */ #define PMU_PMEVTYPER_EL0(n) \ - { PMU_SYS_REG(SYS_PMEVTYPERn_EL0(n)), \ + { PMU_SYS_REG(PMEVTYPERn_EL0(n)), \ .reset = reset_pmevtyper, \ .access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), } @@ -2114,9 +2115,9 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_PMBSR_EL1), undef_access }, /* PMBIDR_EL1 is not trapped */ - { PMU_SYS_REG(SYS_PMINTENSET_EL1), + { PMU_SYS_REG(PMINTENSET_EL1), .access = access_pminten, .reg = PMINTENSET_EL1 }, - { PMU_SYS_REG(SYS_PMINTENCLR_EL1), + { PMU_SYS_REG(PMINTENCLR_EL1), .access = access_pminten, .reg = PMINTENSET_EL1 }, { SYS_DESC(SYS_PMMIR_EL1), trap_raz_wi }, @@ -2163,41 +2164,41 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_CTR_EL0), access_ctr }, { SYS_DESC(SYS_SVCR), undef_access }, - { PMU_SYS_REG(SYS_PMCR_EL0), .access = access_pmcr, + { PMU_SYS_REG(PMCR_EL0), .access = access_pmcr, .reset = reset_pmcr, .reg = PMCR_EL0 }, - { PMU_SYS_REG(SYS_PMCNTENSET_EL0), + { PMU_SYS_REG(PMCNTENSET_EL0), .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, - { PMU_SYS_REG(SYS_PMCNTENCLR_EL0), + { PMU_SYS_REG(PMCNTENCLR_EL0), .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, - { PMU_SYS_REG(SYS_PMOVSCLR_EL0), + { PMU_SYS_REG(PMOVSCLR_EL0), .access = access_pmovs, .reg = PMOVSSET_EL0 }, /* * PM_SWINC_EL0 is exposed to userspace as RAZ/WI, as it was * previously (and pointlessly) advertised in the past... */ - { PMU_SYS_REG(SYS_PMSWINC_EL0), + { PMU_SYS_REG(PMSWINC_EL0), .get_user = get_raz_reg, .set_user = set_wi_reg, .access = access_pmswinc, .reset = NULL }, - { PMU_SYS_REG(SYS_PMSELR_EL0), + { PMU_SYS_REG(PMSELR_EL0), .access = access_pmselr, .reset = reset_pmselr, .reg = PMSELR_EL0 }, - { PMU_SYS_REG(SYS_PMCEID0_EL0), + { PMU_SYS_REG(PMCEID0_EL0), .access = access_pmceid, .reset = NULL }, - { PMU_SYS_REG(SYS_PMCEID1_EL0), + { PMU_SYS_REG(PMCEID1_EL0), .access = access_pmceid, .reset = NULL }, - { PMU_SYS_REG(SYS_PMCCNTR_EL0), + { PMU_SYS_REG(PMCCNTR_EL0), .access = access_pmu_evcntr, .reset = reset_unknown, .reg = PMCCNTR_EL0, .get_user = get_pmu_evcntr}, - { PMU_SYS_REG(SYS_PMXEVTYPER_EL0), + { PMU_SYS_REG(PMXEVTYPER_EL0), .access = access_pmu_evtyper, .reset = NULL }, - { PMU_SYS_REG(SYS_PMXEVCNTR_EL0), + { PMU_SYS_REG(PMXEVCNTR_EL0), .access = access_pmu_evcntr, .reset = NULL }, /* * PMUSERENR_EL0 resets as unknown in 64bit mode while it resets as zero * in 32bit mode. Here we choose to reset it as zero for consistency. */ - { PMU_SYS_REG(SYS_PMUSERENR_EL0), .access = access_pmuserenr, + { PMU_SYS_REG(PMUSERENR_EL0), .access = access_pmuserenr, .reset = reset_val, .reg = PMUSERENR_EL0, .val = 0 }, - { PMU_SYS_REG(SYS_PMOVSSET_EL0), + { PMU_SYS_REG(PMOVSSET_EL0), .access = access_pmovs, .reg = PMOVSSET_EL0 }, { SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 }, @@ -2353,7 +2354,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { * PMCCFILTR_EL0 resets as unknown in 64bit mode while it resets as zero * in 32bit mode. Here we choose to reset it as zero for consistency. */ - { PMU_SYS_REG(SYS_PMCCFILTR_EL0), .access = access_pmu_evtyper, + { PMU_SYS_REG(PMCCFILTR_EL0), .access = access_pmu_evtyper, .reset = reset_val, .reg = PMCCFILTR_EL0, .val = 0 }, EL2_REG(VPIDR_EL2, access_rw, reset_unknown, 0), From 05abb3be91d8788328231ee02973ab3d47f5e3d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Jul 2023 22:47:45 +0300 Subject: [PATCH 099/272] dma-buf/dma-resv: Stop leaking on krealloc() failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently dma_resv_get_fences() will leak the previously allocated array if the fence iteration got restarted and the krealloc_array() fails. Free the old array by hand, and make sure we still clear the returned *fences so the caller won't end up accessing freed memory. Some (but not all) of the callers of dma_resv_get_fences() seem to still trawl through the array even when dma_resv_get_fences() failed. And let's zero out *num_fences as well for good measure. Cc: Sumit Semwal Cc: Christian König Cc: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linaro-mm-sig@lists.linaro.org Fixes: d3c80698c9f5 ("dma-buf: use new iterator in dma_resv_get_fences v3") Signed-off-by: Ville Syrjälä Reviewed-by: Christian König Cc: stable@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230713194745.1751-1-ville.syrjala@linux.intel.com Signed-off-by: Christian König --- drivers/dma-buf/dma-resv.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c index b6f71eb00866..38b4110378de 100644 --- a/drivers/dma-buf/dma-resv.c +++ b/drivers/dma-buf/dma-resv.c @@ -571,6 +571,7 @@ int dma_resv_get_fences(struct dma_resv *obj, enum dma_resv_usage usage, dma_resv_for_each_fence_unlocked(&cursor, fence) { if (dma_resv_iter_is_restarted(&cursor)) { + struct dma_fence **new_fences; unsigned int count; while (*num_fences) @@ -579,13 +580,17 @@ int dma_resv_get_fences(struct dma_resv *obj, enum dma_resv_usage usage, count = cursor.num_fences + 1; /* Eventually re-allocate the array */ - *fences = krealloc_array(*fences, count, - sizeof(void *), - GFP_KERNEL); - if (count && !*fences) { + new_fences = krealloc_array(*fences, count, + sizeof(void *), + GFP_KERNEL); + if (count && !new_fences) { + kfree(*fences); + *fences = NULL; + *num_fences = 0; dma_resv_iter_end(&cursor); return -ENOMEM; } + *fences = new_fences; } (*fences)[(*num_fences)++] = dma_fence_get(fence); From e8bf1741c14eb8e4a4e1364d45aeeab66660ab9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 12 Jul 2023 14:15:56 +0200 Subject: [PATCH 100/272] MAINTAINERS: Redo addition of ssm3515 to APPLE SOUND MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MAINTAINERS entries added in commit 4ac690bbae02 ("ASoC: ssm3515: Add new amp driver") were later erased in a merge commit. Re-add those. Cc: Mark Brown Fixes: af53b00fa3ac ("Merge tag 'v6.4-rc2' into asoc-6.5 to get fixes for CI") Signed-off-by: Martin Povišer Link: https://lore.kernel.org/r/20230712121556.93500-1-povik+lin@cutebit.org Signed-off-by: Mark Brown --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index bcd9da307818..218c99733302 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1934,9 +1934,11 @@ M: Martin Povišer L: asahi@lists.linux.dev L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Maintained +F: Documentation/devicetree/bindings/sound/adi,ssm3515.yaml F: Documentation/devicetree/bindings/sound/apple,* F: sound/soc/apple/* F: sound/soc/codecs/cs42l83-i2c.c +F: sound/soc/codecs/ssm3515.c ARM/APPLE MACHINE SUPPORT M: Hector Martin From cec148c2476a6e06cf8190b20de81f98983b53ca Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Tue, 4 Jul 2023 08:32:40 +0900 Subject: [PATCH 101/272] ata: pata_parport: Add missing protocol modules description Most of the protocol modules for the pata_parport driver are missing a module description, causing warnings such as: WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/ata/pata_parport/aten.o when compiling with W=1. Add the missing MODULE_DESCRIPTION() definitions to avoid these warnings. While at it, also add the missing MODULE_AUTHOR() definitions. Signed-off-by: Damien Le Moal --- drivers/ata/pata_parport/aten.c | 2 ++ drivers/ata/pata_parport/bpck.c | 2 ++ drivers/ata/pata_parport/bpck6.c | 3 ++- drivers/ata/pata_parport/comm.c | 2 ++ drivers/ata/pata_parport/dstr.c | 2 ++ drivers/ata/pata_parport/epat.c | 3 +++ drivers/ata/pata_parport/epia.c | 3 +++ drivers/ata/pata_parport/fit2.c | 3 +++ drivers/ata/pata_parport/fit3.c | 3 +++ drivers/ata/pata_parport/friq.c | 2 ++ drivers/ata/pata_parport/frpw.c | 2 ++ drivers/ata/pata_parport/kbic.c | 3 +++ drivers/ata/pata_parport/ktti.c | 2 ++ drivers/ata/pata_parport/on20.c | 2 ++ drivers/ata/pata_parport/on26.c | 2 ++ 15 files changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/ata/pata_parport/aten.c b/drivers/ata/pata_parport/aten.c index 8328a49a95ef..620ce6c8da5c 100644 --- a/drivers/ata/pata_parport/aten.c +++ b/drivers/ata/pata_parport/aten.c @@ -139,4 +139,6 @@ static struct pi_protocol aten = { }; MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("ATEN EH-100 parallel port IDE adapter protocol driver"); module_pata_parport_driver(aten); diff --git a/drivers/ata/pata_parport/bpck.c b/drivers/ata/pata_parport/bpck.c index 9f4309f9b57f..bba1eda65f36 100644 --- a/drivers/ata/pata_parport/bpck.c +++ b/drivers/ata/pata_parport/bpck.c @@ -502,4 +502,6 @@ static struct pi_protocol bpck = { }; MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("MicroSolutions BACKPACK parallel port IDE adapter protocol driver"); module_pata_parport_driver(bpck); diff --git a/drivers/ata/pata_parport/bpck6.c b/drivers/ata/pata_parport/bpck6.c index c6dbd14120d1..62c2b53325e1 100644 --- a/drivers/ata/pata_parport/bpck6.c +++ b/drivers/ata/pata_parport/bpck6.c @@ -459,5 +459,6 @@ static struct pi_protocol bpck6 = { MODULE_LICENSE("GPL"); MODULE_AUTHOR("Micro Solutions Inc."); -MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE"); +MODULE_DESCRIPTION("Micro Solutions BACKPACK parallel port IDE adapter " + "(version 6 drives) protocol driver"); module_pata_parport_driver(bpck6); diff --git a/drivers/ata/pata_parport/comm.c b/drivers/ata/pata_parport/comm.c index cc5485bd0a5b..4839becbbd56 100644 --- a/drivers/ata/pata_parport/comm.c +++ b/drivers/ata/pata_parport/comm.c @@ -201,4 +201,6 @@ static struct pi_protocol comm = { }; MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("DataStor Commuter parallel port IDE adapter protocol driver"); module_pata_parport_driver(comm); diff --git a/drivers/ata/pata_parport/dstr.c b/drivers/ata/pata_parport/dstr.c index 368d7c7962a9..88930bb1f07e 100644 --- a/drivers/ata/pata_parport/dstr.c +++ b/drivers/ata/pata_parport/dstr.c @@ -230,4 +230,6 @@ static struct pi_protocol dstr = { }; MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("DataStor EP2000 parallel port IDE adapter protocol driver"); module_pata_parport_driver(dstr); diff --git a/drivers/ata/pata_parport/epat.c b/drivers/ata/pata_parport/epat.c index 016bd96bce89..3cb54fcbf0d0 100644 --- a/drivers/ata/pata_parport/epat.c +++ b/drivers/ata/pata_parport/epat.c @@ -358,5 +358,8 @@ static void __exit epat_exit(void) } MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("Shuttle Technologies EPAT parallel port IDE adapter " + "protocol driver"); module_init(epat_init) module_exit(epat_exit) diff --git a/drivers/ata/pata_parport/epia.c b/drivers/ata/pata_parport/epia.c index 920e9f40d401..7aaba474c671 100644 --- a/drivers/ata/pata_parport/epia.c +++ b/drivers/ata/pata_parport/epia.c @@ -306,4 +306,7 @@ static struct pi_protocol epia = { }; MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("Shuttle Technologies EPIA parallel port IDE adapter " + "protocol driver"); module_pata_parport_driver(epia); diff --git a/drivers/ata/pata_parport/fit2.c b/drivers/ata/pata_parport/fit2.c index 6524f3033b1e..de79cf91ad5f 100644 --- a/drivers/ata/pata_parport/fit2.c +++ b/drivers/ata/pata_parport/fit2.c @@ -132,4 +132,7 @@ static struct pi_protocol fit2 = { }; MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("Fidelity International Technology parallel port IDE adapter" + "(older models) protocol driver"); module_pata_parport_driver(fit2); diff --git a/drivers/ata/pata_parport/fit3.c b/drivers/ata/pata_parport/fit3.c index c172a38ae67d..bad7aa920cdc 100644 --- a/drivers/ata/pata_parport/fit3.c +++ b/drivers/ata/pata_parport/fit3.c @@ -193,4 +193,7 @@ static struct pi_protocol fit3 = { }; MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("Fidelity International Technology parallel port IDE adapter" + "(newer models) protocol driver"); module_pata_parport_driver(fit3); diff --git a/drivers/ata/pata_parport/friq.c b/drivers/ata/pata_parport/friq.c index dc428f54fe0c..7abe2ff40685 100644 --- a/drivers/ata/pata_parport/friq.c +++ b/drivers/ata/pata_parport/friq.c @@ -259,4 +259,6 @@ static struct pi_protocol friq = { }; MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("Freecom IQ parallel port IDE adapter protocol driver"); module_pata_parport_driver(friq); diff --git a/drivers/ata/pata_parport/frpw.c b/drivers/ata/pata_parport/frpw.c index 28d9bb2c6baf..7fa9b9857321 100644 --- a/drivers/ata/pata_parport/frpw.c +++ b/drivers/ata/pata_parport/frpw.c @@ -293,4 +293,6 @@ static struct pi_protocol frpw = { }; MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("Freecom Power parallel port IDE adapter protocol driver"); module_pata_parport_driver(frpw); diff --git a/drivers/ata/pata_parport/kbic.c b/drivers/ata/pata_parport/kbic.c index 6023e071516d..fca322627b82 100644 --- a/drivers/ata/pata_parport/kbic.c +++ b/drivers/ata/pata_parport/kbic.c @@ -301,5 +301,8 @@ static void __exit kbic_exit(void) } MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("KingByte Information Systems KBIC-951A and KBIC-971A " + "parallel port IDE adapter protocol driver"); module_init(kbic_init) module_exit(kbic_exit) diff --git a/drivers/ata/pata_parport/ktti.c b/drivers/ata/pata_parport/ktti.c index bca6c20ef617..c078d1934862 100644 --- a/drivers/ata/pata_parport/ktti.c +++ b/drivers/ata/pata_parport/ktti.c @@ -106,4 +106,6 @@ static struct pi_protocol ktti = { }; MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("KT Technology parallel port IDE adapter protocol driver"); module_pata_parport_driver(ktti); diff --git a/drivers/ata/pata_parport/on20.c b/drivers/ata/pata_parport/on20.c index 34e69da2bec8..7c70e5b13a2a 100644 --- a/drivers/ata/pata_parport/on20.c +++ b/drivers/ata/pata_parport/on20.c @@ -142,4 +142,6 @@ static struct pi_protocol on20 = { }; MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("Onspec 90c20 parallel port IDE adapter protocol driver"); module_pata_parport_driver(on20); diff --git a/drivers/ata/pata_parport/on26.c b/drivers/ata/pata_parport/on26.c index 5da317b394c1..c88e5d6f203e 100644 --- a/drivers/ata/pata_parport/on26.c +++ b/drivers/ata/pata_parport/on26.c @@ -310,4 +310,6 @@ static struct pi_protocol on26 = { }; MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Grant R. Guenther "); +MODULE_DESCRIPTION("Onspec 90c26 parallel port IDE adapter protocol driver"); module_pata_parport_driver(on26); From b59c9dc4d9d47b3c4572d826603fde507055b656 Mon Sep 17 00:00:00 2001 From: Haren Myneni Date: Sun, 16 Jul 2023 03:05:06 -0700 Subject: [PATCH 102/272] powerpc/pseries/vas: Hold mmap_mutex after mmap lock during window close Commit 8ef7b9e1765a ("powerpc/pseries/vas: Close windows with DLPAR core removal") unmaps the window paste address and issues HCALL to close window in the hypervisor for migration or DLPAR core removal events. So holds mmap_mutex and then mmap lock before unmap the paste address. But if the user space issue mmap paste address at the same time with the migration event, coproc_mmap() is called after holding the mmap lock which can trigger deadlock when trying to acquire mmap_mutex in coproc_mmap(). t1: mmap() call to mmap t2: Migration event window paste address do_mmap2() migration_store() ksys_mmap_pgoff() pseries_migrate_partition() vm_mmap_pgoff() vas_migration_handler() Acquire mmap lock reconfig_close_windows() do_mmap() lock mmap_mutex mmap_region() Acquire mmap lock call_mmap() //Wait for mmap lock coproc_mmap() unmap vma lock mmap_mutex update window status //wait for mmap_mutex Release mmap lock mmap vma unlock mmap_mutex update window status unlock mmap_mutex ... Release mmap lock Fix this deadlock issue by holding mmap lock first before mmap_mutex in reconfig_close_windows(). Fixes: 8ef7b9e1765a ("powerpc/pseries/vas: Close windows with DLPAR core removal") Signed-off-by: Haren Myneni Signed-off-by: Michael Ellerman Link: https://msgid.link/20230716100506.7833-1-haren@linux.ibm.com --- arch/powerpc/platforms/pseries/vas.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c index 9a44a98ba342..3fbc2a6aa319 100644 --- a/arch/powerpc/platforms/pseries/vas.c +++ b/arch/powerpc/platforms/pseries/vas.c @@ -744,6 +744,12 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds, } task_ref = &win->vas_win.task_ref; + /* + * VAS mmap (coproc_mmap()) and its fault handler + * (vas_mmap_fault()) are called after holding mmap lock. + * So hold mmap mutex after mmap_lock to avoid deadlock. + */ + mmap_write_lock(task_ref->mm); mutex_lock(&task_ref->mmap_mutex); vma = task_ref->vma; /* @@ -752,7 +758,6 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds, */ win->vas_win.status |= flag; - mmap_write_lock(task_ref->mm); /* * vma is set in the original mapping. But this mapping * is done with mmap() after the window is opened with ioctl. @@ -762,8 +767,8 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds, if (vma) zap_vma_pages(vma); - mmap_write_unlock(task_ref->mm); mutex_unlock(&task_ref->mmap_mutex); + mmap_write_unlock(task_ref->mm); /* * Close VAS window in the hypervisor, but do not * free vas_window struct since it may be reused From b49e578b9314db051da0ad72bba24094193f9bd0 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Wed, 12 Jul 2023 23:45:02 +1000 Subject: [PATCH 103/272] Revert "powerpc/bug: Provide better flexibility to WARN_ON/__WARN_FLAGS() with asm goto" This partly reverts commit 1e688dd2a3d6759d416616ff07afc4bb836c4213. That commit aimed at optimising the code around generation of WARN_ON/BUG_ON but this leads to a lot of dead code erroneously generated by GCC. That dead code becomes a problem when we start using objtool validation because objtool will abort validation with a warning as soon as it detects unreachable code. This is because unreachable code might be the indication that objtool doesn't properly decode object text. text data bss dec hex filename 9551585 3627834 224376 13403795 cc8693 vmlinux.before 9535281 3628358 224376 13388015 cc48ef vmlinux.after Once this change is reverted, in a standard configuration (pmac32 + function tracer) the text is reduced by 16k which is around 1.7% We already had problem with it when starting to use objtool on powerpc as a replacement for recordmcount, see commit 93e3f45a2631 ("powerpc: Fix __WARN_FLAGS() for use with Objtool") There is also a problem with at least GCC 12, on ppc64_defconfig + CONFIG_CC_OPTIMIZE_FOR_SIZE=y + CONFIG_DEBUG_SECTION_MISMATCH=y : LD .tmp_vmlinux.kallsyms1 powerpc64-linux-ld: net/ipv4/tcp_input.o:(__ex_table+0xc4): undefined reference to `.L2136' make[2]: *** [scripts/Makefile.vmlinux:36: vmlinux] Error 1 make[1]: *** [/home/chleroy/linux-powerpc/Makefile:1238: vmlinux] Error 2 Taking into account that other problems are encountered with that 'asm goto' in WARN_ON(), including build failures, keeping that change is not worth it allthough it is primarily a compiler bug. Revert it for now. mpe: Retain EMIT_WARN_ENTRY as a synonym for EMIT_BUG_ENTRY to reduce churn, as there are now nearly as many uses of EMIT_WARN_ENTRY as EMIT_BUG_ENTRY. Signed-off-by: Christophe Leroy Acked-by: Naveen N Rao Signed-off-by: Michael Ellerman Link: https://msgid.link/20230712134552.534955-1-mpe@ellerman.id.au --- arch/powerpc/include/asm/bug.h | 69 +++++++--------------------------- arch/powerpc/kernel/traps.c | 9 +---- 2 files changed, 15 insertions(+), 63 deletions(-) diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h index ef42adb44aa3..00c6b0b4ede4 100644 --- a/arch/powerpc/include/asm/bug.h +++ b/arch/powerpc/include/asm/bug.h @@ -4,14 +4,13 @@ #ifdef __KERNEL__ #include -#include #ifdef CONFIG_BUG #ifdef __ASSEMBLY__ #include #ifdef CONFIG_DEBUG_BUGVERBOSE -.macro __EMIT_BUG_ENTRY addr,file,line,flags +.macro EMIT_BUG_ENTRY addr,file,line,flags .section __bug_table,"aw" 5001: .4byte \addr - . .4byte 5002f - . @@ -23,7 +22,7 @@ .previous .endm #else -.macro __EMIT_BUG_ENTRY addr,file,line,flags +.macro EMIT_BUG_ENTRY addr,file,line,flags .section __bug_table,"aw" 5001: .4byte \addr - . .short \flags @@ -32,18 +31,6 @@ .endm #endif /* verbose */ -.macro EMIT_WARN_ENTRY addr,file,line,flags - EX_TABLE(\addr,\addr+4) - __EMIT_BUG_ENTRY \addr,\file,\line,\flags -.endm - -.macro EMIT_BUG_ENTRY addr,file,line,flags - .if \flags & 1 /* BUGFLAG_WARNING */ - .err /* Use EMIT_WARN_ENTRY for warnings */ - .endif - __EMIT_BUG_ENTRY \addr,\file,\line,\flags -.endm - #else /* !__ASSEMBLY__ */ /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and sizeof(struct bug_entry), respectively */ @@ -73,16 +60,6 @@ "i" (sizeof(struct bug_entry)), \ ##__VA_ARGS__) -#define WARN_ENTRY(insn, flags, label, ...) \ - asm_volatile_goto( \ - "1: " insn "\n" \ - EX_TABLE(1b, %l[label]) \ - _EMIT_BUG_ENTRY \ - : : "i" (__FILE__), "i" (__LINE__), \ - "i" (flags), \ - "i" (sizeof(struct bug_entry)), \ - ##__VA_ARGS__ : : label) - /* * BUG_ON() and WARN_ON() do their best to cooperate with compile-time * optimisations. However depending on the complexity of the condition @@ -95,16 +72,7 @@ } while (0) #define HAVE_ARCH_BUG -#define __WARN_FLAGS(flags) do { \ - __label__ __label_warn_on; \ - \ - WARN_ENTRY("twi 31, 0, 0", BUGFLAG_WARNING | (flags), __label_warn_on); \ - barrier_before_unreachable(); \ - __builtin_unreachable(); \ - \ -__label_warn_on: \ - break; \ -} while (0) +#define __WARN_FLAGS(flags) BUG_ENTRY("twi 31, 0, 0", BUGFLAG_WARNING | (flags)) #ifdef CONFIG_PPC64 #define BUG_ON(x) do { \ @@ -117,25 +85,15 @@ __label_warn_on: \ } while (0) #define WARN_ON(x) ({ \ - bool __ret_warn_on = false; \ - do { \ - if (__builtin_constant_p((x))) { \ - if (!(x)) \ - break; \ + int __ret_warn_on = !!(x); \ + if (__builtin_constant_p(__ret_warn_on)) { \ + if (__ret_warn_on) \ __WARN(); \ - __ret_warn_on = true; \ - } else { \ - __label__ __label_warn_on; \ - \ - WARN_ENTRY(PPC_TLNEI " %4, 0", \ - BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN), \ - __label_warn_on, \ - "r" ((__force long)(x))); \ - break; \ -__label_warn_on: \ - __ret_warn_on = true; \ - } \ - } while (0); \ + } else { \ + BUG_ENTRY(PPC_TLNEI " %4, 0", \ + BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN), \ + "r" (__ret_warn_on)); \ + } \ unlikely(__ret_warn_on); \ }) @@ -148,14 +106,13 @@ __label_warn_on: \ #ifdef __ASSEMBLY__ .macro EMIT_BUG_ENTRY addr,file,line,flags .endm -.macro EMIT_WARN_ENTRY addr,file,line,flags -.endm #else /* !__ASSEMBLY__ */ #define _EMIT_BUG_ENTRY -#define _EMIT_WARN_ENTRY #endif #endif /* CONFIG_BUG */ +#define EMIT_WARN_ENTRY EMIT_BUG_ENTRY + #include #ifndef __ASSEMBLY__ diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index e59ec6d32d37..7ef147e2a20d 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1508,13 +1508,8 @@ static void do_program_check(struct pt_regs *regs) if (!(regs->msr & MSR_PR) && /* not user-mode */ report_bug(bugaddr, regs) == BUG_TRAP_TYPE_WARN) { - const struct exception_table_entry *entry; - - entry = search_exception_tables(bugaddr); - if (entry) { - regs_set_return_ip(regs, extable_fixup(entry) + regs->nip - bugaddr); - return; - } + regs_add_return_ip(regs, 4); + return; } if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) && user_mode(regs)) { From fb74c4e3bee283ad8ce981fb744aa8239bed2d7a Mon Sep 17 00:00:00 2001 From: Russell Currey Date: Thu, 13 Jul 2023 14:21:45 +1000 Subject: [PATCH 104/272] powerpc/crypto: Add gitignore for generated P10 AES/GCM .S files aesp10-ppc.S and ghashp10-ppc.S are autogenerated and not tracked by git, so they should be ignored. This is doing the same as the P8 files in drivers/crypto/vmx/.gitignore but for the P10 files in arch/powerpc/crypto. Signed-off-by: Russell Currey Signed-off-by: Michael Ellerman Link: https://msgid.link/20230713042206.85669-1-ruscur@russell.cc --- arch/powerpc/crypto/.gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 arch/powerpc/crypto/.gitignore diff --git a/arch/powerpc/crypto/.gitignore b/arch/powerpc/crypto/.gitignore new file mode 100644 index 000000000000..e1094f08f713 --- /dev/null +++ b/arch/powerpc/crypto/.gitignore @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only +aesp10-ppc.S +ghashp10-ppc.S From 8739312ed2faa79df61d157ac44fda840646d444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 11 Jul 2023 16:31:45 +0200 Subject: [PATCH 105/272] powerpc/512x: lpbfifo: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new() which already returns void. Eventually after all drivers are converted, .remove_new() is renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Signed-off-by: Uwe Kleine-König Signed-off-by: Michael Ellerman Link: https://msgid.link/20230711143145.1192651-1-u.kleine-koenig@pengutronix.de --- arch/powerpc/platforms/512x/mpc512x_lpbfifo.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c b/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c index 1bfb29574caa..c1e981649bd9 100644 --- a/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c +++ b/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c @@ -477,7 +477,7 @@ static int mpc512x_lpbfifo_probe(struct platform_device *pdev) return ret; } -static int mpc512x_lpbfifo_remove(struct platform_device *pdev) +static void mpc512x_lpbfifo_remove(struct platform_device *pdev) { unsigned long flags; struct dma_device *dma_dev = lpbfifo.chan->device; @@ -494,8 +494,6 @@ static int mpc512x_lpbfifo_remove(struct platform_device *pdev) free_irq(lpbfifo.irq, &pdev->dev); irq_dispose_mapping(lpbfifo.irq); dma_release_channel(lpbfifo.chan); - - return 0; } static const struct of_device_id mpc512x_lpbfifo_match[] = { @@ -506,7 +504,7 @@ MODULE_DEVICE_TABLE(of, mpc512x_lpbfifo_match); static struct platform_driver mpc512x_lpbfifo_driver = { .probe = mpc512x_lpbfifo_probe, - .remove = mpc512x_lpbfifo_remove, + .remove_new = mpc512x_lpbfifo_remove, .driver = { .name = DRV_NAME, .of_match_table = mpc512x_lpbfifo_match, From e51df4f81b02bcdd828a04de7c1eb6a92988b61e Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 13 Jul 2023 13:21:12 +0200 Subject: [PATCH 106/272] ASoC: cs42l51: fix driver to properly autoload with automatic module loading In commit 2cb1e0259f50 ("ASoC: cs42l51: re-hook of_match_table pointer"), 9 years ago, some random guy fixed the cs42l51 after it was split into a core part and an I2C part to properly match based on a Device Tree compatible string. However, the fix in this commit is wrong: the MODULE_DEVICE_TABLE(of, ....) is in the core part of the driver, not the I2C part. Therefore, automatic module loading based on module.alias, based on matching with the DT compatible string, loads the core part of the driver, but not the I2C part. And threfore, the i2c_driver is not registered, and the codec is not known to the system, nor matched with a DT node with the corresponding compatible string. In order to fix that, we move the MODULE_DEVICE_TABLE(of, ...) into the I2C part of the driver. The cs42l51_of_match[] array is also moved as well, as it is not possible to have this definition in one file, and the MODULE_DEVICE_TABLE(of, ...) invocation in another file, due to how MODULE_DEVICE_TABLE works. Thanks to this commit, the I2C part of the driver now properly autoloads, and thanks to its dependency on the core part, the core part gets autoloaded as well, resulting in a functional sound card without having to manually load kernel modules. Fixes: 2cb1e0259f50 ("ASoC: cs42l51: re-hook of_match_table pointer") Cc: stable@vger.kernel.org Signed-off-by: Thomas Petazzoni Link: https://lore.kernel.org/r/20230713112112.778576-1-thomas.petazzoni@bootlin.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l51-i2c.c | 6 ++++++ sound/soc/codecs/cs42l51.c | 7 ------- sound/soc/codecs/cs42l51.h | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/cs42l51-i2c.c b/sound/soc/codecs/cs42l51-i2c.c index b2106ff6a7cb..e7db7bcd0296 100644 --- a/sound/soc/codecs/cs42l51-i2c.c +++ b/sound/soc/codecs/cs42l51-i2c.c @@ -19,6 +19,12 @@ static struct i2c_device_id cs42l51_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, cs42l51_i2c_id); +const struct of_device_id cs42l51_of_match[] = { + { .compatible = "cirrus,cs42l51", }, + { } +}; +MODULE_DEVICE_TABLE(of, cs42l51_of_match); + static int cs42l51_i2c_probe(struct i2c_client *i2c) { struct regmap_config config; diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index a67cd3ee84e0..a7079ae0ca09 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -823,13 +823,6 @@ int __maybe_unused cs42l51_resume(struct device *dev) } EXPORT_SYMBOL_GPL(cs42l51_resume); -const struct of_device_id cs42l51_of_match[] = { - { .compatible = "cirrus,cs42l51", }, - { } -}; -MODULE_DEVICE_TABLE(of, cs42l51_of_match); -EXPORT_SYMBOL_GPL(cs42l51_of_match); - MODULE_AUTHOR("Arnaud Patard "); MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs42l51.h b/sound/soc/codecs/cs42l51.h index a79343e8a54e..125703ede113 100644 --- a/sound/soc/codecs/cs42l51.h +++ b/sound/soc/codecs/cs42l51.h @@ -16,7 +16,6 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap); void cs42l51_remove(struct device *dev); int __maybe_unused cs42l51_suspend(struct device *dev); int __maybe_unused cs42l51_resume(struct device *dev); -extern const struct of_device_id cs42l51_of_match[]; #define CS42L51_CHIP_ID 0x1B #define CS42L51_CHIP_REV_A 0x00 From 469e2f28c2cbee2430058c1c9bb6d1675d7195fb Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 7 Jul 2023 14:25:23 +0300 Subject: [PATCH 107/272] ASoC: SOF: ipc3-dtrace: uninitialized data in dfsentry_trace_filter_write() This doesn't check how many bytes the simple_write_to_buffer() writes to the buffer. The only thing that we know is that the first byte is initialized and the last byte of the buffer is set to NUL. However the middle bytes could be uninitialized. There is no need to use simple_write_to_buffer(). This code does not support partial writes but instead passes "pos = 0" as the starting offset regardless of what the user passed as "*ppos". Just use the copy_from_user() function and initialize the whole buffer. Fixes: 671e0b90051e ("ASoC: SOF: Clone the trace code to ipc3-dtrace as fw_tracing implementation") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/74148292-ce4d-4e01-a1a7-921e6767da14@moroto.mountain Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-dtrace.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c index 1d3bca2d28dd..35da85a45a9a 100644 --- a/sound/soc/sof/ipc3-dtrace.c +++ b/sound/soc/sof/ipc3-dtrace.c @@ -186,7 +186,6 @@ static ssize_t dfsentry_trace_filter_write(struct file *file, const char __user struct snd_sof_dfsentry *dfse = file->private_data; struct sof_ipc_trace_filter_elem *elems = NULL; struct snd_sof_dev *sdev = dfse->sdev; - loff_t pos = 0; int num_elems; char *string; int ret; @@ -201,11 +200,11 @@ static ssize_t dfsentry_trace_filter_write(struct file *file, const char __user if (!string) return -ENOMEM; - /* assert null termination */ - string[count] = 0; - ret = simple_write_to_buffer(string, count, &pos, from, count); - if (ret < 0) + if (copy_from_user(string, from, count)) { + ret = -EFAULT; goto error; + } + string[count] = '\0'; ret = trace_filter_parse(sdev, string, &num_elems, &elems); if (ret < 0) From bc64734825c59e18a27ac266b07e14944c111fd8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 12 Jul 2023 12:16:39 +0100 Subject: [PATCH 108/272] regmap: Drop initial version of maximum transfer length fixes When problems were noticed with the register address not being taken into account when limiting raw transfers with I2C devices we fixed this in the core. Unfortunately it has subsequently been realised that a lot of buses were relying on the prior behaviour, partly due to unclear documentation not making it obvious what was intended in the core. This is all more involved to fix than is sensible for a fix commit so let's just drop the original fixes, a separate commit will fix the originally observed problem in an I2C specific way Fixes: 3981514180c9 ("regmap: Account for register length when chunking") Fixes: c8e796895e23 ("regmap: spi-avmm: Fix regmap_bus max_raw_write") Signed-off-by: Mark Brown Reviewed-by: Xu Yilun Cc: stable@kernel.org Link: https://lore.kernel.org/r/20230712-regmap-max-transfer-v1-1-80e2aed22e83@kernel.org Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-spi-avmm.c | 2 +- drivers/base/regmap/regmap.c | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/base/regmap/regmap-spi-avmm.c b/drivers/base/regmap/regmap-spi-avmm.c index 6af692844c19..4c2b94b3e30b 100644 --- a/drivers/base/regmap/regmap-spi-avmm.c +++ b/drivers/base/regmap/regmap-spi-avmm.c @@ -660,7 +660,7 @@ static const struct regmap_bus regmap_spi_avmm_bus = { .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, .val_format_endian_default = REGMAP_ENDIAN_NATIVE, .max_raw_read = SPI_AVMM_VAL_SIZE * MAX_READ_CNT, - .max_raw_write = SPI_AVMM_REG_SIZE + SPI_AVMM_VAL_SIZE * MAX_WRITE_CNT, + .max_raw_write = SPI_AVMM_VAL_SIZE * MAX_WRITE_CNT, .free_context = spi_avmm_bridge_ctx_free, }; diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 89a7f1c459c1..1bfd1727b4da 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -2082,8 +2082,6 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg, size_t val_count = val_len / val_bytes; size_t chunk_count, chunk_bytes; size_t chunk_regs = val_count; - size_t max_data = map->max_raw_write - map->format.reg_bytes - - map->format.pad_bytes; int ret, i; if (!val_count) @@ -2091,8 +2089,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg, if (map->use_single_write) chunk_regs = 1; - else if (map->max_raw_write && val_len > max_data) - chunk_regs = max_data / val_bytes; + else if (map->max_raw_write && val_len > map->max_raw_write) + chunk_regs = map->max_raw_write / val_bytes; chunk_count = val_count / chunk_regs; chunk_bytes = chunk_regs * val_bytes; From 0c9d2eb5e94792fe64019008a04d4df5e57625af Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 12 Jul 2023 12:16:40 +0100 Subject: [PATCH 109/272] regmap: Account for register length in SMBus I/O limits The SMBus I2C buses have limits on the size of transfers they can do but do not factor in the register length meaning we may try to do a transfer longer than our length limit, the core will not take care of this. Future changes will factor this out into the core but there are a number of users that assume current behaviour so let's just do something conservative here. This does not take account padding bits but practically speaking these are very rarely if ever used on I2C buses given that they generally run slowly enough to mean there's no issue. Cc: stable@kernel.org Signed-off-by: Mark Brown Reviewed-by: Xu Yilun Link: https://lore.kernel.org/r/20230712-regmap-max-transfer-v1-2-80e2aed22e83@kernel.org Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-i2c.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c index 980e5ce6a3a3..3ec611dc0c09 100644 --- a/drivers/base/regmap/regmap-i2c.c +++ b/drivers/base/regmap/regmap-i2c.c @@ -242,8 +242,8 @@ static int regmap_i2c_smbus_i2c_read(void *context, const void *reg, static const struct regmap_bus regmap_i2c_smbus_i2c_block = { .write = regmap_i2c_smbus_i2c_write, .read = regmap_i2c_smbus_i2c_read, - .max_raw_read = I2C_SMBUS_BLOCK_MAX, - .max_raw_write = I2C_SMBUS_BLOCK_MAX, + .max_raw_read = I2C_SMBUS_BLOCK_MAX - 1, + .max_raw_write = I2C_SMBUS_BLOCK_MAX - 1, }; static int regmap_i2c_smbus_i2c_write_reg16(void *context, const void *data, @@ -299,8 +299,8 @@ static int regmap_i2c_smbus_i2c_read_reg16(void *context, const void *reg, static const struct regmap_bus regmap_i2c_smbus_i2c_block_reg16 = { .write = regmap_i2c_smbus_i2c_write_reg16, .read = regmap_i2c_smbus_i2c_read_reg16, - .max_raw_read = I2C_SMBUS_BLOCK_MAX, - .max_raw_write = I2C_SMBUS_BLOCK_MAX, + .max_raw_read = I2C_SMBUS_BLOCK_MAX - 2, + .max_raw_write = I2C_SMBUS_BLOCK_MAX - 2, }; static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c, From 057849ccc3d898b8a2dc21933b50ed8fbddc963b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Jul 2023 08:25:55 +0200 Subject: [PATCH 110/272] ALSA: seq: Fix memory leak at error path in snd_seq_create_port() We forgot to release a newly allocated item at the error path in snd_seq_create_port(). This patch fixes it. Fixes: 7c3f0d3d3a11 ("ALSA: seq: Check the conflicting port at port creation") Reported-by: syzbot+cf8e7fa4eeec59b3d485@syzkaller.appspotmail.com Closes: https://lore.kernel.org/r/00000000000098ed3a0600965f89@google.com Link: https://lore.kernel.org/r/20230717062555.31592-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/seq/seq_ports.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index 9b80f8275026..f3f14ff0f80f 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c @@ -149,6 +149,7 @@ int snd_seq_create_port(struct snd_seq_client *client, int port, write_lock_irq(&client->ports_lock); list_for_each_entry(p, &client->ports_list_head, list) { if (p->addr.port == port) { + kfree(new_port); num = -EBUSY; goto unlock; } From 785b3f667b4bf98804cad135005e964df0c750de Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 11 Jul 2023 17:34:10 +0200 Subject: [PATCH 111/272] drm/i915/perf: add sentinel to xehp_oa_b_counters Arrays passed to reg_in_range_table should end with empty record. The patch solves KASAN detected bug with signature: BUG: KASAN: global-out-of-bounds in xehp_is_valid_b_counter_addr+0x2c7/0x350 [i915] Read of size 4 at addr ffffffffa1555d90 by task perf/1518 CPU: 4 PID: 1518 Comm: perf Tainted: G U 6.4.0-kasan_438-g3303d06107f3+ #1 Hardware name: Intel Corporation Meteor Lake Client Platform/MTL-P DDR5 SODIMM SBS RVP, BIOS MTLPFWI1.R00.3223.D80.2305311348 05/31/2023 Call Trace: ... xehp_is_valid_b_counter_addr+0x2c7/0x350 [i915] Fixes: 0fa9349dda03 ("drm/i915/perf: complete programming whitelisting for XEHPSDV") Signed-off-by: Andrzej Hajda Reviewed-by: Andi Shyti Reviewed-by: Nirmoy Das Link: https://patchwork.freedesktop.org/patch/msgid/20230711153410.1224997-1-andrzej.hajda@intel.com (cherry picked from commit 2f42c5afb34b5696cf5fe79e744f99be9b218798) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_perf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 7413c11fb562..49c6f1ff1128 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -4431,6 +4431,7 @@ static const struct i915_range mtl_oam_b_counters[] = { static const struct i915_range xehp_oa_b_counters[] = { { .start = 0xdc48, .end = 0xdc48 }, /* OAA_ENABLE_REG */ { .start = 0xdd00, .end = 0xdd48 }, /* OAG_LCE0_0 - OAA_LENABLE_REG */ + {} }; static const struct i915_range gen7_oa_mux_regs[] = { From 2c27770a7bc88ef7f6614d11d96d8e62017d0b78 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 11 Jul 2023 14:02:14 +0300 Subject: [PATCH 112/272] Revert "drm/i915: use localized __diag_ignore_all() instead of per file" This reverts commit 88e9664434c994e97a9f6f8cdd1535495c660cea. __diag_ignore_all() only works for GCC 8 or later. -Woverride-init (from -Wextra, enabled in i915 Makefile) combined with CONFIG_WERROR=y or W=e breaks the build for older GCC. With i386_defconfig and x86_64_defconfig enabling CONFIG_WERROR=y by default, we really need to roll back the change. An alternative would be to disable -Woverride-init in the Makefile for GCC <8, but the revert seems like the safest bet now. Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/8768 Reported-by: John Garry References: https://lore.kernel.org/r/ad2601c0-84bb-c574-3702-a83ff8faf98c@oracle.com References: https://lore.kernel.org/r/87wmzezns4.fsf@intel.com Fixes: 88e9664434c9 ("drm/i915: use localized __diag_ignore_all() instead of per file") Cc: Gustavo Sousa Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Signed-off-by: Jani Nikula Reviewed-by: Gustavo Sousa Tested-by: John Garry Link: https://patchwork.freedesktop.org/patch/msgid/20230711110214.25093-1-jani.nikula@intel.com (cherry picked from commit 290d161045753240f2100b8f44660426ecc97be5) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/Makefile | 5 +++++ drivers/gpu/drm/i915/display/intel_display_device.c | 5 ----- drivers/gpu/drm/i915/display/intel_fbdev.c | 5 ----- drivers/gpu/drm/i915/i915_pci.c | 5 ----- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 789dce9e2608..dcbda9ba32dd 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -23,6 +23,11 @@ subdir-ccflags-y += $(call cc-option, -Wunused-but-set-variable) subdir-ccflags-y += $(call cc-disable-warning, frame-address) subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror +# Fine grained warnings disable +CFLAGS_i915_pci.o = $(call cc-disable-warning, override-init) +CFLAGS_display/intel_display_device.o = $(call cc-disable-warning, override-init) +CFLAGS_display/intel_fbdev.o = $(call cc-disable-warning, override-init) + subdir-ccflags-y += -I$(srctree)/$(src) # Please keep these build lists sorted! diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index 3fd30e7f0062..f0ee9bcf661d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -16,9 +16,6 @@ #include "intel_display_reg_defs.h" #include "intel_fbc.h" -__diag_push(); -__diag_ignore_all("-Woverride-init", "Allow overriding inherited members"); - static const struct intel_display_device_info no_display = {}; #define PIPE_A_OFFSET 0x70000 @@ -665,8 +662,6 @@ static const struct intel_display_device_info xe_lpdp_display = { BIT(TRANSCODER_C) | BIT(TRANSCODER_D), }; -__diag_pop(); - #undef INTEL_VGA_DEVICE #undef INTEL_QUANTA_VGA_DEVICE #define INTEL_VGA_DEVICE(id, info) { id, info } diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 1cc0ddc6a310..80c3f88310db 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -135,9 +135,6 @@ static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma) return i915_gem_fb_mmap(obj, vma); } -__diag_push(); -__diag_ignore_all("-Woverride-init", "Allow overriding the default ops"); - static const struct fb_ops intelfb_ops = { .owner = THIS_MODULE, __FB_DEFAULT_DEFERRED_OPS_RDWR(intel_fbdev), @@ -149,8 +146,6 @@ static const struct fb_ops intelfb_ops = { .fb_mmap = intel_fbdev_mmap, }; -__diag_pop(); - static int intelfb_alloc(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 3d7a5db9833b..928975d5fe2f 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -38,9 +38,6 @@ #include "i915_reg.h" #include "intel_pci_config.h" -__diag_push(); -__diag_ignore_all("-Woverride-init", "Allow overriding inherited members"); - #define PLATFORM(x) .platform = (x) #define GEN(x) \ .__runtime.graphics.ip.ver = (x), \ @@ -846,8 +843,6 @@ static const struct intel_device_info mtl_info = { #undef PLATFORM -__diag_pop(); - /* * Make sure any device matches here are from most specific to most * general. For example, since the Quanta match is based on the subsystem From ccb381e1af1ace292153c88eb1fffa5683d16a20 Mon Sep 17 00:00:00 2001 From: Benjamin Gray Date: Mon, 10 Jul 2023 14:41:43 +1000 Subject: [PATCH 113/272] powerpc/kasan: Disable KCOV in KASAN code As per the generic KASAN code in mm/kasan, disable KCOV with KCOV_INSTRUMENT := n in the makefile. This fixes a ppc64 boot hang when KCOV and KASAN are enabled. kasan_early_init() gets called before a PACA is initialised, but the KCOV hook expects a valid PACA. Suggested-by: Christophe Leroy Signed-off-by: Benjamin Gray Signed-off-by: Michael Ellerman Link: https://msgid.link/20230710044143.146840-1-bgray@linux.ibm.com --- arch/powerpc/mm/kasan/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/mm/kasan/Makefile b/arch/powerpc/mm/kasan/Makefile index 699eeffd9f55..f9522fd70b2f 100644 --- a/arch/powerpc/mm/kasan/Makefile +++ b/arch/powerpc/mm/kasan/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 KASAN_SANITIZE := n +KCOV_INSTRUMENT := n obj-$(CONFIG_PPC32) += init_32.o obj-$(CONFIG_PPC_8xx) += 8xx.o From 8b6f687743dacce83dbb0c7cfacf88bab00f808a Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Sat, 15 Jul 2023 13:31:32 +0200 Subject: [PATCH 114/272] x86/cpu/amd: Move the errata checking functionality up Avoid new and remove old forward declarations. No functional changes. Signed-off-by: Borislav Petkov (AMD) --- arch/x86/kernel/cpu/amd.c | 139 ++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 72 deletions(-) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 571abf808ea3..27e177f7ef43 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -27,11 +27,6 @@ #include "cpu.h" -static const int amd_erratum_383[]; -static const int amd_erratum_400[]; -static const int amd_erratum_1054[]; -static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum); - /* * nodes_per_socket: Stores the number of nodes per socket. * Refer to Fam15h Models 00-0fh BKDG - CPUID Fn8000_001E_ECX @@ -39,6 +34,73 @@ static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum); */ static u32 nodes_per_socket = 1; +/* + * AMD errata checking + * + * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or + * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that + * have an OSVW id assigned, which it takes as first argument. Both take a + * variable number of family-specific model-stepping ranges created by + * AMD_MODEL_RANGE(). + * + * Example: + * + * const int amd_erratum_319[] = + * AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2), + * AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0), + * AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0)); + */ + +#define AMD_LEGACY_ERRATUM(...) { -1, __VA_ARGS__, 0 } +#define AMD_OSVW_ERRATUM(osvw_id, ...) { osvw_id, __VA_ARGS__, 0 } +#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \ + ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end)) +#define AMD_MODEL_RANGE_FAMILY(range) (((range) >> 24) & 0xff) +#define AMD_MODEL_RANGE_START(range) (((range) >> 12) & 0xfff) +#define AMD_MODEL_RANGE_END(range) ((range) & 0xfff) + +static const int amd_erratum_400[] = + AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), + AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)); + +static const int amd_erratum_383[] = + AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf)); + +/* #1054: Instructions Retired Performance Counter May Be Inaccurate */ +static const int amd_erratum_1054[] = + AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf)); + +static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) +{ + int osvw_id = *erratum++; + u32 range; + u32 ms; + + if (osvw_id >= 0 && osvw_id < 65536 && + cpu_has(cpu, X86_FEATURE_OSVW)) { + u64 osvw_len; + + rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len); + if (osvw_id < osvw_len) { + u64 osvw_bits; + + rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6), + osvw_bits); + return osvw_bits & (1ULL << (osvw_id & 0x3f)); + } + } + + /* OSVW unavailable or ID unknown, match family-model-stepping range */ + ms = (cpu->x86_model << 4) | cpu->x86_stepping; + while ((range = *erratum++)) + if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) && + (ms >= AMD_MODEL_RANGE_START(range)) && + (ms <= AMD_MODEL_RANGE_END(range))) + return true; + + return false; +} + static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) { u32 gprs[8] = { 0 }; @@ -1115,73 +1177,6 @@ static const struct cpu_dev amd_cpu_dev = { cpu_dev_register(amd_cpu_dev); -/* - * AMD errata checking - * - * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or - * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that - * have an OSVW id assigned, which it takes as first argument. Both take a - * variable number of family-specific model-stepping ranges created by - * AMD_MODEL_RANGE(). - * - * Example: - * - * const int amd_erratum_319[] = - * AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2), - * AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0), - * AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0)); - */ - -#define AMD_LEGACY_ERRATUM(...) { -1, __VA_ARGS__, 0 } -#define AMD_OSVW_ERRATUM(osvw_id, ...) { osvw_id, __VA_ARGS__, 0 } -#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \ - ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end)) -#define AMD_MODEL_RANGE_FAMILY(range) (((range) >> 24) & 0xff) -#define AMD_MODEL_RANGE_START(range) (((range) >> 12) & 0xfff) -#define AMD_MODEL_RANGE_END(range) ((range) & 0xfff) - -static const int amd_erratum_400[] = - AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), - AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)); - -static const int amd_erratum_383[] = - AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf)); - -/* #1054: Instructions Retired Performance Counter May Be Inaccurate */ -static const int amd_erratum_1054[] = - AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf)); - -static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) -{ - int osvw_id = *erratum++; - u32 range; - u32 ms; - - if (osvw_id >= 0 && osvw_id < 65536 && - cpu_has(cpu, X86_FEATURE_OSVW)) { - u64 osvw_len; - - rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len); - if (osvw_id < osvw_len) { - u64 osvw_bits; - - rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6), - osvw_bits); - return osvw_bits & (1ULL << (osvw_id & 0x3f)); - } - } - - /* OSVW unavailable or ID unknown, match family-model-stepping range */ - ms = (cpu->x86_model << 4) | cpu->x86_stepping; - while ((range = *erratum++)) - if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) && - (ms >= AMD_MODEL_RANGE_START(range)) && - (ms <= AMD_MODEL_RANGE_END(range))) - return true; - - return false; -} - static DEFINE_PER_CPU_READ_MOSTLY(unsigned long[4], amd_dr_addr_mask); static unsigned int amd_msr_dr_addr_masks[] = { From 522b1d69219d8f083173819fde04f994aa051a98 Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Sat, 15 Jul 2023 13:41:28 +0200 Subject: [PATCH 115/272] x86/cpu/amd: Add a Zenbleed fix Add a fix for the Zen2 VZEROUPPER data corruption bug where under certain circumstances executing VZEROUPPER can cause register corruption or leak data. The optimal fix is through microcode but in the case the proper microcode revision has not been applied, enable a fallback fix using a chicken bit. Signed-off-by: Borislav Petkov (AMD) --- arch/x86/include/asm/microcode.h | 1 + arch/x86/include/asm/microcode_amd.h | 2 + arch/x86/include/asm/msr-index.h | 1 + arch/x86/kernel/cpu/amd.c | 60 ++++++++++++++++++++++++++++ arch/x86/kernel/cpu/common.c | 2 + 5 files changed, 66 insertions(+) diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h index 320566a0443d..66dbba181bd9 100644 --- a/arch/x86/include/asm/microcode.h +++ b/arch/x86/include/asm/microcode.h @@ -5,6 +5,7 @@ #include #include #include +#include struct ucode_patch { struct list_head plist; diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h index e6662adf3af4..9675c621c1ca 100644 --- a/arch/x86/include/asm/microcode_amd.h +++ b/arch/x86/include/asm/microcode_amd.h @@ -48,11 +48,13 @@ extern void __init load_ucode_amd_bsp(unsigned int family); extern void load_ucode_amd_ap(unsigned int family); extern int __init save_microcode_in_initrd_amd(unsigned int family); void reload_ucode_amd(unsigned int cpu); +extern void amd_check_microcode(void); #else static inline void __init load_ucode_amd_bsp(unsigned int family) {} static inline void load_ucode_amd_ap(unsigned int family) {} static inline int __init save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; } static inline void reload_ucode_amd(unsigned int cpu) {} +static inline void amd_check_microcode(void) {} #endif #endif /* _ASM_X86_MICROCODE_AMD_H */ diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 3aedae61af4f..a00a53e15ab7 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -545,6 +545,7 @@ #define MSR_AMD64_DE_CFG 0xc0011029 #define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT 1 #define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE BIT_ULL(MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT) +#define MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT 9 #define MSR_AMD64_BU_CFG2 0xc001102a #define MSR_AMD64_IBSFETCHCTL 0xc0011030 diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 27e177f7ef43..26ad7ca423e7 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -70,6 +70,11 @@ static const int amd_erratum_383[] = static const int amd_erratum_1054[] = AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf)); +static const int amd_zenbleed[] = + AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x30, 0x0, 0x4f, 0xf), + AMD_MODEL_RANGE(0x17, 0x60, 0x0, 0x7f, 0xf), + AMD_MODEL_RANGE(0x17, 0xa0, 0x0, 0xaf, 0xf)); + static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) { int osvw_id = *erratum++; @@ -978,6 +983,47 @@ static void init_amd_zn(struct cpuinfo_x86 *c) } } +static bool cpu_has_zenbleed_microcode(void) +{ + u32 good_rev = 0; + + switch (boot_cpu_data.x86_model) { + case 0x30 ... 0x3f: good_rev = 0x0830107a; break; + case 0x60 ... 0x67: good_rev = 0x0860010b; break; + case 0x68 ... 0x6f: good_rev = 0x08608105; break; + case 0x70 ... 0x7f: good_rev = 0x08701032; break; + case 0xa0 ... 0xaf: good_rev = 0x08a00008; break; + + default: + return false; + break; + } + + if (boot_cpu_data.microcode < good_rev) + return false; + + return true; +} + +static void zenbleed_check(struct cpuinfo_x86 *c) +{ + if (!cpu_has_amd_erratum(c, amd_zenbleed)) + return; + + if (cpu_has(c, X86_FEATURE_HYPERVISOR)) + return; + + if (!cpu_has(c, X86_FEATURE_AVX)) + return; + + if (!cpu_has_zenbleed_microcode()) { + pr_notice_once("Zenbleed: please update your microcode for the most optimal fix\n"); + msr_set_bit(MSR_AMD64_DE_CFG, MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT); + } else { + msr_clear_bit(MSR_AMD64_DE_CFG, MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT); + } +} + static void init_amd(struct cpuinfo_x86 *c) { early_init_amd(c); @@ -1082,6 +1128,8 @@ static void init_amd(struct cpuinfo_x86 *c) if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) && cpu_has(c, X86_FEATURE_AUTOIBRS)) WARN_ON_ONCE(msr_set_bit(MSR_EFER, _EFER_AUTOIBRS)); + + zenbleed_check(c); } #ifdef CONFIG_X86_32 @@ -1230,3 +1278,15 @@ u32 amd_get_highest_perf(void) return 255; } EXPORT_SYMBOL_GPL(amd_get_highest_perf); + +static void zenbleed_check_cpu(void *unused) +{ + struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); + + zenbleed_check(c); +} + +void amd_check_microcode(void) +{ + on_each_cpu(zenbleed_check_cpu, NULL, 1); +} diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 52683fddafaf..0ba1067f4e5f 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -2287,6 +2287,8 @@ void microcode_check(struct cpuinfo_x86 *prev_info) perf_check_microcode(); + amd_check_microcode(); + store_cpu_caps(&curr_info); if (!memcmp(&prev_info->x86_capability, &curr_info.x86_capability, From 269f399dc19f0e5c51711c3ba3bd06e0ef6ef403 Mon Sep 17 00:00:00 2001 From: Matus Gajdos Date: Wed, 12 Jul 2023 14:49:33 +0200 Subject: [PATCH 116/272] ASoC: fsl_sai: Disable bit clock with transmitter Otherwise bit clock remains running writing invalid data to the DAC. Signed-off-by: Matus Gajdos Acked-by: Shengjiu Wang Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230712124934.32232-1-matuszpd@gmail.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 2 +- sound/soc/fsl/fsl_sai.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 54b4bf3744c6..f7676d30c82f 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -713,7 +713,7 @@ static void fsl_sai_config_disable(struct fsl_sai *sai, int dir) u32 xcsr, count = 100; regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), - FSL_SAI_CSR_TERE, 0); + FSL_SAI_CSR_TERE | FSL_SAI_CSR_BCE, 0); /* TERE will remain set till the end of current frame */ do { diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 8254c3547b87..550df87b6a06 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -91,6 +91,7 @@ /* SAI Transmit/Receive Control Register */ #define FSL_SAI_CSR_TERE BIT(31) #define FSL_SAI_CSR_SE BIT(30) +#define FSL_SAI_CSR_BCE BIT(28) #define FSL_SAI_CSR_FR BIT(25) #define FSL_SAI_CSR_SR BIT(24) #define FSL_SAI_CSR_xF_SHIFT 16 From 5ff92181577a89ed12ad4e0e5813751faf16a139 Mon Sep 17 00:00:00 2001 From: Claudio Imbrenda Date: Wed, 5 Jul 2023 13:19:36 +0200 Subject: [PATCH 117/272] KVM: s390: pv: simplify shutdown and fix race Simplify the shutdown of non-protected VMs. There is no need to do complex manipulations of the counter if it was zero. This also fixes a very rare race which caused pages to be torn down from the address space with a non-zero counter even on older machines that don't support the UVC instruction, causing a crash. Reported-by: Marc Hartmayer Fixes: fb491d5500a7 ("KVM: s390: pv: asynchronous destroy for reboot") Reviewed-by: Nico Boehr Signed-off-by: Claudio Imbrenda Message-ID: <20230705111937.33472-2-imbrenda@linux.ibm.com> --- arch/s390/kvm/pv.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c index 2f34c7c3c5ab..bf1fdc7bf89e 100644 --- a/arch/s390/kvm/pv.c +++ b/arch/s390/kvm/pv.c @@ -411,8 +411,12 @@ int kvm_s390_pv_deinit_cleanup_all(struct kvm *kvm, u16 *rc, u16 *rrc) u16 _rc, _rrc; int cc = 0; - /* Make sure the counter does not reach 0 before calling s390_uv_destroy_range */ - atomic_inc(&kvm->mm->context.protected_count); + /* + * Nothing to do if the counter was already 0. Otherwise make sure + * the counter does not reach 0 before calling s390_uv_destroy_range. + */ + if (!atomic_inc_not_zero(&kvm->mm->context.protected_count)) + return 0; *rc = 1; /* If the current VM is protected, destroy it */ From c2fceb59bbda16468bda82b002383bff59de89ab Mon Sep 17 00:00:00 2001 From: Claudio Imbrenda Date: Wed, 5 Jul 2023 13:19:37 +0200 Subject: [PATCH 118/272] KVM: s390: pv: fix index value of replaced ASCE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The index field of the struct page corresponding to a guest ASCE should be 0. When replacing the ASCE in s390_replace_asce(), the index of the new ASCE should also be set to 0. Having the wrong index might lead to the wrong addresses being passed around when notifying pte invalidations, and eventually to validity intercepts (VM crash) if the prefix gets unmapped and the notifier gets called with the wrong address. Reviewed-by: Philippe Mathieu-Daudé Fixes: faa2f72cb356 ("KVM: s390: pv: leak the topmost page table when destroy fails") Reviewed-by: Janosch Frank Signed-off-by: Claudio Imbrenda Message-ID: <20230705111937.33472-3-imbrenda@linux.ibm.com> --- arch/s390/mm/gmap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 989ebd0912b4..9c8af31be970 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -2853,6 +2853,7 @@ int s390_replace_asce(struct gmap *gmap) page = alloc_pages(GFP_KERNEL_ACCOUNT, CRST_ALLOC_ORDER); if (!page) return -ENOMEM; + page->index = 0; table = page_to_virt(page); memcpy(table, gmap->table, 1UL << (CRST_ALLOC_ORDER + PAGE_SHIFT)); From 7686762d1ed092db4d120e29b565712c969dc075 Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Thu, 13 Jul 2023 15:54:23 +0200 Subject: [PATCH 119/272] s390/mm: fix per vma lock fault handling With per-vma locks, handle_mm_fault() may return non-fatal error flags. In this case the code should reset the fault flags before returning. Fixes: e06f47a16573 ("s390/mm: try VMA lock-based page fault handling first") Signed-off-by: Sven Schnelle Reviewed-by: Heiko Carstens Signed-off-by: Heiko Carstens --- arch/s390/mm/fault.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index dbe8394234e2..2f123429a291 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -421,6 +421,8 @@ static inline vm_fault_t do_exception(struct pt_regs *regs, int access) vma_end_read(vma); if (!(fault & VM_FAULT_RETRY)) { count_vm_vma_lock_event(VMA_LOCK_SUCCESS); + if (likely(!(fault & VM_FAULT_ERROR))) + fault = 0; goto out; } count_vm_vma_lock_event(VMA_LOCK_RETRY); From c250ef8954eda2024c8861c36e9fc1b589481fe7 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Tue, 18 Jul 2023 16:57:22 +0200 Subject: [PATCH 120/272] ALSA: hda/realtek: Add quirk for Clevo NS70AU Fixes headset detection on Clevo NS70AU. Co-developed-by: Werner Sembach Signed-off-by: Werner Sembach Signed-off-by: Christoffer Sandberg Cc: Link: https://lore.kernel.org/r/20230718145722.10592-1-wse@tuxedocomputers.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index afb4d82475b4..392e6fce6e02 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9728,6 +9728,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1558, 0x5157, "Clevo W517GU1", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x51a1, "Clevo NS50MU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x51b1, "Clevo NS50AU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1558, 0x51b3, "Clevo NS70AU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x5630, "Clevo NP50RNJS", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x70a1, "Clevo NB70T[HJK]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x70b3, "Clevo NK70SB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), From f75546f58a70da5cfdcec5a45ffc377885ccbee8 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 18 Jul 2023 08:38:37 -0400 Subject: [PATCH 121/272] nfsd: Remove incorrect check in nfsd4_validate_stateid If the client is calling TEST_STATEID, then it is because some event occurred that requires it to check all the stateids for validity and call FREE_STATEID on the ones that have been revoked. In this case, either the stateid exists in the list of stateids associated with that nfs4_client, in which case it should be tested, or it does not. There are no additional conditions to be considered. Reported-by: "Frank Ch. Eigler" Fixes: 7df302f75ee2 ("NFSD: TEST_STATEID should not return NFS4ERR_STALE_STATEID") Cc: stable@vger.kernel.org # v5.7+ Signed-off-by: Trond Myklebust Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever --- fs/nfsd/nfs4state.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 6e61fa3acaf1..3aefbad4cc09 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -6341,8 +6341,6 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) if (ZERO_STATEID(stateid) || ONE_STATEID(stateid) || CLOSE_STATEID(stateid)) return status; - if (!same_clid(&stateid->si_opaque.so_clid, &cl->cl_clientid)) - return status; spin_lock(&cl->cl_lock); s = find_stateid_locked(cl, stateid); if (!s) From 60a2dae4902015f43d144f5a4710f655b2955b9b Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 7 Jul 2023 21:26:10 -0500 Subject: [PATCH 122/272] drm/amd: Use amdgpu_device_pcie_dynamic_switching_supported() for SMU7 SMU7 does a check if the dGPU is inserted into a Rocket Lake system, to turn off DPM. Extend this check to all systems that have problems with dynamic switching by using the amdgpu_device_pcie_dynamic_switching_supported() helper. Signed-off-by: Mario Limonciello Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- .../gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c index 6841a4bce186..1cb402264497 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c @@ -1798,17 +1798,6 @@ static int smu7_disable_dpm_tasks(struct pp_hwmgr *hwmgr) return result; } -static bool intel_core_rkl_chk(void) -{ -#if IS_ENABLED(CONFIG_X86_64) - struct cpuinfo_x86 *c = &cpu_data(0); - - return (c->x86 == 6 && c->x86_model == INTEL_FAM6_ROCKETLAKE); -#else - return false; -#endif -} - static void smu7_init_dpm_defaults(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); @@ -1835,7 +1824,8 @@ static void smu7_init_dpm_defaults(struct pp_hwmgr *hwmgr) data->mclk_dpm_key_disabled = hwmgr->feature_mask & PP_MCLK_DPM_MASK ? false : true; data->sclk_dpm_key_disabled = hwmgr->feature_mask & PP_SCLK_DPM_MASK ? false : true; data->pcie_dpm_key_disabled = - intel_core_rkl_chk() || !(hwmgr->feature_mask & PP_PCIE_DPM_MASK); + !amdgpu_device_pcie_dynamic_switching_supported() || + !(hwmgr->feature_mask & PP_PCIE_DPM_MASK); /* need to set voltage control types before EVV patching */ data->voltage_control = SMU7_VOLTAGE_CONTROL_NONE; data->vddci_control = SMU7_VOLTAGE_CONTROL_NONE; From 2ed5a4c4615b47c70dcd8d7d942207e5a607561d Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Tue, 11 Jul 2023 14:14:43 -0400 Subject: [PATCH 123/272] drm/amd/display: export some optc function for reuse [Why&How] Make a few functions non static so that they can be reused for other asic. This is in preparation for separating out OTG programming sequence for DCN301 Fixes: 1598fc576420 ("drm/amd/display: Program OTG vtotal min/max selectors unconditionally for DCN1+") Reviewed-by: Swapnil Patel Signed-off-by: Aurabindo Pillai Tested-by: Guilherme G. Piccoli Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c | 4 ++-- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c index dfb8f62765f2..5bf4d0aa6230 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c @@ -215,7 +215,7 @@ void optc3_set_odm_bypass(struct timing_generator *optc, optc1->opp_count = 1; } -static void optc3_set_odm_combine(struct timing_generator *optc, int *opp_id, int opp_cnt, +void optc3_set_odm_combine(struct timing_generator *optc, int *opp_id, int opp_cnt, struct dc_crtc_timing *timing) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -293,7 +293,7 @@ static void optc3_set_timing_double_buffer(struct timing_generator *optc, bool e OTG_DRR_TIMING_DBUF_UPDATE_MODE, mode); } -static void optc3_wait_drr_doublebuffer_pending_clear(struct timing_generator *optc) +void optc3_wait_drr_doublebuffer_pending_clear(struct timing_generator *optc) { struct optc *optc1 = DCN10TG_FROM_TG(optc); diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h index fb06dc9a4893..d3a056c12b0d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h @@ -351,6 +351,9 @@ void optc3_set_timing_db_mode(struct timing_generator *optc, bool enable); void optc3_set_odm_bypass(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing); +void optc3_set_odm_combine(struct timing_generator *optc, int *opp_id, int opp_cnt, + struct dc_crtc_timing *timing); +void optc3_wait_drr_doublebuffer_pending_clear(struct timing_generator *optc); void optc3_tg_init(struct timing_generator *optc); void optc3_set_vtotal_min_max(struct timing_generator *optc, int vtotal_min, int vtotal_max); #endif /* __DC_OPTC_DCN30_H__ */ From d1792509e1031a6750f82bc7faa5fc9d7203b5b7 Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Wed, 12 Jul 2023 12:35:16 -0400 Subject: [PATCH 124/272] drm/amd/display: add DCN301 specific logic for OTG programming [Why&How] DCN301 does not have FAMS hence the workaround needed on other DCN3x variants related to OTG min/max selector programming is not applicable for it. Hence isolate it and have it use the old sequence without workaround. Fixes: 1598fc576420 ("drm/amd/display: Program OTG vtotal min/max selectors unconditionally for DCN1+") Reviewed-by: Swapnil Patel Signed-off-by: Aurabindo Pillai Tested-by: Guilherme G. Piccoli Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn301/Makefile | 3 +- .../drm/amd/display/dc/dcn301/dcn301_optc.c | 185 ++++++++++++++++++ .../drm/amd/display/dc/dcn301/dcn301_optc.h | 36 ++++ .../amd/display/dc/dcn301/dcn301_resource.c | 4 +- 4 files changed, 225 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/dc/dcn301/dcn301_optc.c create mode 100644 drivers/gpu/drm/amd/display/dc/dcn301/dcn301_optc.h diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/Makefile b/drivers/gpu/drm/amd/display/dc/dcn301/Makefile index 7aa628c21973..9002cb10a6ae 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn301/Makefile @@ -11,7 +11,8 @@ # Makefile for dcn30. DCN301 = dcn301_init.o dcn301_resource.o dcn301_dccg.o \ - dcn301_dio_link_encoder.o dcn301_hwseq.o dcn301_panel_cntl.o dcn301_hubbub.o + dcn301_dio_link_encoder.o dcn301_hwseq.o dcn301_panel_cntl.o dcn301_hubbub.o \ + dcn301_optc.o AMD_DAL_DCN301 = $(addprefix $(AMDDALPATH)/dc/dcn301/,$(DCN301)) diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_optc.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_optc.c new file mode 100644 index 000000000000..b3cfcb887905 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_optc.c @@ -0,0 +1,185 @@ +/* + * Copyright 2020 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include "reg_helper.h" +#include "dcn301_optc.h" +#include "dc.h" +#include "dcn_calc_math.h" +#include "dc_dmub_srv.h" + +#include "dml/dcn30/dcn30_fpu.h" +#include "dc_trace.h" + +#define REG(reg)\ + optc1->tg_regs->reg + +#define CTX \ + optc1->base.ctx + +#undef FN +#define FN(reg_name, field_name) \ + optc1->tg_shift->field_name, optc1->tg_mask->field_name + + +/** + * optc301_set_drr() - Program dynamic refresh rate registers m_OTGx_OTG_V_TOTAL_*. + * + * @optc: timing_generator instance. + * @params: parameters used for Dynamic Refresh Rate. + */ +void optc301_set_drr( + struct timing_generator *optc, + const struct drr_params *params) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + if (params != NULL && + params->vertical_total_max > 0 && + params->vertical_total_min > 0) { + + if (params->vertical_total_mid != 0) { + + REG_SET(OTG_V_TOTAL_MID, 0, + OTG_V_TOTAL_MID, params->vertical_total_mid - 1); + + REG_UPDATE_2(OTG_V_TOTAL_CONTROL, + OTG_VTOTAL_MID_REPLACING_MAX_EN, 1, + OTG_VTOTAL_MID_FRAME_NUM, + (uint8_t)params->vertical_total_mid_frame_num); + + } + + optc->funcs->set_vtotal_min_max(optc, params->vertical_total_min - 1, params->vertical_total_max - 1); + + REG_UPDATE_5(OTG_V_TOTAL_CONTROL, + OTG_V_TOTAL_MIN_SEL, 1, + OTG_V_TOTAL_MAX_SEL, 1, + OTG_FORCE_LOCK_ON_EVENT, 0, + OTG_SET_V_TOTAL_MIN_MASK_EN, 0, + OTG_SET_V_TOTAL_MIN_MASK, 0); + // Setup manual flow control for EOF via TRIG_A + optc->funcs->setup_manual_trigger(optc); + + } else { + REG_UPDATE_4(OTG_V_TOTAL_CONTROL, + OTG_SET_V_TOTAL_MIN_MASK, 0, + OTG_V_TOTAL_MIN_SEL, 0, + OTG_V_TOTAL_MAX_SEL, 0, + OTG_FORCE_LOCK_ON_EVENT, 0); + + optc->funcs->set_vtotal_min_max(optc, 0, 0); + } +} + + +void optc301_setup_manual_trigger(struct timing_generator *optc) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + REG_SET_8(OTG_TRIGA_CNTL, 0, + OTG_TRIGA_SOURCE_SELECT, 21, + OTG_TRIGA_SOURCE_PIPE_SELECT, optc->inst, + OTG_TRIGA_RISING_EDGE_DETECT_CNTL, 1, + OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, 0, + OTG_TRIGA_POLARITY_SELECT, 0, + OTG_TRIGA_FREQUENCY_SELECT, 0, + OTG_TRIGA_DELAY, 0, + OTG_TRIGA_CLEAR, 1); +} + +static struct timing_generator_funcs dcn30_tg_funcs = { + .validate_timing = optc1_validate_timing, + .program_timing = optc1_program_timing, + .setup_vertical_interrupt0 = optc1_setup_vertical_interrupt0, + .setup_vertical_interrupt1 = optc1_setup_vertical_interrupt1, + .setup_vertical_interrupt2 = optc1_setup_vertical_interrupt2, + .program_global_sync = optc1_program_global_sync, + .enable_crtc = optc2_enable_crtc, + .disable_crtc = optc1_disable_crtc, + /* used by enable_timing_synchronization. Not need for FPGA */ + .is_counter_moving = optc1_is_counter_moving, + .get_position = optc1_get_position, + .get_frame_count = optc1_get_vblank_counter, + .get_scanoutpos = optc1_get_crtc_scanoutpos, + .get_otg_active_size = optc1_get_otg_active_size, + .set_early_control = optc1_set_early_control, + /* used by enable_timing_synchronization. Not need for FPGA */ + .wait_for_state = optc1_wait_for_state, + .set_blank_color = optc3_program_blank_color, + .did_triggered_reset_occur = optc1_did_triggered_reset_occur, + .triplebuffer_lock = optc3_triplebuffer_lock, + .triplebuffer_unlock = optc2_triplebuffer_unlock, + .enable_reset_trigger = optc1_enable_reset_trigger, + .enable_crtc_reset = optc1_enable_crtc_reset, + .disable_reset_trigger = optc1_disable_reset_trigger, + .lock = optc3_lock, + .unlock = optc1_unlock, + .lock_doublebuffer_enable = optc3_lock_doublebuffer_enable, + .lock_doublebuffer_disable = optc3_lock_doublebuffer_disable, + .enable_optc_clock = optc1_enable_optc_clock, + .set_drr = optc301_set_drr, + .get_last_used_drr_vtotal = optc2_get_last_used_drr_vtotal, + .set_vtotal_min_max = optc3_set_vtotal_min_max, + .set_static_screen_control = optc1_set_static_screen_control, + .program_stereo = optc1_program_stereo, + .is_stereo_left_eye = optc1_is_stereo_left_eye, + .tg_init = optc3_tg_init, + .is_tg_enabled = optc1_is_tg_enabled, + .is_optc_underflow_occurred = optc1_is_optc_underflow_occurred, + .clear_optc_underflow = optc1_clear_optc_underflow, + .setup_global_swap_lock = NULL, + .get_crc = optc1_get_crc, + .configure_crc = optc2_configure_crc, + .set_dsc_config = optc3_set_dsc_config, + .get_dsc_status = optc2_get_dsc_status, + .set_dwb_source = NULL, + .set_odm_bypass = optc3_set_odm_bypass, + .set_odm_combine = optc3_set_odm_combine, + .get_optc_source = optc2_get_optc_source, + .set_out_mux = optc3_set_out_mux, + .set_drr_trigger_window = optc3_set_drr_trigger_window, + .set_vtotal_change_limit = optc3_set_vtotal_change_limit, + .set_gsl = optc2_set_gsl, + .set_gsl_source_select = optc2_set_gsl_source_select, + .set_vtg_params = optc1_set_vtg_params, + .program_manual_trigger = optc2_program_manual_trigger, + .setup_manual_trigger = optc301_setup_manual_trigger, + .get_hw_timing = optc1_get_hw_timing, + .wait_drr_doublebuffer_pending_clear = optc3_wait_drr_doublebuffer_pending_clear, +}; + +void dcn301_timing_generator_init(struct optc *optc1) +{ + optc1->base.funcs = &dcn30_tg_funcs; + + optc1->max_h_total = optc1->tg_mask->OTG_H_TOTAL + 1; + optc1->max_v_total = optc1->tg_mask->OTG_V_TOTAL + 1; + + optc1->min_h_blank = 32; + optc1->min_v_blank = 3; + optc1->min_v_blank_interlace = 5; + optc1->min_h_sync_width = 4; + optc1->min_v_sync_width = 1; +} diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_optc.h b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_optc.h new file mode 100644 index 000000000000..b49585682a15 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_optc.h @@ -0,0 +1,36 @@ +/* + * Copyright 2020 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __DC_OPTC_DCN301_H__ +#define __DC_OPTC_DCN301_H__ + +#include "dcn20/dcn20_optc.h" +#include "dcn30/dcn30_optc.h" + +void dcn301_timing_generator_init(struct optc *optc1); +void optc301_setup_manual_trigger(struct timing_generator *optc); +void optc301_set_drr(struct timing_generator *optc, const struct drr_params *params); + +#endif /* __DC_OPTC_DCN301_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c index 3485fbb1093e..1bee9a4636e6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c @@ -42,7 +42,7 @@ #include "dcn30/dcn30_hubp.h" #include "irq/dcn30/irq_service_dcn30.h" #include "dcn30/dcn30_dpp.h" -#include "dcn30/dcn30_optc.h" +#include "dcn301/dcn301_optc.h" #include "dcn20/dcn20_hwseq.h" #include "dcn30/dcn30_hwseq.h" #include "dce110/dce110_hw_sequencer.h" @@ -855,7 +855,7 @@ static struct timing_generator *dcn301_timing_generator_create( tgn10->tg_shift = &optc_shift; tgn10->tg_mask = &optc_mask; - dcn30_timing_generator_init(tgn10); + dcn301_timing_generator_init(tgn10); return &tgn10->base; } From b42ae87a7b3878afaf4c3852ca66c025a5b996e0 Mon Sep 17 00:00:00 2001 From: Guchun Chen Date: Thu, 6 Jul 2023 15:57:21 +0800 Subject: [PATCH 125/272] drm/amdgpu/vkms: relax timer deactivation by hrtimer_try_to_cancel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In below thousands of screen rotation loop tests with virtual display enabled, a CPU hard lockup issue may happen, leading system to unresponsive and crash. do { xrandr --output Virtual --rotate inverted xrandr --output Virtual --rotate right xrandr --output Virtual --rotate left xrandr --output Virtual --rotate normal } while (1); NMI watchdog: Watchdog detected hard LOCKUP on cpu 1 ? hrtimer_run_softirq+0x140/0x140 ? store_vblank+0xe0/0xe0 [drm] hrtimer_cancel+0x15/0x30 amdgpu_vkms_disable_vblank+0x15/0x30 [amdgpu] drm_vblank_disable_and_save+0x185/0x1f0 [drm] drm_crtc_vblank_off+0x159/0x4c0 [drm] ? record_print_text.cold+0x11/0x11 ? wait_for_completion_timeout+0x232/0x280 ? drm_crtc_wait_one_vblank+0x40/0x40 [drm] ? bit_wait_io_timeout+0xe0/0xe0 ? wait_for_completion_interruptible+0x1d7/0x320 ? mutex_unlock+0x81/0xd0 amdgpu_vkms_crtc_atomic_disable It's caused by a stuck in lock dependency in such scenario on different CPUs. CPU1 CPU2 drm_crtc_vblank_off hrtimer_interrupt grab event_lock (irq disabled) __hrtimer_run_queues grab vbl_lock/vblank_time_block amdgpu_vkms_vblank_simulate amdgpu_vkms_disable_vblank drm_handle_vblank hrtimer_cancel grab dev->event_lock So CPU1 stucks in hrtimer_cancel as timer callback is running endless on current clock base, as that timer queue on CPU2 has no chance to finish it because of failing to hold the lock. So NMI watchdog will throw the errors after its threshold, and all later CPUs are impacted/blocked. So use hrtimer_try_to_cancel to fix this, as disable_vblank callback does not need to wait the handler to finish. And also it's not necessary to check the return value of hrtimer_try_to_cancel, because even if it's -1 which means current timer callback is running, it will be reprogrammed in hrtimer_start with calling enable_vblank to make it works. v2: only re-arm timer when vblank is enabled (Christian) and add a Fixes tag as well v3: drop warn printing (Christian) v4: drop superfluous check of blank->enabled in timer function, as it's guaranteed in drm_handle_vblank (Christian) Fixes: 84ec374bd580 ("drm/amdgpu: create amdgpu_vkms (v4)") Cc: stable@vger.kernel.org Suggested-by: Christian König Signed-off-by: Guchun Chen Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c index 53ff91fc6cf6..d0748bcfad16 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c @@ -55,8 +55,9 @@ static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct hrtimer *timer) DRM_WARN("%s: vblank timer overrun\n", __func__); ret = drm_crtc_handle_vblank(crtc); + /* Don't queue timer again when vblank is disabled. */ if (!ret) - DRM_ERROR("amdgpu_vkms failure on handling vblank"); + return HRTIMER_NORESTART; return HRTIMER_RESTART; } @@ -81,7 +82,7 @@ static void amdgpu_vkms_disable_vblank(struct drm_crtc *crtc) { struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); - hrtimer_cancel(&amdgpu_crtc->vblank_timer); + hrtimer_try_to_cancel(&amdgpu_crtc->vblank_timer); } static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc, From 1ca67aba8d11c2849d395013e1fdce02918d5657 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 21 Jun 2023 17:24:59 -0300 Subject: [PATCH 126/272] drm/amd/display: only accept async flips for fast updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Up until now, amdgpu was silently degrading to vsync when user-space requested an async flip but the hardware didn't support it. The hardware doesn't support immediate flips when the update changes the FB pitch, the DCC state, the rotation, enables or disables CRTCs or planes, etc. This is reflected in the dm_crtc_state.update_type field: UPDATE_TYPE_FAST means that immediate flip is supported. Silently degrading async flips to vsync is not the expected behavior from a uAPI point-of-view. Xorg expects async flips to fail if unsupported, to be able to fall back to a blit. i915 already behaves this way. This patch aligns amdgpu with uAPI expectations and returns a failure when an async flip is not possible. Signed-off-by: Simon Ser Reviewed-by: André Almeida Reviewed-by: Alex Deucher Reviewed-by: Harry Wentland Signed-off-by: André Almeida Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++++++++ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index ff0a217b9d56..391130c3a0d5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8125,7 +8125,15 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, * Only allow immediate flips for fast updates that don't * change memory domain, FB pitch, DCC state, rotation or * mirroring. + * + * dm_crtc_helper_atomic_check() only accepts async flips with + * fast updates. */ + if (crtc->state->async_flip && + acrtc_state->update_type != UPDATE_TYPE_FAST) + drm_warn_once(state->dev, + "[PLANE:%d:%s] async flip with non-fast update\n", + plane->base.id, plane->name); bundle->flip_addrs[planes_count].flip_immediate = crtc->state->async_flip && acrtc_state->update_type == UPDATE_TYPE_FAST && diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index 440fc0869a34..30d4c6fd95f5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -398,6 +398,18 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, return -EINVAL; } + /* + * Only allow async flips for fast updates that don't change the FB + * pitch, the DCC state, rotation, etc. + */ + if (crtc_state->async_flip && + dm_crtc_state->update_type != UPDATE_TYPE_FAST) { + drm_dbg_atomic(crtc->dev, + "[CRTC:%d:%s] async flips are only supported for fast updates\n", + crtc->base.id, crtc->name); + return -EINVAL; + } + /* In some use cases, like reset, no stream is attached */ if (!dm_crtc_state->stream) return 0; From a4eb11824170d742531998f4ebd1c6a18b63db47 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 13 Jun 2023 12:15:38 -0400 Subject: [PATCH 127/272] drm/amdgpu/pm: make gfxclock consistent for sienna cichlid Use average gfxclock for consistency with other dGPUs. Reviewed-by: Kenneth Feng Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 6.1.x --- drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index f6599c00a6fd..0cda3b276f61 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -1927,12 +1927,16 @@ static int sienna_cichlid_read_sensor(struct smu_context *smu, *size = 4; break; case AMDGPU_PP_SENSOR_GFX_MCLK: - ret = sienna_cichlid_get_current_clk_freq_by_table(smu, SMU_UCLK, (uint32_t *)data); + ret = sienna_cichlid_get_smu_metrics_data(smu, + METRICS_CURR_UCLK, + (uint32_t *)data); *(uint32_t *)data *= 100; *size = 4; break; case AMDGPU_PP_SENSOR_GFX_SCLK: - ret = sienna_cichlid_get_current_clk_freq_by_table(smu, SMU_GFXCLK, (uint32_t *)data); + ret = sienna_cichlid_get_smu_metrics_data(smu, + METRICS_AVERAGE_GFXCLK, + (uint32_t *)data); *(uint32_t *)data *= 100; *size = 4; break; From 068c8bb10f37bb84824625dbbda053a3a3e0d6e1 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 13 Jun 2023 12:36:17 -0400 Subject: [PATCH 128/272] drm/amdgpu/pm: make mclk consistent for smu 13.0.7 Use current uclk to be consistent with other dGPUs. Reviewed-by: Kenneth Feng Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 6.1.x --- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index 3ba02131e682..b1f0937ccade 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -949,7 +949,7 @@ static int smu_v13_0_7_read_sensor(struct smu_context *smu, break; case AMDGPU_PP_SENSOR_GFX_MCLK: ret = smu_v13_0_7_get_smu_metrics_data(smu, - METRICS_AVERAGE_UCLK, + METRICS_CURR_UCLK, (uint32_t *)data); *(uint32_t *)data *= 100; *size = 4; From b9c2213cdf254fba71b6bd602a0afe051e554ad9 Mon Sep 17 00:00:00 2001 From: Candice Li Date: Wed, 5 Jul 2023 15:00:45 +0800 Subject: [PATCH 129/272] drm/amdgpu: Allow the initramfs generator to include psp_13_0_6_ta Allow the initramfs generator to automatically include psp_13_0_6_ta firmware to initramfs. Signed-off-by: Candice Li Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c index f9cb0d2c89d1..e1a392bcea70 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -49,6 +49,7 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_10_ta.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_11_toc.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_11_ta.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_6_sos.bin"); +MODULE_FIRMWARE("amdgpu/psp_13_0_6_ta.bin"); /* For large FW files the time to complete can be very long */ #define USBC_PD_POLLING_LIMIT_S 240 From 87279fdf5ee0ad1360765ef70389d1c4d0f81bb6 Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Sat, 17 Jun 2023 21:09:46 +0530 Subject: [PATCH 130/272] drm/amd/display: Clean up errors & warnings in amdgpu_dm.c Fix the following errors & warnings reported by checkpatch: ERROR: space required before the open brace '{' ERROR: space required before the open parenthesis '(' ERROR: that open brace { should be on the previous line ERROR: space prohibited before that ',' (ctx:WxW) ERROR: else should follow close brace '}' ERROR: open brace '{' following function definitions go on the next line ERROR: code indent should use tabs where possible WARNING: braces {} are not necessary for single statement blocks WARNING: void function return statements are not generally useful WARNING: Block comments use * on subsequent lines WARNING: Block comments use a trailing */ on a separate line Cc: Rodrigo Siqueira Cc: Aurabindo Pillai Cc: Alex Deucher Signed-off-by: Srinivasan Shanmugam Reviewed-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 133 +++++++++--------- 1 file changed, 65 insertions(+), 68 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 391130c3a0d5..948d61845efd 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -424,12 +424,12 @@ static void dm_pflip_high_irq(void *interrupt_params) spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); - if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_SUBMITTED){ - DC_LOG_PFLIP("amdgpu_crtc->pflip_status = %d !=AMDGPU_FLIP_SUBMITTED(%d) on crtc:%d[%p] \n", - amdgpu_crtc->pflip_status, - AMDGPU_FLIP_SUBMITTED, - amdgpu_crtc->crtc_id, - amdgpu_crtc); + if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_SUBMITTED) { + DC_LOG_PFLIP("amdgpu_crtc->pflip_status = %d !=AMDGPU_FLIP_SUBMITTED(%d) on crtc:%d[%p]\n", + amdgpu_crtc->pflip_status, + AMDGPU_FLIP_SUBMITTED, + amdgpu_crtc->crtc_id, + amdgpu_crtc); spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); return; } @@ -883,7 +883,7 @@ static int dm_set_powergating_state(void *handle, } /* Prototypes of private functions */ -static int dm_early_init(void* handle); +static int dm_early_init(void *handle); /* Allocate memory for FBC compressed data */ static void amdgpu_dm_fbc_init(struct drm_connector *connector) @@ -1282,7 +1282,7 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_ pa_config->system_aperture.start_addr = (uint64_t)logical_addr_low << 18; pa_config->system_aperture.end_addr = (uint64_t)logical_addr_high << 18; - pa_config->system_aperture.agp_base = (uint64_t)agp_base << 24 ; + pa_config->system_aperture.agp_base = (uint64_t)agp_base << 24; pa_config->system_aperture.agp_bot = (uint64_t)agp_bot << 24; pa_config->system_aperture.agp_top = (uint64_t)agp_top << 24; @@ -1365,8 +1365,7 @@ static void dm_handle_hpd_rx_offload_work(struct work_struct *work) DP_TEST_RESPONSE, &test_response.raw, sizeof(test_response)); - } - else if ((dc_link->connector_signal != SIGNAL_TYPE_EDP) && + } else if ((dc_link->connector_signal != SIGNAL_TYPE_EDP) && dc_link_check_link_loss_status(dc_link, &offload_work->data) && dc_link_dp_allow_hpd_rx_irq(dc_link)) { /* offload_work->data is from handle_hpd_rx_irq-> @@ -1554,7 +1553,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) mutex_init(&adev->dm.dc_lock); mutex_init(&adev->dm.audio_lock); - if(amdgpu_dm_irq_init(adev)) { + if (amdgpu_dm_irq_init(adev)) { DRM_ERROR("amdgpu: failed to initialize DM IRQ support.\n"); goto error; } @@ -1696,9 +1695,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) if (amdgpu_dc_debug_mask & DC_DISABLE_STUTTER) adev->dm.dc->debug.disable_stutter = true; - if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) { + if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) adev->dm.dc->debug.disable_dsc = true; - } if (amdgpu_dc_debug_mask & DC_DISABLE_CLOCK_GATING) adev->dm.dc->debug.disable_clock_gate = true; @@ -1942,8 +1940,6 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev) mutex_destroy(&adev->dm.audio_lock); mutex_destroy(&adev->dm.dc_lock); mutex_destroy(&adev->dm.dpia_aux_lock); - - return; } static int load_dmcu_fw(struct amdgpu_device *adev) @@ -1952,7 +1948,7 @@ static int load_dmcu_fw(struct amdgpu_device *adev) int r; const struct dmcu_firmware_header_v1_0 *hdr; - switch(adev->asic_type) { + switch (adev->asic_type) { #if defined(CONFIG_DRM_AMD_DC_SI) case CHIP_TAHITI: case CHIP_PITCAIRN: @@ -2709,7 +2705,7 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, struct dc_scaling_info scaling_infos[MAX_SURFACES]; struct dc_flip_addrs flip_addrs[MAX_SURFACES]; struct dc_stream_update stream_update; - } * bundle; + } *bundle; int k, m; bundle = kzalloc(sizeof(*bundle), GFP_KERNEL); @@ -2739,8 +2735,6 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, cleanup: kfree(bundle); - - return; } static int dm_resume(void *handle) @@ -2954,8 +2948,7 @@ static const struct amd_ip_funcs amdgpu_dm_funcs = { .set_powergating_state = dm_set_powergating_state, }; -const struct amdgpu_ip_block_version dm_ip_block = -{ +const struct amdgpu_ip_block_version dm_ip_block = { .type = AMD_IP_BLOCK_TYPE_DCE, .major = 1, .minor = 0, @@ -3000,9 +2993,12 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) caps->ext_caps = &aconnector->dc_link->dpcd_sink_ext_caps; caps->aux_support = false; - if (caps->ext_caps->bits.oled == 1 /*|| - caps->ext_caps->bits.sdr_aux_backlight_control == 1 || - caps->ext_caps->bits.hdr_aux_backlight_control == 1*/) + if (caps->ext_caps->bits.oled == 1 + /* + * || + * caps->ext_caps->bits.sdr_aux_backlight_control == 1 || + * caps->ext_caps->bits.hdr_aux_backlight_control == 1 + */) caps->aux_support = true; if (amdgpu_backlight == 0) @@ -3269,6 +3265,7 @@ static void dm_handle_mst_sideband_msg(struct amdgpu_dm_connector *aconnector) process_count < max_process_count) { u8 ack[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = {}; u8 retry; + dret = 0; process_count++; @@ -3468,7 +3465,7 @@ static void register_hpd_handlers(struct amdgpu_device *adev) aconnector = to_amdgpu_dm_connector(connector); dc_link = aconnector->dc_link; - if (DC_IRQ_SOURCE_INVALID != dc_link->irq_source_hpd) { + if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) { int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT; int_params.irq_source = dc_link->irq_source_hpd; @@ -3477,7 +3474,7 @@ static void register_hpd_handlers(struct amdgpu_device *adev) (void *) aconnector); } - if (DC_IRQ_SOURCE_INVALID != dc_link->irq_source_hpd_rx) { + if (dc_link->irq_source_hpd_rx != DC_IRQ_SOURCE_INVALID) { /* Also register for DP short pulse (hpd_rx). */ int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT; @@ -3503,7 +3500,7 @@ static int dce60_register_irq_handlers(struct amdgpu_device *adev) struct dc_interrupt_params int_params = {0}; int r; int i; - unsigned client_id = AMDGPU_IRQ_CLIENTID_LEGACY; + unsigned int client_id = AMDGPU_IRQ_CLIENTID_LEGACY; int_params.requested_polarity = INTERRUPT_POLARITY_DEFAULT; int_params.current_polarity = INTERRUPT_POLARITY_DEFAULT; @@ -3517,11 +3514,12 @@ static int dce60_register_irq_handlers(struct amdgpu_device *adev) * Base driver will call amdgpu_dm_irq_handler() for ALL interrupts * coming from DC hardware. * amdgpu_dm_irq_handler() will re-direct the interrupt to DC - * for acknowledging and handling. */ + * for acknowledging and handling. + */ /* Use VBLANK interrupt */ for (i = 0; i < adev->mode_info.num_crtc; i++) { - r = amdgpu_irq_add_id(adev, client_id, i+1 , &adev->crtc_irq); + r = amdgpu_irq_add_id(adev, client_id, i + 1, &adev->crtc_irq); if (r) { DRM_ERROR("Failed to add crtc irq id!\n"); return r; @@ -3529,7 +3527,7 @@ static int dce60_register_irq_handlers(struct amdgpu_device *adev) int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT; int_params.irq_source = - dc_interrupt_to_irq_source(dc, i+1 , 0); + dc_interrupt_to_irq_source(dc, i + 1, 0); c_irq_params = &adev->dm.vblank_params[int_params.irq_source - DC_IRQ_SOURCE_VBLANK1]; @@ -3585,7 +3583,7 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) struct dc_interrupt_params int_params = {0}; int r; int i; - unsigned client_id = AMDGPU_IRQ_CLIENTID_LEGACY; + unsigned int client_id = AMDGPU_IRQ_CLIENTID_LEGACY; if (adev->family >= AMDGPU_FAMILY_AI) client_id = SOC15_IH_CLIENTID_DCE; @@ -3602,7 +3600,8 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) * Base driver will call amdgpu_dm_irq_handler() for ALL interrupts * coming from DC hardware. * amdgpu_dm_irq_handler() will re-direct the interrupt to DC - * for acknowledging and handling. */ + * for acknowledging and handling. + */ /* Use VBLANK interrupt */ for (i = VISLANDS30_IV_SRCID_D1_VERTICAL_INTERRUPT0; i <= VISLANDS30_IV_SRCID_D6_VERTICAL_INTERRUPT0; i++) { @@ -4049,7 +4048,7 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm, } static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps, - unsigned *min, unsigned *max) + unsigned int *min, unsigned int *max) { if (!caps) return 0; @@ -4069,7 +4068,7 @@ static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps, static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps, uint32_t brightness) { - unsigned min, max; + unsigned int min, max; if (!get_brightness_range(caps, &min, &max)) return brightness; @@ -4082,7 +4081,7 @@ static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *c static u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *caps, uint32_t brightness) { - unsigned min, max; + unsigned int min, max; if (!get_brightness_range(caps, &min, &max)) return brightness; @@ -4562,7 +4561,6 @@ fail: static void amdgpu_dm_destroy_drm_device(struct amdgpu_display_manager *dm) { drm_atomic_private_obj_fini(&dm->atomic_obj); - return; } /****************************************************************************** @@ -5394,6 +5392,7 @@ static bool adjust_colour_depth_from_display_info( { enum dc_color_depth depth = timing_out->display_color_depth; int normalized_clk; + do { normalized_clk = timing_out->pix_clk_100hz / 10; /* YCbCr 4:2:0 requires additional adjustment of 1/2 */ @@ -5609,6 +5608,7 @@ create_fake_sink(struct amdgpu_dm_connector *aconnector) { struct dc_sink_init_data sink_init_data = { 0 }; struct dc_sink *sink = NULL; + sink_init_data.link = aconnector->dc_link; sink_init_data.sink_signal = aconnector->dc_link->connector_signal; @@ -5732,7 +5732,7 @@ get_highest_refresh_rate_mode(struct amdgpu_dm_connector *aconnector, return &aconnector->freesync_vid_base; /* Find the preferred mode */ - list_for_each_entry (m, list_head, head) { + list_for_each_entry(m, list_head, head) { if (m->type & DRM_MODE_TYPE_PREFERRED) { m_pref = m; break; @@ -5756,7 +5756,7 @@ get_highest_refresh_rate_mode(struct amdgpu_dm_connector *aconnector, * For some monitors, preferred mode is not the mode with highest * supported refresh rate. */ - list_for_each_entry (m, list_head, head) { + list_for_each_entry(m, list_head, head) { current_refresh = drm_mode_vrefresh(m); if (m->hdisplay == m_pref->hdisplay && @@ -6028,7 +6028,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, * This may not be an error, the use case is when we have no * usermode calls to reset and set mode upon hotplug. In this * case, we call set mode ourselves to restore the previous mode - * and the modelist may not be filled in in time. + * and the modelist may not be filled in time. */ DRM_DEBUG_DRIVER("No preferred mode found\n"); } else { @@ -6051,9 +6051,9 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, drm_mode_set_crtcinfo(&mode, 0); /* - * If scaling is enabled and refresh rate didn't change - * we copy the vic and polarities of the old timings - */ + * If scaling is enabled and refresh rate didn't change + * we copy the vic and polarities of the old timings + */ if (!scale || mode_refresh != preferred_refresh) fill_stream_properties_from_drm_display_mode( stream, &mode, &aconnector->base, con_state, NULL, @@ -6817,6 +6817,7 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder, if (!state->duplicated) { int max_bpc = conn_state->max_requested_bpc; + is_y420 = drm_mode_is_420_also(&connector->display_info, adjusted_mode) && aconnector->force_yuv420_output; color_depth = convert_color_depth_from_display_info(connector, @@ -7135,7 +7136,7 @@ static bool is_duplicate_mode(struct amdgpu_dm_connector *aconnector, { struct drm_display_mode *m; - list_for_each_entry (m, &aconnector->base.probed_modes, head) { + list_for_each_entry(m, &aconnector->base.probed_modes, head) { if (drm_mode_equal(m, mode)) return true; } @@ -7454,7 +7455,6 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, link->priv = aconnector; - DRM_DEBUG_DRIVER("%s()\n", __func__); i2c = create_i2c(link->ddc, link->link_index, &res); if (!i2c) { @@ -8176,8 +8176,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, * DRI3/Present extension with defined target_msc. */ last_flip_vblank = amdgpu_get_vblank_counter_kms(pcrtc); - } - else { + } else { /* For variable refresh rate mode only: * Get vblank of last completed flip to avoid > 1 vrr * flips per video frame by use of throttling, but allow @@ -8510,8 +8509,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dc_resource_state_copy_construct_current(dm->dc, dc_state); } - for_each_oldnew_crtc_in_state (state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, + new_crtc_state, i) { struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); @@ -8534,9 +8533,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); drm_dbg_state(state->dev, - "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, " - "planes_changed:%d, mode_changed:%d,active_changed:%d," - "connectors_changed:%d\n", + "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, planes_changed:%d, mode_changed:%d,active_changed:%d,connectors_changed:%d\n", acrtc->crtc_id, new_crtc_state->enable, new_crtc_state->active, @@ -9112,8 +9109,8 @@ static int do_aquire_global_lock(struct drm_device *dev, &commit->flip_done, 10*HZ); if (ret == 0) - DRM_ERROR("[CRTC:%d:%s] hw_done or flip_done " - "timed out\n", crtc->base.id, crtc->name); + DRM_ERROR("[CRTC:%d:%s] hw_done or flip_done timed out\n", + crtc->base.id, crtc->name); drm_crtc_commit_put(commit); } @@ -9198,7 +9195,8 @@ is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state, return false; } -static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state) { +static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state) +{ u64 num, den, res; struct drm_crtc_state *new_crtc_state = &dm_new_crtc_state->base; @@ -9320,9 +9318,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, goto skip_modeset; drm_dbg_state(state->dev, - "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, " - "planes_changed:%d, mode_changed:%d,active_changed:%d," - "connectors_changed:%d\n", + "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, planes_changed:%d, mode_changed:%d,active_changed:%d,connectors_changed:%d\n", acrtc->crtc_id, new_crtc_state->enable, new_crtc_state->active, @@ -9351,8 +9347,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, old_crtc_state)) { new_crtc_state->mode_changed = false; DRM_DEBUG_DRIVER( - "Mode change not required for front porch change, " - "setting mode_changed to %d", + "Mode change not required for front porch change, setting mode_changed to %d", new_crtc_state->mode_changed); set_freesync_fixed_config(dm_new_crtc_state); @@ -9364,9 +9359,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, struct drm_display_mode *high_mode; high_mode = get_highest_refresh_rate_mode(aconnector, false); - if (!drm_mode_equal(&new_crtc_state->mode, high_mode)) { + if (!drm_mode_equal(&new_crtc_state->mode, high_mode)) set_freesync_fixed_config(dm_new_crtc_state); - } } ret = dm_atomic_get_state(state, &dm_state); @@ -9534,6 +9528,7 @@ static bool should_reset_plane(struct drm_atomic_state *state, */ for_each_oldnew_plane_in_state(state, other, old_other_state, new_other_state, i) { struct amdgpu_framebuffer *old_afb, *new_afb; + if (other->type == DRM_PLANE_TYPE_CURSOR) continue; @@ -9632,11 +9627,12 @@ static int dm_check_cursor_fb(struct amdgpu_crtc *new_acrtc, } /* Core DRM takes care of checking FB modifiers, so we only need to - * check tiling flags when the FB doesn't have a modifier. */ + * check tiling flags when the FB doesn't have a modifier. + */ if (!(fb->flags & DRM_MODE_FB_MODIFIERS)) { if (adev->family < AMDGPU_FAMILY_AI) { linear = AMDGPU_TILING_GET(afb->tiling_flags, ARRAY_MODE) != DC_ARRAY_2D_TILED_THIN1 && - AMDGPU_TILING_GET(afb->tiling_flags, ARRAY_MODE) != DC_ARRAY_1D_TILED_THIN1 && + AMDGPU_TILING_GET(afb->tiling_flags, ARRAY_MODE) != DC_ARRAY_1D_TILED_THIN1 && AMDGPU_TILING_GET(afb->tiling_flags, MICRO_TILE_MODE) == 0; } else { linear = AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE) == 0; @@ -9858,12 +9854,12 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state, /* On DCE and DCN there is no dedicated hardware cursor plane. We get a * cursor per pipe but it's going to inherit the scaling and * positioning from the underlying pipe. Check the cursor plane's - * blending properties match the underlying planes'. */ + * blending properties match the underlying planes'. + */ new_cursor_state = drm_atomic_get_new_plane_state(state, cursor); - if (!new_cursor_state || !new_cursor_state->fb) { + if (!new_cursor_state || !new_cursor_state->fb) return 0; - } dm_get_oriented_plane_size(new_cursor_state, &cursor_src_w, &cursor_src_h); cursor_scale_w = new_cursor_state->crtc_w * 1000 / cursor_src_w; @@ -9908,6 +9904,7 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm struct drm_connector_state *conn_state, *old_conn_state; struct amdgpu_dm_connector *aconnector = NULL; int i; + for_each_oldnew_connector_in_state(state, connector, old_conn_state, conn_state, i) { if (!conn_state->crtc) conn_state = old_conn_state; @@ -10342,7 +10339,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, } /* Store the overall update type for use later in atomic check. */ - for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) { + for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { struct dm_crtc_state *dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); @@ -10364,7 +10361,7 @@ fail: else if (ret == -EINTR || ret == -EAGAIN || ret == -ERESTARTSYS) DRM_DEBUG_DRIVER("Atomic check stopped due to signal.\n"); else - DRM_DEBUG_DRIVER("Atomic check failed with err: %d \n", ret); + DRM_DEBUG_DRIVER("Atomic check failed with err: %d\n", ret); trace_amdgpu_dm_atomic_check_finish(state, ret); From 4f6d9e38c4d244ad106eb9ebd8c0e1215e866f35 Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Wed, 9 Mar 2022 17:05:05 +0800 Subject: [PATCH 131/272] drm/amd/display: Add polling method to handle MST reply packet [Why] Specific TBT4 dock doesn't send out short HPD to notify source that IRQ event DOWN_REP_MSG_RDY is set. Which violates the spec and cause source can't send out streams to mst sinks. [How] To cover this misbehavior, add an additional polling method to detect DOWN_REP_MSG_RDY is set. HPD driven handling method is still kept. Just hook up our handler to drm mgr->cbs->poll_hpd_irq(). Cc: Mario Limonciello Cc: Alex Deucher Cc: stable@vger.kernel.org Reviewed-by: Jerry Zuo Acked-by: Alan Liu Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 117 +++++------------- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 7 ++ .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 110 ++++++++++++++++ .../display/amdgpu_dm/amdgpu_dm_mst_types.h | 11 ++ 4 files changed, 159 insertions(+), 86 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 948d61845efd..0fa739fd6a9c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1347,6 +1347,15 @@ static void dm_handle_hpd_rx_offload_work(struct work_struct *work) if (amdgpu_in_reset(adev)) goto skip; + if (offload_work->data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY || + offload_work->data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY) { + dm_handle_mst_sideband_msg_ready_event(&aconnector->mst_mgr, DOWN_OR_UP_MSG_RDY_EVENT); + spin_lock_irqsave(&offload_work->offload_wq->offload_lock, flags); + offload_work->offload_wq->is_handling_mst_msg_rdy_event = false; + spin_unlock_irqrestore(&offload_work->offload_wq->offload_lock, flags); + goto skip; + } + mutex_lock(&adev->dm.dc_lock); if (offload_work->data.bytes.device_service_irq.bits.AUTOMATED_TEST) { dc_link_dp_handle_automated_test(dc_link); @@ -3232,87 +3241,6 @@ static void handle_hpd_irq(void *param) } -static void dm_handle_mst_sideband_msg(struct amdgpu_dm_connector *aconnector) -{ - u8 esi[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = { 0 }; - u8 dret; - bool new_irq_handled = false; - int dpcd_addr; - int dpcd_bytes_to_read; - - const int max_process_count = 30; - int process_count = 0; - - const struct dc_link_status *link_status = dc_link_get_status(aconnector->dc_link); - - if (link_status->dpcd_caps->dpcd_rev.raw < 0x12) { - dpcd_bytes_to_read = DP_LANE0_1_STATUS - DP_SINK_COUNT; - /* DPCD 0x200 - 0x201 for downstream IRQ */ - dpcd_addr = DP_SINK_COUNT; - } else { - dpcd_bytes_to_read = DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI; - /* DPCD 0x2002 - 0x2005 for downstream IRQ */ - dpcd_addr = DP_SINK_COUNT_ESI; - } - - dret = drm_dp_dpcd_read( - &aconnector->dm_dp_aux.aux, - dpcd_addr, - esi, - dpcd_bytes_to_read); - - while (dret == dpcd_bytes_to_read && - process_count < max_process_count) { - u8 ack[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = {}; - u8 retry; - - dret = 0; - - process_count++; - - DRM_DEBUG_DRIVER("ESI %02x %02x %02x\n", esi[0], esi[1], esi[2]); - /* handle HPD short pulse irq */ - if (aconnector->mst_mgr.mst_state) - drm_dp_mst_hpd_irq_handle_event(&aconnector->mst_mgr, - esi, - ack, - &new_irq_handled); - - if (new_irq_handled) { - /* ACK at DPCD to notify down stream */ - for (retry = 0; retry < 3; retry++) { - ssize_t wret; - - wret = drm_dp_dpcd_writeb(&aconnector->dm_dp_aux.aux, - dpcd_addr + 1, - ack[1]); - if (wret == 1) - break; - } - - if (retry == 3) { - DRM_ERROR("Failed to ack MST event.\n"); - return; - } - - drm_dp_mst_hpd_irq_send_new_request(&aconnector->mst_mgr); - /* check if there is new irq to be handled */ - dret = drm_dp_dpcd_read( - &aconnector->dm_dp_aux.aux, - dpcd_addr, - esi, - dpcd_bytes_to_read); - - new_irq_handled = false; - } else { - break; - } - } - - if (process_count == max_process_count) - DRM_DEBUG_DRIVER("Loop exceeded max iterations\n"); -} - static void schedule_hpd_rx_offload_work(struct hpd_rx_irq_offload_work_queue *offload_wq, union hpd_irq_data hpd_irq_data) { @@ -3374,7 +3302,23 @@ static void handle_hpd_rx_irq(void *param) if (dc_link_dp_allow_hpd_rx_irq(dc_link)) { if (hpd_irq_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY || hpd_irq_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY) { - dm_handle_mst_sideband_msg(aconnector); + bool skip = false; + + /* + * DOWN_REP_MSG_RDY is also handled by polling method + * mgr->cbs->poll_hpd_irq() + */ + spin_lock(&offload_wq->offload_lock); + skip = offload_wq->is_handling_mst_msg_rdy_event; + + if (!skip) + offload_wq->is_handling_mst_msg_rdy_event = true; + + spin_unlock(&offload_wq->offload_lock); + + if (!skip) + schedule_hpd_rx_offload_work(offload_wq, hpd_irq_data); + goto out; } @@ -3483,11 +3427,11 @@ static void register_hpd_handlers(struct amdgpu_device *adev) amdgpu_dm_irq_register_interrupt(adev, &int_params, handle_hpd_rx_irq, (void *) aconnector); - - if (adev->dm.hpd_rx_offload_wq) - adev->dm.hpd_rx_offload_wq[dc_link->link_index].aconnector = - aconnector; } + + if (adev->dm.hpd_rx_offload_wq) + adev->dm.hpd_rx_offload_wq[connector->index].aconnector = + aconnector; } } @@ -7296,6 +7240,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, aconnector->as_type = ADAPTIVE_SYNC_TYPE_NONE; memset(&aconnector->vsdb_info, 0, sizeof(aconnector->vsdb_info)); mutex_init(&aconnector->hpd_lock); + mutex_init(&aconnector->handle_mst_msg_ready); /* * configure support HPD hot plug connector_>polled default value is 0 diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 4561f55afa99..9fb5bb3a75a7 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -194,6 +194,11 @@ struct hpd_rx_irq_offload_work_queue { * we're handling link loss */ bool is_handling_link_loss; + /** + * @is_handling_mst_msg_rdy_event: Used to prevent inserting mst message + * ready event when we're already handling mst message ready event + */ + bool is_handling_mst_msg_rdy_event; /** * @aconnector: The aconnector that this work queue is attached to */ @@ -638,6 +643,8 @@ struct amdgpu_dm_connector { struct drm_dp_mst_port *mst_output_port; struct amdgpu_dm_connector *mst_root; struct drm_dp_aux *dsc_aux; + struct mutex handle_mst_msg_ready; + /* TODO see if we can merge with ddc_bus or make a dm_connector */ struct amdgpu_i2c_adapter *i2c; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 46d0a8f57e55..888e80f498e9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -619,8 +619,118 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, return connector; } +void dm_handle_mst_sideband_msg_ready_event( + struct drm_dp_mst_topology_mgr *mgr, + enum mst_msg_ready_type msg_rdy_type) +{ + uint8_t esi[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = { 0 }; + uint8_t dret; + bool new_irq_handled = false; + int dpcd_addr; + uint8_t dpcd_bytes_to_read; + const uint8_t max_process_count = 30; + uint8_t process_count = 0; + u8 retry; + struct amdgpu_dm_connector *aconnector = + container_of(mgr, struct amdgpu_dm_connector, mst_mgr); + + + const struct dc_link_status *link_status = dc_link_get_status(aconnector->dc_link); + + if (link_status->dpcd_caps->dpcd_rev.raw < 0x12) { + dpcd_bytes_to_read = DP_LANE0_1_STATUS - DP_SINK_COUNT; + /* DPCD 0x200 - 0x201 for downstream IRQ */ + dpcd_addr = DP_SINK_COUNT; + } else { + dpcd_bytes_to_read = DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI; + /* DPCD 0x2002 - 0x2005 for downstream IRQ */ + dpcd_addr = DP_SINK_COUNT_ESI; + } + + mutex_lock(&aconnector->handle_mst_msg_ready); + + while (process_count < max_process_count) { + u8 ack[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = {}; + + process_count++; + + dret = drm_dp_dpcd_read( + &aconnector->dm_dp_aux.aux, + dpcd_addr, + esi, + dpcd_bytes_to_read); + + if (dret != dpcd_bytes_to_read) { + DRM_DEBUG_KMS("DPCD read and acked number is not as expected!"); + break; + } + + DRM_DEBUG_DRIVER("ESI %02x %02x %02x\n", esi[0], esi[1], esi[2]); + + switch (msg_rdy_type) { + case DOWN_REP_MSG_RDY_EVENT: + /* Only handle DOWN_REP_MSG_RDY case*/ + esi[1] &= DP_DOWN_REP_MSG_RDY; + break; + case UP_REQ_MSG_RDY_EVENT: + /* Only handle UP_REQ_MSG_RDY case*/ + esi[1] &= DP_UP_REQ_MSG_RDY; + break; + default: + /* Handle both cases*/ + esi[1] &= (DP_DOWN_REP_MSG_RDY | DP_UP_REQ_MSG_RDY); + break; + } + + if (!esi[1]) + break; + + /* handle MST irq */ + if (aconnector->mst_mgr.mst_state) + drm_dp_mst_hpd_irq_handle_event(&aconnector->mst_mgr, + esi, + ack, + &new_irq_handled); + + if (new_irq_handled) { + /* ACK at DPCD to notify down stream */ + for (retry = 0; retry < 3; retry++) { + ssize_t wret; + + wret = drm_dp_dpcd_writeb(&aconnector->dm_dp_aux.aux, + dpcd_addr + 1, + ack[1]); + if (wret == 1) + break; + } + + if (retry == 3) { + DRM_ERROR("Failed to ack MST event.\n"); + return; + } + + drm_dp_mst_hpd_irq_send_new_request(&aconnector->mst_mgr); + + new_irq_handled = false; + } else { + break; + } + } + + mutex_unlock(&aconnector->handle_mst_msg_ready); + + if (process_count == max_process_count) + DRM_DEBUG_DRIVER("Loop exceeded max iterations\n"); +} + +static void dm_handle_mst_down_rep_msg_ready(struct drm_dp_mst_topology_mgr *mgr) +{ + dm_handle_mst_sideband_msg_ready_event(mgr, DOWN_REP_MSG_RDY_EVENT); +} + static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { .add_connector = dm_dp_add_mst_connector, + .poll_hpd_irq = dm_handle_mst_down_rep_msg_ready, }; void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h index 1e4ede1e57ab..37c820ab0fdb 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h @@ -49,6 +49,13 @@ #define PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B 1031 #define PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B 1000 +enum mst_msg_ready_type { + NONE_MSG_RDY_EVENT = 0, + DOWN_REP_MSG_RDY_EVENT = 1, + UP_REQ_MSG_RDY_EVENT = 2, + DOWN_OR_UP_MSG_RDY_EVENT = 3 +}; + struct amdgpu_display_manager; struct amdgpu_dm_connector; @@ -61,6 +68,10 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, void dm_dp_create_fake_mst_encoders(struct amdgpu_device *adev); +void dm_handle_mst_sideband_msg_ready_event( + struct drm_dp_mst_topology_mgr *mgr, + enum mst_msg_ready_type msg_rdy_type); + struct dsc_mst_fairness_vars { int pbn; bool dsc_enabled; From 5a25cefc0920088bb9afafeb80ad3dcd84fe278b Mon Sep 17 00:00:00 2001 From: Taimur Hassan Date: Tue, 20 Jun 2023 17:00:28 -0400 Subject: [PATCH 132/272] drm/amd/display: check TG is non-null before checking if enabled [Why & How] If there is no TG allocation we can dereference a NULL pointer when checking if the TG is enabled. Cc: Mario Limonciello Cc: Alex Deucher Cc: stable@vger.kernel.org Reviewed-by: Nicholas Kazlauskas Acked-by: Alan Liu Signed-off-by: Taimur Hassan Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index a50309039d08..9834b75f1837 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -3278,7 +3278,8 @@ void dcn10_wait_for_mpcc_disconnect( if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst]) { struct hubp *hubp = get_hubp_by_inst(res_pool, mpcc_inst); - if (pipe_ctx->stream_res.tg->funcs->is_tg_enabled(pipe_ctx->stream_res.tg)) + if (pipe_ctx->stream_res.tg && + pipe_ctx->stream_res.tg->funcs->is_tg_enabled(pipe_ctx->stream_res.tg)) res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst); pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false; hubp->funcs->set_blank(hubp, true); From a460beefe77d780ac48f19d39333852a7f93ffc1 Mon Sep 17 00:00:00 2001 From: Zhikai Zhai Date: Fri, 30 Jun 2023 11:35:14 +0800 Subject: [PATCH 133/272] drm/amd/display: Disable MPC split by default on special asic [WHY] All of pipes will be used when the MPC split enable on the dcn which just has 2 pipes. Then MPO enter will trigger the minimal transition which need programe dcn from 2 pipes MPC split to 2 pipes MPO. This action will cause lag if happen frequently. [HOW] Disable the MPC split for the platform which dcn resource is limited Cc: Mario Limonciello Cc: Alex Deucher Cc: stable@vger.kernel.org Reviewed-by: Alvin Lee Acked-by: Alan Liu Signed-off-by: Zhikai Zhai Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c index 45956ef6f3f9..131b8b82afc0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c @@ -65,7 +65,7 @@ static const struct dc_debug_options debug_defaults_drv = { .timing_trace = false, .clock_trace = true, .disable_pplib_clock_request = true, - .pipe_split_policy = MPC_SPLIT_DYNAMIC, + .pipe_split_policy = MPC_SPLIT_AVOID, .force_single_disp_pipe_split = false, .disable_dcc = DCC_ENABLE, .vsr_support = true, From 2a9482e55968ed7368afaa9c2133404069117320 Mon Sep 17 00:00:00 2001 From: Daniel Miess Date: Thu, 22 Jun 2023 08:11:48 -0400 Subject: [PATCH 134/272] drm/amd/display: Prevent vtotal from being set to 0 [Why] In dcn314 DML the destination pipe vtotal was being set to the crtc adjustment vtotal_min value even in cases where that value is 0. [How] Only set vtotal to the crtc adjustment vtotal_min value in cases where the value is non-zero. Cc: Mario Limonciello Cc: Alex Deucher Cc: stable@vger.kernel.org Reviewed-by: Nicholas Kazlauskas Acked-by: Alan Liu Signed-off-by: Daniel Miess Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c index d9e049e7ff0a..ed8ddb75b333 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c @@ -295,7 +295,11 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c pipe = &res_ctx->pipe_ctx[i]; timing = &pipe->stream->timing; - pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min; + if (pipe->stream->adjust.v_total_min != 0) + pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min; + else + pipes[pipe_cnt].pipe.dest.vtotal = timing->v_total; + pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive; pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, dcn3_14_ip.VBlankNomDefaultUS); pipes[pipe_cnt].pipe.dest.vblank_nom = max(pipes[pipe_cnt].pipe.dest.vblank_nom, timing->v_sync_width); From 2387ccf43e3c6cb5dbd757c5ef410cca9f14b971 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Thu, 29 Jun 2023 10:35:59 -0400 Subject: [PATCH 135/272] drm/amd/display: Keep PHY active for DP displays on DCN31 [Why & How] Port of a change that went into DCN314 to keep the PHY enabled when we have a connected and active DP display. The PHY can hang if PHY refclk is disabled inadvertently. Cc: Mario Limonciello Cc: Alex Deucher Cc: stable@vger.kernel.org Reviewed-by: Josip Pavic Acked-by: Alan Liu Signed-off-by: Nicholas Kazlauskas Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c index 7ccd96959256..3db4ef564b99 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c @@ -87,6 +87,11 @@ static int dcn31_get_active_display_cnt_wa( stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK || stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) tmds_present = true; + + /* Checking stream / link detection ensuring that PHY is active*/ + if (dc_is_dp_signal(stream->signal) && !stream->dpms_off) + display_count++; + } for (i = 0; i < dc->link_count; i++) { From dcaa32e1f58473b9f4ac566fadd326956be83138 Mon Sep 17 00:00:00 2001 From: Guchun Chen Date: Mon, 17 Jul 2023 09:55:07 +0800 Subject: [PATCH 136/272] drm/amdgpu: Allocate root PD on correct partition file_priv needs to be setup firstly, otherwise, root PD will always be allocated on partition 0, even if opening the device from other partitions. Fixes: 3ebfd221c1a8 ("drm/amdkfd: Store xcp partition id to amdgpu bo") Signed-off-by: Guchun Chen Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index cca5a495611f..61d5472d60a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -1229,13 +1229,13 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) pasid = 0; } - r = amdgpu_vm_init(adev, &fpriv->vm); + r = amdgpu_xcp_open_device(adev, fpriv, file_priv); if (r) goto error_pasid; - r = amdgpu_xcp_open_device(adev, fpriv, file_priv); + r = amdgpu_vm_init(adev, &fpriv->vm); if (r) - goto error_vm; + goto error_pasid; r = amdgpu_vm_set_pasid(adev, &fpriv->vm, pasid); if (r) From 8ecee4cbc72b53551c1d33251a48c912d70282ea Mon Sep 17 00:00:00 2001 From: Guchun Chen Date: Thu, 13 Jul 2023 15:09:37 +0800 Subject: [PATCH 137/272] drm/amdgpu: fix slab-out-of-bounds issue in amdgpu_vm_pt_create MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recent code set xcp_id stored from file private data when opening device to amdgpu bo for accounting memory usage etc, but not all VMs are attached to this fpriv structure like the vm cases in amdgpu_mes_self_test, otherwise, KASAN will complain below out of bound access. And more importantly, VM code should not touch fpriv structure, so drop fpriv code handling from amdgpu_vm_pt. [ 77.292314] BUG: KASAN: slab-out-of-bounds in amdgpu_vm_pt_create+0x17e/0x4b0 [amdgpu] [ 77.293845] Read of size 4 at addr ffff888102c48a48 by task modprobe/1069 [ 77.294146] Call Trace: [ 77.294178] [ 77.294208] dump_stack_lvl+0x49/0x63 [ 77.294260] print_report+0x16f/0x4a6 [ 77.294307] ? amdgpu_vm_pt_create+0x17e/0x4b0 [amdgpu] [ 77.295979] ? kasan_complete_mode_report_info+0x3c/0x200 [ 77.296057] ? amdgpu_vm_pt_create+0x17e/0x4b0 [amdgpu] [ 77.297556] kasan_report+0xb4/0x130 [ 77.297609] ? amdgpu_vm_pt_create+0x17e/0x4b0 [amdgpu] [ 77.299202] __asan_load4+0x6f/0x90 [ 77.299272] amdgpu_vm_pt_create+0x17e/0x4b0 [amdgpu] [ 77.300796] ? amdgpu_init+0x6e/0x1000 [amdgpu] [ 77.302222] ? amdgpu_vm_pt_clear+0x750/0x750 [amdgpu] [ 77.303721] ? preempt_count_sub+0x18/0xc0 [ 77.303786] amdgpu_vm_init+0x39e/0x870 [amdgpu] [ 77.305186] ? amdgpu_vm_wait_idle+0x90/0x90 [amdgpu] [ 77.306683] ? kasan_set_track+0x25/0x30 [ 77.306737] ? kasan_save_alloc_info+0x1b/0x30 [ 77.306795] ? __kasan_kmalloc+0x87/0xa0 [ 77.306852] amdgpu_mes_self_test+0x169/0x620 [amdgpu] v2: without specifying xcp partition for PD/PT bo, the xcp id is -1. Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2686 Fixes: 3ebfd221c1a8 ("drm/amdkfd: Store xcp partition id to amdgpu bo") Signed-off-by: Guchun Chen Tested-by: Mikhail Gavrilov Reviewed-by: Felix Kuehling Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 5 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 5 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c | 11 ++++++----- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 61d5472d60a6..12414a713256 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -1233,7 +1233,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) if (r) goto error_pasid; - r = amdgpu_vm_init(adev, &fpriv->vm); + r = amdgpu_vm_init(adev, &fpriv->vm, fpriv->xcp_id); if (r) goto error_pasid; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c index e9091ebfe230..f808841310fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -1382,7 +1382,7 @@ int amdgpu_mes_self_test(struct amdgpu_device *adev) goto error_pasid; } - r = amdgpu_vm_init(adev, vm); + r = amdgpu_vm_init(adev, vm, -1); if (r) { DRM_ERROR("failed to initialize vm\n"); goto error_pasid; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 291977b93b1d..ec1ec08d4058 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2121,13 +2121,14 @@ long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout) * * @adev: amdgpu_device pointer * @vm: requested vm + * @xcp_id: GPU partition selection id * * Init @vm fields. * * Returns: * 0 for success, error for failure. */ -int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) +int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id) { struct amdgpu_bo *root_bo; struct amdgpu_bo_vm *root; @@ -2177,7 +2178,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) vm->evicting = false; r = amdgpu_vm_pt_create(adev, vm, adev->vm_manager.root_level, - false, &root); + false, &root, xcp_id); if (r) goto error_free_delayed; root_bo = &root->bo; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 9c85d494f2a2..ffac7413c657 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -392,7 +392,7 @@ int amdgpu_vm_set_pasid(struct amdgpu_device *adev, struct amdgpu_vm *vm, u32 pasid); long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout); -int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm); +int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id); int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm); void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm); void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); @@ -475,7 +475,8 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm, struct amdgpu_bo_vm *vmbo, bool immediate); int amdgpu_vm_pt_create(struct amdgpu_device *adev, struct amdgpu_vm *vm, - int level, bool immediate, struct amdgpu_bo_vm **vmbo); + int level, bool immediate, struct amdgpu_bo_vm **vmbo, + int32_t xcp_id); void amdgpu_vm_pt_free_root(struct amdgpu_device *adev, struct amdgpu_vm *vm); bool amdgpu_vm_pt_is_root_clean(struct amdgpu_device *adev, struct amdgpu_vm *vm); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c index dea1a64be44d..6949d777fd98 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c @@ -498,11 +498,12 @@ exit: * @level: the page table level * @immediate: use a immediate update * @vmbo: pointer to the buffer object pointer + * @xcp_id: GPU partition id */ int amdgpu_vm_pt_create(struct amdgpu_device *adev, struct amdgpu_vm *vm, - int level, bool immediate, struct amdgpu_bo_vm **vmbo) + int level, bool immediate, struct amdgpu_bo_vm **vmbo, + int32_t xcp_id) { - struct amdgpu_fpriv *fpriv = container_of(vm, struct amdgpu_fpriv, vm); struct amdgpu_bo_param bp; struct amdgpu_bo *bo; struct dma_resv *resv; @@ -535,7 +536,7 @@ int amdgpu_vm_pt_create(struct amdgpu_device *adev, struct amdgpu_vm *vm, bp.type = ttm_bo_type_kernel; bp.no_wait_gpu = immediate; - bp.xcp_id_plus1 = fpriv->xcp_id == ~0 ? 0 : fpriv->xcp_id + 1; + bp.xcp_id_plus1 = xcp_id + 1; if (vm->root.bo) bp.resv = vm->root.bo->tbo.base.resv; @@ -561,7 +562,7 @@ int amdgpu_vm_pt_create(struct amdgpu_device *adev, struct amdgpu_vm *vm, bp.type = ttm_bo_type_kernel; bp.resv = bo->tbo.base.resv; bp.bo_ptr_size = sizeof(struct amdgpu_bo); - bp.xcp_id_plus1 = fpriv->xcp_id == ~0 ? 0 : fpriv->xcp_id + 1; + bp.xcp_id_plus1 = xcp_id + 1; r = amdgpu_bo_create(adev, &bp, &(*vmbo)->shadow); @@ -606,7 +607,7 @@ static int amdgpu_vm_pt_alloc(struct amdgpu_device *adev, return 0; amdgpu_vm_eviction_unlock(vm); - r = amdgpu_vm_pt_create(adev, vm, cursor->level, immediate, &pt); + r = amdgpu_vm_pt_create(adev, vm, cursor->level, immediate, &pt, 0); amdgpu_vm_eviction_lock(vm); if (r) return r; From 8e78127143086bd89aa099740c1767d64fe80631 Mon Sep 17 00:00:00 2001 From: Guchun Chen Date: Thu, 13 Jul 2023 15:55:58 +0800 Subject: [PATCH 138/272] drm/amdgpu/vm: use the same xcp_id from root PD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Other PDs/PTs allocation should just use the same xcp_id as that stored in root PD. Suggested-by: Christian König Signed-off-by: Guchun Chen Reviewed-by: Felix Kuehling Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c index 6949d777fd98..5431332bbdb8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c @@ -607,7 +607,8 @@ static int amdgpu_vm_pt_alloc(struct amdgpu_device *adev, return 0; amdgpu_vm_eviction_unlock(vm); - r = amdgpu_vm_pt_create(adev, vm, cursor->level, immediate, &pt, 0); + r = amdgpu_vm_pt_create(adev, vm, cursor->level, immediate, &pt, + vm->root.bo->xcp_id); amdgpu_vm_eviction_lock(vm); if (r) return r; From b13d3e9c6b62597a5c31fdc74febb3bc588893bf Mon Sep 17 00:00:00 2001 From: Guchun Chen Date: Fri, 14 Jul 2023 19:38:16 +0800 Subject: [PATCH 139/272] drm/amdgpu: use a macro to define no xcp partition case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ~0 as no xcp partition is used in several places, so improve its definition by a macro for code consistency. Suggested-by: Christian König Signed-off-by: Guchun Chen Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h | 2 ++ drivers/gpu/drm/amd/amdgpu/aqua_vanjaram_reg_init.c | 4 ++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index a7f314ddd173..d34c3ef8f3ed 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -1709,7 +1709,8 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( alloc_flags |= (flags & KFD_IOC_ALLOC_MEM_FLAGS_PUBLIC) ? AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED : 0; } - xcp_id = fpriv->xcp_id == ~0 ? 0 : fpriv->xcp_id; + xcp_id = fpriv->xcp_id == AMDGPU_XCP_NO_PARTITION ? + 0 : fpriv->xcp_id; } else if (flags & KFD_IOC_ALLOC_MEM_FLAGS_GTT) { domain = alloc_domain = AMDGPU_GEM_DOMAIN_GTT; alloc_flags = 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c index d175e862f222..9c9cca129498 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c @@ -363,7 +363,7 @@ int amdgpu_xcp_open_device(struct amdgpu_device *adev, if (!adev->xcp_mgr) return 0; - fpriv->xcp_id = ~0; + fpriv->xcp_id = AMDGPU_XCP_NO_PARTITION; for (i = 0; i < MAX_XCP; ++i) { if (!adev->xcp_mgr->xcp[i].ddev) break; @@ -381,7 +381,7 @@ int amdgpu_xcp_open_device(struct amdgpu_device *adev, } } - fpriv->vm.mem_id = fpriv->xcp_id == ~0 ? -1 : + fpriv->vm.mem_id = fpriv->xcp_id == AMDGPU_XCP_NO_PARTITION ? -1 : adev->xcp_mgr->xcp[fpriv->xcp_id].mem_id; return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h index 0f8026d64ea5..9a1036aeec2a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h @@ -37,6 +37,8 @@ #define AMDGPU_XCP_FL_NONE 0 #define AMDGPU_XCP_FL_LOCKED (1 << 0) +#define AMDGPU_XCP_NO_PARTITION (~0) + struct amdgpu_fpriv; enum AMDGPU_XCP_IP_BLOCK { diff --git a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram_reg_init.c b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram_reg_init.c index 16471b81a1f5..72b629a78c62 100644 --- a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram_reg_init.c +++ b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram_reg_init.c @@ -68,7 +68,7 @@ static void aqua_vanjaram_set_xcp_id(struct amdgpu_device *adev, enum AMDGPU_XCP_IP_BLOCK ip_blk; uint32_t inst_mask; - ring->xcp_id = ~0; + ring->xcp_id = AMDGPU_XCP_NO_PARTITION; if (adev->xcp_mgr->mode == AMDGPU_XCP_MODE_NONE) return; @@ -177,7 +177,7 @@ static int aqua_vanjaram_select_scheds( u32 sel_xcp_id; int i; - if (fpriv->xcp_id == ~0) { + if (fpriv->xcp_id == AMDGPU_XCP_NO_PARTITION) { u32 least_ref_cnt = ~0; fpriv->xcp_id = 0; From 6adc2272aaaf84f34b652cf77f770c6fcc4b8336 Mon Sep 17 00:00:00 2001 From: Ondrej Mosnacek Date: Tue, 18 Jul 2023 13:56:07 +0200 Subject: [PATCH 140/272] io_uring: don't audit the capability check in io_uring_create() The check being unconditional may lead to unwanted denials reported by LSMs when a process has the capability granted by DAC, but denied by an LSM. In the case of SELinux such denials are a problem, since they can't be effectively filtered out via the policy and when not silenced, they produce noise that may hide a true problem or an attack. Since not having the capability merely means that the created io_uring context will be accounted against the current user's RLIMIT_MEMLOCK limit, we can disable auditing of denials for this check by using ns_capable_noaudit() instead of capable(). Fixes: 2b188cc1bb85 ("Add io_uring IO interface") Link: https://bugzilla.redhat.com/show_bug.cgi?id=2193317 Signed-off-by: Ondrej Mosnacek Reviewed-by: Jeff Moyer Link: https://lore.kernel.org/r/20230718115607.65652-1-omosnace@redhat.com Signed-off-by: Jens Axboe --- io_uring/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 7505de2428e0..a9923676d16d 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -3870,7 +3870,7 @@ static __cold int io_uring_create(unsigned entries, struct io_uring_params *p, ctx->syscall_iopoll = 1; ctx->compat = in_compat_syscall(); - if (!capable(CAP_IPC_LOCK)) + if (!ns_capable_noaudit(&init_user_ns, CAP_IPC_LOCK)) ctx->user = get_uid(current_user()); /* From 752a281032b2d6f4564be827e082bde6f7d2fd4f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 19 Jul 2023 14:40:49 +1000 Subject: [PATCH 141/272] drm/nouveau/i2c: fix number of aux event slots This was completely bogus before, using maximum DCB device index rather than maximum AUX ID to size the buffer that stores event refcounts. *Pretty* unlikely to have been an actual problem on most configurations, that is, unless you've got one of the rare boards that have off-chip DP. There, it'll likely crash. Cc: stable@vger.kernel.org # 6.4+ Signed-off-by: Ben Skeggs Reviewed-by: Karol Herbst Signed-off-by: Karol Herbst Link: https://patchwork.freedesktop.org/patch/msgid/20230719044051.6975-1-skeggsb@gmail.com --- drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h | 4 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c | 11 +++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h index 40a1065ae626..ef441dfdea09 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h @@ -16,7 +16,7 @@ struct nvkm_i2c_bus { const struct nvkm_i2c_bus_func *func; struct nvkm_i2c_pad *pad; #define NVKM_I2C_BUS_CCB(n) /* 'n' is ccb index */ (n) -#define NVKM_I2C_BUS_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x100) +#define NVKM_I2C_BUS_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x10) #define NVKM_I2C_BUS_PRI /* ccb primary comm. port */ -1 #define NVKM_I2C_BUS_SEC /* ccb secondary comm. port */ -2 int id; @@ -38,7 +38,7 @@ struct nvkm_i2c_aux { const struct nvkm_i2c_aux_func *func; struct nvkm_i2c_pad *pad; #define NVKM_I2C_AUX_CCB(n) /* 'n' is ccb index */ (n) -#define NVKM_I2C_AUX_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x100) +#define NVKM_I2C_AUX_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x10) int id; struct mutex mutex; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c index 976539de4220..731b2f68d3db 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c @@ -260,10 +260,11 @@ nvkm_i2c_new_(const struct nvkm_i2c_func *func, struct nvkm_device *device, { struct nvkm_bios *bios = device->bios; struct nvkm_i2c *i2c; + struct nvkm_i2c_aux *aux; struct dcb_i2c_entry ccbE; struct dcb_output dcbE; u8 ver, hdr; - int ret, i; + int ret, i, ids; if (!(i2c = *pi2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) return -ENOMEM; @@ -406,5 +407,11 @@ nvkm_i2c_new_(const struct nvkm_i2c_func *func, struct nvkm_device *device, } } - return nvkm_event_init(&nvkm_i2c_intr_func, &i2c->subdev, 4, i, &i2c->event); + ids = 0; + list_for_each_entry(aux, &i2c->aux, head) + ids = max(ids, aux->id + 1); + if (!ids) + return 0; + + return nvkm_event_init(&nvkm_i2c_intr_func, &i2c->subdev, 4, ids, &i2c->event); } From 2b5d1c29f6c4cb19369ef92881465e5ede75f4ef Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 19 Jul 2023 14:40:50 +1000 Subject: [PATCH 142/272] drm/nouveau/disp: PIOR DP uses GPIO for HPD, not PMGR AUX interrupts Fixes crash on boards with ANX9805 TMDS/DP encoders. Cc: stable@vger.kernel.org # 6.4+ Signed-off-by: Ben Skeggs Reviewed-by: Karol Herbst Signed-off-by: Karol Herbst Link: https://patchwork.freedesktop.org/patch/msgid/20230719044051.6975-2-skeggsb@gmail.com --- .../gpu/drm/nouveau/nvkm/engine/disp/uconn.c | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c index dad942be6679..46b057fe1412 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c @@ -81,20 +81,29 @@ nvkm_uconn_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_ return -ENOSYS; list_for_each_entry(outp, &conn->disp->outps, head) { - if (outp->info.connector == conn->index && outp->dp.aux) { - if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG ) bits |= NVKM_I2C_PLUG; - if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_I2C_UNPLUG; - if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ ) bits |= NVKM_I2C_IRQ; + if (outp->info.connector == conn->index) + break; + } - return nvkm_uevent_add(uevent, &device->i2c->event, outp->dp.aux->id, bits, - nvkm_uconn_uevent_aux); - } + if (&outp->head == &conn->disp->outps) + return -EINVAL; + + if (outp->dp.aux && !outp->info.location) { + if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG ) bits |= NVKM_I2C_PLUG; + if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_I2C_UNPLUG; + if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ ) bits |= NVKM_I2C_IRQ; + + return nvkm_uevent_add(uevent, &device->i2c->event, outp->dp.aux->id, bits, + nvkm_uconn_uevent_aux); } if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG ) bits |= NVKM_GPIO_HI; if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_GPIO_LO; - if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ) - return -EINVAL; + if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ) { + /* TODO: support DP IRQ on ANX9805 and remove this hack. */ + if (!outp->info.location) + return -EINVAL; + } return nvkm_uevent_add(uevent, &device->gpio->event, conn->info.hpd, bits, nvkm_uconn_uevent_gpio); From ea293f823a8805735d9e00124df81a8f448ed1ae Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 19 Jul 2023 14:40:51 +1000 Subject: [PATCH 143/272] drm/nouveau/kms/nv50-: init hpd_irq_lock for PIOR DP Fixes OOPS on boards with ANX9805 DP encoders. Cc: stable@vger.kernel.org # 6.4+ Signed-off-by: Ben Skeggs Reviewed-by: Karol Herbst Signed-off-by: Karol Herbst Link: https://patchwork.freedesktop.org/patch/msgid/20230719044051.6975-3-skeggsb@gmail.com --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 38d3fad0d97a..1bec819da876 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1877,6 +1877,8 @@ nv50_pior_destroy(struct drm_encoder *encoder) nvif_outp_dtor(&nv_encoder->outp); drm_encoder_cleanup(encoder); + + mutex_destroy(&nv_encoder->dp.hpd_irq_lock); kfree(encoder); } @@ -1921,6 +1923,8 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) nv_encoder->i2c = ddc; nv_encoder->aux = aux; + mutex_init(&nv_encoder->dp.hpd_irq_lock); + encoder = to_drm_encoder(nv_encoder); encoder->possible_crtcs = dcbe->heads; encoder->possible_clones = 0; From 5a7adc6c1069ce31ef4f606ae9c05592c80a6ab5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 10 Jul 2023 14:34:25 +0200 Subject: [PATCH 144/272] gpio: tps68470: Make tps68470_gpio_output() always set the initial value Make tps68470_gpio_output() call tps68470_gpio_set() for output-only pins too, so that the initial value passed to gpiod_direction_output() is honored for these pins too. Fixes: 275b13a65547 ("gpio: Add support for TPS68470 GPIOs") Reviewed-by: Andy Shevchenko Reviewed-by: Daniel Scally Tested-by: Daniel Scally Reviewed-by: Sakari Ailus Signed-off-by: Hans de Goede Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-tps68470.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-tps68470.c b/drivers/gpio/gpio-tps68470.c index aaddcabe9b35..532deaddfd4e 100644 --- a/drivers/gpio/gpio-tps68470.c +++ b/drivers/gpio/gpio-tps68470.c @@ -91,13 +91,13 @@ static int tps68470_gpio_output(struct gpio_chip *gc, unsigned int offset, struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); struct regmap *regmap = tps68470_gpio->tps68470_regmap; + /* Set the initial value */ + tps68470_gpio_set(gc, offset, value); + /* rest are always outputs */ if (offset >= TPS68470_N_REGULAR_GPIO) return 0; - /* Set the initial value */ - tps68470_gpio_set(gc, offset, value); - return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset), TPS68470_GPIO_MODE_MASK, TPS68470_GPIO_MODE_OUT_CMOS); From 106ea7ffd56b0f9454cd4f625474967f12ac4dbd Mon Sep 17 00:00:00 2001 From: Andrew Donnellan Date: Wed, 19 Jul 2023 17:18:21 +1000 Subject: [PATCH 145/272] Revert "powerpc/64s: Remove support for ELFv1 little endian userspace" This reverts commit 606787fed7268feb256957872586370b56af697a. ELFv1 with LE has never been a thing, and people who try to make ELFv1 LE binaries are maniacs who need to be stopped, but unfortunately there are ELFv1 LE binaries out there in the wild. One such binary is the ppc64el (as Debian calls it) helper for arch-test[0], a tool for detecting architectures that can be executed on a given machine by means of attempting to execute helper binaries compiled for each architecture and seeing which binaries succeed and fail. The helpers are small snippets of assembly, and the ppc64el assembly doesn't include the right directives to generate an ELFv2 binary. This results in arch-test incorrectly determining that a ppc64el kernel can't execute a ppc64el userspace, which in turn means that a number of developer tools such as debootstrap will break (assuming arch-test is installed). [0] https://github.com/kilobyte/arch-test Signed-off-by: Andrew Donnellan Signed-off-by: Michael Ellerman Link: https://msgid.link/20230719071821.320594-1-ajd@linux.ibm.com --- arch/powerpc/include/asm/elf.h | 6 ------ arch/powerpc/include/asm/thread_info.h | 6 +----- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h index a26ca097d032..79f1c480b5eb 100644 --- a/arch/powerpc/include/asm/elf.h +++ b/arch/powerpc/include/asm/elf.h @@ -12,14 +12,8 @@ /* * This is used to ensure we don't load something for the wrong architecture. - * 64le only supports ELFv2 64-bit binaries (64be supports v1 and v2). */ -#if defined(CONFIG_PPC64) && defined(CONFIG_CPU_LITTLE_ENDIAN) -#define elf_check_arch(x) (((x)->e_machine == ELF_ARCH) && \ - (((x)->e_flags & 0x3) == 0x2)) -#else #define elf_check_arch(x) ((x)->e_machine == ELF_ARCH) -#endif #define compat_elf_check_arch(x) ((x)->e_machine == EM_PPC) #define CORE_DUMP_USE_REGSET diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index bc5d39a835fe..bf5dde1a4114 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h @@ -183,13 +183,9 @@ static inline bool test_thread_local_flags(unsigned int flags) #define clear_tsk_compat_task(tsk) do { } while (0) #endif -#ifdef CONFIG_PPC64 -#ifdef CONFIG_CPU_BIG_ENDIAN +#if defined(CONFIG_PPC64) #define is_elf2_task() (test_thread_flag(TIF_ELF2ABI)) #else -#define is_elf2_task() (1) -#endif -#else #define is_elf2_task() (0) #endif From 1945063eb59e64d2919cb14d54d081476d9e53bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 17 Jul 2023 16:27:43 +0200 Subject: [PATCH 146/272] gpio: mvebu: Make use of devm_pwmchip_add MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows to get rid of a call to pwmchip_remove() in the error path. There is no .remove function for this driver, so this change fixes a resource leak when a gpio-mvebu device is unbound. Fixes: 757642f9a584 ("gpio: mvebu: Add limited PWM support") Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-mvebu.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index a68f682aec01..a35958e7adf6 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -874,7 +874,7 @@ static int mvebu_pwm_probe(struct platform_device *pdev, spin_lock_init(&mvpwm->lock); - return pwmchip_add(&mvpwm->chip); + return devm_pwmchip_add(dev, &mvpwm->chip); } #ifdef CONFIG_DEBUG_FS @@ -1243,8 +1243,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) if (!mvchip->domain) { dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n", mvchip->chip.label); - err = -ENODEV; - goto err_pwm; + return -ENODEV; } err = irq_alloc_domain_generic_chips( @@ -1296,9 +1295,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev) err_domain: irq_domain_remove(mvchip->domain); -err_pwm: - pwmchip_remove(&mvchip->mvpwm->chip); - return err; } From b460a52257b1f5299ca70b7d1bb32442d3ce7bf6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 19 Jul 2023 00:30:40 +0100 Subject: [PATCH 147/272] regcache: Push async I/O request down into the rbtree cache Currently the regcache core unconditionally enables async I/O for all cache types, causing problems for the maple tree cache which dynamically allocates the buffers used to write registers to the device since async requires the buffers to be kept around until the I/O has been completed. This use of async I/O is mainly for the rbtree cache which stores data in a format directly usable for regmap_raw_write(), though there is a special case for single register writes which would also have allowed it to be used with the flat cache. It is a bit of a landmine for other caches since it implicitly converts sync operations to async, and with modern hardware it is not clear that async I/O is actually a performance win as shown by the performance work David Jander did with SPI. In multi core systems the cost of managing concurrency ends up swamping the performance benefit and almost all modern systems are multi core. Address this by pushing the enablement of async I/O down into the rbtree cache where it is actively used, avoiding surprises for other cache implementations. Reported-by: Charles Keepax Fixes: bfa0b38c1483 ("regmap: maple: Implement block sync for the maple tree cache") Reviewed-by: Charles Keepax Tested-by: Charles Keepax Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20230719-regcache-async-rbtree-v1-1-b03d30cf1daf@kernel.org Signed-off-by: Mark Brown --- drivers/base/regmap/regcache-rbtree.c | 4 ++++ drivers/base/regmap/regcache.c | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index fabf87058d80..584bcc55f56e 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c @@ -471,6 +471,8 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min, unsigned int start, end; int ret; + map->async = true; + rbtree_ctx = map->cache; for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { rbnode = rb_entry(node, struct regcache_rbtree_node, node); @@ -499,6 +501,8 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min, return ret; } + map->async = false; + return regmap_async_complete(map); } diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 28bc3ae9458a..7d3e47436056 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -368,8 +368,6 @@ int regcache_sync(struct regmap *map) if (!map->cache_dirty) goto out; - map->async = true; - /* Apply any patch first */ map->cache_bypass = true; for (i = 0; i < map->patch_regs; i++) { @@ -392,7 +390,6 @@ int regcache_sync(struct regmap *map) out: /* Restore the bypass state */ - map->async = false; map->cache_bypass = bypass; map->no_sync_defaults = false; map->unlock(map->lock_arg); From a2a93f4e2fd400907f89753025d1e4bebb64d4db Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 19 Jul 2023 13:43:36 +0200 Subject: [PATCH 148/272] selftests: ALSA: Add test-pcmtest-driver to .gitignore It was forgotten to add the new binary to .gitignore. Let's fix it. Fixes: 10b98a4db11a ("selftests: ALSA: Add test for the 'pcmtest' driver") Link: https://lore.kernel.org/r/20230719114336.18409-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- tools/testing/selftests/alsa/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/alsa/.gitignore b/tools/testing/selftests/alsa/.gitignore index 2b0d11797f25..12dc3fcd3456 100644 --- a/tools/testing/selftests/alsa/.gitignore +++ b/tools/testing/selftests/alsa/.gitignore @@ -1,2 +1,3 @@ mixer-test pcm-test +test-pcmtest-driver From 0659400f18c0e6c0c69d74fe5d09e7f6fbbd52a2 Mon Sep 17 00:00:00 2001 From: Luka Guzenko Date: Tue, 18 Jul 2023 18:12:41 +0200 Subject: [PATCH 149/272] ALSA: hda/realtek: Enable Mute LED on HP Laptop 15s-eq2xxx The HP Laptop 15s-eq2xxx uses ALC236 codec and controls the mute LED using COEF 0x07 index 1. No existing quirk covers this configuration. Adds a new quirk and enables it for the device. Signed-off-by: Luka Guzenko Cc: Link: https://lore.kernel.org/r/20230718161241.393181-1-l.guzenko@web.de Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 392e6fce6e02..ac2996595183 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4624,6 +4624,21 @@ static void alc236_fixup_hp_mute_led_coefbit(struct hda_codec *codec, } } +static void alc236_fixup_hp_mute_led_coefbit2(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + spec->mute_led_polarity = 0; + spec->mute_led_coef.idx = 0x07; + spec->mute_led_coef.mask = 1; + spec->mute_led_coef.on = 1; + spec->mute_led_coef.off = 0; + snd_hda_gen_add_mute_led_cdev(codec, coef_mute_led_set); + } +} + /* turn on/off mic-mute LED per capture hook by coef bit */ static int coef_micmute_led_set(struct led_classdev *led_cdev, enum led_brightness brightness) @@ -7144,6 +7159,7 @@ enum { ALC285_FIXUP_HP_GPIO_LED, ALC285_FIXUP_HP_MUTE_LED, ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED, + ALC236_FIXUP_HP_MUTE_LED_COEFBIT2, ALC236_FIXUP_HP_GPIO_LED, ALC236_FIXUP_HP_MUTE_LED, ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF, @@ -8633,6 +8649,10 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc285_fixup_hp_spectre_x360_mute_led, }, + [ALC236_FIXUP_HP_MUTE_LED_COEFBIT2] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc236_fixup_hp_mute_led_coefbit2, + }, [ALC236_FIXUP_HP_GPIO_LED] = { .type = HDA_FIXUP_FUNC, .v.func = alc236_fixup_hp_gpio_led, @@ -9517,6 +9537,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x886d, "HP ZBook Fury 17.3 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8870, "HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8873, "HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), + SND_PCI_QUIRK(0x103c, 0x887a, "HP Laptop 15s-eq2xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8895, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED), SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED), From d46b0a05bdc849d39c75268ddaf654c59bd6785c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 19 Jul 2023 19:56:08 +0200 Subject: [PATCH 150/272] Revert "intel_idle: Add __init annotation to matchup_vm_state_with_baremetal()" This reverts commit b2918089d5cb ("intel_idle: Add __init annotation to matchup_vm_state_with_baremetal()"), because the commit fixed by it will be reverted. Signed-off-by: Rafael J. Wysocki --- drivers/idle/intel_idle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index b930036edbbe..34201d7ef33e 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -2147,7 +2147,7 @@ static void __init intel_idle_cpuidle_devices_uninit(void) * All our short idle states are dominated by vmexit/vmenter latencies, * not the underlying hardware latencies so we keep our values for these. */ -static void __init matchup_vm_state_with_baremetal(void) +static void matchup_vm_state_with_baremetal(void) { int cstate; From a5155c023d6a2c9ff5f4fad5f75117578a58affc Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 19 Jul 2023 19:57:39 +0200 Subject: [PATCH 151/272] Revert "intel_idle: Add a "Long HLT" C1 state for the VM guest mode" This reverts commit 0fac214bb75e ("intel_idle: Add a "Long HLT" C1 state for the VM guest mode"), because there is a coding mistake in it and its validity is questioned. Link: https://lore.kernel.org/all/20230711132553.GN3062772@hirez.programming.kicks-ass.net Requested-by: Peter Zijlstra Signed-off-by: Rafael J. Wysocki --- drivers/idle/intel_idle.c | 55 --------------------------------------- 1 file changed, 55 deletions(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 34201d7ef33e..a80e1f520293 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -1287,13 +1287,6 @@ static struct cpuidle_state vmguest_cstates[] __initdata = { .exit_latency = 5, .target_residency = 10, .enter = &intel_idle_hlt, }, - { - .name = "C1L", - .desc = "Long HLT", - .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TLB_FLUSHED, - .exit_latency = 5, - .target_residency = 200, - .enter = &intel_idle_hlt, }, { .enter = NULL } }; @@ -2137,45 +2130,6 @@ static void __init intel_idle_cpuidle_devices_uninit(void) cpuidle_unregister_device(per_cpu_ptr(intel_idle_cpuidle_devices, i)); } -/* - * Match up the latency and break even point of the bare metal (cpu based) - * states with the deepest VM available state. - * - * We only want to do this for the deepest state, the ones that has - * the TLB_FLUSHED flag set on the . - * - * All our short idle states are dominated by vmexit/vmenter latencies, - * not the underlying hardware latencies so we keep our values for these. - */ -static void matchup_vm_state_with_baremetal(void) -{ - int cstate; - - for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) { - int matching_cstate; - - if (intel_idle_max_cstate_reached(cstate)) - break; - - if (!cpuidle_state_table[cstate].enter) - break; - - if (!(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_TLB_FLUSHED)) - continue; - - for (matching_cstate = 0; matching_cstate < CPUIDLE_STATE_MAX; ++matching_cstate) { - if (!icpu->state_table[matching_cstate].enter) - break; - if (icpu->state_table[matching_cstate].exit_latency > cpuidle_state_table[cstate].exit_latency) { - cpuidle_state_table[cstate].exit_latency = icpu->state_table[matching_cstate].exit_latency; - cpuidle_state_table[cstate].target_residency = icpu->state_table[matching_cstate].target_residency; - } - } - - } -} - - static int __init intel_idle_vminit(const struct x86_cpu_id *id) { int retval; @@ -2191,15 +2145,6 @@ static int __init intel_idle_vminit(const struct x86_cpu_id *id) if (!intel_idle_cpuidle_devices) return -ENOMEM; - /* - * We don't know exactly what the host will do when we go idle, but as a worst estimate - * we can assume that the exit latency of the deepest host state will be hit for our - * deep (long duration) guest idle state. - * The same logic applies to the break even point for the long duration guest idle state. - * So lets copy these two properties from the table we found for the host CPU type. - */ - matchup_vm_state_with_baremetal(); - intel_idle_cpuidle_driver_init(&intel_idle_driver); retval = cpuidle_register_driver(&intel_idle_driver); From 5534f44627418897cd901d725303ce3dedd7bc1e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 19 Jul 2023 20:10:03 +0200 Subject: [PATCH 152/272] Revert "intel_idle: Add support for using intel_idle in a VM guest using just hlt" This reverts commit 2f3d08f074b0 ("intel_idle: Add support for using intel_idle in a VM guest using just hlt"), because it causes functional issues to appear and it is not really useful without a related commit that got reverted previously. Link: https://lore.kernel.org/linux-pm/5c7de6d5-7706-c4a5-7c41-146db1269aff@intel.com Reported-by: Xiaoyao Li Requested-by: Peter Zijlstra Signed-off-by: Rafael J. Wysocki --- drivers/idle/intel_idle.c | 117 +------------------------------------- 1 file changed, 1 insertion(+), 116 deletions(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index a80e1f520293..256c2d42e350 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -199,43 +199,6 @@ static __cpuidle int intel_idle_xstate(struct cpuidle_device *dev, return __intel_idle(dev, drv, index); } -static __always_inline int __intel_idle_hlt(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index) -{ - raw_safe_halt(); - raw_local_irq_disable(); - return index; -} - -/** - * intel_idle_hlt - Ask the processor to enter the given idle state using hlt. - * @dev: cpuidle device of the target CPU. - * @drv: cpuidle driver (assumed to point to intel_idle_driver). - * @index: Target idle state index. - * - * Use the HLT instruction to notify the processor that the CPU represented by - * @dev is idle and it can try to enter the idle state corresponding to @index. - * - * Must be called under local_irq_disable(). - */ -static __cpuidle int intel_idle_hlt(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index) -{ - return __intel_idle_hlt(dev, drv, index); -} - -static __cpuidle int intel_idle_hlt_irq_on(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index) -{ - int ret; - - raw_local_irq_enable(); - ret = __intel_idle_hlt(dev, drv, index); - raw_local_irq_disable(); - - return ret; -} - /** * intel_idle_s2idle - Ask the processor to enter the given idle state. * @dev: cpuidle device of the target CPU. @@ -1279,18 +1242,6 @@ static struct cpuidle_state snr_cstates[] __initdata = { .enter = NULL } }; -static struct cpuidle_state vmguest_cstates[] __initdata = { - { - .name = "C1", - .desc = "HLT", - .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_IRQ_ENABLE, - .exit_latency = 5, - .target_residency = 10, - .enter = &intel_idle_hlt, }, - { - .enter = NULL } -}; - static const struct idle_cpu idle_cpu_nehalem __initconst = { .state_table = nehalem_cstates, .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, @@ -1890,16 +1841,6 @@ static bool __init intel_idle_verify_cstate(unsigned int mwait_hint) static void state_update_enter_method(struct cpuidle_state *state, int cstate) { - if (state->enter == intel_idle_hlt) { - if (force_irq_on) { - pr_info("forced intel_idle_irq for state %d\n", cstate); - state->enter = intel_idle_hlt_irq_on; - } - return; - } - if (state->enter == intel_idle_hlt_irq_on) - return; /* no update scenarios */ - if (state->flags & CPUIDLE_FLAG_INIT_XSTATE) { /* * Combining with XSTATE with IBRS or IRQ_ENABLE flags @@ -1933,21 +1874,6 @@ static void state_update_enter_method(struct cpuidle_state *state, int cstate) } } -/* - * For mwait based states, we want to verify the cpuid data to see if the state - * is actually supported by this specific CPU. - * For non-mwait based states, this check should be skipped. - */ -static bool should_verify_mwait(struct cpuidle_state *state) -{ - if (state->enter == intel_idle_hlt) - return false; - if (state->enter == intel_idle_hlt_irq_on) - return false; - - return true; -} - static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv) { int cstate; @@ -1996,7 +1922,7 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv) } mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags); - if (should_verify_mwait(&cpuidle_state_table[cstate]) && !intel_idle_verify_cstate(mwait_hint)) + if (!intel_idle_verify_cstate(mwait_hint)) continue; /* Structure copy. */ @@ -2130,45 +2056,6 @@ static void __init intel_idle_cpuidle_devices_uninit(void) cpuidle_unregister_device(per_cpu_ptr(intel_idle_cpuidle_devices, i)); } -static int __init intel_idle_vminit(const struct x86_cpu_id *id) -{ - int retval; - - cpuidle_state_table = vmguest_cstates; - - icpu = (const struct idle_cpu *)id->driver_data; - - pr_debug("v" INTEL_IDLE_VERSION " model 0x%X\n", - boot_cpu_data.x86_model); - - intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device); - if (!intel_idle_cpuidle_devices) - return -ENOMEM; - - intel_idle_cpuidle_driver_init(&intel_idle_driver); - - retval = cpuidle_register_driver(&intel_idle_driver); - if (retval) { - struct cpuidle_driver *drv = cpuidle_get_driver(); - printk(KERN_DEBUG pr_fmt("intel_idle yielding to %s\n"), - drv ? drv->name : "none"); - goto init_driver_fail; - } - - retval = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "idle/intel:online", - intel_idle_cpu_online, NULL); - if (retval < 0) - goto hp_setup_fail; - - return 0; -hp_setup_fail: - intel_idle_cpuidle_devices_uninit(); - cpuidle_unregister_driver(&intel_idle_driver); -init_driver_fail: - free_percpu(intel_idle_cpuidle_devices); - return retval; -} - static int __init intel_idle_init(void) { const struct x86_cpu_id *id; @@ -2187,8 +2074,6 @@ static int __init intel_idle_init(void) id = x86_match_cpu(intel_idle_ids); if (id) { if (!boot_cpu_has(X86_FEATURE_MWAIT)) { - if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) - return intel_idle_vminit(id); pr_debug("Please enable MWAIT in BIOS SETUP\n"); return -ENODEV; } From 80b6051085c5fedcb1dfd7b2562a63a83655c4d8 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Wed, 5 Jul 2023 10:40:01 +0800 Subject: [PATCH 153/272] scsi: sg: Fix checking return value of blk_get_queue() Commit fcaa174a9c99 ("scsi/sg: don't grab scsi host module reference") make a mess how blk_get_queue() is called, blk_get_queue() returns true on success while the caller expects it returns 0 on success. Fix this problem and also add a corresponding error message on failure. Fixes: fcaa174a9c99 ("scsi/sg: don't grab scsi host module reference") Reported-by: Marc Hartmayer Closes: https://lore.kernel.org/all/87lefv622n.fsf@linux.ibm.com/ Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20230705024001.177585-1-yukuai1@huaweicloud.com Tested-by: Shin'ichiro Kawasaki Tested-by: Marc Hartmayer Reviewed-by: Christoph Hellwig Reviewed-by: Marc Hartmayer Signed-off-by: Martin K. Petersen --- drivers/scsi/sg.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 89fa046c7158..0d8afffd1683 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1497,9 +1497,10 @@ sg_add_device(struct device *cl_dev) int error; unsigned long iflags; - error = blk_get_queue(scsidp->request_queue); - if (error) - return error; + if (!blk_get_queue(scsidp->request_queue)) { + pr_warn("%s: get scsi_device queue failed\n", __func__); + return -ENODEV; + } error = -ENOMEM; cdev = cdev_alloc(); From 03b89a08484a88fb9e0604cab2b3eb0c2f265c74 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 12 Jul 2023 10:59:36 +0200 Subject: [PATCH 154/272] vgacon: switch vgacon_scrolldelta() and vgacon_restore_screen() Switch vgacon_scrolldelta() and vgacon_restore_screen() positions, so that the former is not needed to be forward-declared. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Helge Deller Cc: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Helge Deller --- drivers/video/console/vgacon.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index e25ba523892e..fbed2862c317 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -142,12 +142,6 @@ static inline void vga_set_mem_top(struct vc_data *c) write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2); } -static void vgacon_restore_screen(struct vc_data *c) -{ - if (c->vc_origin != c->vc_visible_origin) - vgacon_scrolldelta(c, 0); -} - static void vgacon_scrolldelta(struct vc_data *c, int lines) { vc_scrolldelta_helper(c, lines, vga_rolled_over, (void *)vga_vram_base, @@ -155,6 +149,12 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) vga_set_mem_top(c); } +static void vgacon_restore_screen(struct vc_data *c) +{ + if (c->vc_origin != c->vc_visible_origin) + vgacon_scrolldelta(c, 0); +} + static const char *vgacon_startup(void) { const char *display_desc = NULL; From 6ceed69cde8fe4a78fe50d62d7a88a5c1eed4709 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 12 Jul 2023 10:59:37 +0200 Subject: [PATCH 155/272] vgacon: remove unneeded forward declarations Most of the forward declarations in vgacon are not needed. Drop them. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Helge Deller Cc: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Helge Deller --- drivers/video/console/vgacon.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index fbed2862c317..a34cdfcc10c2 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -65,16 +65,8 @@ static struct vgastate vgastate; * Interface used by the world */ -static const char *vgacon_startup(void); -static void vgacon_init(struct vc_data *c, int init); -static void vgacon_deinit(struct vc_data *c); -static void vgacon_cursor(struct vc_data *c, int mode); -static int vgacon_switch(struct vc_data *c); -static int vgacon_blank(struct vc_data *c, int blank, int mode_switch); -static void vgacon_scrolldelta(struct vc_data *c, int lines); static int vgacon_set_origin(struct vc_data *c); -static void vgacon_save_screen(struct vc_data *c); -static void vgacon_invert_region(struct vc_data *c, u16 * p, int count); + static struct uni_pagedict *vgacon_uni_pagedir; static int vgacon_refcount; From c900dc6858e87e2f2396954377ae956925b17135 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 12 Jul 2023 10:59:38 +0200 Subject: [PATCH 156/272] vgacon: remove unused xpos from vgacon_set_cursor_size() xpos is unused, remove it. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Helge Deller Cc: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Helge Deller --- drivers/video/console/vgacon.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index a34cdfcc10c2..7cb15851ea56 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -437,7 +437,7 @@ static void vgacon_invert_region(struct vc_data *c, u16 * p, int count) } } -static void vgacon_set_cursor_size(int xpos, int from, int to) +static void vgacon_set_cursor_size(int from, int to) { unsigned long flags; int curs, cure; @@ -479,9 +479,9 @@ static void vgacon_cursor(struct vc_data *c, int mode) case CM_ERASE: write_vga(14, (c->vc_pos - vga_vram_base) / 2); if (vga_video_type >= VIDEO_TYPE_VGAC) - vgacon_set_cursor_size(c->state.x, 31, 30); + vgacon_set_cursor_size(31, 30); else - vgacon_set_cursor_size(c->state.x, 31, 31); + vgacon_set_cursor_size(31, 31); break; case CM_MOVE: @@ -489,8 +489,7 @@ static void vgacon_cursor(struct vc_data *c, int mode) write_vga(14, (c->vc_pos - vga_vram_base) / 2); switch (CUR_SIZE(c->vc_cursor_type)) { case CUR_UNDERLINE: - vgacon_set_cursor_size(c->state.x, - c->vc_cell_height - + vgacon_set_cursor_size(c->vc_cell_height - (c->vc_cell_height < 10 ? 2 : 3), c->vc_cell_height - @@ -498,35 +497,31 @@ static void vgacon_cursor(struct vc_data *c, int mode) 10 ? 1 : 2)); break; case CUR_TWO_THIRDS: - vgacon_set_cursor_size(c->state.x, - c->vc_cell_height / 3, + vgacon_set_cursor_size(c->vc_cell_height / 3, c->vc_cell_height - (c->vc_cell_height < 10 ? 1 : 2)); break; case CUR_LOWER_THIRD: - vgacon_set_cursor_size(c->state.x, - (c->vc_cell_height * 2) / 3, + vgacon_set_cursor_size((c->vc_cell_height * 2) / 3, c->vc_cell_height - (c->vc_cell_height < 10 ? 1 : 2)); break; case CUR_LOWER_HALF: - vgacon_set_cursor_size(c->state.x, - c->vc_cell_height / 2, + vgacon_set_cursor_size(c->vc_cell_height / 2, c->vc_cell_height - (c->vc_cell_height < 10 ? 1 : 2)); break; case CUR_NONE: if (vga_video_type >= VIDEO_TYPE_VGAC) - vgacon_set_cursor_size(c->state.x, 31, 30); + vgacon_set_cursor_size(31, 30); else - vgacon_set_cursor_size(c->state.x, 31, 31); + vgacon_set_cursor_size(31, 31); break; default: - vgacon_set_cursor_size(c->state.x, 1, - c->vc_cell_height); + vgacon_set_cursor_size(1, c->vc_cell_height); break; } break; From 93686f6b01df3e904569ee7265ee181d859b201d Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 12 Jul 2023 10:59:39 +0200 Subject: [PATCH 157/272] vgacon: let vgacon_doresize() return void The return value is neither used, nor vgacon_doresize() returns an error. So change the reurn type to void. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Helge Deller Cc: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Helge Deller --- drivers/video/console/vgacon.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 7cb15851ea56..07f6b97d9b81 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -528,7 +528,7 @@ static void vgacon_cursor(struct vc_data *c, int mode) } } -static int vgacon_doresize(struct vc_data *c, +static void vgacon_doresize(struct vc_data *c, unsigned int width, unsigned int height) { unsigned long flags; @@ -587,7 +587,6 @@ static int vgacon_doresize(struct vc_data *c, } raw_spin_unlock_irqrestore(&vga_lock, flags); - return 0; } static int vgacon_switch(struct vc_data *c) From 1023ca1973c6253f7ba9024b2b0c27168f50ab3d Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 12 Jul 2023 10:59:40 +0200 Subject: [PATCH 158/272] vgacon: cache vc_cell_height in vgacon_cursor() There are many places c->vc_cell_height is used in the code of vgacon_cursor(). Caching the value to a local variable makes the code much easier to follow. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Helge Deller Cc: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Helge Deller --- drivers/video/console/vgacon.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 07f6b97d9b81..7ad047bcae17 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -470,11 +470,15 @@ static void vgacon_set_cursor_size(int from, int to) static void vgacon_cursor(struct vc_data *c, int mode) { + unsigned int c_height; + if (c->vc_mode != KD_TEXT) return; vgacon_restore_screen(c); + c_height = c->vc_cell_height; + switch (mode) { case CM_ERASE: write_vga(14, (c->vc_pos - vga_vram_base) / 2); @@ -489,30 +493,22 @@ static void vgacon_cursor(struct vc_data *c, int mode) write_vga(14, (c->vc_pos - vga_vram_base) / 2); switch (CUR_SIZE(c->vc_cursor_type)) { case CUR_UNDERLINE: - vgacon_set_cursor_size(c->vc_cell_height - - (c->vc_cell_height < - 10 ? 2 : 3), - c->vc_cell_height - - (c->vc_cell_height < - 10 ? 1 : 2)); + vgacon_set_cursor_size(c_height - + (c_height < 10 ? 2 : 3), + c_height - + (c_height < 10 ? 1 : 2)); break; case CUR_TWO_THIRDS: - vgacon_set_cursor_size(c->vc_cell_height / 3, - c->vc_cell_height - - (c->vc_cell_height < - 10 ? 1 : 2)); + vgacon_set_cursor_size(c_height / 3, c_height - + (c_height < 10 ? 1 : 2)); break; case CUR_LOWER_THIRD: - vgacon_set_cursor_size((c->vc_cell_height * 2) / 3, - c->vc_cell_height - - (c->vc_cell_height < - 10 ? 1 : 2)); + vgacon_set_cursor_size(c_height * 2 / 3, c_height - + (c_height < 10 ? 1 : 2)); break; case CUR_LOWER_HALF: - vgacon_set_cursor_size(c->vc_cell_height / 2, - c->vc_cell_height - - (c->vc_cell_height < - 10 ? 1 : 2)); + vgacon_set_cursor_size(c_height / 2, c_height - + (c_height < 10 ? 1 : 2)); break; case CUR_NONE: if (vga_video_type >= VIDEO_TYPE_VGAC) @@ -521,7 +517,7 @@ static void vgacon_cursor(struct vc_data *c, int mode) vgacon_set_cursor_size(31, 31); break; default: - vgacon_set_cursor_size(1, c->vc_cell_height); + vgacon_set_cursor_size(1, c_height); break; } break; From 4f2ba39a40480e6019133730f1741fdbb7137290 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 12 Jul 2023 10:59:41 +0200 Subject: [PATCH 159/272] sticon: make sticon_set_def_font() void and remove op parameter sticon_set_def_font() always returns 0, so make it void. And remove an unused 'op' parameter. Signed-off-by: "Jiri Slaby (SUSE)" Cc: "James E.J. Bottomley" Cc: Helge Deller Cc: linux-parisc@vger.kernel.org Cc: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Helge Deller --- drivers/video/console/sticon.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index d11cfd2d68b5..992a4fa431aa 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -156,7 +156,7 @@ static bool sticon_scroll(struct vc_data *conp, unsigned int t, return false; } -static int sticon_set_def_font(int unit, struct console_font *op) +static void sticon_set_def_font(int unit) { if (font_data[unit] != STI_DEF_FONT) { if (--FNTREFCOUNT(font_data[unit]) == 0) { @@ -165,8 +165,6 @@ static int sticon_set_def_font(int unit, struct console_font *op) } font_data[unit] = STI_DEF_FONT; } - - return 0; } static int sticon_set_font(struct vc_data *vc, struct console_font *op, @@ -246,7 +244,7 @@ static int sticon_set_font(struct vc_data *vc, struct console_font *op, vc->vc_video_erase_char, font_data[vc->vc_num]); /* delete old font in case it is a user font */ - sticon_set_def_font(unit, NULL); + sticon_set_def_font(unit); FNTREFCOUNT(cooked_font)++; font_data[unit] = cooked_font; @@ -264,7 +262,9 @@ static int sticon_set_font(struct vc_data *vc, struct console_font *op, static int sticon_font_default(struct vc_data *vc, struct console_font *op, char *name) { - return sticon_set_def_font(vc->vc_num, op); + sticon_set_def_font(vc->vc_num); + + return 0; } static int sticon_font_set(struct vc_data *vc, struct console_font *font, @@ -297,7 +297,7 @@ static void sticon_deinit(struct vc_data *c) /* free memory used by user font */ for (i = 0; i < MAX_NR_CONSOLES; i++) - sticon_set_def_font(i, NULL); + sticon_set_def_font(i); } static void sticon_clear(struct vc_data *conp, int sy, int sx, int height, From 933ab3a81cb73d08bc6b4eadeb3a98c9194abdf5 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 12 Jul 2023 10:59:42 +0200 Subject: [PATCH 160/272] fbcon: remove unused display (p) from fbcon_redraw() The parameter is unused. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Daniel Vetter Cc: Helge Deller Cc: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Helge Deller --- drivers/video/fbdev/core/fbcon.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index c6c9d040bdec..887fad44e7ec 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -1612,8 +1612,7 @@ static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info, } } -static void fbcon_redraw(struct vc_data *vc, struct fbcon_display *p, - int line, int count, int offset) +static void fbcon_redraw(struct vc_data *vc, int line, int count, int offset) { unsigned short *d = (unsigned short *) (vc->vc_origin + vc->vc_size_row * line); @@ -1827,7 +1826,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, case SCROLL_REDRAW: redraw_up: - fbcon_redraw(vc, p, t, b - t - count, + fbcon_redraw(vc, t, b - t - count, count * vc->vc_cols); fbcon_clear(vc, b - count, 0, count, vc->vc_cols); scr_memsetw((unsigned short *) (vc->vc_origin + @@ -1913,7 +1912,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, case SCROLL_REDRAW: redraw_down: - fbcon_redraw(vc, p, b - 1, b - t - count, + fbcon_redraw(vc, b - 1, b - t - count, -count * vc->vc_cols); fbcon_clear(vc, t, 0, count, vc->vc_cols); scr_memsetw((unsigned short *) (vc->vc_origin + From 298e082558d86aa904486d087ce45d35c1122f1e Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 12 Jul 2023 17:11:23 +0100 Subject: [PATCH 161/272] fbdev: kyro: make some const read-only arrays static and reduce type size Don't populate the const read-only arrays on the stack but instead make them static const. Use smaller types to use less storage for the arrays. Also makes the object code a little smaller. Signed-off-by: Colin Ian King Signed-off-by: Helge Deller --- drivers/video/fbdev/kyro/STG4000InitDevice.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/video/fbdev/kyro/STG4000InitDevice.c b/drivers/video/fbdev/kyro/STG4000InitDevice.c index edfa0a04854d..79886a246638 100644 --- a/drivers/video/fbdev/kyro/STG4000InitDevice.c +++ b/drivers/video/fbdev/kyro/STG4000InitDevice.c @@ -83,11 +83,11 @@ volatile u32 i,count=0; \ static u32 InitSDRAMRegisters(volatile STG4000REG __iomem *pSTGReg, u32 dwSubSysID, u32 dwRevID) { - u32 adwSDRAMArgCfg0[] = { 0xa0, 0x80, 0xa0, 0xa0, 0xa0 }; - u32 adwSDRAMCfg1[] = { 0x8732, 0x8732, 0xa732, 0xa732, 0x8732 }; - u32 adwSDRAMCfg2[] = { 0x87d2, 0x87d2, 0xa7d2, 0x87d2, 0xa7d2 }; - u32 adwSDRAMRsh[] = { 36, 39, 40 }; - u32 adwChipSpeed[] = { 110, 120, 125 }; + static const u8 adwSDRAMArgCfg0[] = { 0xa0, 0x80, 0xa0, 0xa0, 0xa0 }; + static const u16 adwSDRAMCfg1[] = { 0x8732, 0x8732, 0xa732, 0xa732, 0x8732 }; + static const u16 adwSDRAMCfg2[] = { 0x87d2, 0x87d2, 0xa7d2, 0x87d2, 0xa7d2 }; + static const u8 adwSDRAMRsh[] = { 36, 39, 40 }; + static const u8 adwChipSpeed[] = { 110, 120, 125 }; u32 dwMemTypeIdx; u32 dwChipSpeedIdx; From 4e88761f5f8c7869f15a2046b1a1116f4fab4ac8 Mon Sep 17 00:00:00 2001 From: Zhang Shurong Date: Sat, 15 Jul 2023 16:16:56 +0800 Subject: [PATCH 162/272] fbdev: au1200fb: Fix missing IRQ check in au1200fb_drv_probe This func misses checking for platform_get_irq()'s call and may passes the negative error codes to request_irq(), which takes unsigned IRQ #, causing it to fail with -EINVAL, overriding an original error code. Fix this by stop calling request_irq() with invalid IRQ #s. Fixes: 1630d85a8312 ("au1200fb: fix hardcoded IRQ") Signed-off-by: Zhang Shurong Signed-off-by: Helge Deller --- drivers/video/fbdev/au1200fb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index 5c232eb13724..c137d6afe484 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1732,6 +1732,9 @@ static int au1200fb_drv_probe(struct platform_device *dev) /* Now hook interrupt too */ irq = platform_get_irq(dev, 0); + if (irq < 0) + return irq; + ret = request_irq(irq, au1200fb_handle_irq, IRQF_SHARED, "lcd", (void *)dev); if (ret) { From 9d5651ad2ae7b2ddfc56ff243a08937d9681f950 Mon Sep 17 00:00:00 2001 From: Yuanjun Gong Date: Mon, 17 Jul 2023 22:48:09 +0800 Subject: [PATCH 163/272] fbdev: ep93xx-fb: fix return value check in ep93xxfb_probe function clk_prepare_enable may fail in ep93xxfb_probe, therefore, add a return value check to clk_prepare_enable and handle the error. Signed-off-by: Yuanjun Gong Signed-off-by: Helge Deller --- drivers/video/fbdev/ep93xx-fb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c index 94fe52928be2..22158d9ca8dd 100644 --- a/drivers/video/fbdev/ep93xx-fb.c +++ b/drivers/video/fbdev/ep93xx-fb.c @@ -548,7 +548,9 @@ static int ep93xxfb_probe(struct platform_device *pdev) } ep93xxfb_set_par(info); - clk_prepare_enable(fbi->clk); + err = clk_prepare_enable(fbi->clk); + if (err) + goto failed_check; err = register_framebuffer(info); if (err) From e8812acb5bf724f2fc23a500e590c776ebda7b0a Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jul 2023 08:32:26 -0600 Subject: [PATCH 164/272] fbdev: Explicitly include correct DT includes The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Reviewed-by: Thomas Zimmermann Signed-off-by: Rob Herring Signed-off-by: Helge Deller --- drivers/video/fbdev/bw2.c | 3 ++- drivers/video/fbdev/cg14.c | 3 ++- drivers/video/fbdev/cg3.c | 3 ++- drivers/video/fbdev/cg6.c | 3 ++- drivers/video/fbdev/ffb.c | 3 ++- drivers/video/fbdev/grvga.c | 3 +-- drivers/video/fbdev/leo.c | 3 ++- drivers/video/fbdev/mb862xx/mb862xxfb_accel.c | 4 +--- drivers/video/fbdev/mb862xx/mb862xxfbdrv.c | 6 +++--- drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c | 2 +- drivers/video/fbdev/p9100.c | 3 ++- drivers/video/fbdev/platinumfb.c | 4 ++-- drivers/video/fbdev/sbuslib.c | 2 +- drivers/video/fbdev/sunxvr1000.c | 3 ++- drivers/video/fbdev/sunxvr2500.c | 2 +- drivers/video/fbdev/sunxvr500.c | 2 +- drivers/video/fbdev/tcx.c | 3 ++- drivers/video/fbdev/xilinxfb.c | 5 ++--- 18 files changed, 31 insertions(+), 26 deletions(-) diff --git a/drivers/video/fbdev/bw2.c b/drivers/video/fbdev/bw2.c index 025d663dc6fd..39f438de0d6b 100644 --- a/drivers/video/fbdev/bw2.c +++ b/drivers/video/fbdev/bw2.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/video/fbdev/cg14.c b/drivers/video/fbdev/cg14.c index 832a82f45c80..90fdc9d9bf5a 100644 --- a/drivers/video/fbdev/cg14.c +++ b/drivers/video/fbdev/cg14.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/video/fbdev/cg3.c b/drivers/video/fbdev/cg3.c index 6335cd364c74..98c60f72046a 100644 --- a/drivers/video/fbdev/cg3.c +++ b/drivers/video/fbdev/cg3.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/video/fbdev/cg6.c b/drivers/video/fbdev/cg6.c index 6884572efea1..6427b85f1a94 100644 --- a/drivers/video/fbdev/cg6.c +++ b/drivers/video/fbdev/cg6.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/video/fbdev/ffb.c b/drivers/video/fbdev/ffb.c index c6d3111dcbb0..c473841eb6ff 100644 --- a/drivers/video/fbdev/ffb.c +++ b/drivers/video/fbdev/ffb.c @@ -16,7 +16,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/video/fbdev/grvga.c b/drivers/video/fbdev/grvga.c index 9aa15be29ea9..d4a9a58b3691 100644 --- a/drivers/video/fbdev/grvga.c +++ b/drivers/video/fbdev/grvga.c @@ -12,8 +12,7 @@ #include #include -#include -#include +#include #include #include #include diff --git a/drivers/video/fbdev/leo.c b/drivers/video/fbdev/leo.c index 3ffc0a725f89..89ca48235dbe 100644 --- a/drivers/video/fbdev/leo.c +++ b/drivers/video/fbdev/leo.c @@ -16,8 +16,9 @@ #include #include #include -#include #include +#include +#include #include diff --git a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c index 61aed7fc0b8d..c35a7479fbf2 100644 --- a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c +++ b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c @@ -15,9 +15,7 @@ #include #include #include -#if defined(CONFIG_OF) -#include -#endif + #include "mb862xxfb.h" #include "mb862xx_reg.h" #include "mb862xxfb_accel.h" diff --git a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c index b5c8fcab9940..9dc347d163cf 100644 --- a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c +++ b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c @@ -18,11 +18,11 @@ #include #include #include -#if defined(CONFIG_OF) +#include #include #include -#include -#endif +#include + #include "mb862xxfb.h" #include "mb862xx_reg.h" diff --git a/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c b/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c index ba94a0a7bd4f..77fce1223a64 100644 --- a/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c +++ b/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c @@ -15,12 +15,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include