From: Chao Yu chao@kernel.org
[ Upstream commit 956fa1ddc132e028f3b7d4cf17e6bfc8cb36c7fd ]
Let's check return value of f2fs_reserve_new_block() in do_recover_data() rather than letting it fails silently.
Also refactoring check condition on return value of f2fs_reserve_new_block() as below: - trigger f2fs_bug_on() only for ENOSPC case; - use do-while statement to avoid redundant codes;
Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/recovery.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index dea95b48b647..4f4db465220f 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -683,7 +683,16 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, */ if (dest == NEW_ADDR) { f2fs_truncate_data_blocks_range(&dn, 1); - f2fs_reserve_new_block(&dn); + do { + err = f2fs_reserve_new_block(&dn); + if (err == -ENOSPC) { + f2fs_bug_on(sbi, 1); + break; + } + } while (err && + IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION)); + if (err) + goto err; continue; }
@@ -691,12 +700,14 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, if (f2fs_is_valid_blkaddr(sbi, dest, META_POR)) {
if (src == NULL_ADDR) { - err = f2fs_reserve_new_block(&dn); - while (err && - IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION)) + do { err = f2fs_reserve_new_block(&dn); - /* We should not get -ENOSPC */ - f2fs_bug_on(sbi, err); + if (err == -ENOSPC) { + f2fs_bug_on(sbi, 1); + break; + } + } while (err && + IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION)); if (err) goto err; }
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 26257869672fd4a06a60c2da841e15fb2cb47bbe ]
In a couple of loops over the all streams, we check the bitmap against the loop counter. A more correct reference would be, however, the index of each stream, instead.
This patch corrects the check of bitmaps to the stream index.
Note that this change doesn't fix anything for now; all existing drivers set up the stream indices properly, hence the loop count is always equal with the stream index. That said, this change is only for consistency.
Link: https://lore.kernel.org/r/20231121154125.4888-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/hda/hdac_stream.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index 741a5d17ae4c..ecd3aec57c87 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -629,17 +629,15 @@ void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev, struct hdac_stream *s; bool inited = false; u64 cycle_last = 0; - int i = 0;
list_for_each_entry(s, &bus->stream_list, list) { - if (streams & (1 << i)) { + if ((streams & (1 << s->index))) { azx_timecounter_init(s, inited, cycle_last); if (!inited) { inited = true; cycle_last = s->tc.cycle_last; } } - i++; }
snd_pcm_gettime(runtime, &runtime->trigger_tstamp); @@ -684,14 +682,13 @@ void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start, unsigned int streams) { struct hdac_bus *bus = azx_dev->bus; - int i, nwait, timeout; + int nwait, timeout; struct hdac_stream *s;
for (timeout = 5000; timeout; timeout--) { nwait = 0; - i = 0; list_for_each_entry(s, &bus->stream_list, list) { - if (!(streams & (1 << i++))) + if (!(streams & (1 << s->index))) continue;
if (start) {
From: Cristian Ciocaltea cristian.ciocaltea@collabora.com
[ Upstream commit 67c7666fe808c3a7af3cc6f9d0a3dd3acfd26115 ]
The virtual widget example makes use of an undefined SND_SOC_DAPM_NOPM argument passed to SND_SOC_DAPM_MIXER(). Replace with the correct SND_SOC_NOPM definition.
Signed-off-by: Cristian Ciocaltea cristian.ciocaltea@collabora.com Link: https://lore.kernel.org/r/20231121120751.77355-1-cristian.ciocaltea@collabor... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/sound/soc/dapm.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst index 8e44107933ab..c3154ce6e1b2 100644 --- a/Documentation/sound/soc/dapm.rst +++ b/Documentation/sound/soc/dapm.rst @@ -234,7 +234,7 @@ corresponding soft power control. In this case it is necessary to create a virtual widget - a widget with no control bits e.g. ::
- SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
This can be used to merge to signal paths together in software.
From: Ville Syrjälä ville.syrjala@linux.intel.com
[ Upstream commit c6fbb6bca10838485b820e8a26c23996f77ce580 ]
The current implementation of drm_color_lut_extract() generates weird results. Eg. if we go through all the values for 16->8bpc conversion we see the following pattern:
in out (count) 0 - 7f -> 0 (128) 80 - 17f -> 1 (256) 180 - 27f -> 2 (256) 280 - 37f -> 3 (256) ... fb80 - fc7f -> fc (256) fc80 - fd7f -> fd (256) fd80 - fe7f -> fe (256) fe80 - ffff -> ff (384)
So less values map to 0 and more values map 0xff, which doesn't seem particularly great.
To get just the same number of input values to map to the same output values we'd just need to drop the rounding entrirely. But perhaps a better idea would be to follow the OpenGL int<->float conversion rules, in which case we get the following results:
in out (count) 0 - 80 -> 0 (129) 81 - 181 -> 1 (257) 182 - 282 -> 2 (257) 283 - 383 -> 3 (257) ... fc7c - fd7c -> fc (257) fd7d - fe7d -> fd (257) fe7e - ff7e -> fe (257) ff7f - ffff -> ff (129)
Note that since the divisor is constant the compiler is able to optimize away the integer division in most cases. The only exception is the _ULL() case on 32bit architectures since that gets emitted as inline asm via do_div() and thus the compiler doesn't get to optimize it.
Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20231013131402.24072-2-ville.s... Reviewed-by: Chaitanya Kumar Borah chaitanya.kumar.borah@intel.com Reviewed-by: Jani Nikula jani.nikula@intel.com Acked-by: Maxime Ripard mripard@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/drm/drm_color_mgmt.h | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 81c298488b0c..54b2b2467bfd 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -36,20 +36,17 @@ struct drm_plane; * * Extract a degamma/gamma LUT value provided by user (in the form of * &drm_color_lut entries) and round it to the precision supported by the - * hardware. + * hardware, following OpenGL int<->float conversion rules + * (see eg. OpenGL 4.6 specification - 2.3.5 Fixed-Point Data Conversions). */ static inline u32 drm_color_lut_extract(u32 user_input, int bit_precision) { - u32 val = user_input; - u32 max = 0xffff >> (16 - bit_precision); - - /* Round only if we're not using full precision. */ - if (bit_precision < 16) { - val += 1UL << (16 - bit_precision - 1); - val >>= 16 - bit_precision; - } - - return clamp_val(val, 0, max); + if (bit_precision > 16) + return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(user_input, (1 << bit_precision) - 1), + (1 << 16) - 1); + else + return DIV_ROUND_CLOSEST(user_input * ((1 << bit_precision) - 1), + (1 << 16) - 1); }
u64 drm_color_ctm_s31_32_to_qm_n(u64 user_input, u32 m, u32 n);
On Mon, Jan 22, 2024 at 10:08:05AM -0500, Sasha Levin wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
[ Upstream commit c6fbb6bca10838485b820e8a26c23996f77ce580 ]
Why is this being backported?
The current implementation of drm_color_lut_extract() generates weird results. Eg. if we go through all the values for 16->8bpc conversion we see the following pattern:
in out (count) 0 - 7f -> 0 (128) 80 - 17f -> 1 (256) 180 - 27f -> 2 (256) 280 - 37f -> 3 (256) ... fb80 - fc7f -> fc (256) fc80 - fd7f -> fd (256) fd80 - fe7f -> fe (256) fe80 - ffff -> ff (384)
So less values map to 0 and more values map 0xff, which doesn't seem particularly great.
To get just the same number of input values to map to the same output values we'd just need to drop the rounding entrirely. But perhaps a better idea would be to follow the OpenGL int<->float conversion rules, in which case we get the following results:
in out (count) 0 - 80 -> 0 (129) 81 - 181 -> 1 (257) 182 - 282 -> 2 (257) 283 - 383 -> 3 (257) ... fc7c - fd7c -> fc (257) fd7d - fe7d -> fd (257) fe7e - ff7e -> fe (257) ff7f - ffff -> ff (129)
Note that since the divisor is constant the compiler is able to optimize away the integer division in most cases. The only exception is the _ULL() case on 32bit architectures since that gets emitted as inline asm via do_div() and thus the compiler doesn't get to optimize it.
Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20231013131402.24072-2-ville.s... Reviewed-by: Chaitanya Kumar Borah chaitanya.kumar.borah@intel.com Reviewed-by: Jani Nikula jani.nikula@intel.com Acked-by: Maxime Ripard mripard@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
include/drm/drm_color_mgmt.h | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 81c298488b0c..54b2b2467bfd 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -36,20 +36,17 @@ struct drm_plane;
- Extract a degamma/gamma LUT value provided by user (in the form of
- &drm_color_lut entries) and round it to the precision supported by the
- hardware.
- hardware, following OpenGL int<->float conversion rules
*/
- (see eg. OpenGL 4.6 specification - 2.3.5 Fixed-Point Data Conversions).
static inline u32 drm_color_lut_extract(u32 user_input, int bit_precision) {
- u32 val = user_input;
- u32 max = 0xffff >> (16 - bit_precision);
- /* Round only if we're not using full precision. */
- if (bit_precision < 16) {
val += 1UL << (16 - bit_precision - 1);
val >>= 16 - bit_precision;
- }
- return clamp_val(val, 0, max);
- if (bit_precision > 16)
return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(user_input, (1 << bit_precision) - 1),
(1 << 16) - 1);
- else
return DIV_ROUND_CLOSEST(user_input * ((1 << bit_precision) - 1),
(1 << 16) - 1);
} u64 drm_color_ctm_s31_32_to_qm_n(u64 user_input, u32 m, u32 n); -- 2.43.0
On Mon, Jan 22, 2024 at 06:50:00PM +0200, Ville Syrjälä wrote:
On Mon, Jan 22, 2024 at 10:08:05AM -0500, Sasha Levin wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
[ Upstream commit c6fbb6bca10838485b820e8a26c23996f77ce580 ]
Why is this being backported?
Is this not a fix for an issue?
On Tue, Jan 30, 2024 at 06:00:18PM -0500, Sasha Levin wrote:
On Mon, Jan 22, 2024 at 06:50:00PM +0200, Ville Syrjälä wrote:
On Mon, Jan 22, 2024 at 10:08:05AM -0500, Sasha Levin wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
[ Upstream commit c6fbb6bca10838485b820e8a26c23996f77ce580 ]
Why is this being backported?
Is this not a fix for an issue?
It is, for a very minor one that's not really going to hurt anyone. But it doesn't exist in a vacuum so backprting it alone can introduce other issues that people will actually notice. If I wanted it backported I would have have tagged it as such.
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit 504e08cebe1d4e1efe25f915234f646e74a364a8 ]
If refcount is less than 1, we should just warn, unlock dentry and return true, so that the caller doesn't try to do anything else.
Taking care of that leaves the rest of "lockref_put_return() has failed" case equivalent to "decrement refcount and rejoin the normal slow path after the point where we grab ->d_lock".
NOTE: lockref_put_return() is strictly a fastpath thing - unlike the rest of lockref primitives, it does not contain a fallback. Caller (and it looks like fast_dput() is the only legitimate one in the entire kernel) has to do that itself. Reasons for lockref_put_return() failures: * ->d_lock held by somebody * refcount <= 0 * ... or an architecture not supporting lockref use of cmpxchg - sparc, anything non-SMP, config with spinlock debugging...
We could add a fallback, but it would be a clumsy API - we'd have to distinguish between: (1) refcount > 1 - decremented, lock not held on return (2) refcount < 1 - left alone, probably no sense to hold the lock (3) refcount is 1, no cmphxcg - decremented, lock held on return (4) refcount is 1, cmphxcg supported - decremented, lock *NOT* held on return. We want to return with no lock held in case (4); that's the whole point of that thing. We very much do not want to have the fallback in case (3) return without a lock, since the caller might have to retake it in that case. So it wouldn't be more convenient than doing the fallback in the caller and it would be very easy to screw up, especially since the test coverage would suck - no way to test (3) and (4) on the same kernel build.
Reviewed-by: Christian Brauner brauner@kernel.org Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- fs/dcache.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/dcache.c b/fs/dcache.c index 52e6d5fdab6b..b09bc88dbbec 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -787,12 +787,12 @@ static inline bool fast_dput(struct dentry *dentry) */ if (unlikely(ret < 0)) { spin_lock(&dentry->d_lock); - if (dentry->d_lockref.count > 1) { - dentry->d_lockref.count--; + if (WARN_ON_ONCE(dentry->d_lockref.count <= 0)) { spin_unlock(&dentry->d_lock); return true; } - return false; + dentry->d_lockref.count--; + goto locked; }
/* @@ -850,6 +850,7 @@ static inline bool fast_dput(struct dentry *dentry) * else could have killed it and marked it dead. Either way, we * don't need to do anything else. */ +locked: if (dentry->d_lockref.count) { spin_unlock(&dentry->d_lock); return true;
From: Jack Wang jinpu.wang@ionos.com
[ Upstream commit 753fff78f430704548f45eda52d6d55371a52c0f ]
Return the error code in case of ib_sa_join_multicast fail.
Signed-off-by: Jack Wang jinpu.wang@ionos.com Link: https://lore.kernel.org/r/20231121130316.126364-2-jinpu.wang@ionos.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 5b3154503bf4..9e6967a40042 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -546,6 +546,7 @@ static int ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast) spin_unlock_irq(&priv->lock); complete(&mcast->done); spin_lock_irq(&priv->lock); + return ret; } return 0; }
From: Kamil Duljas kamil.duljas@gmail.com
[ Upstream commit 8c91ca76f44804868d12aed20ebdbc2f89aa7d60 ]
trace_filter_parse() allocs memory for *out and when -ENOMEM is returned, caller function, dfsentry_trace_filter_write() trying to freed this memory.
After this patch, the memory is freed in trace_filter_parse() before -EINVAL returned. In caller function removed kfree(elms) from error label
Signed-off-by: Kamil Duljas kamil.duljas@gmail.com Link: https://lore.kernel.org/r/20231116220102.2097-2-kamil.duljas@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sof/ipc3-dtrace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c index 8cf421577378..c626cefa0ec5 100644 --- a/sound/soc/sof/ipc3-dtrace.c +++ b/sound/soc/sof/ipc3-dtrace.c @@ -137,6 +137,7 @@ static int trace_filter_parse(struct snd_sof_dev *sdev, char *string, dev_err(sdev->dev, "Parsing filter entry '%s' failed with %d\n", entry, entry_len); + kfree(*out); return -EINVAL; } } @@ -215,13 +216,13 @@ static ssize_t dfsentry_trace_filter_write(struct file *file, const char __user ret = ipc3_trace_update_filter(sdev, num_elems, elems); if (ret < 0) { dev_err(sdev->dev, "Filter update failed: %d\n", ret); + kfree(elems); goto error; } } ret = count; error: kfree(string); - kfree(elems); return ret; }
From: Hsin-Yi Wang hsinyi@chromium.org
[ Upstream commit 9f7843b515811aea6c56527eb195b622e9c01f12 ]
Generic edp gets mode from edid. However, some panels report incorrect mode in this way, resulting in glitches on panel. Introduce a new quirk additional_mode to the generic edid to pick a correct hardcoded mode.
Signed-off-by: Hsin-Yi Wang hsinyi@chromium.org Reviewed-by: Douglas Anderson dianders@chromium.org Signed-off-by: Douglas Anderson dianders@chromium.org Link: https://patchwork.freedesktop.org/patch/msgid/20231117215056.1883314-2-hsiny... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-edp.c | 48 +++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index a163585a2a52..259b193e4dab 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -203,6 +203,9 @@ struct edp_panel_entry {
/** @name: Name of this panel (for printing to logs). */ const char *name; + + /** @override_edid_mode: Override the mode obtained by edid. */ + const struct drm_display_mode *override_edid_mode; };
struct panel_edp { @@ -301,6 +304,24 @@ static unsigned int panel_edp_get_display_modes(struct panel_edp *panel, return num; }
+static int panel_edp_override_edid_mode(struct panel_edp *panel, + struct drm_connector *connector, + const struct drm_display_mode *override_mode) +{ + struct drm_display_mode *mode; + + mode = drm_mode_duplicate(connector->dev, override_mode); + if (!mode) { + dev_err(panel->base.dev, "failed to add additional mode\n"); + return 0; + } + + mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + drm_mode_set_name(mode); + drm_mode_probed_add(connector, mode); + return 1; +} + static int panel_edp_get_non_edid_modes(struct panel_edp *panel, struct drm_connector *connector) { @@ -568,6 +589,9 @@ static int panel_edp_get_modes(struct drm_panel *panel, { struct panel_edp *p = to_panel_edp(panel); int num = 0; + bool has_override_edid_mode = p->detected_panel && + p->detected_panel != ERR_PTR(-EINVAL) && + p->detected_panel->override_edid_mode;
/* probe EDID if a DDC bus is available */ if (p->ddc) { @@ -575,9 +599,18 @@ static int panel_edp_get_modes(struct drm_panel *panel,
if (!p->edid) p->edid = drm_get_edid(connector, p->ddc); - - if (p->edid) - num += drm_add_edid_modes(connector, p->edid); + if (p->edid) { + if (has_override_edid_mode) { + /* + * override_edid_mode is specified. Use + * override_edid_mode instead of from edid. + */ + num += panel_edp_override_edid_mode(p, connector, + p->detected_panel->override_edid_mode); + } else { + num += drm_add_edid_modes(connector, p->edid); + } + }
pm_runtime_mark_last_busy(panel->dev); pm_runtime_put_autosuspend(panel->dev); @@ -1859,6 +1892,15 @@ static const struct panel_delay delay_200_500_e200 = { .delay = _delay \ }
+#define EDP_PANEL_ENTRY2(vend_chr_0, vend_chr_1, vend_chr_2, product_id, _delay, _name, _mode) \ +{ \ + .name = _name, \ + .panel_id = drm_edid_encode_panel_id(vend_chr_0, vend_chr_1, vend_chr_2, \ + product_id), \ + .delay = _delay, \ + .override_edid_mode = _mode \ +} + /* * This table is used to figure out power sequencing delays for panels that * are detected by EDID. Entries here may point to entries in the
From: Xin Ji xji@analogixsemi.com
[ Upstream commit e3af7053de3f685c96158373bc234b2feca1f160 ]
Polling firmware HPD GPIO status, set HPD irq detect window to 2ms after firmware HPD GPIO initial done
Signed-off-by: Xin Ji xji@analogixsemi.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20231120091038.284825-2-xji@an... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/analogix/anx7625.c | 51 ++++++++++++++++------- drivers/gpu/drm/bridge/analogix/anx7625.h | 4 ++ 2 files changed, 40 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index cf86cc05b7fc..6b79ad38f3ab 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1300,10 +1300,32 @@ static void anx7625_config(struct anx7625_data *ctx) XTAL_FRQ_SEL, XTAL_FRQ_27M); }
+static int anx7625_hpd_timer_config(struct anx7625_data *ctx) +{ + int ret; + + /* Set irq detect window to 2ms */ + ret = anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, + HPD_DET_TIMER_BIT0_7, HPD_TIME & 0xFF); + ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, + HPD_DET_TIMER_BIT8_15, + (HPD_TIME >> 8) & 0xFF); + ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, + HPD_DET_TIMER_BIT16_23, + (HPD_TIME >> 16) & 0xFF); + + return ret; +} + +static int anx7625_read_hpd_gpio_config_status(struct anx7625_data *ctx) +{ + return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, GPIO_CTRL_2); +} + static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) { struct device *dev = &ctx->client->dev; - int ret; + int ret, val;
/* Reset main ocm */ ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, 0x88, 0x40); @@ -1317,6 +1339,19 @@ static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature fail.\n"); else DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature succeeded.\n"); + + /* + * Make sure the HPD GPIO already be configured after OCM release before + * setting HPD detect window register. Here we poll the status register + * at maximum 40ms, then config HPD irq detect window register + */ + readx_poll_timeout(anx7625_read_hpd_gpio_config_status, + ctx, val, + ((val & HPD_SOURCE) || (val < 0)), + 2000, 2000 * 20); + + /* Set HPD irq detect window to 2ms */ + anx7625_hpd_timer_config(ctx); }
static int anx7625_ocm_loading_check(struct anx7625_data *ctx) @@ -1440,20 +1475,6 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx)
static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx) { - int ret; - - /* Set irq detect window to 2ms */ - ret = anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, - HPD_DET_TIMER_BIT0_7, HPD_TIME & 0xFF); - ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, - HPD_DET_TIMER_BIT8_15, - (HPD_TIME >> 8) & 0xFF); - ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, - HPD_DET_TIMER_BIT16_23, - (HPD_TIME >> 16) & 0xFF); - if (ret < 0) - return ret; - return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); }
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index 14f33d6be289..498d06cad250 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -259,6 +259,10 @@ #define AP_MIPI_RX_EN BIT(5) /* 1: MIPI RX input in 0: no RX in */ #define AP_DISABLE_PD BIT(6) #define AP_DISABLE_DISPLAY BIT(7) + +#define GPIO_CTRL_2 0x49 +#define HPD_SOURCE BIT(6) + /***************************************************************/ /* Register definition of device address 0x84 */ #define MIPI_PHY_CONTROL_3 0x03
From: Meenakshikumar Somasundaram meenakshikumar.somasundaram@amd.com
[ Upstream commit c4b8394e76adba4f50a3c2696c75b214a291e24a ]
[Why] When otg workaround is applied during clock update, otgs of tiled display went out of sync.
[How] To call dc_trigger_sync() after clock update to sync otgs again.
Reviewed-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Acked-by: Hamza Mahfooz hamza.mahfooz@amd.com Signed-off-by: Meenakshikumar Somasundaram meenakshikumar.somasundaram@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 7a309547c2b3..f415733f1a97 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1903,6 +1903,10 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c wait_for_no_pipes_pending(dc, context); /* pplib is notified if disp_num changed */ dc->hwss.optimize_bandwidth(dc, context); + /* Need to do otg sync again as otg could be out of sync due to otg + * workaround applied during clock update + */ + dc_trigger_sync(dc, context); }
if (dc->hwss.update_dsc_pg)
From: Laurent Pinchart laurent.pinchart@ideasonboard.com
[ Upstream commit 30d187cd74874aaf24e1b4a2dd2a64dc850c6b14 ]
V4L2 subdev operations have moved from operating on a v4l2_subdev_pad_config to a v4l2_subdev_state a long time ago. Fix remaining incorrect references to pad config in function and variable names.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Reviewed-by: Jacopo Mondi jacopo.mondi@ideasonboard.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- .../media/platform/renesas/vsp1/vsp1_brx.c | 40 +++++---- .../media/platform/renesas/vsp1/vsp1_clu.c | 3 +- .../media/platform/renesas/vsp1/vsp1_entity.c | 85 +++++++++---------- .../media/platform/renesas/vsp1/vsp1_entity.h | 10 +-- .../media/platform/renesas/vsp1/vsp1_hgo.c | 4 +- .../media/platform/renesas/vsp1/vsp1_hgt.c | 4 +- .../media/platform/renesas/vsp1/vsp1_histo.c | 24 +++--- .../media/platform/renesas/vsp1/vsp1_hsit.c | 11 ++- .../media/platform/renesas/vsp1/vsp1_lif.c | 2 +- .../media/platform/renesas/vsp1/vsp1_rpf.c | 8 +- .../media/platform/renesas/vsp1/vsp1_rwpf.c | 37 ++++---- .../media/platform/renesas/vsp1/vsp1_sru.c | 36 ++++---- .../media/platform/renesas/vsp1/vsp1_uds.c | 39 ++++----- .../media/platform/renesas/vsp1/vsp1_uif.c | 24 +++--- .../media/platform/renesas/vsp1/vsp1_video.c | 4 +- .../media/platform/renesas/vsp1/vsp1_wpf.c | 10 +-- 16 files changed, 162 insertions(+), 179 deletions(-)
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_brx.c b/drivers/media/platform/renesas/vsp1/vsp1_brx.c index 89385b4cabe5..23e815cea825 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_brx.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_brx.c @@ -136,29 +136,28 @@ static int brx_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_format *fmt) { struct vsp1_brx *brx = to_brx(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; int ret = 0;
mutex_lock(&brx->entity.lock);
- config = vsp1_entity_get_pad_config(&brx->entity, sd_state, - fmt->which); - if (!config) { + state = vsp1_entity_get_state(&brx->entity, sd_state, fmt->which); + if (!state) { ret = -EINVAL; goto done; }
- brx_try_format(brx, config, fmt->pad, &fmt->format); + brx_try_format(brx, state, fmt->pad, &fmt->format);
- format = vsp1_entity_get_pad_format(&brx->entity, config, fmt->pad); + format = vsp1_entity_get_pad_format(&brx->entity, state, fmt->pad); *format = fmt->format;
/* Reset the compose rectangle. */ if (fmt->pad != brx->entity.source_pad) { struct v4l2_rect *compose;
- compose = brx_get_compose(brx, config, fmt->pad); + compose = brx_get_compose(brx, state, fmt->pad); compose->left = 0; compose->top = 0; compose->width = format->width; @@ -171,7 +170,7 @@ static int brx_set_format(struct v4l2_subdev *subdev,
for (i = 0; i <= brx->entity.source_pad; ++i) { format = vsp1_entity_get_pad_format(&brx->entity, - config, i); + state, i); format->code = fmt->format.code; } } @@ -186,7 +185,7 @@ static int brx_get_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_selection *sel) { struct vsp1_brx *brx = to_brx(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state;
if (sel->pad == brx->entity.source_pad) return -EINVAL; @@ -200,13 +199,13 @@ static int brx_get_selection(struct v4l2_subdev *subdev, return 0;
case V4L2_SEL_TGT_COMPOSE: - config = vsp1_entity_get_pad_config(&brx->entity, sd_state, - sel->which); - if (!config) + state = vsp1_entity_get_state(&brx->entity, sd_state, + sel->which); + if (!state) return -EINVAL;
mutex_lock(&brx->entity.lock); - sel->r = *brx_get_compose(brx, config, sel->pad); + sel->r = *brx_get_compose(brx, state, sel->pad); mutex_unlock(&brx->entity.lock); return 0;
@@ -220,7 +219,7 @@ static int brx_set_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_selection *sel) { struct vsp1_brx *brx = to_brx(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; struct v4l2_rect *compose; int ret = 0; @@ -233,9 +232,8 @@ static int brx_set_selection(struct v4l2_subdev *subdev,
mutex_lock(&brx->entity.lock);
- config = vsp1_entity_get_pad_config(&brx->entity, sd_state, - sel->which); - if (!config) { + state = vsp1_entity_get_state(&brx->entity, sd_state, sel->which); + if (!state) { ret = -EINVAL; goto done; } @@ -244,7 +242,7 @@ static int brx_set_selection(struct v4l2_subdev *subdev, * The compose rectangle top left corner must be inside the output * frame. */ - format = vsp1_entity_get_pad_format(&brx->entity, config, + format = vsp1_entity_get_pad_format(&brx->entity, state, brx->entity.source_pad); sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1); sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1); @@ -253,11 +251,11 @@ static int brx_set_selection(struct v4l2_subdev *subdev, * Scaling isn't supported, the compose rectangle size must be identical * to the sink format size. */ - format = vsp1_entity_get_pad_format(&brx->entity, config, sel->pad); + format = vsp1_entity_get_pad_format(&brx->entity, state, sel->pad); sel->r.width = format->width; sel->r.height = format->height;
- compose = brx_get_compose(brx, config, sel->pad); + compose = brx_get_compose(brx, state, sel->pad); *compose = sel->r;
done: @@ -293,7 +291,7 @@ static void brx_configure_stream(struct vsp1_entity *entity, unsigned int flags; unsigned int i;
- format = vsp1_entity_get_pad_format(&brx->entity, brx->entity.config, + format = vsp1_entity_get_pad_format(&brx->entity, brx->entity.state, brx->entity.source_pad);
/* diff --git a/drivers/media/platform/renesas/vsp1/vsp1_clu.c b/drivers/media/platform/renesas/vsp1/vsp1_clu.c index c5217fee24f1..50a5c0dc0e86 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_clu.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_clu.c @@ -182,8 +182,7 @@ static void clu_configure_stream(struct vsp1_entity *entity, * The yuv_mode can't be changed during streaming. Cache it internally * for future runtime configuration calls. */ - format = vsp1_entity_get_pad_format(&clu->entity, - clu->entity.config, + format = vsp1_entity_get_pad_format(&clu->entity, clu->entity.state, CLU_PAD_SINK); clu->yuv_mode = format->code == MEDIA_BUS_FMT_AYUV8_1X32; } diff --git a/drivers/media/platform/renesas/vsp1/vsp1_entity.c b/drivers/media/platform/renesas/vsp1/vsp1_entity.c index c31f05a80bb5..47413f5c4824 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_entity.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_entity.c @@ -101,27 +101,26 @@ void vsp1_entity_configure_partition(struct vsp1_entity *entity, */
/** - * vsp1_entity_get_pad_config - Get the pad configuration for an entity + * vsp1_entity_get_state - Get the subdev state for an entity * @entity: the entity * @sd_state: the TRY state - * @which: configuration selector (ACTIVE or TRY) + * @which: state selector (ACTIVE or TRY) * * When called with which set to V4L2_SUBDEV_FORMAT_ACTIVE the caller must hold * the entity lock to access the returned configuration. * - * Return the pad configuration requested by the which argument. The TRY - * configuration is passed explicitly to the function through the cfg argument - * and simply returned when requested. The ACTIVE configuration comes from the - * entity structure. + * Return the subdev state requested by the which argument. The TRY state is + * passed explicitly to the function through the sd_state argument and simply + * returned when requested. The ACTIVE state comes from the entity structure. */ struct v4l2_subdev_state * -vsp1_entity_get_pad_config(struct vsp1_entity *entity, - struct v4l2_subdev_state *sd_state, - enum v4l2_subdev_format_whence which) +vsp1_entity_get_state(struct vsp1_entity *entity, + struct v4l2_subdev_state *sd_state, + enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_ACTIVE: - return entity->config; + return entity->state; case V4L2_SUBDEV_FORMAT_TRY: default: return sd_state; @@ -176,10 +175,11 @@ vsp1_entity_get_pad_selection(struct vsp1_entity *entity, /* * vsp1_entity_init_cfg - Initialize formats on all pads * @subdev: V4L2 subdevice - * @cfg: V4L2 subdev pad configuration + * @sd_state: V4L2 subdev state * - * Initialize all pad formats with default values in the given pad config. This - * function can be used as a handler for the subdev pad::init_cfg operation. + * Initialize all pad formats with default values in the given subdev state. + * This function can be used as a handler for the subdev pad::init_cfg + * operation. */ int vsp1_entity_init_cfg(struct v4l2_subdev *subdev, struct v4l2_subdev_state *sd_state) @@ -202,7 +202,7 @@ int vsp1_entity_init_cfg(struct v4l2_subdev *subdev, /* * vsp1_subdev_get_pad_format - Subdev pad get_fmt handler * @subdev: V4L2 subdevice - * @cfg: V4L2 subdev pad configuration + * @sd_state: V4L2 subdev state * @fmt: V4L2 subdev format * * This function implements the subdev get_fmt pad operation. It can be used as @@ -213,14 +213,14 @@ int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev, struct v4l2_subdev_format *fmt) { struct vsp1_entity *entity = to_vsp1_entity(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state;
- config = vsp1_entity_get_pad_config(entity, sd_state, fmt->which); - if (!config) + state = vsp1_entity_get_state(entity, sd_state, fmt->which); + if (!state) return -EINVAL;
mutex_lock(&entity->lock); - fmt->format = *vsp1_entity_get_pad_format(entity, config, fmt->pad); + fmt->format = *vsp1_entity_get_pad_format(entity, state, fmt->pad); mutex_unlock(&entity->lock);
return 0; @@ -229,7 +229,7 @@ int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev, /* * vsp1_subdev_enum_mbus_code - Subdev pad enum_mbus_code handler * @subdev: V4L2 subdevice - * @cfg: V4L2 subdev pad configuration + * @sd_state: V4L2 subdev state * @code: Media bus code enumeration * @codes: Array of supported media bus codes * @ncodes: Number of supported media bus codes @@ -252,7 +252,7 @@ int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
code->code = codes[code->index]; } else { - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format;
/* @@ -262,13 +262,12 @@ int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev, if (code->index) return -EINVAL;
- config = vsp1_entity_get_pad_config(entity, sd_state, - code->which); - if (!config) + state = vsp1_entity_get_state(entity, sd_state, code->which); + if (!state) return -EINVAL;
mutex_lock(&entity->lock); - format = vsp1_entity_get_pad_format(entity, config, 0); + format = vsp1_entity_get_pad_format(entity, state, 0); code->code = format->code; mutex_unlock(&entity->lock); } @@ -279,7 +278,7 @@ int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev, /* * vsp1_subdev_enum_frame_size - Subdev pad enum_frame_size handler * @subdev: V4L2 subdevice - * @cfg: V4L2 subdev pad configuration + * @sd_state: V4L2 subdev state * @fse: Frame size enumeration * @min_width: Minimum image width * @min_height: Minimum image height @@ -298,15 +297,15 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev, unsigned int max_width, unsigned int max_height) { struct vsp1_entity *entity = to_vsp1_entity(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; int ret = 0;
- config = vsp1_entity_get_pad_config(entity, sd_state, fse->which); - if (!config) + state = vsp1_entity_get_state(entity, sd_state, fse->which); + if (!state) return -EINVAL;
- format = vsp1_entity_get_pad_format(entity, config, fse->pad); + format = vsp1_entity_get_pad_format(entity, state, fse->pad);
mutex_lock(&entity->lock);
@@ -339,7 +338,7 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev, /* * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler * @subdev: V4L2 subdevice - * @cfg: V4L2 subdev pad configuration + * @sd_state: V4L2 subdev state * @fmt: V4L2 subdev format * @codes: Array of supported media bus codes * @ncodes: Number of supported media bus codes @@ -362,7 +361,7 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev, unsigned int max_width, unsigned int max_height) { struct vsp1_entity *entity = to_vsp1_entity(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; struct v4l2_rect *selection; unsigned int i; @@ -370,13 +369,13 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
mutex_lock(&entity->lock);
- config = vsp1_entity_get_pad_config(entity, sd_state, fmt->which); - if (!config) { + state = vsp1_entity_get_state(entity, sd_state, fmt->which); + if (!state) { ret = -EINVAL; goto done; }
- format = vsp1_entity_get_pad_format(entity, config, fmt->pad); + format = vsp1_entity_get_pad_format(entity, state, fmt->pad);
if (fmt->pad == entity->source_pad) { /* The output format can't be modified. */ @@ -404,18 +403,18 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev, fmt->format = *format;
/* Propagate the format to the source pad. */ - format = vsp1_entity_get_pad_format(entity, config, entity->source_pad); + format = vsp1_entity_get_pad_format(entity, state, entity->source_pad); *format = fmt->format;
/* Reset the crop and compose rectangles. */ - selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad, + selection = vsp1_entity_get_pad_selection(entity, state, fmt->pad, V4L2_SEL_TGT_CROP); selection->left = 0; selection->top = 0; selection->width = format->width; selection->height = format->height;
- selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad, + selection = vsp1_entity_get_pad_selection(entity, state, fmt->pad, V4L2_SEL_TGT_COMPOSE); selection->left = 0; selection->top = 0; @@ -672,18 +671,18 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, vsp1_entity_init_cfg(subdev, NULL);
/* - * Allocate the pad configuration to store formats and selection + * Allocate the subdev state to store formats and selection * rectangles. */ /* * FIXME: Drop this call, drivers are not supposed to use * __v4l2_subdev_state_alloc(). */ - entity->config = __v4l2_subdev_state_alloc(&entity->subdev, - "vsp1:config->lock", &key); - if (IS_ERR(entity->config)) { + entity->state = __v4l2_subdev_state_alloc(&entity->subdev, + "vsp1:state->lock", &key); + if (IS_ERR(entity->state)) { media_entity_cleanup(&entity->subdev.entity); - return PTR_ERR(entity->config); + return PTR_ERR(entity->state); }
return 0; @@ -695,6 +694,6 @@ void vsp1_entity_destroy(struct vsp1_entity *entity) entity->ops->destroy(entity); if (entity->subdev.ctrl_handler) v4l2_ctrl_handler_free(entity->subdev.ctrl_handler); - __v4l2_subdev_state_free(entity->config); + __v4l2_subdev_state_free(entity->state); media_entity_cleanup(&entity->subdev.entity); } diff --git a/drivers/media/platform/renesas/vsp1/vsp1_entity.h b/drivers/media/platform/renesas/vsp1/vsp1_entity.h index f22724439cdc..68bf4424cfdf 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_entity.h +++ b/drivers/media/platform/renesas/vsp1/vsp1_entity.h @@ -115,9 +115,9 @@ struct vsp1_entity { unsigned int sink_pad;
struct v4l2_subdev subdev; - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state;
- struct mutex lock; /* Protects the pad config */ + struct mutex lock; /* Protects the state */ };
static inline struct vsp1_entity *to_vsp1_entity(struct v4l2_subdev *subdev) @@ -137,9 +137,9 @@ int vsp1_entity_link_setup(struct media_entity *entity, const struct media_pad *remote, u32 flags);
struct v4l2_subdev_state * -vsp1_entity_get_pad_config(struct vsp1_entity *entity, - struct v4l2_subdev_state *sd_state, - enum v4l2_subdev_format_whence which); +vsp1_entity_get_state(struct vsp1_entity *entity, + struct v4l2_subdev_state *sd_state, + enum v4l2_subdev_format_whence which); struct v4l2_mbus_framefmt * vsp1_entity_get_pad_format(struct vsp1_entity *entity, struct v4l2_subdev_state *sd_state, diff --git a/drivers/media/platform/renesas/vsp1/vsp1_hgo.c b/drivers/media/platform/renesas/vsp1/vsp1_hgo.c index bf3f981f93a1..4a55a46bc70f 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_hgo.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_hgo.c @@ -140,9 +140,9 @@ static void hgo_configure_stream(struct vsp1_entity *entity, unsigned int hratio; unsigned int vratio;
- crop = vsp1_entity_get_pad_selection(entity, entity->config, + crop = vsp1_entity_get_pad_selection(entity, entity->state, HISTO_PAD_SINK, V4L2_SEL_TGT_CROP); - compose = vsp1_entity_get_pad_selection(entity, entity->config, + compose = vsp1_entity_get_pad_selection(entity, entity->state, HISTO_PAD_SINK, V4L2_SEL_TGT_COMPOSE);
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_hgt.c b/drivers/media/platform/renesas/vsp1/vsp1_hgt.c index aa1c718e0453..8281b86874ab 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_hgt.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_hgt.c @@ -139,9 +139,9 @@ static void hgt_configure_stream(struct vsp1_entity *entity, u8 upper; unsigned int i;
- crop = vsp1_entity_get_pad_selection(entity, entity->config, + crop = vsp1_entity_get_pad_selection(entity, entity->state, HISTO_PAD_SINK, V4L2_SEL_TGT_CROP); - compose = vsp1_entity_get_pad_selection(entity, entity->config, + compose = vsp1_entity_get_pad_selection(entity, entity->state, HISTO_PAD_SINK, V4L2_SEL_TGT_COMPOSE);
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_histo.c b/drivers/media/platform/renesas/vsp1/vsp1_histo.c index f22449dd654c..71155282ca11 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_histo.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_histo.c @@ -203,7 +203,7 @@ static int histo_get_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_selection *sel) { struct vsp1_histogram *histo = subdev_to_histo(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; int ret = 0; @@ -213,9 +213,8 @@ static int histo_get_selection(struct v4l2_subdev *subdev,
mutex_lock(&histo->entity.lock);
- config = vsp1_entity_get_pad_config(&histo->entity, sd_state, - sel->which); - if (!config) { + state = vsp1_entity_get_state(&histo->entity, sd_state, sel->which); + if (!state) { ret = -EINVAL; goto done; } @@ -223,7 +222,7 @@ static int histo_get_selection(struct v4l2_subdev *subdev, switch (sel->target) { case V4L2_SEL_TGT_COMPOSE_BOUNDS: case V4L2_SEL_TGT_COMPOSE_DEFAULT: - crop = vsp1_entity_get_pad_selection(&histo->entity, config, + crop = vsp1_entity_get_pad_selection(&histo->entity, state, HISTO_PAD_SINK, V4L2_SEL_TGT_CROP); sel->r.left = 0; @@ -234,7 +233,7 @@ static int histo_get_selection(struct v4l2_subdev *subdev,
case V4L2_SEL_TGT_CROP_BOUNDS: case V4L2_SEL_TGT_CROP_DEFAULT: - format = vsp1_entity_get_pad_format(&histo->entity, config, + format = vsp1_entity_get_pad_format(&histo->entity, state, HISTO_PAD_SINK); sel->r.left = 0; sel->r.top = 0; @@ -244,7 +243,7 @@ static int histo_get_selection(struct v4l2_subdev *subdev,
case V4L2_SEL_TGT_COMPOSE: case V4L2_SEL_TGT_CROP: - sel->r = *vsp1_entity_get_pad_selection(&histo->entity, config, + sel->r = *vsp1_entity_get_pad_selection(&histo->entity, state, sel->pad, sel->target); break;
@@ -346,7 +345,7 @@ static int histo_set_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_selection *sel) { struct vsp1_histogram *histo = subdev_to_histo(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; int ret;
if (sel->pad != HISTO_PAD_SINK) @@ -354,17 +353,16 @@ static int histo_set_selection(struct v4l2_subdev *subdev,
mutex_lock(&histo->entity.lock);
- config = vsp1_entity_get_pad_config(&histo->entity, sd_state, - sel->which); - if (!config) { + state = vsp1_entity_get_state(&histo->entity, sd_state, sel->which); + if (!state) { ret = -EINVAL; goto done; }
if (sel->target == V4L2_SEL_TGT_CROP) - ret = histo_set_crop(subdev, config, sel); + ret = histo_set_crop(subdev, state, sel); else if (sel->target == V4L2_SEL_TGT_COMPOSE) - ret = histo_set_compose(subdev, config, sel); + ret = histo_set_compose(subdev, state, sel); else ret = -EINVAL;
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_hsit.c b/drivers/media/platform/renesas/vsp1/vsp1_hsit.c index 361a870380c2..6342ac7bdf54 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_hsit.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_hsit.c @@ -66,20 +66,19 @@ static int hsit_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_format *fmt) { struct vsp1_hsit *hsit = to_hsit(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; int ret = 0;
mutex_lock(&hsit->entity.lock);
- config = vsp1_entity_get_pad_config(&hsit->entity, sd_state, - fmt->which); - if (!config) { + state = vsp1_entity_get_state(&hsit->entity, sd_state, fmt->which); + if (!state) { ret = -EINVAL; goto done; }
- format = vsp1_entity_get_pad_format(&hsit->entity, config, fmt->pad); + format = vsp1_entity_get_pad_format(&hsit->entity, state, fmt->pad);
if (fmt->pad == HSIT_PAD_SOURCE) { /* @@ -102,7 +101,7 @@ static int hsit_set_format(struct v4l2_subdev *subdev, fmt->format = *format;
/* Propagate the format to the source pad. */ - format = vsp1_entity_get_pad_format(&hsit->entity, config, + format = vsp1_entity_get_pad_format(&hsit->entity, state, HSIT_PAD_SOURCE); *format = fmt->format; format->code = hsit->inverse ? MEDIA_BUS_FMT_ARGB8888_1X32 diff --git a/drivers/media/platform/renesas/vsp1/vsp1_lif.c b/drivers/media/platform/renesas/vsp1/vsp1_lif.c index 186a5730e1e3..a135f5399be2 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_lif.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_lif.c @@ -94,7 +94,7 @@ static void lif_configure_stream(struct vsp1_entity *entity, unsigned int obth; unsigned int lbth;
- format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config, + format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.state, LIF_PAD_SOURCE);
switch (entity->vsp1->version & VI6_IP_VERSION_MODEL_MASK) { diff --git a/drivers/media/platform/renesas/vsp1/vsp1_rpf.c b/drivers/media/platform/renesas/vsp1/vsp1_rpf.c index 75083cb234fe..e2c7df1bd6c6 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_rpf.c @@ -89,10 +89,10 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
/* Format */ sink_format = vsp1_entity_get_pad_format(&rpf->entity, - rpf->entity.config, + rpf->entity.state, RWPF_PAD_SINK); source_format = vsp1_entity_get_pad_format(&rpf->entity, - rpf->entity.config, + rpf->entity.state, RWPF_PAD_SOURCE);
infmt = VI6_RPF_INFMT_CIPM @@ -114,7 +114,7 @@ static void rpf_configure_stream(struct vsp1_entity *entity, const struct v4l2_rect *compose;
compose = vsp1_entity_get_pad_selection(pipe->brx, - pipe->brx->config, + pipe->brx->state, rpf->brx_input, V4L2_SEL_TGT_COMPOSE); left = compose->left; @@ -258,7 +258,7 @@ static void rpf_configure_partition(struct vsp1_entity *entity, * offsets are needed, as planes 2 and 3 always have identical * strides. */ - crop = *vsp1_rwpf_get_crop(rpf, rpf->entity.config); + crop = *vsp1_rwpf_get_crop(rpf, rpf->entity.state);
/* * Partition Algorithm Control diff --git a/drivers/media/platform/renesas/vsp1/vsp1_rwpf.c b/drivers/media/platform/renesas/vsp1/vsp1_rwpf.c index 22a82d218152..8a4165368f53 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_rwpf.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_rwpf.c @@ -62,15 +62,14 @@ static int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_format *fmt) { struct vsp1_rwpf *rwpf = to_rwpf(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; int ret = 0;
mutex_lock(&rwpf->entity.lock);
- config = vsp1_entity_get_pad_config(&rwpf->entity, sd_state, - fmt->which); - if (!config) { + state = vsp1_entity_get_state(&rwpf->entity, sd_state, fmt->which); + if (!state) { ret = -EINVAL; goto done; } @@ -81,7 +80,7 @@ static int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
- format = vsp1_entity_get_pad_format(&rwpf->entity, config, fmt->pad); + format = vsp1_entity_get_pad_format(&rwpf->entity, state, fmt->pad);
if (fmt->pad == RWPF_PAD_SOURCE) { /* @@ -107,7 +106,7 @@ static int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_rect *crop;
/* Update the sink crop rectangle. */ - crop = vsp1_rwpf_get_crop(rwpf, config); + crop = vsp1_rwpf_get_crop(rwpf, state); crop->left = 0; crop->top = 0; crop->width = fmt->format.width; @@ -115,7 +114,7 @@ static int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, }
/* Propagate the format to the source pad. */ - format = vsp1_entity_get_pad_format(&rwpf->entity, config, + format = vsp1_entity_get_pad_format(&rwpf->entity, state, RWPF_PAD_SOURCE); *format = fmt->format;
@@ -134,7 +133,7 @@ static int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_selection *sel) { struct vsp1_rwpf *rwpf = to_rwpf(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; int ret = 0;
@@ -147,20 +146,19 @@ static int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev,
mutex_lock(&rwpf->entity.lock);
- config = vsp1_entity_get_pad_config(&rwpf->entity, sd_state, - sel->which); - if (!config) { + state = vsp1_entity_get_state(&rwpf->entity, sd_state, sel->which); + if (!state) { ret = -EINVAL; goto done; }
switch (sel->target) { case V4L2_SEL_TGT_CROP: - sel->r = *vsp1_rwpf_get_crop(rwpf, config); + sel->r = *vsp1_rwpf_get_crop(rwpf, state); break;
case V4L2_SEL_TGT_CROP_BOUNDS: - format = vsp1_entity_get_pad_format(&rwpf->entity, config, + format = vsp1_entity_get_pad_format(&rwpf->entity, state, RWPF_PAD_SINK); sel->r.left = 0; sel->r.top = 0; @@ -183,7 +181,7 @@ static int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_selection *sel) { struct vsp1_rwpf *rwpf = to_rwpf(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; int ret = 0; @@ -200,15 +198,14 @@ static int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
mutex_lock(&rwpf->entity.lock);
- config = vsp1_entity_get_pad_config(&rwpf->entity, sd_state, - sel->which); - if (!config) { + state = vsp1_entity_get_state(&rwpf->entity, sd_state, sel->which); + if (!state) { ret = -EINVAL; goto done; }
/* Make sure the crop rectangle is entirely contained in the image. */ - format = vsp1_entity_get_pad_format(&rwpf->entity, config, + format = vsp1_entity_get_pad_format(&rwpf->entity, state, RWPF_PAD_SINK);
/* @@ -229,11 +226,11 @@ static int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev, sel->r.height = min_t(unsigned int, sel->r.height, format->height - sel->r.top);
- crop = vsp1_rwpf_get_crop(rwpf, config); + crop = vsp1_rwpf_get_crop(rwpf, state); *crop = sel->r;
/* Propagate the format to the source pad. */ - format = vsp1_entity_get_pad_format(&rwpf->entity, config, + format = vsp1_entity_get_pad_format(&rwpf->entity, state, RWPF_PAD_SOURCE); format->width = crop->width; format->height = crop->height; diff --git a/drivers/media/platform/renesas/vsp1/vsp1_sru.c b/drivers/media/platform/renesas/vsp1/vsp1_sru.c index b614a2aea461..2dd6f8575614 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_sru.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_sru.c @@ -123,16 +123,15 @@ static int sru_enum_frame_size(struct v4l2_subdev *subdev, struct v4l2_subdev_frame_size_enum *fse) { struct vsp1_sru *sru = to_sru(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; int ret = 0;
- config = vsp1_entity_get_pad_config(&sru->entity, sd_state, - fse->which); - if (!config) + state = vsp1_entity_get_state(&sru->entity, sd_state, fse->which); + if (!state) return -EINVAL;
- format = vsp1_entity_get_pad_format(&sru->entity, config, SRU_PAD_SINK); + format = vsp1_entity_get_pad_format(&sru->entity, state, SRU_PAD_SINK);
mutex_lock(&sru->entity.lock);
@@ -221,31 +220,30 @@ static int sru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_format *fmt) { struct vsp1_sru *sru = to_sru(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; int ret = 0;
mutex_lock(&sru->entity.lock);
- config = vsp1_entity_get_pad_config(&sru->entity, sd_state, - fmt->which); - if (!config) { + state = vsp1_entity_get_state(&sru->entity, sd_state, fmt->which); + if (!state) { ret = -EINVAL; goto done; }
- sru_try_format(sru, config, fmt->pad, &fmt->format); + sru_try_format(sru, state, fmt->pad, &fmt->format);
- format = vsp1_entity_get_pad_format(&sru->entity, config, fmt->pad); + format = vsp1_entity_get_pad_format(&sru->entity, state, fmt->pad); *format = fmt->format;
if (fmt->pad == SRU_PAD_SINK) { /* Propagate the format to the source pad. */ - format = vsp1_entity_get_pad_format(&sru->entity, config, + format = vsp1_entity_get_pad_format(&sru->entity, state, SRU_PAD_SOURCE); *format = fmt->format;
- sru_try_format(sru, config, SRU_PAD_SOURCE, format); + sru_try_format(sru, state, SRU_PAD_SOURCE, format); }
done: @@ -280,9 +278,9 @@ static void sru_configure_stream(struct vsp1_entity *entity, struct v4l2_mbus_framefmt *output; u32 ctrl0;
- input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, + input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.state, SRU_PAD_SINK); - output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, + output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.state, SRU_PAD_SOURCE);
if (input->code == MEDIA_BUS_FMT_ARGB8888_1X32) @@ -310,9 +308,9 @@ static unsigned int sru_max_width(struct vsp1_entity *entity, struct v4l2_mbus_framefmt *input; struct v4l2_mbus_framefmt *output;
- input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, + input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.state, SRU_PAD_SINK); - output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, + output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.state, SRU_PAD_SOURCE);
/* @@ -336,9 +334,9 @@ static void sru_partition(struct vsp1_entity *entity, struct v4l2_mbus_framefmt *input; struct v4l2_mbus_framefmt *output;
- input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, + input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.state, SRU_PAD_SINK); - output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, + output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.state, SRU_PAD_SOURCE);
/* Adapt if SRUx2 is enabled. */ diff --git a/drivers/media/platform/renesas/vsp1/vsp1_uds.c b/drivers/media/platform/renesas/vsp1/vsp1_uds.c index 1c290cda005a..59ff4ae46cea 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_uds.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_uds.c @@ -128,17 +128,15 @@ static int uds_enum_frame_size(struct v4l2_subdev *subdev, struct v4l2_subdev_frame_size_enum *fse) { struct vsp1_uds *uds = to_uds(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; int ret = 0;
- config = vsp1_entity_get_pad_config(&uds->entity, sd_state, - fse->which); - if (!config) + state = vsp1_entity_get_state(&uds->entity, sd_state, fse->which); + if (!state) return -EINVAL;
- format = vsp1_entity_get_pad_format(&uds->entity, config, - UDS_PAD_SINK); + format = vsp1_entity_get_pad_format(&uds->entity, state, UDS_PAD_SINK);
mutex_lock(&uds->entity.lock);
@@ -205,31 +203,30 @@ static int uds_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_format *fmt) { struct vsp1_uds *uds = to_uds(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; int ret = 0;
mutex_lock(&uds->entity.lock);
- config = vsp1_entity_get_pad_config(&uds->entity, sd_state, - fmt->which); - if (!config) { + state = vsp1_entity_get_state(&uds->entity, sd_state, fmt->which); + if (!state) { ret = -EINVAL; goto done; }
- uds_try_format(uds, config, fmt->pad, &fmt->format); + uds_try_format(uds, state, fmt->pad, &fmt->format);
- format = vsp1_entity_get_pad_format(&uds->entity, config, fmt->pad); + format = vsp1_entity_get_pad_format(&uds->entity, state, fmt->pad); *format = fmt->format;
if (fmt->pad == UDS_PAD_SINK) { /* Propagate the format to the source pad. */ - format = vsp1_entity_get_pad_format(&uds->entity, config, + format = vsp1_entity_get_pad_format(&uds->entity, state, UDS_PAD_SOURCE); *format = fmt->format;
- uds_try_format(uds, config, UDS_PAD_SOURCE, format); + uds_try_format(uds, state, UDS_PAD_SOURCE, format); }
done: @@ -269,9 +266,9 @@ static void uds_configure_stream(struct vsp1_entity *entity, unsigned int vscale; bool multitap;
- input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, + input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.state, UDS_PAD_SINK); - output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, + output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.state, UDS_PAD_SOURCE);
hscale = uds_compute_ratio(input->width, output->width); @@ -314,7 +311,7 @@ static void uds_configure_partition(struct vsp1_entity *entity, struct vsp1_partition *partition = pipe->partition; const struct v4l2_mbus_framefmt *output;
- output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, + output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.state, UDS_PAD_SOURCE);
/* Input size clipping. */ @@ -339,9 +336,9 @@ static unsigned int uds_max_width(struct vsp1_entity *entity, const struct v4l2_mbus_framefmt *input; unsigned int hscale;
- input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, + input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.state, UDS_PAD_SINK); - output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, + output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.state, UDS_PAD_SOURCE); hscale = output->width / input->width;
@@ -381,9 +378,9 @@ static void uds_partition(struct vsp1_entity *entity, partition->uds_sink = *window; partition->uds_source = *window;
- input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, + input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.state, UDS_PAD_SINK); - output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, + output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.state, UDS_PAD_SOURCE);
partition->uds_sink.width = window->width * input->width diff --git a/drivers/media/platform/renesas/vsp1/vsp1_uif.c b/drivers/media/platform/renesas/vsp1/vsp1_uif.c index 83d7f17df80e..d84d10f35090 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_uif.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_uif.c @@ -86,7 +86,7 @@ static int uif_get_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_selection *sel) { struct vsp1_uif *uif = to_uif(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; int ret = 0;
@@ -95,9 +95,8 @@ static int uif_get_selection(struct v4l2_subdev *subdev,
mutex_lock(&uif->entity.lock);
- config = vsp1_entity_get_pad_config(&uif->entity, sd_state, - sel->which); - if (!config) { + state = vsp1_entity_get_state(&uif->entity, sd_state, sel->which); + if (!state) { ret = -EINVAL; goto done; } @@ -105,7 +104,7 @@ static int uif_get_selection(struct v4l2_subdev *subdev, switch (sel->target) { case V4L2_SEL_TGT_CROP_BOUNDS: case V4L2_SEL_TGT_CROP_DEFAULT: - format = vsp1_entity_get_pad_format(&uif->entity, config, + format = vsp1_entity_get_pad_format(&uif->entity, state, UIF_PAD_SINK); sel->r.left = 0; sel->r.top = 0; @@ -114,7 +113,7 @@ static int uif_get_selection(struct v4l2_subdev *subdev, break;
case V4L2_SEL_TGT_CROP: - sel->r = *vsp1_entity_get_pad_selection(&uif->entity, config, + sel->r = *vsp1_entity_get_pad_selection(&uif->entity, state, sel->pad, sel->target); break;
@@ -133,7 +132,7 @@ static int uif_set_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_selection *sel) { struct vsp1_uif *uif = to_uif(subdev); - struct v4l2_subdev_state *config; + struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; struct v4l2_rect *selection; int ret = 0; @@ -144,15 +143,14 @@ static int uif_set_selection(struct v4l2_subdev *subdev,
mutex_lock(&uif->entity.lock);
- config = vsp1_entity_get_pad_config(&uif->entity, sd_state, - sel->which); - if (!config) { + state = vsp1_entity_get_state(&uif->entity, sd_state, sel->which); + if (!state) { ret = -EINVAL; goto done; }
/* The crop rectangle must be inside the input frame. */ - format = vsp1_entity_get_pad_format(&uif->entity, config, UIF_PAD_SINK); + format = vsp1_entity_get_pad_format(&uif->entity, state, UIF_PAD_SINK);
sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1); sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1); @@ -162,7 +160,7 @@ static int uif_set_selection(struct v4l2_subdev *subdev, format->height - sel->r.top);
/* Store the crop rectangle. */ - selection = vsp1_entity_get_pad_selection(&uif->entity, config, + selection = vsp1_entity_get_pad_selection(&uif->entity, state, sel->pad, V4L2_SEL_TGT_CROP); *selection = sel->r;
@@ -206,7 +204,7 @@ static void uif_configure_stream(struct vsp1_entity *entity, vsp1_uif_write(uif, dlb, VI6_UIF_DISCOM_DOCMPMR, VI6_UIF_DISCOM_DOCMPMR_SEL(9));
- crop = vsp1_entity_get_pad_selection(entity, entity->config, + crop = vsp1_entity_get_pad_selection(entity, entity->state, UIF_PAD_SINK, V4L2_SEL_TGT_CROP);
left = crop->left; diff --git a/drivers/media/platform/renesas/vsp1/vsp1_video.c b/drivers/media/platform/renesas/vsp1/vsp1_video.c index 9d24647c8f32..af5da185261d 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_video.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_video.c @@ -197,7 +197,7 @@ static void vsp1_video_calculate_partition(struct vsp1_pipeline *pipe, * at the WPF sink. */ format = vsp1_entity_get_pad_format(&pipe->output->entity, - pipe->output->entity.config, + pipe->output->entity.state, RWPF_PAD_SINK);
/* A single partition simply processes the output size in full. */ @@ -262,7 +262,7 @@ static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) * at the WPF sink. */ format = vsp1_entity_get_pad_format(&pipe->output->entity, - pipe->output->entity.config, + pipe->output->entity.state, RWPF_PAD_SINK); div_size = format->width;
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_wpf.c b/drivers/media/platform/renesas/vsp1/vsp1_wpf.c index 94e91d7bb56c..4c1de322963d 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_wpf.c @@ -66,10 +66,10 @@ static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf, unsigned int rotation) }
sink_format = vsp1_entity_get_pad_format(&wpf->entity, - wpf->entity.config, + wpf->entity.state, RWPF_PAD_SINK); source_format = vsp1_entity_get_pad_format(&wpf->entity, - wpf->entity.config, + wpf->entity.state, RWPF_PAD_SOURCE);
mutex_lock(&wpf->entity.lock); @@ -269,10 +269,10 @@ static void wpf_configure_stream(struct vsp1_entity *entity, int ret;
sink_format = vsp1_entity_get_pad_format(&wpf->entity, - wpf->entity.config, + wpf->entity.state, RWPF_PAD_SINK); source_format = vsp1_entity_get_pad_format(&wpf->entity, - wpf->entity.config, + wpf->entity.state, RWPF_PAD_SOURCE);
/* Format */ @@ -407,7 +407,7 @@ static void wpf_configure_partition(struct vsp1_entity *entity, unsigned int i;
sink_format = vsp1_entity_get_pad_format(&wpf->entity, - wpf->entity.config, + wpf->entity.state, RWPF_PAD_SINK); width = sink_format->width; height = sink_format->height;
From: Jaegeuk Kim jaegeuk@kernel.org
[ Upstream commit 9dad4d964291295ef48243d4e03972b85138bc9f ]
1. do roll forward recovery 2. update current segments pointers 3. fix the entire zones' write pointers 4. do checkpoint
Reviewed-by: Daeho Jeong daehojeong@google.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/recovery.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 4f4db465220f..53a6487f91e4 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -898,6 +898,8 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) if (!err && fix_curseg_write_pointer && !f2fs_readonly(sbi->sb) && f2fs_sb_has_blkzoned(sbi)) { err = f2fs_fix_curseg_write_pointer(sbi); + if (!err) + err = f2fs_check_write_pointer(sbi); ret = err; }
From: Venkata Prasad Potturu venkataprasad.potturu@amd.com
[ Upstream commit c3ab23a10771bbe06300e5374efa809789c65455 ]
Add sys_vendor and product_name dmi entries for acp5x platform.
Signed-off-by: Venkata Prasad Potturu venkataprasad.potturu@amd.com Link: https://lore.kernel.org/r/20231206110620.1695591-1-venkataprasad.potturu@amd... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/amd/acp-config.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/sound/soc/amd/acp-config.c b/sound/soc/amd/acp-config.c index 0932473b6394..9ee71a99a087 100644 --- a/sound/soc/amd/acp-config.c +++ b/sound/soc/amd/acp-config.c @@ -3,7 +3,7 @@ // This file is provided under a dual BSD/GPLv2 license. When using or // redistributing this file, you may do so under either license. // -// Copyright(c) 2021 Advanced Micro Devices, Inc. +// Copyright(c) 2021, 2023 Advanced Micro Devices, Inc. // // Authors: Ajit Kumar Pandey AjitKumar.Pandey@amd.com // @@ -35,6 +35,19 @@ static const struct config_entry config_table[] = { {} }, }, + { + .flags = FLAG_AMD_LEGACY, + .device = ACP_PCI_DEV_ID, + .dmi_table = (const struct dmi_system_id []) { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Valve"), + DMI_MATCH(DMI_PRODUCT_NAME, "Jupiter"), + }, + }, + {} + }, + }, { .flags = FLAG_AMD_SOF, .device = ACP_PCI_DEV_ID,
From: Alex Hung alex.hung@amd.com
[ Upstream commit 8a307777c36e15f38c9f23778babcd368144c7d8 ]
[WHY] wb_enabled field is set to false before it is used, and the following code will never be executed.
[HOW] Setting wb_enable to false after all removal work is completed.
Reviewed-by: Harry Wentland harry.wentland@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 556c57c390ff..12b73b0ff19e 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -514,18 +514,13 @@ bool dc_stream_remove_writeback(struct dc *dc, return false; }
-// stream->writeback_info[dwb_pipe_inst].wb_enabled = false; - for (i = 0; i < stream->num_wb_info; i++) { - /*dynamic update*/ - if (stream->writeback_info[i].wb_enabled && - stream->writeback_info[i].dwb_pipe_inst == dwb_pipe_inst) { - stream->writeback_info[i].wb_enabled = false; - } - } - /* remove writeback info for disabled writeback pipes from stream */ for (i = 0, j = 0; i < stream->num_wb_info; i++) { if (stream->writeback_info[i].wb_enabled) { + + if (stream->writeback_info[i].dwb_pipe_inst == dwb_pipe_inst) + stream->writeback_info[i].wb_enabled = false; + if (j < i) /* trim the array */ stream->writeback_info[j] = stream->writeback_info[i];
From: Alex Hung alex.hung@amd.com
[ Upstream commit 5b89d2ccc8466e0445a4994cb288fc009b565de5 ]
[WHY] Counter j was not updated to present the num of writeback_info when writeback pipes are removed.
[HOW] update j (num of writeback info) under the correct condition.
Reviewed-by: Harry Wentland harry.wentland@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 12b73b0ff19e..b59db6c95820 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -521,10 +521,11 @@ bool dc_stream_remove_writeback(struct dc *dc, if (stream->writeback_info[i].dwb_pipe_inst == dwb_pipe_inst) stream->writeback_info[i].wb_enabled = false;
- if (j < i) - /* trim the array */ + /* trim the array */ + if (j < i) { stream->writeback_info[j] = stream->writeback_info[i]; - j++; + j++; + } } } stream->num_wb_info = j;
From: Tomi Valkeinen tomi.valkeinen@ideasonboard.com
[ Upstream commit 1d3062fad9c7313fff9970a88e0538a24480ffb8 ]
smatch reports:
drivers/gpu/drm/drm_file.c:967 drm_show_memory_stats() error: uninitialized symbol 'supported_status'.
'supported_status' is only set in one code path. I'm not familiar with the code to say if that path will always be ran in real life, but whether that is the case or not, I think it is good to initialize 'supported_status' to 0 to silence the warning (and possibly fix a bug).
Reviewed-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com Acked-by: Maxime Ripard mripard@kernel.org Signed-off-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Link: https://patchwork.freedesktop.org/patch/msgid/20231103-uninit-fixes-v2-1-c22... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index a8b4d918e9a3..d6a0572984b5 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -406,7 +406,7 @@ int drm_open(struct inode *inode, struct file *filp) { struct drm_device *dev; struct drm_minor *minor; - int retcode; + int retcode = 0; int need_setup = 0;
minor = drm_minor_acquire(iminor(inode));
From: Tomi Valkeinen tomi.valkeinen@ideasonboard.com
[ Upstream commit f9af8f0c1dc567a5a6a6318ff324c45d80d4a60f ]
smatch reports:
drivers/gpu/drm/drm_framebuffer.c:654 drm_mode_getfb2_ioctl() error: uninitialized symbol 'ret'.
'ret' is possibly not set when there are no errors, causing the error above. I can't say if that ever happens in real-life, but in any case I think it is good to initialize 'ret' to 0.
Reviewed-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com Acked-by: Maxime Ripard mripard@kernel.org Signed-off-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Link: https://patchwork.freedesktop.org/patch/msgid/20231103-uninit-fixes-v2-2-c22... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_framebuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 2dd97473ca10..72ad1715f8e7 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -570,7 +570,7 @@ int drm_mode_getfb2_ioctl(struct drm_device *dev, struct drm_mode_fb_cmd2 *r = data; struct drm_framebuffer *fb; unsigned int i; - int ret; + int ret = 0;
if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL;
From: Tomi Valkeinen tomi.valkeinen@ideasonboard.com
[ Upstream commit 90d50b8d85834e73536fdccd5aa913b30494fef0 ]
It's been reported that DSI host driver's detach can be called without the attach ever happening:
https://lore.kernel.org/all/20230412073954.20601-1-tony@atomide.com/
After reading the code, I think this is what happens:
We have a DSI host defined in the device tree and a DSI peripheral under that host (i.e. an i2c device using the DSI as data bus doesn't exhibit this behavior).
The host driver calls mipi_dsi_host_register(), which causes (via a few functions) mipi_dsi_device_add() to be called for the DSI peripheral. So now we have a DSI device under the host, but attach hasn't been called.
Normally the probing of the devices continues, and eventually the DSI peripheral's driver will call mipi_dsi_attach(), attaching the peripheral.
However, if the host driver's probe encounters an error after calling mipi_dsi_host_register(), and before the peripheral has called mipi_dsi_attach(), the host driver will do cleanups and return an error from its probe function. The cleanups include calling mipi_dsi_host_unregister().
mipi_dsi_host_unregister() will call two functions for all its DSI peripheral devices: mipi_dsi_detach() and mipi_dsi_device_unregister(). The latter makes sense, as the device exists, but the former may be wrong as attach has not necessarily been done.
To fix this, track the attached state of the peripheral, and only detach from mipi_dsi_host_unregister() if the peripheral was attached.
Note that I have only tested this with a board with an i2c DSI peripheral, not with a "pure" DSI peripheral.
However, slightly related, the unregister machinery still seems broken. E.g. if the DSI host driver is unbound, it'll detach and unregister the DSI peripherals. After that, when the DSI peripheral driver unbound it'll call detach either directly or using the devm variant, leading to a crash. And probably the driver will crash if it happens, for some reason, to try to send a message via the DSI bus.
But that's another topic.
Tested-by: H. Nikolaus Schaller hns@goldelico.com Acked-by: Maxime Ripard mripard@kernel.org Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.com Tested-by: Tony Lindgren tony@atomide.com Signed-off-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Link: https://patchwork.freedesktop.org/patch/msgid/20230921-dsi-detach-fix-v1-1-d... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_mipi_dsi.c | 17 +++++++++++++++-- include/drm/drm_mipi_dsi.h | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 853208e8dd73..ef7ec68867df 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -346,7 +346,8 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) { struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
- mipi_dsi_detach(dsi); + if (dsi->attached) + mipi_dsi_detach(dsi); mipi_dsi_device_unregister(dsi);
return 0; @@ -369,11 +370,18 @@ EXPORT_SYMBOL(mipi_dsi_host_unregister); int mipi_dsi_attach(struct mipi_dsi_device *dsi) { const struct mipi_dsi_host_ops *ops = dsi->host->ops; + int ret;
if (!ops || !ops->attach) return -ENOSYS;
- return ops->attach(dsi->host, dsi); + ret = ops->attach(dsi->host, dsi); + if (ret) + return ret; + + dsi->attached = true; + + return 0; } EXPORT_SYMBOL(mipi_dsi_attach);
@@ -385,9 +393,14 @@ int mipi_dsi_detach(struct mipi_dsi_device *dsi) { const struct mipi_dsi_host_ops *ops = dsi->host->ops;
+ if (WARN_ON(!dsi->attached)) + return -EINVAL; + if (!ops || !ops->detach) return -ENOSYS;
+ dsi->attached = false; + return ops->detach(dsi->host, dsi); } EXPORT_SYMBOL(mipi_dsi_detach); diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 9054a5185e1a..31171914990a 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -168,6 +168,7 @@ struct mipi_dsi_device_info { * struct mipi_dsi_device - DSI peripheral device * @host: DSI host for this peripheral * @dev: driver model device node for this peripheral + * @attached: the DSI device has been successfully attached * @name: DSI peripheral chip type * @channel: virtual channel assigned to the peripheral * @format: pixel format for video mode @@ -184,6 +185,7 @@ struct mipi_dsi_device_info { struct mipi_dsi_device { struct mipi_dsi_host *host; struct device dev; + bool attached;
char name[DSI_DEV_NAME_SIZE]; unsigned int channel;
From: Ghanshyam Agrawal ghanshyam1898@gmail.com
[ Upstream commit b3695e86d25aafbe175dd51f6aaf6f68d341d590 ]
The function stk1160_dbg gets called too many times, which causes the output to get flooded with messages. Since stk1160_dbg uses printk, it is now replaced with printk_ratelimited.
Suggested-by: Phillip Potter phil@philpotter.co.uk Signed-off-by: Ghanshyam Agrawal ghanshyam1898@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/stk1160/stk1160-video.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c index 4e966f6bf608..366f0e4a5dc0 100644 --- a/drivers/media/usb/stk1160/stk1160-video.c +++ b/drivers/media/usb/stk1160/stk1160-video.c @@ -107,8 +107,7 @@ void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len)
/* * TODO: These stk1160_dbg are very spammy! - * We should 1) check why we are getting them - * and 2) add ratelimit. + * We should check why we are getting them. * * UPDATE: One of the reasons (the only one?) for getting these * is incorrect standard (mismatch between expected and configured). @@ -151,7 +150,7 @@ void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len)
/* Let the bug hunt begin! sanity checks! */ if (lencopy < 0) { - stk1160_dbg("copy skipped: negative lencopy\n"); + printk_ratelimited(KERN_DEBUG "copy skipped: negative lencopy\n"); return; }
From: Michael Tretter m.tretter@pengutronix.de
[ Upstream commit 9e7dc39260edac180c206bb6149595a40eabae3e ]
When using 32 bit RGB formats, the RGA on the rk3568 produces wrong colors as the wrong color channels are read or written. The reason is that the format description for the channel swizzeling is wrong and the wrong bits are configured. For example, when converting ARGB32 to NV12, the alpha channel is used as blue channel.. This doesn't happen if the color format is the same on both sides.
Fix the color_swap settings of the formats to correctly handle 32 bit RGB formats.
For RGA_COLOR_FMT_XBGR8888, the RGA_COLOR_ALPHA_SWAP bit doesn't have an effect. Thus, it isn't possible to handle the V4L2_PIX_FMT_XRGB32. Thus, it is removed from the list of supported formats.
Signed-off-by: Michael Tretter m.tretter@pengutronix.de Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/rockchip/rga/rga.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index 61b25fcf826e..9b20cef5afc6 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -187,25 +187,16 @@ static int rga_setup_ctrls(struct rga_ctx *ctx) static struct rga_fmt formats[] = { { .fourcc = V4L2_PIX_FMT_ARGB32, - .color_swap = RGA_COLOR_RB_SWAP, + .color_swap = RGA_COLOR_ALPHA_SWAP, .hw_format = RGA_COLOR_FMT_ABGR8888, .depth = 32, .uv_factor = 1, .y_div = 1, .x_div = 1, }, - { - .fourcc = V4L2_PIX_FMT_XRGB32, - .color_swap = RGA_COLOR_RB_SWAP, - .hw_format = RGA_COLOR_FMT_XBGR8888, - .depth = 32, - .uv_factor = 1, - .y_div = 1, - .x_div = 1, - }, { .fourcc = V4L2_PIX_FMT_ABGR32, - .color_swap = RGA_COLOR_ALPHA_SWAP, + .color_swap = RGA_COLOR_RB_SWAP, .hw_format = RGA_COLOR_FMT_ABGR8888, .depth = 32, .uv_factor = 1, @@ -214,7 +205,7 @@ static struct rga_fmt formats[] = { }, { .fourcc = V4L2_PIX_FMT_XBGR32, - .color_swap = RGA_COLOR_ALPHA_SWAP, + .color_swap = RGA_COLOR_RB_SWAP, .hw_format = RGA_COLOR_FMT_XBGR8888, .depth = 32, .uv_factor = 1,
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit 5ec42bf04d72fd6d0a6855810cc779e0ee31dfd7 ]
The PCI ID insertion follows the increasing order in the table, but this hardware follows MTL (MeteorLake).
Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Péter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Acked-by: Mark Brown broonie@kernel.org Link: https://lore.kernel.org/r/20231204212710.185976-2-pierre-louis.bossart@linux... Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index b76ff0850618..73cc1e7dd15a 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -3000,6 +3000,7 @@ #define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0 #define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2 #define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 +#define PCI_DEVICE_ID_INTEL_HDA_ARL 0x7728 #define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119 #define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a #define PCI_DEVICE_ID_INTEL_E6XX_CU 0x8183
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit a31014ebad617868c246d3985ff80d891f03711e ]
Yet another PCI ID.
Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Péter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Acked-by: Mark Brown broonie@kernel.org Link: https://lore.kernel.org/r/20231204212710.185976-3-pierre-louis.bossart@linux... Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/pci/hda/hda_intel.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 5aaf3dcecf27..a26f2a2d44cf 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2549,6 +2549,8 @@ static const struct pci_device_id azx_ids[] = { /* Lunarlake-P */ { PCI_DEVICE(0x8086, 0xa828), .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, + /* Arrow Lake */ + { PCI_DEVICE_DATA(INTEL, HDA_ARL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) }, /* Broxton-P(Apollolake) */ { PCI_DEVICE(0x8086, 0x5a98), .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
From: Tomi Valkeinen tomi.valkeinen@ideasonboard.com
[ Upstream commit 85d2a31fe4d9be1555f621ead7a520d8791e0f74 ]
In all known platforms the ISP has dedicated IRQ lines, but for some reason the driver uses IRQF_SHARED.
Supporting IRQF_SHARED properly requires handling interrupts even when our device is disabled, and the driver does not handle this. To avoid adding such code, and to be sure the driver won't accidentally be used in a platform with shared interrupts, let's drop the IRQF_SHARED flag.
Link: https://lore.kernel.org/r/20231207-rkisp-irq-fix-v3-1-358a2c871a3c@ideasonbo...
Tested-by: Adam Ford aford173@gmail.com #imx8mp-beacon Signed-off-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c index f2475c6235ea..e2352a056098 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c @@ -542,7 +542,7 @@ static int rkisp1_probe(struct platform_device *pdev) if (irq < 0) return irq;
- ret = devm_request_irq(dev, irq, info->isrs[i].isr, IRQF_SHARED, + ret = devm_request_irq(dev, irq, info->isrs[i].isr, 0, dev_driver_string(dev), dev); if (ret) { dev_err(dev, "request irq failed: %d\n", ret);
From: Tomi Valkeinen tomi.valkeinen@ideasonboard.com
[ Upstream commit 3eb7910e1b16a2c136be26a8380f21469225b2f6 ]
The IRQ handler rkisp1_isr() calls sub-handlers, all of which returns an irqreturn_t value, but rkisp1_isr() ignores those values and always returns IRQ_HANDLED.
Fix this by collecting the return values, and returning IRQ_HANDLED or IRQ_NONE as appropriate.
Link: https://lore.kernel.org/r/20231207-rkisp-irq-fix-v3-2-358a2c871a3c@ideasonbo...
Tested-by: Adam Ford aford173@gmail.com #imx8mp-beacon Signed-off-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../media/platform/rockchip/rkisp1/rkisp1-dev.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c index e2352a056098..01c831fb3240 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c @@ -442,17 +442,25 @@ static int rkisp1_entities_register(struct rkisp1_device *rkisp1)
static irqreturn_t rkisp1_isr(int irq, void *ctx) { + irqreturn_t ret = IRQ_NONE; + /* * Call rkisp1_capture_isr() first to handle the frame that * potentially completed using the current frame_sequence number before * it is potentially incremented by rkisp1_isp_isr() in the vertical * sync. */ - rkisp1_capture_isr(irq, ctx); - rkisp1_isp_isr(irq, ctx); - rkisp1_csi_isr(irq, ctx);
- return IRQ_HANDLED; + if (rkisp1_capture_isr(irq, ctx) == IRQ_HANDLED) + ret = IRQ_HANDLED; + + if (rkisp1_isp_isr(irq, ctx) == IRQ_HANDLED) + ret = IRQ_HANDLED; + + if (rkisp1_csi_isr(irq, ctx) == IRQ_HANDLED) + ret = IRQ_HANDLED; + + return ret; }
static const char * const px30_isp_clks[] = {
From: Tomi Valkeinen tomi.valkeinen@ideasonboard.com
[ Upstream commit 0753874617de883c6d4da903142f334f76a75d70 ]
Store the IRQ lines used by the driver for easy access. These are needed in future patches which fix IRQ race issues.
Link: https://lore.kernel.org/r/20231207-rkisp-irq-fix-v3-3-358a2c871a3c@ideasonbo...
Tested-by: Adam Ford aford173@gmail.com #imx8mp-beacon Signed-off-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../platform/rockchip/rkisp1/rkisp1-common.h | 11 ++++++++++- .../media/platform/rockchip/rkisp1/rkisp1-dev.c | 17 +++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h index a1293c45aae1..f9ec1c613894 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h @@ -61,6 +61,14 @@ struct dentry; RKISP1_CIF_ISP_EXP_END | \ RKISP1_CIF_ISP_HIST_MEASURE_RDY)
+/* IRQ lines */ +enum rkisp1_irq_line { + RKISP1_IRQ_ISP = 0, + RKISP1_IRQ_MI, + RKISP1_IRQ_MIPI, + RKISP1_NUM_IRQS, +}; + /* enum for the resizer pads */ enum rkisp1_rsz_pad { RKISP1_RSZ_PAD_SINK, @@ -441,7 +449,6 @@ struct rkisp1_debug { * struct rkisp1_device - ISP platform device * * @base_addr: base register address - * @irq: the irq number * @dev: a pointer to the struct device * @clk_size: number of clocks * @clks: array of clocks @@ -459,6 +466,7 @@ struct rkisp1_debug { * @stream_lock: serializes {start/stop}_streaming callbacks between the capture devices. * @debug: debug params to be exposed on debugfs * @info: version-specific ISP information + * @irqs: IRQ line numbers */ struct rkisp1_device { void __iomem *base_addr; @@ -479,6 +487,7 @@ struct rkisp1_device { struct mutex stream_lock; /* serialize {start/stop}_streaming cb between capture devices */ struct rkisp1_debug debug; const struct rkisp1_info *info; + int irqs[RKISP1_NUM_IRQS]; };
/* diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c index 01c831fb3240..3f39b65f4809 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c @@ -114,6 +114,7 @@ struct rkisp1_isr_data { const char *name; irqreturn_t (*isr)(int irq, void *ctx); + u32 line_mask; };
/* ---------------------------------------------------------------------------- @@ -471,9 +472,9 @@ static const char * const px30_isp_clks[] = { };
static const struct rkisp1_isr_data px30_isp_isrs[] = { - { "isp", rkisp1_isp_isr }, - { "mi", rkisp1_capture_isr }, - { "mipi", rkisp1_csi_isr }, + { "isp", rkisp1_isp_isr, BIT(RKISP1_IRQ_ISP) }, + { "mi", rkisp1_capture_isr, BIT(RKISP1_IRQ_MI) }, + { "mipi", rkisp1_csi_isr, BIT(RKISP1_IRQ_MIPI) }, };
static const struct rkisp1_info px30_isp_info = { @@ -492,7 +493,7 @@ static const char * const rk3399_isp_clks[] = { };
static const struct rkisp1_isr_data rk3399_isp_isrs[] = { - { NULL, rkisp1_isr }, + { NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) | BIT(RKISP1_IRQ_MIPI) }, };
static const struct rkisp1_info rk3399_isp_info = { @@ -543,6 +544,9 @@ static int rkisp1_probe(struct platform_device *pdev) if (IS_ERR(rkisp1->base_addr)) return PTR_ERR(rkisp1->base_addr);
+ for (unsigned int il = 0; il < ARRAY_SIZE(rkisp1->irqs); ++il) + rkisp1->irqs[il] = -1; + for (i = 0; i < info->isr_size; i++) { irq = info->isrs[i].name ? platform_get_irq_byname(pdev, info->isrs[i].name) @@ -550,6 +554,11 @@ static int rkisp1_probe(struct platform_device *pdev) if (irq < 0) return irq;
+ for (unsigned int il = 0; il < ARRAY_SIZE(rkisp1->irqs); ++il) { + if (info->isrs[i].line_mask & BIT(il)) + rkisp1->irqs[il] = irq; + } + ret = devm_request_irq(dev, irq, info->isrs[i].isr, 0, dev_driver_string(dev), dev); if (ret) {
From: Tomi Valkeinen tomi.valkeinen@ideasonboard.com
[ Upstream commit 870565f063a58576e8a4529f122cac4325c6b395 ]
In rkisp1_isp_stop() and rkisp1_csi_disable() the driver masks the interrupts and then apparently assumes that the interrupt handler won't be running, and proceeds in the stop procedure. This is not the case, as the interrupt handler can already be running, which would lead to the ISP being disabled while the interrupt handler handling a captured frame.
This brings up two issues: 1) the ISP could be powered off while the interrupt handler is still running and accessing registers, leading to board lockup, and 2) the interrupt handler code and the code that disables the streaming might do things that conflict.
It is not clear to me if 2) causes a real issue, but 1) can be seen with a suitable delay (or printk in my case) in the interrupt handler, leading to board lockup.
Link: https://lore.kernel.org/r/20231207-rkisp-irq-fix-v3-4-358a2c871a3c@ideasonbo...
Tested-by: Adam Ford aford173@gmail.com #imx8mp-beacon Signed-off-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../platform/rockchip/rkisp1/rkisp1-csi.c | 14 ++++++++++++- .../platform/rockchip/rkisp1/rkisp1-isp.c | 20 ++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c index d7acc94e10f8..e862f515cc6d 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c @@ -141,8 +141,20 @@ static void rkisp1_csi_disable(struct rkisp1_csi *csi) struct rkisp1_device *rkisp1 = csi->rkisp1; u32 val;
- /* Mask and clear interrupts. */ + /* Mask MIPI interrupts. */ rkisp1_write(rkisp1, RKISP1_CIF_MIPI_IMSC, 0); + + /* Flush posted writes */ + rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC); + + /* + * Wait until the IRQ handler has ended. The IRQ handler may get called + * even after this, but it will return immediately as the MIPI + * interrupts have been masked. + */ + synchronize_irq(rkisp1->irqs[RKISP1_IRQ_MIPI]); + + /* Clear MIPI interrupt status */ rkisp1_write(rkisp1, RKISP1_CIF_MIPI_ICR, ~0);
val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL); diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c index 585cf3f53469..00dca284c122 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c @@ -281,11 +281,25 @@ static void rkisp1_isp_stop(struct rkisp1_isp *isp) * ISP(mi) stop in mi frame end -> Stop ISP(mipi) -> * Stop ISP(isp) ->wait for ISP isp off */ - /* stop and clear MI and ISP interrupts */ - rkisp1_write(rkisp1, RKISP1_CIF_ISP_IMSC, 0); - rkisp1_write(rkisp1, RKISP1_CIF_ISP_ICR, ~0);
+ /* Mask MI and ISP interrupts */ + rkisp1_write(rkisp1, RKISP1_CIF_ISP_IMSC, 0); rkisp1_write(rkisp1, RKISP1_CIF_MI_IMSC, 0); + + /* Flush posted writes */ + rkisp1_read(rkisp1, RKISP1_CIF_MI_IMSC); + + /* + * Wait until the IRQ handler has ended. The IRQ handler may get called + * even after this, but it will return immediately as the MI and ISP + * interrupts have been masked. + */ + synchronize_irq(rkisp1->irqs[RKISP1_IRQ_ISP]); + if (rkisp1->irqs[RKISP1_IRQ_ISP] != rkisp1->irqs[RKISP1_IRQ_MI]) + synchronize_irq(rkisp1->irqs[RKISP1_IRQ_MI]); + + /* Clear MI and ISP interrupt status */ + rkisp1_write(rkisp1, RKISP1_CIF_ISP_ICR, ~0); rkisp1_write(rkisp1, RKISP1_CIF_MI_ICR, ~0);
/* stop ISP */
From: Xing Tong Wu xingtong.wu@siemens.com
[ Upstream commit 8b3800256abad20e91c2698607f9b28591407b19 ]
Setting the fan speed is only valid in manual mode; it is not possible to set the fan's speed in automatic mode. Return error when attempting to set the fan speed in automatic mode.
Signed-off-by: Xing Tong Wu xingtong.wu@siemens.com Link: https://lore.kernel.org/r/20231121081604.2499-3-xingtong_wu@163.com Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/nct6775-core.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/hwmon/nct6775-core.c b/drivers/hwmon/nct6775-core.c index 80310845fb99..9720ad214c20 100644 --- a/drivers/hwmon/nct6775-core.c +++ b/drivers/hwmon/nct6775-core.c @@ -2462,6 +2462,13 @@ store_pwm(struct device *dev, struct device_attribute *attr, const char *buf, int err; u16 reg;
+ /* + * The fan control mode should be set to manual if the user wants to adjust + * the fan speed. Otherwise, it will fail to set. + */ + if (index == 0 && data->pwm_enable[nr] > manual) + return -EBUSY; + err = kstrtoul(buf, 10, &val); if (err < 0) return err;
From: Kees Cook keescook@chromium.org
[ Upstream commit 4265eb062a7303e537ab3792ade31f424c3c5189 ]
Without visibility into the initializers for data->innr, GCC suspects using it as an index could walk off the end of the various 14-element arrays in data. Perform an explicit clamp to the array size. Silences the following warning with GCC 12+:
../drivers/hwmon/pc87360.c: In function 'pc87360_update_device': ../drivers/hwmon/pc87360.c:341:49: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 341 | data->in_max[i] = pc87360_read_value(data, | ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ 342 | LD_IN, i, | ~~~~~~~~~ 343 | PC87365_REG_IN_MAX); | ~~~~~~~~~~~~~~~~~~~ ../drivers/hwmon/pc87360.c:209:12: note: at offset 255 into destination object 'in_max' of size 14 209 | u8 in_max[14]; /* Register value */ | ^~~~~~
Cc: Jim Cromie jim.cromie@gmail.com Cc: Jean Delvare jdelvare@suse.com Cc: Guenter Roeck linux@roeck-us.net Cc: linux-hwmon@vger.kernel.org Signed-off-by: Kees Cook keescook@chromium.org Reviewed-by: Gustavo A. R. Silva gustavoars@kernel.org Link: https://lore.kernel.org/r/20231130200207.work.679-kees@kernel.org [groeck: Added comment into code clarifying context] Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/pc87360.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index a4adc8bd531f..534a6072036c 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c @@ -323,7 +323,11 @@ static struct pc87360_data *pc87360_update_device(struct device *dev) }
/* Voltages */ - for (i = 0; i < data->innr; i++) { + /* + * The min() below does not have any practical meaning and is + * only needed to silence a warning observed with gcc 12+. + */ + for (i = 0; i < min(data->innr, ARRAY_SIZE(data->in)); i++) { data->in_status[i] = pc87360_read_value(data, LD_IN, i, PC87365_REG_IN_STATUS); /* Clear bits */
From: Chao Yu chao@kernel.org
[ Upstream commit 4961acdd65c956e97c1a000c82d91a8c1cdbe44b ]
It needs to add missing gcing flag on page during block migration, in order to garantee migrated data be persisted during checkpoint, otherwise out-of-order persistency between data and node may cause data corruption after SPOR.
Similar issue was fixed by commit 2d1fe8a86bf5 ("f2fs: fix to tag gcing flag on page during file defragment").
Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/compress.c | 4 +++- fs/f2fs/file.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 4cb58e8d699e..3d9f6495a4db 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1026,8 +1026,10 @@ static void set_cluster_dirty(struct compress_ctx *cc) int i;
for (i = 0; i < cc->cluster_size; i++) - if (cc->rpages[i]) + if (cc->rpages[i]) { set_page_dirty(cc->rpages[i]); + set_page_private_gcing(cc->rpages[i]); + } }
static int prepare_compress_overwrite(struct compress_ctx *cc, diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 9b9fb3c57ec6..d69abe32d91d 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1326,6 +1326,7 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode, } memcpy_page(pdst, 0, psrc, 0, PAGE_SIZE); set_page_dirty(pdst); + set_page_private_gcing(pdst); f2fs_put_page(pdst, 1); f2fs_put_page(psrc, 1);
@@ -4032,6 +4033,7 @@ static int redirty_blocks(struct inode *inode, pgoff_t page_idx, int len) f2fs_bug_on(F2FS_I_SB(inode), !page);
set_page_dirty(page); + set_page_private_gcing(page); f2fs_put_page(page, 1); f2fs_put_page(page, 0); }
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 16ac5b21b31b439f03cdf44c153c5f5af94fb3eb ]
Based on grepping through the source code this driver appears to be missing a call to drm_atomic_helper_shutdown() at system shutdown time and at driver unbind time. Among other things, this means that if a panel is in use that it won't be cleanly powered off at system shutdown time.
The fact that we should call drm_atomic_helper_shutdown() in the case of OS shutdown/restart and at driver remove (or unbind) time comes straight out of the kernel doc "driver instance overview" in drm_drv.c.
A few notes about this fix: - When adding drm_atomic_helper_shutdown() to the unbind path, I added it after drm_kms_helper_poll_fini() since that's when other drivers seemed to have it. - Technically with a previous patch, ("drm/atomic-helper: drm_atomic_helper_shutdown(NULL) should be a noop"), we don't actually need to check to see if our "drm" pointer is NULL before calling drm_atomic_helper_shutdown(). We'll leave the "if" test in, though, so that this patch can land without any dependencies. It could potentially be removed later. - This patch also makes sure to set the drvdata to NULL in the case of bind errors to make sure that shutdown can't access freed data.
Suggested-by: Maxime Ripard mripard@kernel.org Reviewed-by: Maxime Ripard mripard@kernel.org Signed-off-by: Douglas Anderson dianders@chromium.org Tested-by: Marek Szyprowski m.szyprowski@samsung.com Reviewed-by: Marek Szyprowski m.szyprowski@samsung.com Signed-off-by: Inki Dae inki.dae@samsung.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 16c539657f73..4095b0d3ac2e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -309,6 +309,7 @@ static int exynos_drm_bind(struct device *dev) drm_mode_config_cleanup(drm); exynos_drm_cleanup_dma(drm); kfree(private); + dev_set_drvdata(dev, NULL); err_free_drm: drm_dev_put(drm);
@@ -323,6 +324,7 @@ static void exynos_drm_unbind(struct device *dev)
exynos_drm_fbdev_fini(drm); drm_kms_helper_poll_fini(drm); + drm_atomic_helper_shutdown(drm);
component_unbind_all(drm->dev, drm); drm_mode_config_cleanup(drm); @@ -360,9 +362,18 @@ static int exynos_drm_platform_remove(struct platform_device *pdev) return 0; }
+static void exynos_drm_platform_shutdown(struct platform_device *pdev) +{ + struct drm_device *drm = platform_get_drvdata(pdev); + + if (drm) + drm_atomic_helper_shutdown(drm); +} + static struct platform_driver exynos_drm_platform_driver = { .probe = exynos_drm_platform_probe, .remove = exynos_drm_platform_remove, + .shutdown = exynos_drm_platform_shutdown, .driver = { .name = "exynos-drm", .pm = &exynos_drm_pm_ops,
From: Daniel Vacek neelx@redhat.com
[ Upstream commit 4f973e211b3b1c6d36f7c6a19239d258856749f9 ]
Releasing the `priv->lock` while iterating the `priv->multicast_list` in `ipoib_mcast_join_task()` opens a window for `ipoib_mcast_dev_flush()` to remove the items while in the middle of iteration. If the mcast is removed while the lock was dropped, the for loop spins forever resulting in a hard lockup (as was reported on RHEL 4.18.0-372.75.1.el8_6 kernel):
Task A (kworker/u72:2 below) | Task B (kworker/u72:0 below) -----------------------------------+----------------------------------- ipoib_mcast_join_task(work) | ipoib_ib_dev_flush_light(work) spin_lock_irq(&priv->lock) | __ipoib_ib_dev_flush(priv, ...) list_for_each_entry(mcast, | ipoib_mcast_dev_flush(dev = priv->dev) &priv->multicast_list, list) | ipoib_mcast_join(dev, mcast) | spin_unlock_irq(&priv->lock) | | spin_lock_irqsave(&priv->lock, flags) | list_for_each_entry_safe(mcast, tmcast, | &priv->multicast_list, list) | list_del(&mcast->list); | list_add_tail(&mcast->list, &remove_list) | spin_unlock_irqrestore(&priv->lock, flags) spin_lock_irq(&priv->lock) | | ipoib_mcast_remove_list(&remove_list) (Here, `mcast` is no longer on the | list_for_each_entry_safe(mcast, tmcast, `priv->multicast_list` and we keep | remove_list, list) spinning on the `remove_list` of | >>> wait_for_completion(&mcast->done) the other thread which is blocked | and the list is still valid on | it's stack.)
Fix this by keeping the lock held and changing to GFP_ATOMIC to prevent eventual sleeps. Unfortunately we could not reproduce the lockup and confirm this fix but based on the code review I think this fix should address such lockups.
crash> bc 31 PID: 747 TASK: ff1c6a1a007e8000 CPU: 31 COMMAND: "kworker/u72:2" -- [exception RIP: ipoib_mcast_join_task+0x1b1] RIP: ffffffffc0944ac1 RSP: ff646f199a8c7e00 RFLAGS: 00000002 RAX: 0000000000000000 RBX: ff1c6a1a04dc82f8 RCX: 0000000000000000 work (&priv->mcast_task{,.work}) RDX: ff1c6a192d60ac68 RSI: 0000000000000286 RDI: ff1c6a1a04dc8000 &mcast->list RBP: ff646f199a8c7e90 R8: ff1c699980019420 R9: ff1c6a1920c9a000 R10: ff646f199a8c7e00 R11: ff1c6a191a7d9800 R12: ff1c6a192d60ac00 mcast R13: ff1c6a1d82200000 R14: ff1c6a1a04dc8000 R15: ff1c6a1a04dc82d8 dev priv (&priv->lock) &priv->multicast_list (aka head) ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 --- <NMI exception stack> --- #5 [ff646f199a8c7e00] ipoib_mcast_join_task+0x1b1 at ffffffffc0944ac1 [ib_ipoib] #6 [ff646f199a8c7e98] process_one_work+0x1a7 at ffffffff9bf10967
crash> rx ff646f199a8c7e68 ff646f199a8c7e68: ff1c6a1a04dc82f8 <<< work = &priv->mcast_task.work
crash> list -hO ipoib_dev_priv.multicast_list ff1c6a1a04dc8000 (empty)
crash> ipoib_dev_priv.mcast_task.work.func,mcast_mutex.owner.counter ff1c6a1a04dc8000 mcast_task.work.func = 0xffffffffc0944910 <ipoib_mcast_join_task>, mcast_mutex.owner.counter = 0xff1c69998efec000
crash> b 8 PID: 8 TASK: ff1c69998efec000 CPU: 33 COMMAND: "kworker/u72:0" -- #3 [ff646f1980153d50] wait_for_completion+0x96 at ffffffff9c7d7646 #4 [ff646f1980153d90] ipoib_mcast_remove_list+0x56 at ffffffffc0944dc6 [ib_ipoib] #5 [ff646f1980153de8] ipoib_mcast_dev_flush+0x1a7 at ffffffffc09455a7 [ib_ipoib] #6 [ff646f1980153e58] __ipoib_ib_dev_flush+0x1a4 at ffffffffc09431a4 [ib_ipoib] #7 [ff646f1980153e98] process_one_work+0x1a7 at ffffffff9bf10967
crash> rx ff646f1980153e68 ff646f1980153e68: ff1c6a1a04dc83f0 <<< work = &priv->flush_light
crash> ipoib_dev_priv.flush_light.func,broadcast ff1c6a1a04dc8000 flush_light.func = 0xffffffffc0943820 <ipoib_ib_dev_flush_light>, broadcast = 0x0,
The mcast(s) on the `remove_list` (the remaining part of the ex `priv->multicast_list`):
crash> list -s ipoib_mcast.done.done ipoib_mcast.list -H ff646f1980153e10 | paste - - ff1c6a192bd0c200 done.done = 0x0, ff1c6a192d60ac00 done.done = 0x0,
Reported-by: Yuya Fujita-bishamonten fj-lsoft-rh-driver@dl.jp.fujitsu.com Signed-off-by: Daniel Vacek neelx@redhat.com Link: https://lore.kernel.org/all/20231212080746.1528802-1-neelx@redhat.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 9e6967a40042..319d4288eddd 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -531,21 +531,17 @@ static int ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast) if (test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) rec.join_state = SENDONLY_FULLMEMBER_JOIN; } - spin_unlock_irq(&priv->lock);
multicast = ib_sa_join_multicast(&ipoib_sa_client, priv->ca, priv->port, - &rec, comp_mask, GFP_KERNEL, + &rec, comp_mask, GFP_ATOMIC, ipoib_mcast_join_complete, mcast); - spin_lock_irq(&priv->lock); if (IS_ERR(multicast)) { ret = PTR_ERR(multicast); ipoib_warn(priv, "ib_sa_join_multicast failed, status %d\n", ret); /* Requeue this join task with a backoff delay */ __ipoib_mcast_schedule_join_thread(priv, mcast, 1); clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); - spin_unlock_irq(&priv->lock); complete(&mcast->done); - spin_lock_irq(&priv->lock); return ret; } return 0;
From: Ming Qian ming.qian@nxp.com
[ Upstream commit f9c8ddce2fe3b767582f299d03fc8fb85943568c ]
mutext_lock should not be called in condition of wait_event, otherwise, when CONFIG_DEBUG_ATOMIC_SLEEP is enabled, we may meet the following warning: do not call blocking ops when !TASK_RUNNING; state=2 WARNING: CPU: 5 PID: 741 at kernel/sched/core.c:9859 __might_sleep+0x80/0xa4 Hardware name: Freescale i.MX8QM MEK (DT) pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __might_sleep+0x80/0xa4 lr : __might_sleep+0x80/0xa4 sp : ffffffc0123738a0 x29: ffffffc0123738a0 x28: ffffffc009194c48 x27: ffffffc00bbc1050 x26: ffffff8814b282f0 x25: ffffff8814b280d0 x24: ffffff8814b28080 x23: 0000000000000001 x22: 0000000000000032 x21: ffffffc00bbc1000 x20: 000000000000011b x19: ffffffc009324670 x18: 00000000fffffffd x17: 30303c5b20746120 x16: 74657320323d6574 x15: 617473203b474e49 x14: 00058b5b8b9aa1f1 x13: ffffffc00903cda0 x12: 00000000d744fcc9 x11: 000000000000001c x10: 00000000000009a0 x9 : ffffffc0090201f4 x8 : ffffff8828245000 x7 : 0000000000000001 x6 : 0000000000000001 x5 : 00000000410fd080 x4 : 0000000000000002 x3 : ffffff8815aab4c8 x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffffff8828244600 Call trace: __might_sleep+0x80/0xa4 mutex_lock+0x2c/0x80 sync_session_response+0x110/0x310 vpu_session_send_cmd+0x18c/0x244 vpu_session_start+0x38/0x70 vdec_start_session+0x1b4/0x3e0 vpu_vb2_start_streaming+0xa0/0x1c4 vb2_start_streaming+0x74/0x160 vb2_core_qbuf+0x488/0x650 vb2_qbuf+0x9c/0x100 v4l2_m2m_qbuf+0x7c/0x224 v4l2_m2m_ioctl_qbuf+0x20/0x2c v4l_qbuf+0x50/0x6c __video_do_ioctl+0x174/0x3f0 video_usercopy+0x210/0x7cc video_ioctl2+0x20/0x30 v4l2_ioctl+0x48/0x6c
we need to refine check_is_responsed() to remove the mutext_lock, each cmd has a monotonically increasing id, and cmds are executed sequentially, so we can check the id of the last reponsed cmd, then determine whether a command has been responded or not.
Signed-off-by: Ming Qian ming.qian@nxp.com CC: Xiaolei Wang xiaolei.wang@windriver.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/amphion/vpu.h | 3 ++- drivers/media/platform/amphion/vpu_cmds.c | 28 ++++++++--------------- drivers/media/platform/amphion/vpu_v4l2.c | 1 + 3 files changed, 12 insertions(+), 20 deletions(-)
diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h index deb2288d4290..4f3d23b55b6d 100644 --- a/drivers/media/platform/amphion/vpu.h +++ b/drivers/media/platform/amphion/vpu.h @@ -152,7 +152,6 @@ struct vpu_core { struct vpu_mbox tx_type; struct vpu_mbox tx_data; struct vpu_mbox rx; - unsigned long cmd_seq;
wait_queue_head_t ack_wq; struct completion cmp; @@ -251,6 +250,8 @@ struct vpu_inst {
struct list_head cmd_q; void *pending; + unsigned long cmd_seq; + atomic_long_t last_response_cmd;
struct vpu_inst_ops *ops; const struct vpu_format *formats; diff --git a/drivers/media/platform/amphion/vpu_cmds.c b/drivers/media/platform/amphion/vpu_cmds.c index 235b71398d40..c68163af29dc 100644 --- a/drivers/media/platform/amphion/vpu_cmds.c +++ b/drivers/media/platform/amphion/vpu_cmds.c @@ -34,6 +34,7 @@ struct vpu_cmd_t { struct vpu_cmd_request *request; struct vpu_rpc_event *pkt; unsigned long key; + atomic_long_t *last_response_cmd; };
static struct vpu_cmd_request vpu_cmd_requests[] = { @@ -117,6 +118,8 @@ static void vpu_free_cmd(struct vpu_cmd_t *cmd) { if (!cmd) return; + if (cmd->last_response_cmd) + atomic_long_set(cmd->last_response_cmd, cmd->key); vfree(cmd->pkt); vfree(cmd); } @@ -174,7 +177,8 @@ static int vpu_request_cmd(struct vpu_inst *inst, u32 id, void *data, return -ENOMEM;
mutex_lock(&core->cmd_lock); - cmd->key = core->cmd_seq++; + cmd->key = ++inst->cmd_seq; + cmd->last_response_cmd = &inst->last_response_cmd; if (key) *key = cmd->key; if (sync) @@ -248,26 +252,12 @@ void vpu_clear_request(struct vpu_inst *inst)
static bool check_is_responsed(struct vpu_inst *inst, unsigned long key) { - struct vpu_core *core = inst->core; - struct vpu_cmd_t *cmd; - bool flag = true; + unsigned long last_response = atomic_long_read(&inst->last_response_cmd);
- mutex_lock(&core->cmd_lock); - cmd = inst->pending; - if (cmd && key == cmd->key) { - flag = false; - goto exit; - } - list_for_each_entry(cmd, &inst->cmd_q, list) { - if (key == cmd->key) { - flag = false; - break; - } - } -exit: - mutex_unlock(&core->cmd_lock); + if (key <= last_response && (last_response - key) < (ULONG_MAX >> 1)) + return true;
- return flag; + return false; }
static int sync_session_response(struct vpu_inst *inst, unsigned long key, long timeout, int try) diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c index e5c8e1a753cc..e7a18948c4ab 100644 --- a/drivers/media/platform/amphion/vpu_v4l2.c +++ b/drivers/media/platform/amphion/vpu_v4l2.c @@ -631,6 +631,7 @@ int vpu_v4l2_open(struct file *file, struct vpu_inst *inst) func = &vpu->decoder;
atomic_set(&inst->ref_count, 0); + atomic_long_set(&inst->last_response_cmd, 0); vpu_inst_get(inst); inst->vpu = vpu; inst->core = vpu_request_core(vpu, inst->type);
From: Su Hui suhui@nfschina.com
[ Upstream commit 09b4195021be69af1e1936cca995712a6d0f2562 ]
Error code is assigned to 'stat', return 'stat' rather than '-1'.
Signed-off-by: Su Hui suhui@nfschina.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/pci/ddbridge/ddbridge-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c index 91733ab9f58c..363badab7cf0 100644 --- a/drivers/media/pci/ddbridge/ddbridge-main.c +++ b/drivers/media/pci/ddbridge/ddbridge-main.c @@ -238,7 +238,7 @@ static int ddb_probe(struct pci_dev *pdev, ddb_unmap(dev); pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); - return -1; + return stat; }
/****************************************************************************/
From: Kieran Bingham kieran.bingham@ideasonboard.com
[ Upstream commit d7b95ad7a8d56248dfc34f861e445fad7a4004f4 ]
The V4L2_CID_HBLANK control is marked as readonly and can only be a single value.
Set the minimum and maximum value to match the mode value.
Reviewed-by: Umang Jain umang.jain@ideasonboard.com Signed-off-by: Kieran Bingham kieran.bingham@ideasonboard.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/imx335.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index 078ede2b7a00..8e91767d6130 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -971,8 +971,8 @@ static int imx335_init_controls(struct imx335 *imx335) imx335->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, &imx335_ctrl_ops, V4L2_CID_HBLANK, - IMX335_REG_MIN, - IMX335_REG_MAX, + mode->hblank, + mode->hblank, 1, mode->hblank); if (imx335->hblank_ctrl) imx335->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
From: Alvin Lee alvin.lee2@amd.com
[ Upstream commit dd4e4bb28843393065eed279e869fac248d03f0f ]
[Description] For mode programming we want to extend the prefetch as much as possible (up to oto, or as long as we can for equ) if we're not already applying the 60us prefetch requirement. This is to avoid intermittent underflow issues during prefetch.
The prefetch extension is applied under the following scenarios: 1. We're in prefetch mode 1 (i.e. we don't support MCLK switch in blank) 2. We're using subvp or drr methods of p-state switch, in which case we we don't care if prefetch takes up more of the blanking time
Mode programming typically chooses the smallest prefetch time possible (i.e. highest bandwidth during prefetch) presumably to create margin between p-states / c-states that happen in vblank and prefetch. Therefore we only apply this prefetch extension when p-state in vblank is not required (UCLK p-states take up the most vblank time).
Reviewed-by: Jun Lei jun.lei@amd.com Acked-by: Aurabindo Pillai aurabindo.pillai@amd.com Signed-off-by: Alvin Lee alvin.lee2@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../dc/dml/dcn32/display_mode_vba_32.c | 3 ++ .../dc/dml/dcn32/display_mode_vba_util_32.c | 33 +++++++++++++++---- .../dc/dml/dcn32/display_mode_vba_util_32.h | 1 + 3 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c index 19f55657272e..cc8c1a48c5c4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c @@ -810,6 +810,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman (v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ? mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, + mode_lib->vba.PrefetchModePerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] > 0 || mode_lib->vba.DRAMClockChangeRequirementFinal == false, + /* Output */ &v->DSTXAfterScaler[k], &v->DSTYAfterScaler[k], @@ -3291,6 +3293,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l v->SwathHeightCThisState[k], v->TWait, (v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ? mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, + mode_lib->vba.PrefetchModePerState[i][j] > 0 || mode_lib->vba.DRAMClockChangeRequirementFinal == false,
/* Output */ &v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.DSTXAfterScaler[k], diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c index 23e4be2ad63f..7f4fc49be35c 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c @@ -3418,6 +3418,7 @@ bool dml32_CalculatePrefetchSchedule( unsigned int SwathHeightC, double TWait, double TPreReq, + bool ExtendPrefetchIfPossible, /* Output */ double *DSTXAfterScaler, double *DSTYAfterScaler, @@ -3887,12 +3888,32 @@ bool dml32_CalculatePrefetchSchedule( /* Clamp to oto for bandwidth calculation */ LinesForPrefetchBandwidth = dst_y_prefetch_oto; } else { - *DestinationLinesForPrefetch = dst_y_prefetch_equ; - TimeForFetchingMetaPTE = Tvm_equ; - TimeForFetchingRowInVBlank = Tr0_equ; - *PrefetchBandwidth = prefetch_bw_equ; - /* Clamp to equ for bandwidth calculation */ - LinesForPrefetchBandwidth = dst_y_prefetch_equ; + /* For mode programming we want to extend the prefetch as much as possible + * (up to oto, or as long as we can for equ) if we're not already applying + * the 60us prefetch requirement. This is to avoid intermittent underflow + * issues during prefetch. + * + * The prefetch extension is applied under the following scenarios: + * 1. We're in prefetch mode > 0 (i.e. we don't support MCLK switch in blank) + * 2. We're using subvp or drr methods of p-state switch, in which case we + * we don't care if prefetch takes up more of the blanking time + * + * Mode programming typically chooses the smallest prefetch time possible + * (i.e. highest bandwidth during prefetch) presumably to create margin between + * p-states / c-states that happen in vblank and prefetch. Therefore we only + * apply this prefetch extension when p-state in vblank is not required (UCLK + * p-states take up the most vblank time). + */ + if (ExtendPrefetchIfPossible && TPreReq == 0 && VStartup < MaxVStartup) { + MyError = true; + } else { + *DestinationLinesForPrefetch = dst_y_prefetch_equ; + TimeForFetchingMetaPTE = Tvm_equ; + TimeForFetchingRowInVBlank = Tr0_equ; + *PrefetchBandwidth = prefetch_bw_equ; + /* Clamp to equ for bandwidth calculation */ + LinesForPrefetchBandwidth = dst_y_prefetch_equ; + } }
*DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * TimeForFetchingMetaPTE / LineTime, 1.0) / 4.0; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h index 779c6805f599..1823434d8ede 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h @@ -744,6 +744,7 @@ bool dml32_CalculatePrefetchSchedule( unsigned int SwathHeightC, double TWait, double TPreReq, + bool ExtendPrefetchIfPossible, /* Output */ double *DSTXAfterScaler, double *DSTYAfterScaler,
From: Rob Clark robdclark@chromium.org
[ Upstream commit 2b72e50c62de60ad2d6bcd86aa38d4ccbdd633f2 ]
When we start getting these, we get a *lot*. So ratelimit it to not flood dmesg.
Signed-off-by: Rob Clark robdclark@chromium.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Patchwork: https://patchwork.freedesktop.org/patch/571584/ Link: https://lore.kernel.org/r/20231211182000.218088-1-robdclark@gmail.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 5 ++++- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 547f9f2b9fcb..f7d44a0bd605 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -38,6 +38,9 @@ #define DPU_ERROR_ENC(e, fmt, ...) DPU_ERROR("enc%d " fmt,\ (e) ? (e)->base.base.id : -1, ##__VA_ARGS__)
+#define DPU_ERROR_ENC_RATELIMITED(e, fmt, ...) DPU_ERROR_RATELIMITED("enc%d " fmt,\ + (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) + /* * Two to anticipate panels that can do cmd/vid dynamic switching * plan is to create all possible physical encoder types, and switch between @@ -2385,7 +2388,7 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t) return; }
- DPU_ERROR_ENC(dpu_enc, "frame done timeout\n"); + DPU_ERROR_ENC_RATELIMITED(dpu_enc, "frame done timeout\n");
event = DPU_ENCODER_FRAME_EVENT_ERROR; trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index ed80ed6784ee..bb35aa5f5709 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -51,6 +51,7 @@ } while (0)
#define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__) +#define DPU_ERROR_RATELIMITED(fmt, ...) pr_err_ratelimited("[dpu error]" fmt, ##__VA_ARGS__)
/** * ktime_compare_safe - compare two ktime structures
From: Abhinav Kumar quic_abhinavk@quicinc.com
[ Upstream commit 79caf2f2202b9eaad3a5a726e4b33807f67d0f1b ]
For YUV cases, setting the required format bits was missed out in the register programming. Lets fix it now in preparation of adding YUV formats support for writeback.
changes in v2: - dropped the fixes tag as its not a fix but adding new functionality
Signed-off-by: Abhinav Kumar quic_abhinavk@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/571814/ Link: https://lore.kernel.org/r/20231212205254.12422-4-quic_abhinavk@quicinc.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c index a3e413d27717..63dc2ee446d4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c @@ -105,6 +105,9 @@ static void dpu_hw_wb_setup_format(struct dpu_hw_wb *ctx, dst_format |= BIT(14); /* DST_ALPHA_X */ }
+ if (DPU_FORMAT_IS_YUV(fmt)) + dst_format |= BIT(15); + pattern = (fmt->element[3] << 24) | (fmt->element[2] << 16) | (fmt->element[1] << 8) |
From: "Wang, Beyond" Wang.Beyond@amd.com
[ Upstream commit 94aeb4117343d072e3a35b9595bcbfc0058ee724 ]
Issue: during evict or validate happened on amdgpu_bo, the 'from' and 'to' is always same in ftrace event of amdgpu_bo_move
where calling the 'trace_amdgpu_bo_move', the comment says move_notify is called before move happens, but actually it is called after move happens, here the new_mem is same as bo->resource
Fix: move trace_amdgpu_bo_move from move_notify to amdgpu_bo_move
Signed-off-by: Wang, Beyond Wang.Beyond@amd.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 13 +------------ drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 4 +--- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 5 +++-- 3 files changed, 5 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 0ee7c935fba1..cde2fd2f7117 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -1222,19 +1222,15 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, * amdgpu_bo_move_notify - notification about a memory move * @bo: pointer to a buffer object * @evict: if this move is evicting the buffer from the graphics address space - * @new_mem: new information of the bufer object * * Marks the corresponding &amdgpu_bo buffer object as invalid, also performs * bookkeeping. * TTM driver callback which is called when ttm moves a buffer. */ -void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, - bool evict, - struct ttm_resource *new_mem) +void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict) { struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); struct amdgpu_bo *abo; - struct ttm_resource *old_mem = bo->resource;
if (!amdgpu_bo_is_amdgpu_bo(bo)) return; @@ -1251,13 +1247,6 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, /* remember the eviction */ if (evict) atomic64_inc(&adev->num_evictions); - - /* update statistics */ - if (!new_mem) - return; - - /* move_notify is called before move happens */ - trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type); }
void amdgpu_bo_get_memory(struct amdgpu_bo *bo, uint64_t *vram_mem, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index 6dcd7bab42fb..2ada421e79e4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -312,9 +312,7 @@ int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata, int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, size_t buffer_size, uint32_t *metadata_size, uint64_t *flags); -void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, - bool evict, - struct ttm_resource *new_mem); +void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict); void amdgpu_bo_release_notify(struct ttm_buffer_object *bo); vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo); void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 10469f20a10c..158b791883f0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -555,10 +555,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict, return r; }
+ trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type); out: /* update statistics */ atomic64_add(bo->base.size, &adev->num_bytes_moved); - amdgpu_bo_move_notify(bo, evict, new_mem); + amdgpu_bo_move_notify(bo, evict); return 0; }
@@ -1503,7 +1504,7 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo, static void amdgpu_bo_delete_mem_notify(struct ttm_buffer_object *bo) { - amdgpu_bo_move_notify(bo, false, NULL); + amdgpu_bo_move_notify(bo, false); }
static struct ttm_device_funcs amdgpu_bo_driver = {
From: Kuan-Wei Chiu visitorckw@gmail.com
[ Upstream commit bfbea9e5667cfa9552c3d88f023386f017f6c308 ]
In cases where kcalloc() fails for the 'clk_data->clks' allocation, the code path does not handle the failure gracefully, potentially leading to a memory leak. This fix ensures proper cleanup by freeing the allocated memory for 'clk_data' before returning.
Signed-off-by: Kuan-Wei Chiu visitorckw@gmail.com Link: https://lore.kernel.org/r/20231210165040.3407545-1-visitorckw@gmail.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/hisilicon/clk-hi3620.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index a3d04c7c3da8..eb9c139babc3 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -467,8 +467,10 @@ static void __init hi3620_mmc_clk_init(struct device_node *node) return;
clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL); - if (!clk_data->clks) + if (!clk_data->clks) { + kfree(clk_data); return; + }
for (i = 0; i < num; i++) { struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
From: Kuan-Wei Chiu visitorckw@gmail.com
[ Upstream commit 2fbabea626b6467eb4e6c4cb7a16523da12e43b4 ]
In cases where mapping of mpmu/apmu/apbc registers fails, the code path does not handle the failure gracefully, potentially leading to a memory leak. This fix ensures proper cleanup by freeing the allocated memory for 'pxa_unit' before returning.
Signed-off-by: Kuan-Wei Chiu visitorckw@gmail.com Link: https://lore.kernel.org/r/20231210175232.3414584-1-visitorckw@gmail.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/mmp/clk-of-pxa168.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c index 130d1a723879..cb0ebbd82038 100644 --- a/drivers/clk/mmp/clk-of-pxa168.c +++ b/drivers/clk/mmp/clk-of-pxa168.c @@ -306,18 +306,21 @@ static void __init pxa168_clk_init(struct device_node *np) pxa_unit->mpmu_base = of_iomap(np, 0); if (!pxa_unit->mpmu_base) { pr_err("failed to map mpmu registers\n"); + kfree(pxa_unit); return; }
pxa_unit->apmu_base = of_iomap(np, 1); if (!pxa_unit->apmu_base) { pr_err("failed to map apmu registers\n"); + kfree(pxa_unit); return; }
pxa_unit->apbc_base = of_iomap(np, 2); if (!pxa_unit->apbc_base) { pr_err("failed to map apbc registers\n"); + kfree(pxa_unit); return; }
From: Werner Fischer devlists@wefi.net
[ Upstream commit d12971849d71781c1e4ffd1117d4878ce233d319 ]
WDTCTRL bit 3 sets the mode choice for the clock input of IT8784/IT8786. Some motherboards require this bit to be set to 1 (= PCICLK mode), otherwise the watchdog functionality gets broken. The BIOS of those motherboards sets WDTCTRL bit 3 already to 1.
Instead of setting all bits of WDTCTRL to 0 by writing 0x00 to it, keep bit 3 of it unchanged for IT8784/IT8786 chips. In this way, bit 3 keeps the status as set by the BIOS of the motherboard.
Watchdog tests have been successful with this patch with the following systems: IT8784: Thomas-Krenn LES plus v2 (YANLING YL-KBRL2 V2) IT8786: Thomas-Krenn LES plus v3 (YANLING YL-CLU L2) IT8786: Thomas-Krenn LES network 6L v2 (YANLING YL-CLU6L)
Link: https://lore.kernel.org/all/140b264d-341f-465b-8715-dacfe84b3f71@roeck-us.ne...
Signed-off-by: Werner Fischer devlists@wefi.net Reviewed-by: Guenter Roeck linux@roeck-us.net Link: https://lore.kernel.org/r/20231213094525.11849-4-devlists@wefi.net Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Wim Van Sebroeck wim@linux-watchdog.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/watchdog/it87_wdt.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c index bb1122909396..843f9f8e3917 100644 --- a/drivers/watchdog/it87_wdt.c +++ b/drivers/watchdog/it87_wdt.c @@ -255,6 +255,7 @@ static struct watchdog_device wdt_dev = { static int __init it87_wdt_init(void) { u8 chip_rev; + u8 ctrl; int rc;
rc = superio_enter(); @@ -313,7 +314,18 @@ static int __init it87_wdt_init(void)
superio_select(GPIO); superio_outb(WDT_TOV1, WDTCFG); - superio_outb(0x00, WDTCTRL); + + switch (chip_type) { + case IT8784_ID: + case IT8786_ID: + ctrl = superio_inb(WDTCTRL); + ctrl &= 0x08; + superio_outb(ctrl, WDTCTRL); + break; + default: + superio_outb(0x00, WDTCTRL); + } + superio_exit();
if (timeout < 1 || timeout > max_units * 60) {
From: Josip Pavic josip.pavic@amd.com
[ Upstream commit 6fb12518ca58412dc51054e2a7400afb41328d85 ]
[Why] This variable currently overflows after about 71 minutes. This doesn't cause any known functional issues but it does make debugging more difficult.
[How] Make it a 64-bit variable.
Reviewed-by: Aric Cyr aric.cyr@amd.com Acked-by: Wayne Lin wayne.lin@amd.com Signed-off-by: Josip Pavic josip.pavic@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h index 46c2b991aa10..811c117665e7 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -244,7 +244,7 @@ enum pixel_format { #define DC_MAX_DIRTY_RECTS 3 struct dc_flip_addrs { struct dc_plane_address address; - unsigned int flip_timestamp_in_us; + unsigned long long flip_timestamp_in_us; bool flip_immediate; /* TODO: add flip duration for FreeSync */ bool triplebuffer_flips;
From: Alexander Stein alexander.stein@ew.tq-group.com
[ Upstream commit 3f5f63adeea7e7aa715e101ffe4b4ac9705f9664 ]
To be compatible with SCU firmware based on 1.15 a different clock routing for LVDS is needed.
Signed-off-by: Oliver F. Brown oliver.brown@oss.nxp.com Signed-off-by: Ranjani Vaidyanathan ranjani.vaidyanathan@nxp.com Signed-off-by: Alexander Stein alexander.stein@ew.tq-group.com Reviewed-by: Abel Vesa abel.vesa@linaro.org Link: https://lore.kernel.org/r/20231218122407.2757175-1-alexander.stein@ew.tq-gro... Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-imx8qxp.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c index 273de1f29307..1066ea16de62 100644 --- a/drivers/clk/imx/clk-imx8qxp.c +++ b/drivers/clk/imx/clk-imx8qxp.c @@ -67,6 +67,22 @@ static const char * const lcd_pxl_sels[] = { "lcd_pxl_bypass_div_clk", };
+static const char *const lvds0_sels[] = { + "clk_dummy", + "clk_dummy", + "clk_dummy", + "clk_dummy", + "mipi0_lvds_bypass_clk", +}; + +static const char *const lvds1_sels[] = { + "clk_dummy", + "clk_dummy", + "clk_dummy", + "clk_dummy", + "mipi1_lvds_bypass_clk", +}; + static const char * const mipi_sels[] = { "clk_dummy", "clk_dummy", @@ -201,9 +217,9 @@ static int imx8qxp_clk_probe(struct platform_device *pdev) /* MIPI-LVDS SS */ imx_clk_scu("mipi0_bypass_clk", IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_BYPASS); imx_clk_scu("mipi0_pixel_clk", IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PER); - imx_clk_scu("mipi0_lvds_pixel_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC2); imx_clk_scu("mipi0_lvds_bypass_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_BYPASS); - imx_clk_scu("mipi0_lvds_phy_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC3); + imx_clk_scu2("mipi0_lvds_pixel_clk", lvds0_sels, ARRAY_SIZE(lvds0_sels), IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC2); + imx_clk_scu2("mipi0_lvds_phy_clk", lvds0_sels, ARRAY_SIZE(lvds0_sels), IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC3); imx_clk_scu2("mipi0_dsi_tx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_MST_BUS); imx_clk_scu2("mipi0_dsi_rx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_SLV_BUS); imx_clk_scu2("mipi0_dsi_phy_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PHY); @@ -213,9 +229,9 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
imx_clk_scu("mipi1_bypass_clk", IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_BYPASS); imx_clk_scu("mipi1_pixel_clk", IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_PER); - imx_clk_scu("mipi1_lvds_pixel_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC2); imx_clk_scu("mipi1_lvds_bypass_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_BYPASS); - imx_clk_scu("mipi1_lvds_phy_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC3); + imx_clk_scu2("mipi1_lvds_pixel_clk", lvds1_sels, ARRAY_SIZE(lvds1_sels), IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC2); + imx_clk_scu2("mipi1_lvds_phy_clk", lvds1_sels, ARRAY_SIZE(lvds1_sels), IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC3);
imx_clk_scu2("mipi1_dsi_tx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_MST_BUS); imx_clk_scu2("mipi1_dsi_rx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_SLV_BUS);
From: "Stanley.Yang" Stanley.Yang@amd.com
[ Upstream commit a32c6f7f5737cc7e31cd7ad5133f0d96fca12ea6 ]
The ecc_irq is disabled while GPU mode2 reset suspending process, but not be enabled during GPU mode2 reset resume process.
Changed from V1: only do sdma/gfx ras_late_init in aldebaran_mode2_restore_ip delete amdgpu_ras_late_resume function
Changed from V2: check umc ras supported before put ecc_irq
Signed-off-by: Stanley.Yang Stanley.Yang@amd.com Reviewed-by: Tao Zhou tao.zhou1@amd.com Reviewed-by: Hawking Zhang Hawking.Zhang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/aldebaran.c | 26 +++++++++++++++++++++++++- drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 4 ++++ drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 5 +++++ drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 4 ++++ 4 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/aldebaran.c b/drivers/gpu/drm/amd/amdgpu/aldebaran.c index 2b97b8a96fb4..fa6193535d48 100644 --- a/drivers/gpu/drm/amd/amdgpu/aldebaran.c +++ b/drivers/gpu/drm/amd/amdgpu/aldebaran.c @@ -333,6 +333,7 @@ aldebaran_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl, { struct list_head *reset_device_list = reset_context->reset_device_list; struct amdgpu_device *tmp_adev = NULL; + struct amdgpu_ras *con; int r;
if (reset_device_list == NULL) @@ -358,7 +359,30 @@ aldebaran_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl, */ amdgpu_register_gpu_instance(tmp_adev);
- /* Resume RAS */ + /* Resume RAS, ecc_irq */ + con = amdgpu_ras_get_context(tmp_adev); + if (!amdgpu_sriov_vf(tmp_adev) && con) { + if (tmp_adev->sdma.ras && + tmp_adev->sdma.ras->ras_block.ras_late_init) { + r = tmp_adev->sdma.ras->ras_block.ras_late_init(tmp_adev, + &tmp_adev->sdma.ras->ras_block.ras_comm); + if (r) { + dev_err(tmp_adev->dev, "SDMA failed to execute ras_late_init! ret:%d\n", r); + goto end; + } + } + + if (tmp_adev->gfx.ras && + tmp_adev->gfx.ras->ras_block.ras_late_init) { + r = tmp_adev->gfx.ras->ras_block.ras_late_init(tmp_adev, + &tmp_adev->gfx.ras->ras_block.ras_comm); + if (r) { + dev_err(tmp_adev->dev, "GFX failed to execute ras_late_init! ret:%d\n", r); + goto end; + } + } + } + amdgpu_ras_resume(tmp_adev);
/* Update PSP FW topology after reset */ diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c index d96ee48e1706..35921b41fc27 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c @@ -1144,6 +1144,10 @@ static int gmc_v10_0_hw_fini(void *handle)
amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0);
+ if (adev->gmc.ecc_irq.funcs && + amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) + amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); + return 0; }
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c index 7124347d2b6c..310a5607d83b 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c @@ -951,6 +951,11 @@ static int gmc_v11_0_hw_fini(void *handle) }
amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); + + if (adev->gmc.ecc_irq.funcs && + amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) + amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); + gmc_v11_0_gart_disable(adev);
return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 0d9e9d9dd4a1..409e3aa018f2 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -1900,6 +1900,10 @@ static int gmc_v9_0_hw_fini(void *handle)
amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0);
+ if (adev->gmc.ecc_irq.funcs && + amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) + amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); + return 0; }
From: Felix Kuehling Felix.Kuehling@amd.com
[ Upstream commit ec9ba4821fa52b5efdbc4cdf0a77497990655231 ]
Change the rules for amdgpu_sync_resv to let KFD synchronize with VM fences on page table reservations. This fixes intermittent memory corruption after evictions when using amdgpu_vm_handle_moved to update page tables for VM mappings managed through render nodes.
Signed-off-by: Felix Kuehling Felix.Kuehling@amd.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index 090e66a1b284..54bdbd83a8cc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c @@ -191,7 +191,8 @@ static bool amdgpu_sync_test_fence(struct amdgpu_device *adev,
/* Never sync to VM updates either. */ if (fence_owner == AMDGPU_FENCE_OWNER_VM && - owner != AMDGPU_FENCE_OWNER_UNDEFINED) + owner != AMDGPU_FENCE_OWNER_UNDEFINED && + owner != AMDGPU_FENCE_OWNER_KFD) return false;
/* Ignore fences depending on the sync mode */
From: Relja Vojvodic relja.vojvodic@amd.com
[ Upstream commit 292c2116b2ae84c7e799ae340981e60551b18f5e ]
For certain dual display configs that had one display using a 1080p mode, the DPM level used to drive the configs regressed from DPM 0 to DPM 3. This was caused by a missing check that should have only limited the pipe segments on non-phantom pipes. This caused issues with detile buffer allocation, which dissallow subvp from being used
Tested-by: Daniel Wheeler daniel.wheeler@amd.com Reviewed-by: Dillon Varone dillon.varone@amd.com Reviewed-by: Martin Leung martin.leung@amd.com Acked-by: Rodrigo Siqueira rodrigo.siqueira@amd.com Signed-off-by: Relja Vojvodic relja.vojvodic@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c index fa3778849db1..5e0fcb80bf36 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c @@ -216,7 +216,7 @@ bool dcn32_subvp_in_use(struct dc *dc, for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
- if (pipe->stream && pipe->stream->mall_stream_config.type != SUBVP_NONE) + if (pipe->stream && pipe->stream->mall_stream_config.type != SUBVP_PHANTOM != SUBVP_NONE) return true; } return false;
From: Srinivasan Shanmugam srinivasan.shanmugam@amd.com
[ Upstream commit 13a1851f923d9a7a78a477497295c2dfd16ad4a4 ]
Fixes the below: drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c:1404 amdgpu_ucode_request() warn: '*fw' from request_firmware() not released on lines: 1404.
Cc: Mario Limonciello mario.limonciello@amd.com Cc: Lijo Lazar lijo.lazar@amd.com Cc: Christian König christian.koenig@amd.com Cc: Alex Deucher alexander.deucher@amd.com Signed-off-by: Srinivasan Shanmugam srinivasan.shanmugam@amd.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index 6e7058a2d1c8..779707f19c88 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -1110,9 +1110,13 @@ int amdgpu_ucode_request(struct amdgpu_device *adev, const struct firmware **fw,
if (err) return -ENODEV; + err = amdgpu_ucode_validate(*fw); - if (err) + if (err) { dev_dbg(adev->dev, ""%s" failed to validate\n", fw_name); + release_firmware(*fw); + *fw = NULL; + }
return err; }
From: Srinivasan Shanmugam srinivasan.shanmugam@amd.com
[ Upstream commit bf2ad4fb8adca89374b54b225d494e0b1956dbea ]
Return value of container_of(...) can't be null, so null check is not required for 'fence'. Hence drop its NULL check.
Fixes the below: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c:93 to_amdgpu_amdkfd_fence() warn: can 'fence' even be NULL?
Cc: Felix Kuehling Felix.Kuehling@amd.com Cc: Christian König christian.koenig@amd.com Cc: Alex Deucher alexander.deucher@amd.com Signed-off-by: Srinivasan Shanmugam srinivasan.shanmugam@amd.com Reviewed-by: Felix Kuehling felix.kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c index 469785d33791..1ef758ac5076 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c @@ -90,7 +90,7 @@ struct amdgpu_amdkfd_fence *to_amdgpu_amdkfd_fence(struct dma_fence *f) return NULL;
fence = container_of(f, struct amdgpu_amdkfd_fence, base); - if (fence && f->ops == &amdkfd_fence_ops) + if (f->ops == &amdkfd_fence_ops) return fence;
return NULL;
From: Srinivasan Shanmugam srinivasan.shanmugam@amd.com
[ Upstream commit b1a428b45dc7e47c7acc2ad0d08d8a6dda910c4c ]
Fix the following about iterator use: drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_topology.c:1456 kfd_add_peer_prop() warn: iterator used outside loop: 'iolink3'
Cc: Felix Kuehling Felix.Kuehling@amd.com Cc: Christian König christian.koenig@amd.com Cc: Alex Deucher alexander.deucher@amd.com Signed-off-by: Srinivasan Shanmugam srinivasan.shanmugam@amd.com Reviewed-by: Felix Kuehling felix.kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 24 ++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 713f893d2530..977e13cd36e8 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -1510,17 +1510,19 @@ static int kfd_add_peer_prop(struct kfd_topology_device *kdev, /* CPU->CPU link*/ cpu_dev = kfd_topology_device_by_proximity_domain(iolink1->node_to); if (cpu_dev) { - list_for_each_entry(iolink3, &cpu_dev->io_link_props, list) - if (iolink3->node_to == iolink2->node_to) - break; - - props->weight += iolink3->weight; - props->min_latency += iolink3->min_latency; - props->max_latency += iolink3->max_latency; - props->min_bandwidth = min(props->min_bandwidth, - iolink3->min_bandwidth); - props->max_bandwidth = min(props->max_bandwidth, - iolink3->max_bandwidth); + list_for_each_entry(iolink3, &cpu_dev->io_link_props, list) { + if (iolink3->node_to != iolink2->node_to) + continue; + + props->weight += iolink3->weight; + props->min_latency += iolink3->min_latency; + props->max_latency += iolink3->max_latency; + props->min_bandwidth = min(props->min_bandwidth, + iolink3->min_bandwidth); + props->max_bandwidth = min(props->max_bandwidth, + iolink3->max_bandwidth); + break; + } } else { WARN(1, "CPU node not found"); }
From: bo liu bo.liu@senarytech.com
[ Upstream commit 7aeb259086487417f0fecf66e325bee133e8813a ]
When OMTP headset plugin the headset jack of CX8070 and SN6160 sound cards, the headset type detection circuit will recognize the headset type as CTIA. At this point, plugout and plugin the headset will get the correct headset type as OMTP. The reason for the failure of headset type recognition is that the sound card creation will enable the VREF voltage of the headset mic, which interferes with the headset type automatic detection circuit. Plugout and plugin the headset will restart the headset detection and get the correct headset type. The patch is disable the VREF voltage when the headset is not present, and will enable the VREF voltage when the headset is present.
Signed-off-by: bo liu bo.liu@senarytech.com Link: https://lore.kernel.org/r/20240108110235.3867-1-bo.liu@senarytech.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/pci/hda/patch_conexant.c | 115 ++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index a889cccdd607..e8819e8a9876 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -21,6 +21,12 @@ #include "hda_jack.h" #include "hda_generic.h"
+enum { + CX_HEADSET_NOPRESENT = 0, + CX_HEADSET_PARTPRESENT, + CX_HEADSET_ALLPRESENT, +}; + struct conexant_spec { struct hda_gen_spec gen;
@@ -42,7 +48,8 @@ struct conexant_spec { unsigned int gpio_led; unsigned int gpio_mute_led_mask; unsigned int gpio_mic_led_mask; - + unsigned int headset_present_flag; + bool is_cx8070_sn6140; };
@@ -164,6 +171,27 @@ static void cxt_init_gpio_led(struct hda_codec *codec) } }
+static void cx_fixup_headset_recog(struct hda_codec *codec) +{ + unsigned int mic_persent; + + /* fix some headset type recognize fail issue, such as EDIFIER headset */ + /* set micbiasd output current comparator threshold from 66% to 55%. */ + snd_hda_codec_write(codec, 0x1c, 0, 0x320, 0x010); + /* set OFF voltage for DFET from -1.2V to -0.8V, set headset micbias registor + * value adjustment trim from 2.2K ohms to 2.0K ohms. + */ + snd_hda_codec_write(codec, 0x1c, 0, 0x3b0, 0xe10); + /* fix reboot headset type recognize fail issue */ + mic_persent = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0x0); + if (mic_persent & AC_PINSENSE_PRESENCE) + /* enable headset mic VREF */ + snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24); + else + /* disable headset mic VREF */ + snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20); +} + static int cx_auto_init(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; @@ -174,6 +202,9 @@ static int cx_auto_init(struct hda_codec *codec) cxt_init_gpio_led(codec); snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
+ if (spec->is_cx8070_sn6140) + cx_fixup_headset_recog(codec); + return 0; }
@@ -192,6 +223,77 @@ static void cx_auto_free(struct hda_codec *codec) snd_hda_gen_free(codec); }
+static void cx_process_headset_plugin(struct hda_codec *codec) +{ + unsigned int val; + unsigned int count = 0; + + /* Wait headset detect done. */ + do { + val = snd_hda_codec_read(codec, 0x1c, 0, 0xca0, 0x0); + if (val & 0x080) { + codec_dbg(codec, "headset type detect done!\n"); + break; + } + msleep(20); + count++; + } while (count < 3); + val = snd_hda_codec_read(codec, 0x1c, 0, 0xcb0, 0x0); + if (val & 0x800) { + codec_dbg(codec, "headset plugin, type is CTIA\n"); + snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24); + } else if (val & 0x400) { + codec_dbg(codec, "headset plugin, type is OMTP\n"); + snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24); + } else { + codec_dbg(codec, "headphone plugin\n"); + } +} + +static void cx_update_headset_mic_vref(struct hda_codec *codec, unsigned int res) +{ + unsigned int phone_present, mic_persent, phone_tag, mic_tag; + struct conexant_spec *spec = codec->spec; + + /* In cx8070 and sn6140, the node 16 can only be config to headphone or disabled, + * the node 19 can only be config to microphone or disabled. + * Check hp&mic tag to process headset pulgin&plugout. + */ + phone_tag = snd_hda_codec_read(codec, 0x16, 0, AC_VERB_GET_UNSOLICITED_RESPONSE, 0x0); + mic_tag = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_UNSOLICITED_RESPONSE, 0x0); + if ((phone_tag & (res >> AC_UNSOL_RES_TAG_SHIFT)) || + (mic_tag & (res >> AC_UNSOL_RES_TAG_SHIFT))) { + phone_present = snd_hda_codec_read(codec, 0x16, 0, AC_VERB_GET_PIN_SENSE, 0x0); + if (!(phone_present & AC_PINSENSE_PRESENCE)) {/* headphone plugout */ + spec->headset_present_flag = CX_HEADSET_NOPRESENT; + snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20); + return; + } + if (spec->headset_present_flag == CX_HEADSET_NOPRESENT) { + spec->headset_present_flag = CX_HEADSET_PARTPRESENT; + } else if (spec->headset_present_flag == CX_HEADSET_PARTPRESENT) { + mic_persent = snd_hda_codec_read(codec, 0x19, 0, + AC_VERB_GET_PIN_SENSE, 0x0); + /* headset is present */ + if ((phone_present & AC_PINSENSE_PRESENCE) && + (mic_persent & AC_PINSENSE_PRESENCE)) { + cx_process_headset_plugin(codec); + spec->headset_present_flag = CX_HEADSET_ALLPRESENT; + } + } + } +} + +static void cx_jack_unsol_event(struct hda_codec *codec, unsigned int res) +{ + struct conexant_spec *spec = codec->spec; + + if (spec->is_cx8070_sn6140) + cx_update_headset_mic_vref(codec, res); + + snd_hda_jack_unsol_event(codec, res); +} + #ifdef CONFIG_PM static int cx_auto_suspend(struct hda_codec *codec) { @@ -205,7 +307,7 @@ static const struct hda_codec_ops cx_auto_patch_ops = { .build_pcms = snd_hda_gen_build_pcms, .init = cx_auto_init, .free = cx_auto_free, - .unsol_event = snd_hda_jack_unsol_event, + .unsol_event = cx_jack_unsol_event, #ifdef CONFIG_PM .suspend = cx_auto_suspend, .check_power_status = snd_hda_gen_check_power_status, @@ -1042,6 +1144,15 @@ static int patch_conexant_auto(struct hda_codec *codec) codec->spec = spec; codec->patch_ops = cx_auto_patch_ops;
+ /* init cx8070/sn6140 flag and reset headset_present_flag */ + switch (codec->core.vendor_id) { + case 0x14f11f86: + case 0x14f11f87: + spec->is_cx8070_sn6140 = true; + spec->headset_present_flag = CX_HEADSET_NOPRESENT; + break; + } + cx_auto_parse_eapd(codec); spec->gen.own_eapd_ctl = 1;
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit bb05367a66a9990d2c561282f5620bb1dbe40c28 ]
If file opened with v2 lease is upgraded with v1 lease, smb server should response v2 lease create context to client. This patch fix smb2.lease.v2_epoch2 test failure.
This test case assumes the following scenario: 1. smb2 create with v2 lease(R, LEASE1 key) 2. smb server return smb2 create response with v2 lease context(R, LEASE1 key, epoch + 1) 3. smb2 create with v1 lease(RH, LEASE1 key) 4. smb server return smb2 create response with v2 lease context(RH, LEASE1 key, epoch + 2)
i.e. If same client(same lease key) try to open a file that is being opened with v2 lease with v1 lease, smb server should return v2 lease.
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Acked-by: Tom Talpey tom@talpey.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/oplock.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c index af0f6914eca4..ebb7d100c851 100644 --- a/fs/smb/server/oplock.c +++ b/fs/smb/server/oplock.c @@ -1036,6 +1036,7 @@ static void copy_lease(struct oplock_info *op1, struct oplock_info *op2) lease2->duration = lease1->duration; lease2->flags = lease1->flags; lease2->epoch = lease1->epoch++; + lease2->version = lease1->version; }
static int add_lease_global_list(struct oplock_info *opinfo)
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 6fc0a265e1b932e5e97a038f99e29400a93baad0 ]
smb2_set_ea() can be called in parent inode lock range. So add get_write argument to smb2_set_ea() not to call nested mnt_want_write().
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/smb2pdu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 6e5ed0ac578a..8d4e2c666c34 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -2309,11 +2309,12 @@ static noinline int create_smb2_pipe(struct ksmbd_work *work) * @eabuf: set info command buffer * @buf_len: set info command buffer length * @path: dentry path for get ea + * @get_write: get write access to a mount * * Return: 0 on success, otherwise error */ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len, - const struct path *path) + const struct path *path, bool get_write) { struct user_namespace *user_ns = mnt_user_ns(path->mnt); char *attr_name = NULL, *value; @@ -3001,7 +3002,7 @@ int smb2_open(struct ksmbd_work *work)
rc = smb2_set_ea(&ea_buf->ea, le32_to_cpu(ea_buf->ccontext.DataLength), - &path); + &path, false); if (rc == -EOPNOTSUPP) rc = 0; else if (rc) @@ -5990,7 +5991,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, return -EINVAL;
return smb2_set_ea((struct smb2_ea_info *)req->Buffer, - buf_len, &fp->filp->f_path); + buf_len, &fp->filp->f_path, true); } case FILE_POSITION_INFORMATION: {
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 3fc74c65b367476874da5fe6f633398674b78e5a ]
Send lease break notification on FILE_RENAME_INFORMATION request. This patch fix smb2.lease.v2_epoch2 test failure.
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/oplock.c | 9 +++++++-- fs/smb/server/smb2pdu.c | 1 + 2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c index ebb7d100c851..252f5b96862b 100644 --- a/fs/smb/server/oplock.c +++ b/fs/smb/server/oplock.c @@ -546,6 +546,7 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci, atomic_read(&ci->sop_count)) == 1) { if (lease->state != SMB2_LEASE_NONE_LE && lease->state == (lctx->req_state & lease->state)) { + lease->epoch++; lease->state |= lctx->req_state; if (lctx->req_state & SMB2_LEASE_WRITE_CACHING_LE) @@ -556,13 +557,17 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci, atomic_read(&ci->sop_count)) > 1) { if (lctx->req_state == (SMB2_LEASE_READ_CACHING_LE | - SMB2_LEASE_HANDLE_CACHING_LE)) + SMB2_LEASE_HANDLE_CACHING_LE)) { + lease->epoch++; lease->state = lctx->req_state; + } }
if (lctx->req_state && lease->state == - SMB2_LEASE_NONE_LE) + SMB2_LEASE_NONE_LE) { + lease->epoch++; lease_none_upgrade(opinfo, lctx->req_state); + } } read_lock(&ci->m_lock); } diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 8d4e2c666c34..f5468cfb523d 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -5567,6 +5567,7 @@ static int smb2_rename(struct ksmbd_work *work, if (!file_info->ReplaceIfExists) flags = RENAME_NOREPLACE;
+ smb_break_all_levII_oplock(work, fp, 0); rc = ksmbd_vfs_rename(work, &fp->filp->f_path, new_name, flags); out: kfree(new_name);
linux-stable-mirror@lists.linaro.org