Short summary of fixes pull:

ast:
 - Preserve correct bits on register I/O
 
 dma-fence:
 - Use correct timeline name
 
 etnaviv:
 - Use correct GPU adress space for flush
 
 imx:
 - parallel-display: Fix bridge handling
 
 nouveau:
 - Fix locking in scheduler
 
 panel:
 - kingdisplay-kd097d04: Disable EOT packet
 - sitronix-st7789v: Use correct SYNC flags
 
 sched:
 - Fix locking to avoid race condition
 - Fix SIGKILL handling
 
 sysfb:
 - Avoid NULL-pointer access
 -----BEGIN PGP SIGNATURE-----
 
 iQFPBAABCgA5FiEEchf7rIzpz2NEoWjlaA3BHVMLeiMFAmkDws4bFIAAAAAABAAO
 bWFudTIsMi41KzEuMTEsMiwyAAoJEGgNwR1TC3ojbRsIAIZfTB5wdbtH8lp5Z+bA
 B+JzT30FM5URllVsmytKRczOb1SfdVRBiFyd0alpws6EEb5ouHpq0ZIRGk3LZsx1
 4542gu4ByVszVu5UiHRTLuc7OcdNU8anndFkERRUd6tZAm3/R4RWsHoREiHRib7/
 6EqTKq+FZjDQ4nw71Fykc/lzpM/XGXdIm2P66cfMJM/jKs0iXLRpOx6QyQyRkllv
 AkbVsHA1MSWnp9KSZzATkDsOviV7+xVQSxg0AqNlrRSxUuy08GqVrwLm/lrBVKNZ
 +YkAQ6mPxGIPgv8gS6Qgoy1B9Aoiw9RqmRnL0fgV86M4n8Dpxaw1u2kLkDmlYHSM
 Ug8=
 =LWM9
 -----END PGP SIGNATURE-----

Merge tag 'drm-misc-fixes-2025-10-30' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes

Short summary of fixes pull:

ast:
- Preserve correct bits on register I/O

dma-fence:
- Use correct timeline name

etnaviv:
- Use correct GPU adress space for flush

imx:
- parallel-display: Fix bridge handling

nouveau:
- Fix locking in scheduler

panel:
- kingdisplay-kd097d04: Disable EOT packet
- sitronix-st7789v: Use correct SYNC flags

sched:
- Fix locking to avoid race condition
- Fix SIGKILL handling

sysfb:
- Avoid NULL-pointer access

Signed-off-by: Simona Vetter <simona.vetter@ffwll.ch>
From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20251030195644.GA188441@localhost.localdomain
This commit is contained in:
Simona Vetter 2025-10-31 19:10:04 +01:00
commit b095398586
9 changed files with 44 additions and 23 deletions

View File

@ -1141,7 +1141,7 @@ const char __rcu *dma_fence_timeline_name(struct dma_fence *fence)
"RCU protection is required for safe access to returned string");
if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
return fence->ops->get_driver_name(fence);
return fence->ops->get_timeline_name(fence);
else
return "signaled-timeline";
}

View File

@ -282,13 +282,13 @@ static inline void __ast_write8_i(void __iomem *addr, u32 reg, u8 index, u8 val)
__ast_write8(addr, reg + 1, val);
}
static inline void __ast_write8_i_masked(void __iomem *addr, u32 reg, u8 index, u8 read_mask,
static inline void __ast_write8_i_masked(void __iomem *addr, u32 reg, u8 index, u8 preserve_mask,
u8 val)
{
u8 tmp = __ast_read8_i_masked(addr, reg, index, read_mask);
u8 tmp = __ast_read8_i_masked(addr, reg, index, preserve_mask);
tmp |= val;
__ast_write8_i(addr, reg, index, tmp);
val &= ~preserve_mask;
__ast_write8_i(addr, reg, index, tmp | val);
}
static inline u32 ast_read32(struct ast_device *ast, u32 reg)

View File

@ -310,8 +310,12 @@ EXPORT_SYMBOL(drm_gem_destroy_shadow_plane_state);
void __drm_gem_reset_shadow_plane(struct drm_plane *plane,
struct drm_shadow_plane_state *shadow_plane_state)
{
__drm_atomic_helper_plane_reset(plane, &shadow_plane_state->base);
drm_format_conv_state_init(&shadow_plane_state->fmtcnv_state);
if (shadow_plane_state) {
__drm_atomic_helper_plane_reset(plane, &shadow_plane_state->base);
drm_format_conv_state_init(&shadow_plane_state->fmtcnv_state);
} else {
__drm_atomic_helper_plane_reset(plane, NULL);
}
}
EXPORT_SYMBOL(__drm_gem_reset_shadow_plane);

View File

@ -347,7 +347,7 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
u32 link_target, link_dwords;
bool switch_context = gpu->exec_state != exec_state;
bool switch_mmu_context = gpu->mmu_context != mmu_context;
unsigned int new_flush_seq = READ_ONCE(gpu->mmu_context->flush_seq);
unsigned int new_flush_seq = READ_ONCE(mmu_context->flush_seq);
bool need_flush = switch_mmu_context || gpu->flush_seq != new_flush_seq;
bool has_blt = !!(gpu->identity.minor_features5 &
chipMinorFeatures5_BLT_ENGINE);

View File

@ -25,19 +25,18 @@
struct imx_parallel_display_encoder {
struct drm_encoder encoder;
struct drm_bridge bridge;
struct imx_parallel_display *pd;
};
struct imx_parallel_display {
struct device *dev;
u32 bus_format;
struct drm_bridge *next_bridge;
struct drm_bridge bridge;
};
static inline struct imx_parallel_display *bridge_to_imxpd(struct drm_bridge *b)
{
return container_of(b, struct imx_parallel_display_encoder, bridge)->pd;
return container_of(b, struct imx_parallel_display, bridge);
}
static const u32 imx_pd_bus_fmts[] = {
@ -195,15 +194,13 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
if (IS_ERR(imxpd_encoder))
return PTR_ERR(imxpd_encoder);
imxpd_encoder->pd = imxpd;
encoder = &imxpd_encoder->encoder;
bridge = &imxpd_encoder->bridge;
bridge = &imxpd->bridge;
ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node);
if (ret)
return ret;
bridge->funcs = &imx_pd_bridge_funcs;
drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
connector = drm_bridge_connector_init(drm, encoder);
@ -228,9 +225,10 @@ static int imx_pd_probe(struct platform_device *pdev)
u32 bus_format = 0;
const char *fmt;
imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL);
if (!imxpd)
return -ENOMEM;
imxpd = devm_drm_bridge_alloc(dev, struct imx_parallel_display, bridge,
&imx_pd_bridge_funcs);
if (IS_ERR(imxpd))
return PTR_ERR(imxpd);
/* port@1 is the output port */
imxpd->next_bridge = devm_drm_of_get_bridge(dev, np, 1, 0);
@ -258,6 +256,8 @@ static int imx_pd_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, imxpd);
devm_drm_bridge_add(dev, &imxpd->bridge);
return component_add(dev, &imx_pd_ops);
}

