From 343f5683cfa443000904c88ce2e23656375fc51c Mon Sep 17 00:00:00 2001 From: Lizhi Hou Date: Wed, 10 Dec 2025 20:51:25 -0800 Subject: accel/amdxdna: Fix race where send ring appears full due to delayed head update The firmware sends a response and interrupts the driver before advancing the mailbox send ring head pointer. As a result, the driver may observe the response and attempt to send a new request before the firmware has updated the head pointer. In this window, the send ring still appears full, causing the driver to incorrectly fail the send operation. This race can be triggered more easily in a multithreaded environment, leading to unexpected and spurious "send ring full" failures. To address this, poll the send ring head pointer for up to 100us before returning a full-ring condition. This allows the firmware time to update the head pointer. Fixes: b87f920b9344 ("accel/amdxdna: Support hardware mailbox") Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Lizhi Hou Link: https://patch.msgid.link/20251211045125.1724604-1-lizhi.hou@amd.com --- drivers/accel/amdxdna/amdxdna_mailbox.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/accel/amdxdna/amdxdna_mailbox.c b/drivers/accel/amdxdna/amdxdna_mailbox.c index a60a85ce564c..469242ed8224 100644 --- a/drivers/accel/amdxdna/amdxdna_mailbox.c +++ b/drivers/accel/amdxdna/amdxdna_mailbox.c @@ -191,26 +191,34 @@ mailbox_send_msg(struct mailbox_channel *mb_chann, struct mailbox_msg *mb_msg) u32 head, tail; u32 start_addr; u32 tmp_tail; + int ret; head = mailbox_get_headptr(mb_chann, CHAN_RES_X2I); tail = mb_chann->x2i_tail; - ringbuf_size = mailbox_get_ringbuf_size(mb_chann, CHAN_RES_X2I); + ringbuf_size = mailbox_get_ringbuf_size(mb_chann, CHAN_RES_X2I) - sizeof(u32); start_addr = mb_chann->res[CHAN_RES_X2I].rb_start_addr; tmp_tail = tail + mb_msg->pkg_size; - if (tail < head && tmp_tail >= head) - goto no_space; - - if (tail >= head && (tmp_tail > ringbuf_size - sizeof(u32) && - mb_msg->pkg_size >= head)) - goto no_space; - if (tail >= head && tmp_tail > ringbuf_size - sizeof(u32)) { +check_again: + if (tail >= head && tmp_tail > ringbuf_size) { write_addr = mb_chann->mb->res.ringbuf_base + start_addr + tail; writel(TOMBSTONE, write_addr); /* tombstone is set. Write from the start of the ringbuf */ tail = 0; + tmp_tail = tail + mb_msg->pkg_size; + } + + if (tail < head && tmp_tail >= head) { + ret = read_poll_timeout(mailbox_get_headptr, head, + tmp_tail < head || tail >= head, + 1, 100, false, mb_chann, CHAN_RES_X2I); + if (ret) + return ret; + + if (tail >= head) + goto check_again; } write_addr = mb_chann->mb->res.ringbuf_base + start_addr + tail; @@ -222,9 +230,6 @@ mailbox_send_msg(struct mailbox_channel *mb_chann, struct mailbox_msg *mb_msg) mb_msg->pkg.header.id); return 0; - -no_space: - return -ENOSPC; } static int -- cgit v1.2.3 From 38b069333b58c86b7588d59cc55a065611190926 Mon Sep 17 00:00:00 2001 From: Matthew Brost Date: Tue, 9 Dec 2025 12:00:38 -0800 Subject: drm/sched: Add several job helpers to avoid drivers touching scheduler state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the past, drivers used to reach into scheduler internals—this must end because it makes it difficult to change scheduler internals, as driver-side code must also be updated. Add helpers to check if the scheduler is stopped and to query a job’s signaled state to avoid reaching into scheduler internals. These are expected to be used driver-side in recovery and debug flows. Signed-off-by: Matthew Brost Reviewed-by: Niranjana Vishwanathapura Link: https://patch.msgid.link/20251209200039.1366764-2-matthew.brost@intel.com --- drivers/gpu/drm/scheduler/sched_main.c | 36 ++++++++++++++++++++++++++++++++-- include/drm/gpu_scheduler.h | 2 ++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 1d4f1b822e7b..5f08719a35f5 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -344,7 +344,7 @@ drm_sched_rq_select_entity_fifo(struct drm_gpu_scheduler *sched, */ static void drm_sched_run_job_queue(struct drm_gpu_scheduler *sched) { - if (!READ_ONCE(sched->pause_submit)) + if (!drm_sched_is_stopped(sched)) queue_work(sched->submit_wq, &sched->work_run_job); } @@ -354,7 +354,7 @@ static void drm_sched_run_job_queue(struct drm_gpu_scheduler *sched) */ static void drm_sched_run_free_queue(struct drm_gpu_scheduler *sched) { - if (!READ_ONCE(sched->pause_submit)) + if (!drm_sched_is_stopped(sched)) queue_work(sched->submit_wq, &sched->work_free_job); } @@ -1567,3 +1567,35 @@ void drm_sched_wqueue_start(struct drm_gpu_scheduler *sched) queue_work(sched->submit_wq, &sched->work_free_job); } EXPORT_SYMBOL(drm_sched_wqueue_start); + +/** + * drm_sched_is_stopped() - Checks whether drm_sched is stopped + * @sched: DRM scheduler + * + * Return: true if sched is stopped, false otherwise + */ +bool drm_sched_is_stopped(struct drm_gpu_scheduler *sched) +{ + return READ_ONCE(sched->pause_submit); +} +EXPORT_SYMBOL(drm_sched_is_stopped); + +/** + * drm_sched_job_is_signaled() - DRM scheduler job is signaled + * @job: DRM scheduler job + * + * Determine if DRM scheduler job is signaled. DRM scheduler should be stopped + * to obtain a stable snapshot of state. Both parent fence (hardware fence) and + * finished fence (software fence) are checked to determine signaling state. + * + * Return: true if job is signaled, false otherwise + */ +bool drm_sched_job_is_signaled(struct drm_sched_job *job) +{ + struct drm_sched_fence *s_fence = job->s_fence; + + WARN_ON(!drm_sched_is_stopped(job->sched)); + return (s_fence->parent && dma_fence_is_signaled(s_fence->parent)) || + dma_fence_is_signaled(&s_fence->finished); +} +EXPORT_SYMBOL(drm_sched_job_is_signaled); diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index fb88301b3c45..86b6075ce799 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -645,6 +645,7 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad); void drm_sched_start(struct drm_gpu_scheduler *sched, int errno); void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched); void drm_sched_fault(struct drm_gpu_scheduler *sched); +bool drm_sched_is_stopped(struct drm_gpu_scheduler *sched); struct drm_gpu_scheduler * drm_sched_pick_best(struct drm_gpu_scheduler **sched_list, @@ -674,6 +675,7 @@ bool drm_sched_job_has_dependency(struct drm_sched_job *job, struct dma_fence *fence); void drm_sched_job_cleanup(struct drm_sched_job *job); void drm_sched_increase_karma(struct drm_sched_job *bad); +bool drm_sched_job_is_signaled(struct drm_sched_job *job); static inline bool drm_sched_invalidate_job(struct drm_sched_job *s_job, int threshold) -- cgit v1.2.3 From d8684ae1cdcf848d21e00bc0e0de821d694a207b Mon Sep 17 00:00:00 2001 From: Matthew Brost Date: Tue, 9 Dec 2025 12:00:39 -0800 Subject: drm/sched: Add pending job list iterator Stop open coding pending job list in drivers. Add pending job list iterator which safely walks DRM scheduler list asserting DRM scheduler is stopped. Signed-off-by: Matthew Brost Reviewed-by: Niranjana Vishwanathapura Link: https://patch.msgid.link/20251209200039.1366764-3-matthew.brost@intel.com --- drivers/gpu/drm/scheduler/sched_main.c | 4 ++- include/drm/gpu_scheduler.h | 50 ++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 5f08719a35f5..bd7936c03da2 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -729,7 +729,9 @@ EXPORT_SYMBOL(drm_sched_start); * * Drivers can still save and restore their state for recovery operations, but * we shouldn't make this a general scheduler feature around the dma_fence - * interface. + * interface. The suggested driver-side replacement is to use + * drm_sched_for_each_pending_job() after stopping the scheduler and implement + * their own recovery operations. */ void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched) { diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index 86b6075ce799..78e07c2507c7 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -700,4 +700,54 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity, struct drm_gpu_scheduler **sched_list, unsigned int num_sched_list); +/** + * struct drm_sched_pending_job_iter - DRM scheduler pending job iterator state + * @sched: DRM scheduler associated with pending job iterator + */ +struct drm_sched_pending_job_iter { + struct drm_gpu_scheduler *sched; +}; + +/* Drivers should never call this directly */ +static inline struct drm_sched_pending_job_iter +__drm_sched_pending_job_iter_begin(struct drm_gpu_scheduler *sched) +{ + struct drm_sched_pending_job_iter iter = { + .sched = sched, + }; + + WARN_ON(!drm_sched_is_stopped(sched)); + return iter; +} + +/* Drivers should never call this directly */ +static inline void +__drm_sched_pending_job_iter_end(const struct drm_sched_pending_job_iter iter) +{ + WARN_ON(!drm_sched_is_stopped(iter.sched)); +} + +DEFINE_CLASS(drm_sched_pending_job_iter, struct drm_sched_pending_job_iter, + __drm_sched_pending_job_iter_end(_T), + __drm_sched_pending_job_iter_begin(__sched), + struct drm_gpu_scheduler *__sched); +static inline void * +class_drm_sched_pending_job_iter_lock_ptr(class_drm_sched_pending_job_iter_t *_T) +{ return _T; } +#define class_drm_sched_pending_job_iter_is_conditional false + +/** + * drm_sched_for_each_pending_job() - Iterator for each pending job in scheduler + * @__job: Current pending job being iterated over + * @__sched: DRM scheduler to iterate over pending jobs + * @__entity: DRM scheduler entity to filter jobs, NULL indicates no filter + * + * Iterator for each pending job in scheduler, filtering on an entity, and + * enforcing scheduler is fully stopped + */ +#define drm_sched_for_each_pending_job(__job, __sched, __entity) \ + scoped_guard(drm_sched_pending_job_iter, (__sched)) \ + list_for_each_entry((__job), &(__sched)->pending_list, list) \ + for_each_if(!(__entity) || (__job)->entity == (__entity)) + #endif -- cgit v1.2.3 From 0df70ce615c78f8d16d96ef18960f365200fc5d6 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 11:27:06 +0200 Subject: drm/gem: fix build for mm_get_unmapped_area() call after backmerge Commit 9ac09bb9feac ("mm: consistently use current->mm in mm_get_unmapped_area()") upstream dropped a parameter from mm_get_unmapped_area() while commit 99bda20d6d4c ("drm/gem: Introduce drm_gem_get_unmapped_area() fop") in drm-misc-next added a new user. Drop the extra parameter from the call. Fixes: 7f790dd21a93 ("Merge drm/drm-next into drm-misc-next") Cc: Maxime Ripard Reviewed-by: Francois Dugast Reviewed-by: Badal Nilawar Link: https://patch.msgid.link/20251215092706.3218018-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/drm_gem.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index ca1956608261..36c8af123877 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -1299,8 +1299,7 @@ unsigned long drm_gem_get_unmapped_area(struct file *filp, unsigned long uaddr, obj = drm_gem_object_lookup_at_offset(filp, pgoff, len >> PAGE_SHIFT); if (IS_ERR(obj) || !obj->filp || !obj->filp->f_op->get_unmapped_area) - return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0, - flags); + return mm_get_unmapped_area(filp, uaddr, len, 0, flags); ret = obj->filp->f_op->get_unmapped_area(obj->filp, uaddr, len, 0, flags); -- cgit v1.2.3 From c497e5979084224330cf1e789cc9fdce9097c5f2 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Mon, 15 Dec 2025 10:46:43 +0100 Subject: drm/sitronix/st7571-i2c: rename 'struct drm_device' in st7571_device Rename st7571_device.dev to st7571_device.drm in preparation to introduce a 'struct device' member to this structure. Reviewed-by: Javier Martinez Canillas Signed-off-by: Marcus Folkesson Link: https://patch.msgid.link/20251215-st7571-split-v3-1-d5f3205c3138@gmail.com Signed-off-by: Javier Martinez Canillas --- drivers/gpu/drm/sitronix/st7571-i2c.c | 60 +++++++++++++++++------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/sitronix/st7571-i2c.c b/drivers/gpu/drm/sitronix/st7571-i2c.c index 4e73c8b415d6..71814a3eb93b 100644 --- a/drivers/gpu/drm/sitronix/st7571-i2c.c +++ b/drivers/gpu/drm/sitronix/st7571-i2c.c @@ -112,7 +112,7 @@ struct st7571_panel_format { }; struct st7571_device { - struct drm_device dev; + struct drm_device drm; struct drm_plane primary_plane; struct drm_crtc crtc; @@ -166,9 +166,9 @@ struct st7571_device { u8 *row; }; -static inline struct st7571_device *drm_to_st7571(struct drm_device *dev) +static inline struct st7571_device *drm_to_st7571(struct drm_device *drm) { - return container_of(dev, struct st7571_device, dev); + return container_of(drm, struct st7571_device, drm); } static int st7571_regmap_write(void *context, const void *data, size_t count) @@ -467,7 +467,7 @@ static void st7571_primary_plane_helper_atomic_update(struct drm_plane *plane, struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); struct drm_framebuffer *fb = plane_state->fb; struct drm_atomic_helper_damage_iter iter; - struct drm_device *dev = plane->dev; + struct drm_device *drm = plane->dev; struct drm_rect damage; struct st7571_device *st7571 = drm_to_st7571(plane->dev); int ret, idx; @@ -479,7 +479,7 @@ static void st7571_primary_plane_helper_atomic_update(struct drm_plane *plane, if (ret) return; - if (!drm_dev_enter(dev, &idx)) + if (!drm_dev_enter(drm, &idx)) goto out_drm_gem_fb_end_cpu_access; drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); @@ -501,11 +501,11 @@ out_drm_gem_fb_end_cpu_access: static void st7571_primary_plane_helper_atomic_disable(struct drm_plane *plane, struct drm_atomic_state *state) { - struct drm_device *dev = plane->dev; + struct drm_device *drm = plane->dev; struct st7571_device *st7571 = drm_to_st7571(plane->dev); int idx; - if (!drm_dev_enter(dev, &idx)) + if (!drm_dev_enter(drm, &idx)) return; st7571_fb_clear_screen(st7571); @@ -621,20 +621,20 @@ static struct drm_display_mode st7571_mode(struct st7571_device *st7571) static int st7571_mode_config_init(struct st7571_device *st7571) { - struct drm_device *dev = &st7571->dev; + struct drm_device *drm = &st7571->drm; const struct st7571_panel_constraints *constraints = &st7571->pdata->constraints; int ret; - ret = drmm_mode_config_init(dev); + ret = drmm_mode_config_init(drm); if (ret) return ret; - dev->mode_config.min_width = constraints->min_ncols; - dev->mode_config.min_height = constraints->min_nlines; - dev->mode_config.max_width = constraints->max_ncols; - dev->mode_config.max_height = constraints->max_nlines; - dev->mode_config.preferred_depth = 24; - dev->mode_config.funcs = &st7571_mode_config_funcs; + drm->mode_config.min_width = constraints->min_ncols; + drm->mode_config.min_height = constraints->min_nlines; + drm->mode_config.max_width = constraints->max_ncols; + drm->mode_config.max_height = constraints->max_nlines; + drm->mode_config.preferred_depth = 24; + drm->mode_config.funcs = &st7571_mode_config_funcs; return 0; } @@ -643,10 +643,10 @@ static int st7571_plane_init(struct st7571_device *st7571, const struct st7571_panel_format *pformat) { struct drm_plane *primary_plane = &st7571->primary_plane; - struct drm_device *dev = &st7571->dev; + struct drm_device *drm = &st7571->drm; int ret; - ret = drm_universal_plane_init(dev, primary_plane, 0, + ret = drm_universal_plane_init(drm, primary_plane, 0, &st7571_primary_plane_funcs, pformat->formats, pformat->nformats, @@ -665,10 +665,10 @@ static int st7571_crtc_init(struct st7571_device *st7571) { struct drm_plane *primary_plane = &st7571->primary_plane; struct drm_crtc *crtc = &st7571->crtc; - struct drm_device *dev = &st7571->dev; + struct drm_device *drm = &st7571->drm; int ret; - ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL, + ret = drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL, &st7571_crtc_funcs, NULL); if (ret) return ret; @@ -682,10 +682,10 @@ static int st7571_encoder_init(struct st7571_device *st7571) { struct drm_encoder *encoder = &st7571->encoder; struct drm_crtc *crtc = &st7571->crtc; - struct drm_device *dev = &st7571->dev; + struct drm_device *drm = &st7571->drm; int ret; - ret = drm_encoder_init(dev, encoder, &st7571_encoder_funcs, DRM_MODE_ENCODER_NONE, NULL); + ret = drm_encoder_init(drm, encoder, &st7571_encoder_funcs, DRM_MODE_ENCODER_NONE, NULL); if (ret) return ret; @@ -700,10 +700,10 @@ static int st7571_connector_init(struct st7571_device *st7571) { struct drm_connector *connector = &st7571->connector; struct drm_encoder *encoder = &st7571->encoder; - struct drm_device *dev = &st7571->dev; + struct drm_device *drm = &st7571->drm; int ret; - ret = drm_connector_init(dev, connector, &st7571_connector_funcs, + ret = drm_connector_init(drm, connector, &st7571_connector_funcs, DRM_MODE_CONNECTOR_Unknown); if (ret) return ret; @@ -934,15 +934,15 @@ static int st7571_lcd_init(struct st7571_device *st7571) static int st7571_probe(struct i2c_client *client) { struct st7571_device *st7571; - struct drm_device *dev; + struct drm_device *drm; int ret; st7571 = devm_drm_dev_alloc(&client->dev, &st7571_driver, - struct st7571_device, dev); + struct st7571_device, drm); if (IS_ERR(st7571)) return PTR_ERR(st7571); - dev = &st7571->dev; + drm = &st7571->drm; st7571->client = client; i2c_set_clientdata(client, st7571); st7571->pdata = device_get_match_data(&client->dev); @@ -1010,14 +1010,14 @@ static int st7571_probe(struct i2c_client *client) return dev_err_probe(&client->dev, ret, "Failed to initialize connector\n"); - drm_mode_config_reset(dev); + drm_mode_config_reset(drm); - ret = drm_dev_register(dev, 0); + ret = drm_dev_register(drm, 0); if (ret) return dev_err_probe(&client->dev, ret, "Failed to register DRM device\n"); - drm_client_setup(dev, NULL); + drm_client_setup(drm, NULL); return 0; } @@ -1025,7 +1025,7 @@ static void st7571_remove(struct i2c_client *client) { struct st7571_device *st7571 = i2c_get_clientdata(client); - drm_dev_unplug(&st7571->dev); + drm_dev_unplug(&st7571->drm); } static const struct st7571_panel_data st7567_config = { -- cgit v1.2.3 From bc12f3e1a84f16444aa33f0ee9edf829cf9ba796 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Mon, 15 Dec 2025 10:46:44 +0100 Subject: drm/sitronix/st7571-i2c: add 'struct device' to st7571_device Keep a copy of the device structure instead of referring to i2c_client. This is a preparation step to separate the generic part from all i2c stuff. Reviewed-by: Javier Martinez Canillas Signed-off-by: Marcus Folkesson Link: https://patch.msgid.link/20251215-st7571-split-v3-2-d5f3205c3138@gmail.com Signed-off-by: Javier Martinez Canillas --- drivers/gpu/drm/sitronix/st7571-i2c.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/sitronix/st7571-i2c.c b/drivers/gpu/drm/sitronix/st7571-i2c.c index 71814a3eb93b..2b52919d7dd4 100644 --- a/drivers/gpu/drm/sitronix/st7571-i2c.c +++ b/drivers/gpu/drm/sitronix/st7571-i2c.c @@ -113,6 +113,7 @@ struct st7571_panel_format { struct st7571_device { struct drm_device drm; + struct device *dev; struct drm_plane primary_plane; struct drm_crtc crtc; @@ -741,7 +742,7 @@ static const struct regmap_config st7571_regmap_config = { static int st7571_validate_parameters(struct st7571_device *st7571) { - struct device *dev = st7571->dev.dev; + struct device *dev = st7571->dev; const struct st7571_panel_constraints *constraints = &st7571->pdata->constraints; if (st7571->width_mm == 0) { @@ -781,7 +782,7 @@ static int st7571_validate_parameters(struct st7571_device *st7571) static int st7567_parse_dt(struct st7571_device *st7567) { - struct device *dev = &st7567->client->dev; + struct device *dev = st7567->dev; struct device_node *np = dev->of_node; struct display_timing dt; int ret; @@ -808,7 +809,7 @@ static int st7567_parse_dt(struct st7571_device *st7567) static int st7571_parse_dt(struct st7571_device *st7571) { - struct device *dev = &st7571->client->dev; + struct device *dev = st7571->dev; struct device_node *np = dev->of_node; struct display_timing dt; int ret; @@ -943,9 +944,10 @@ static int st7571_probe(struct i2c_client *client) return PTR_ERR(st7571); drm = &st7571->drm; + st7571->dev = &client->dev; st7571->client = client; i2c_set_clientdata(client, st7571); - st7571->pdata = device_get_match_data(&client->dev); + st7571->pdata = device_get_match_data(st7571->dev); ret = st7571->pdata->parse_dt(st7571); if (ret) @@ -966,20 +968,20 @@ static int st7571_probe(struct i2c_client *client) if (i2c_check_functionality(client->adapter, I2C_FUNC_PROTOCOL_MANGLING)) st7571->ignore_nak = true; - st7571->regmap = devm_regmap_init(&client->dev, &st7571_regmap_bus, + st7571->regmap = devm_regmap_init(st7571->dev, &st7571_regmap_bus, client, &st7571_regmap_config); if (IS_ERR(st7571->regmap)) { - return dev_err_probe(&client->dev, PTR_ERR(st7571->regmap), + return dev_err_probe(st7571->dev, PTR_ERR(st7571->regmap), "Failed to initialize regmap\n"); } - st7571->hwbuf = devm_kzalloc(&client->dev, + st7571->hwbuf = devm_kzalloc(st7571->dev, (st7571->nlines * st7571->ncols * st7571->bpp) / 8, GFP_KERNEL); if (!st7571->hwbuf) return -ENOMEM; - st7571->row = devm_kzalloc(&client->dev, + st7571->row = devm_kzalloc(st7571->dev, (st7571->ncols * st7571->bpp), GFP_KERNEL); if (!st7571->row) @@ -987,34 +989,34 @@ static int st7571_probe(struct i2c_client *client) ret = st7571_mode_config_init(st7571); if (ret) - return dev_err_probe(&client->dev, ret, + return dev_err_probe(st7571->dev, ret, "Failed to initialize mode config\n"); ret = st7571_plane_init(st7571, st7571->pformat); if (ret) - return dev_err_probe(&client->dev, ret, + return dev_err_probe(st7571->dev, ret, "Failed to initialize primary plane\n"); ret = st7571_crtc_init(st7571); if (ret < 0) - return dev_err_probe(&client->dev, ret, + return dev_err_probe(st7571->dev, ret, "Failed to initialize CRTC\n"); ret = st7571_encoder_init(st7571); if (ret < 0) - return dev_err_probe(&client->dev, ret, + return dev_err_probe(st7571->dev, ret, "Failed to initialize encoder\n"); ret = st7571_connector_init(st7571); if (ret < 0) - return dev_err_probe(&client->dev, ret, + return dev_err_probe(st7571->dev, ret, "Failed to initialize connector\n"); drm_mode_config_reset(drm); ret = drm_dev_register(drm, 0); if (ret) - return dev_err_probe(&client->dev, ret, + return dev_err_probe(st7571->dev, ret, "Failed to register DRM device\n"); drm_client_setup(drm, NULL); -- cgit v1.2.3 From d93a4354686b9a43d9f825a6859abba334b7ec86 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Mon, 15 Dec 2025 10:46:45 +0100 Subject: drm/sitronix/st7571-i2c: move common structures to st7571.h Move all structures that will be common for all interfaces (SPI/I2C) to a separate header file. Reviewed-by: Javier Martinez Canillas Signed-off-by: Marcus Folkesson Link: https://patch.msgid.link/20251215-st7571-split-v3-3-d5f3205c3138@gmail.com Signed-off-by: Javier Martinez Canillas --- MAINTAINERS | 1 + drivers/gpu/drm/sitronix/st7571-i2c.c | 91 +--------------------------- drivers/gpu/drm/sitronix/st7571.h | 108 ++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 89 deletions(-) create mode 100644 drivers/gpu/drm/sitronix/st7571.h diff --git a/MAINTAINERS b/MAINTAINERS index 5b11839cba9d..c4bc270679a5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8201,6 +8201,7 @@ S: Maintained F: Documentation/devicetree/bindings/display/sitronix,st7567.yaml F: Documentation/devicetree/bindings/display/sitronix,st7571.yaml F: drivers/gpu/drm/sitronix/st7571-i2c.c +F: drivers/gpu/drm/sitronix/st7571.h DRM DRIVER FOR SITRONIX ST7701 PANELS M: Jagan Teki diff --git a/drivers/gpu/drm/sitronix/st7571-i2c.c b/drivers/gpu/drm/sitronix/st7571-i2c.c index 2b52919d7dd4..af27658a5e15 100644 --- a/drivers/gpu/drm/sitronix/st7571-i2c.c +++ b/drivers/gpu/drm/sitronix/st7571-i2c.c @@ -35,6 +35,8 @@ #include