View File

@ -482,6 +482,17 @@ nouveau_sched_create(struct nouveau_sched **psched, struct nouveau_drm *drm,
return 0;
}
static bool
nouveau_sched_job_list_empty(struct nouveau_sched *sched)
{
bool empty;
spin_lock(&sched->job.list.lock);
empty = list_empty(&sched->job.list.head);
spin_unlock(&sched->job.list.lock);
return empty;
}
static void
nouveau_sched_fini(struct nouveau_sched *sched)
@ -489,8 +500,7 @@ nouveau_sched_fini(struct nouveau_sched *sched)
struct drm_gpu_scheduler *drm_sched = &sched->base;
struct drm_sched_entity *entity = &sched->entity;
rmb(); /* for list_empty to work without lock */
wait_event(sched->job.wq, list_empty(&sched->job.list.head));
wait_event(sched->job.wq, nouveau_sched_job_list_empty(sched));
drm_sched_entity_fini(entity);
drm_sched_fini(drm_sched);

View File

@ -359,7 +359,7 @@ static int kingdisplay_panel_probe(struct mipi_dsi_device *dsi)
dsi->lanes = 4;
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
MIPI_DSI_MODE_LPM;
MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET;
kingdisplay = devm_drm_panel_alloc(&dsi->dev, __typeof(*kingdisplay), base,
&kingdisplay_panel_funcs,

View File

@ -249,6 +249,11 @@ static const struct drm_display_mode default_mode = {
.flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
};
/*
* The mode data for this panel has been reverse engineered without access
* to the panel datasheet / manual. Using DRM_MODE_FLAG_PHSYNC like all
* other panels results in garbage data on the display.
*/
static const struct drm_display_mode t28cp45tn89_mode = {
.clock = 6008,
.hdisplay = 240,
@ -261,7 +266,7 @@ static const struct drm_display_mode t28cp45tn89_mode = {
.vtotal = 320 + 8 + 4 + 4,
.width_mm = 43,
.height_mm = 57,
.flags = DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC,
.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
};
static const struct drm_display_mode et028013dma_mode = {

View File

@ -70,6 +70,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
entity->guilty = guilty;
entity->num_sched_list = num_sched_list;
entity->priority = priority;
entity->last_user = current->group_leader;
/*
* It's perfectly valid to initialize an entity without having a valid
* scheduler attached. It's just not valid to use the scheduler before it
@ -302,7 +303,7 @@ long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout)
/* For a killed process disallow further enqueueing of jobs. */
last_user = cmpxchg(&entity->last_user, current->group_leader, NULL);
if ((!last_user || last_user == current->group_leader) &&
if (last_user == current->group_leader &&
(current->flags & PF_EXITING) && (current->exit_code == SIGKILL))
drm_sched_entity_kill(entity);
@ -552,10 +553,11 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
drm_sched_rq_remove_entity(entity->rq, entity);
entity->rq = rq;
}
spin_unlock(&entity->lock);
if (entity->num_sched_list == 1)
entity->sched_list = NULL;
spin_unlock(&entity->lock);
}
/**