summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2026-03-08 23:06:57 +0300
committerDave Airlie <airlied@redhat.com>2026-03-08 23:07:03 +0300
commit5f0a63f81a027becb06a71406e0941c5d12e074d (patch)
tree644b64d1ab50a79b9cc7d4a55168d5e7cd9bca5b /drivers/gpu
parent057ad0ef4da61a8ba654c691e3fc3933d92b7d5f (diff)
parentd2e20c8951e4bb5f4a828aed39813599980353b6 (diff)
downloadlinux-5f0a63f81a027becb06a71406e0941c5d12e074d.tar.xz
Merge tag 'drm-misc-next-2026-03-05' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next
drm-misc-next for v7.1: Cross-subsystem Changes: dma-buf: - Prepare for compile-time concurrency analysis Core Changes: buddy: - Improve assert testing sched: - Fix race condition in drm_sched_fini() - Mark slow tests Driver Changes: bridge: - waveshare-dsi: Fix register and attach; Support 1..4 DSI lanes plus DT bindings gma500: - Use DRM client buffer for fbdev framebuffer gud: - Test for imported buffers with helper imagination: - Fix power domain handling ivpu: - Update boot API to v3.29.4 - Limit per-user number of doorbells and contexts nouveau: - Test for imported buffers with helper panel: - panel-edp: Fix timings for BOE NV140WUM-N64 panfrost: - Test for imported buffers with helper panthor: - Test for imported buffers with helper vc4: - Test for imported buffers with helper Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patch.msgid.link/20260305081140.GA171266@linux.fritz.box
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/buddy.c36
-rw-r--r--drivers/gpu/drm/bridge/waveshare-dsi.c14
-rw-r--r--drivers/gpu/drm/drm_client.c3
-rw-r--r--drivers/gpu/drm/gma500/fbdev.c101
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c104
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h6
-rw-r--r--drivers/gpu/drm/gud/gud_pipe.c2
-rw-r--r--drivers/gpu/drm/imagination/pvr_power.c52
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c2
-rw-r--r--drivers/gpu/drm/panel/panel-edp.c9
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_gem.c2
-rw-r--r--drivers/gpu/drm/panthor/panthor_gem.c2
-rw-r--r--drivers/gpu/drm/scheduler/sched_main.c38
-rw-r--r--drivers/gpu/drm/scheduler/tests/tests_basic.c4
-rw-r--r--drivers/gpu/drm/vc4/vc4_bo.c2
-rw-r--r--drivers/gpu/drm/vc4/vc4_gem.c2
-rw-r--r--drivers/gpu/tests/gpu_buddy_test.c2
17 files changed, 149 insertions, 232 deletions
diff --git a/drivers/gpu/buddy.c b/drivers/gpu/buddy.c
index b27761246d4b..da5a1222f46b 100644
--- a/drivers/gpu/buddy.c
+++ b/drivers/gpu/buddy.c
@@ -3,8 +3,7 @@
* Copyright © 2021 Intel Corporation
*/
-#include <kunit/test-bug.h>
-
+#include <linux/bug.h>
#include <linux/export.h>
#include <linux/kmemleak.h>
#include <linux/module.h>
@@ -12,6 +11,28 @@
#include <linux/gpu_buddy.h>
+/**
+ * gpu_buddy_assert - assert a condition in the buddy allocator
+ * @condition: condition expected to be true
+ *
+ * When CONFIG_KUNIT is enabled, evaluates @condition and, if false, triggers
+ * a WARN_ON() and also calls kunit_fail_current_test() so that any running
+ * kunit test is properly marked as failed. The stringified condition is
+ * included in the failure message for easy identification.
+ *
+ * When CONFIG_KUNIT is not enabled, this reduces to WARN_ON() so production
+ * builds retain the same warning semantics as before.
+ */
+#if IS_ENABLED(CONFIG_KUNIT)
+#include <kunit/test-bug.h>
+#define gpu_buddy_assert(condition) do { \
+ if (WARN_ON(!(condition))) \
+ kunit_fail_current_test("gpu_buddy_assert(" #condition ")"); \
+} while (0)
+#else
+#define gpu_buddy_assert(condition) WARN_ON(!(condition))
+#endif
+
static struct kmem_cache *slab_blocks;
static unsigned int
@@ -268,8 +289,8 @@ static int __force_merge(struct gpu_buddy *mm,
if (!gpu_buddy_block_is_free(buddy))
continue;
- WARN_ON(gpu_buddy_block_is_clear(block) ==
- gpu_buddy_block_is_clear(buddy));
+ gpu_buddy_assert(gpu_buddy_block_is_clear(block) !=
+ gpu_buddy_block_is_clear(buddy));
/*
* Advance to the next node when the current node is the buddy,
@@ -415,8 +436,7 @@ void gpu_buddy_fini(struct gpu_buddy *mm)
start = gpu_buddy_block_offset(mm->roots[i]);
__force_merge(mm, start, start + size, order);
- if (WARN_ON(!gpu_buddy_block_is_free(mm->roots[i])))
- kunit_fail_current_test("buddy_fini() root");
+ gpu_buddy_assert(gpu_buddy_block_is_free(mm->roots[i]));
gpu_block_free(mm, mm->roots[i]);
@@ -424,7 +444,7 @@ void gpu_buddy_fini(struct gpu_buddy *mm)
size -= root_size;
}
- WARN_ON(mm->avail != mm->size);
+ gpu_buddy_assert(mm->avail == mm->size);
for_each_free_tree(i)
kfree(mm->free_trees[i]);
@@ -541,7 +561,7 @@ static void __gpu_buddy_free_list(struct gpu_buddy *mm,
{
struct gpu_buddy_block *block, *on;
- WARN_ON(mark_dirty && mark_clear);
+ gpu_buddy_assert(!(mark_dirty && mark_clear));
list_for_each_entry_safe(block, on, objects, link) {
if (mark_clear)
diff --git a/drivers/gpu/drm/bridge/waveshare-dsi.c b/drivers/gpu/drm/bridge/waveshare-dsi.c
index 43f4e7412d72..0497c7ecbc7a 100644
--- a/drivers/gpu/drm/bridge/waveshare-dsi.c
+++ b/drivers/gpu/drm/bridge/waveshare-dsi.c
@@ -66,7 +66,12 @@ static int ws_bridge_attach_dsi(struct ws_bridge *ws)
dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
MIPI_DSI_CLOCK_NON_CONTINUOUS;
dsi->format = MIPI_DSI_FMT_RGB888;
- dsi->lanes = 2;
+ dsi->lanes = drm_of_get_data_lanes_count_ep(dev->of_node, 0, 0, 1, 4);
+ if (dsi->lanes < 0) {
+ dev_warn(dev, "Invalid or missing DSI lane count %d, falling back to 2 lanes\n",
+ dsi->lanes);
+ dsi->lanes = 2; /* Old DT backward compatibility */
+ }
ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0)
@@ -80,11 +85,6 @@ static int ws_bridge_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
{
struct ws_bridge *ws = bridge_to_ws_bridge(bridge);
- int ret;
-
- ret = ws_bridge_attach_dsi(ws);
- if (ret)
- return ret;
return drm_bridge_attach(encoder, ws->next_bridge,
&ws->bridge, flags);
@@ -179,7 +179,7 @@ static int ws_bridge_probe(struct i2c_client *i2c)
ws->bridge.of_node = dev->of_node;
devm_drm_bridge_add(dev, &ws->bridge);
- return 0;
+ return ws_bridge_attach_dsi(ws);
}
static const struct of_device_id ws_bridge_of_ids[] = {
diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 6236ec46d62a..46c465bce98c 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -204,7 +204,7 @@ void drm_client_buffer_delete(struct drm_client_buffer *buffer)
}
EXPORT_SYMBOL(drm_client_buffer_delete);
-static struct drm_client_buffer *
+struct drm_client_buffer *
drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height,
u32 format, u32 handle, u32 pitch)
{
@@ -265,6 +265,7 @@ err_delete:
kfree(buffer);
return ERR_PTR(ret);
}
+EXPORT_SYMBOL(drm_client_buffer_create);
/**
* drm_client_buffer_vmap_local - Map DRM client buffer into address space
diff --git a/drivers/gpu/drm/gma500/fbdev.c b/drivers/gpu/drm/gma500/fbdev.c
index c26926babc2a..d1e93588234f 100644
--- a/drivers/gpu/drm/gma500/fbdev.c
+++ b/drivers/gpu/drm/gma500/fbdev.c
@@ -72,17 +72,10 @@ static int psb_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
static void psb_fbdev_fb_destroy(struct fb_info *info)
{
struct drm_fb_helper *fb_helper = info->par;
- struct drm_framebuffer *fb = fb_helper->fb;
- struct drm_gem_object *obj = fb->obj[0];
drm_fb_helper_fini(fb_helper);
- drm_framebuffer_unregister_private(fb);
- drm_framebuffer_cleanup(fb);
- kfree(fb);
-
- drm_gem_object_put(obj);
-
+ drm_client_buffer_delete(fb_helper->buffer);
drm_client_release(&fb_helper->client);
}
@@ -105,78 +98,76 @@ static const struct drm_fb_helper_funcs psb_fbdev_fb_helper_funcs = {
int psb_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper,
struct drm_fb_helper_surface_size *sizes)
{
- struct drm_device *dev = fb_helper->dev;
+ struct drm_client_dev *client = &fb_helper->client;
+ struct drm_device *dev = client->dev;
+ struct drm_file *file = client->file;
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
struct pci_dev *pdev = to_pci_dev(dev->dev);
struct fb_info *info = fb_helper->info;
- struct drm_framebuffer *fb;
- struct drm_mode_fb_cmd2 mode_cmd = { };
- int size;
- int ret;
+ u32 fourcc, pitch;
+ u64 size;
+ const struct drm_format_info *format;
+ struct drm_client_buffer *buffer;
struct psb_gem_object *backing;
struct drm_gem_object *obj;
- u32 bpp, depth;
+ u32 handle;
+ int ret;
/* No 24-bit packed mode */
if (sizes->surface_bpp == 24) {
sizes->surface_bpp = 32;
sizes->surface_depth = 24;
}
- bpp = sizes->surface_bpp;
- depth = sizes->surface_depth;
-
- /*
- * If the mode does not fit in 32 bit then switch to 16 bit to get
- * a console on full resolution. The X mode setting server will
- * allocate its own 32-bit GEM framebuffer.
- */
- size = ALIGN(sizes->surface_width * DIV_ROUND_UP(bpp, 8), 64) *
- sizes->surface_height;
- size = ALIGN(size, PAGE_SIZE);
-
- if (size > dev_priv->vram_stolen_size) {
- sizes->surface_bpp = 16;
- sizes->surface_depth = 16;
- }
- bpp = sizes->surface_bpp;
- depth = sizes->surface_depth;
- mode_cmd.width = sizes->surface_width;
- mode_cmd.height = sizes->surface_height;
- mode_cmd.pitches[0] = ALIGN(mode_cmd.width * DIV_ROUND_UP(bpp, 8), 64);
- mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
-
- size = mode_cmd.pitches[0] * mode_cmd.height;
- size = ALIGN(size, PAGE_SIZE);
+try_psb_gem_create:
+ fourcc = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
+ format = drm_get_format_info(dev, fourcc, DRM_FORMAT_MOD_LINEAR);
+ pitch = ALIGN(drm_format_info_min_pitch(format, 0, sizes->surface_width), SZ_64);
+ size = ALIGN(pitch * sizes->surface_height, PAGE_SIZE);
/* Allocate the framebuffer in the GTT with stolen page backing */
backing = psb_gem_create(dev, size, "fb", true, PAGE_SIZE);
- if (IS_ERR(backing))
- return PTR_ERR(backing);
+ if (IS_ERR(backing)) {
+ ret = PTR_ERR(backing);
+ if (ret == -EBUSY && sizes->surface_bpp > 16) {
+ /*
+ * If the mode does not fit in 32 bit then switch to 16 bit to
+ * get a console on full resolution. User-space compositors will
+ * allocate their own 32-bit framebuffers.
+ */
+ sizes->surface_bpp = 16;
+ sizes->surface_depth = 16;
+ goto try_psb_gem_create;
+ }
+ return ret;
+ }
obj = &backing->base;
- fb = psb_framebuffer_create(dev,
- drm_get_format_info(dev, mode_cmd.pixel_format,
- mode_cmd.modifier[0]),
- &mode_cmd, obj);
- if (IS_ERR(fb)) {
- ret = PTR_ERR(fb);
+ ret = drm_gem_handle_create(file, obj, &handle);
+ if (ret)
goto err_drm_gem_object_put;
+
+ buffer = drm_client_buffer_create(client, sizes->surface_width, sizes->surface_height,
+ fourcc, handle, pitch);
+ if (IS_ERR(buffer)) {
+ ret = PTR_ERR(buffer);
+ goto err_drm_gem_handle_delete;
}
fb_helper->funcs = &psb_fbdev_fb_helper_funcs;
- fb_helper->fb = fb;
+ fb_helper->buffer = buffer;
+ fb_helper->fb = buffer->fb;
info->fbops = &psb_fbdev_fb_ops;
/* Accessed stolen memory directly */
info->screen_base = dev_priv->vram_addr + backing->offset;
- info->screen_size = size;
+ info->screen_size = obj->size;
drm_fb_helper_fill_info(info, fb_helper, sizes);
info->fix.smem_start = dev_priv->stolen_base + backing->offset;
- info->fix.smem_len = size;
+ info->fix.smem_len = obj->size;
info->fix.ywrapstep = 0;
info->fix.ypanstep = 0;
info->fix.mmio_start = pci_resource_start(pdev, 0);
@@ -186,10 +177,18 @@ int psb_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper,
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
- dev_dbg(dev->dev, "allocated %dx%d fb\n", fb->width, fb->height);
+ dev_dbg(dev->dev, "allocated %dx%d fb\n", buffer->fb->width, buffer->fb->height);
+
+ /* The handle is only needed for creating the framebuffer.*/
+ drm_gem_handle_delete(file, handle);
+
+ /* The framebuffer still holds a references on the GEM object. */
+ drm_gem_object_put(obj);
return 0;
+err_drm_gem_handle_delete:
+ drm_gem_handle_delete(file, handle);
err_drm_gem_object_put:
drm_gem_object_put(obj);
return ret;
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index fe1f43f0abff..37a9f666c0f2 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -12,111 +12,25 @@
#include "framebuffer.h"
#include "psb_drv.h"
-static const struct drm_framebuffer_funcs psb_fb_funcs = {
- .destroy = drm_gem_fb_destroy,
- .create_handle = drm_gem_fb_create_handle,
-};
-
-/**
- * psb_framebuffer_init - initialize a framebuffer
- * @dev: our DRM device
- * @fb: framebuffer to set up
- * @mode_cmd: mode description
- * @obj: backing object
- *
- * Configure and fill in the boilerplate for our frame buffer. Return
- * 0 on success or an error code if we fail.
- */
-static int psb_framebuffer_init(struct drm_device *dev,
- struct drm_framebuffer *fb,
- const struct drm_format_info *info,
- const struct drm_mode_fb_cmd2 *mode_cmd,
- struct drm_gem_object *obj)
+static struct drm_framebuffer *
+psb_user_framebuffer_create(struct drm_device *dev, struct drm_file *filp,
+ const struct drm_format_info *info,
+ const struct drm_mode_fb_cmd2 *cmd)
{
- int ret;
-
/*
* Reject unknown formats, YUV formats, and formats with more than
* 4 bytes per pixel.
*/
if (!info->depth || info->cpp[0] > 4)
- return -EINVAL;
-
- if (mode_cmd->pitches[0] & 63)
- return -EINVAL;
-
- drm_helper_mode_fill_fb_struct(dev, fb, info, mode_cmd);
- fb->obj[0] = obj;
- ret = drm_framebuffer_init(dev, fb, &psb_fb_funcs);
- if (ret) {
- dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
- return ret;
- }
- return 0;
-}
-
-/**
- * psb_framebuffer_create - create a framebuffer backed by gt
- * @dev: our DRM device
- * @info: pixel format information
- * @mode_cmd: the description of the requested mode
- * @obj: the backing object
- *
- * Create a framebuffer object backed by the gt, and fill in the
- * boilerplate required
- *
- * TODO: review object references
- */
-struct drm_framebuffer *psb_framebuffer_create(struct drm_device *dev,
- const struct drm_format_info *info,
- const struct drm_mode_fb_cmd2 *mode_cmd,
- struct drm_gem_object *obj)
-{
- struct drm_framebuffer *fb;
- int ret;
-
- fb = kzalloc_obj(*fb);
- if (!fb)
- return ERR_PTR(-ENOMEM);
-
- ret = psb_framebuffer_init(dev, fb, info, mode_cmd, obj);
- if (ret) {
- kfree(fb);
- return ERR_PTR(ret);
- }
- return fb;
-}
-
-/**
- * psb_user_framebuffer_create - create framebuffer
- * @dev: our DRM device
- * @filp: client file
- * @cmd: mode request
- *
- * Create a new framebuffer backed by a userspace GEM object
- */
-static struct drm_framebuffer *psb_user_framebuffer_create
- (struct drm_device *dev, struct drm_file *filp,
- const struct drm_format_info *info,
- const struct drm_mode_fb_cmd2 *cmd)
-{
- struct drm_gem_object *obj;
- struct drm_framebuffer *fb;
+ return ERR_PTR(-EINVAL);
/*
- * Find the GEM object and thus the gtt range object that is
- * to back this space
+ * Pitch must be aligned to 64 bytes.
*/
- obj = drm_gem_object_lookup(filp, cmd->handles[0]);
- if (obj == NULL)
- return ERR_PTR(-ENOENT);
-
- /* Let the core code do all the work */
- fb = psb_framebuffer_create(dev, info, cmd, obj);
- if (IS_ERR(fb))
- drm_gem_object_put(obj);
+ if (cmd->pitches[0] & 63)
+ return ERR_PTR(-EINVAL);
- return fb;
+ return drm_gem_fb_create(dev, filp, info, cmd);
}
static const struct drm_mode_config_funcs psb_mode_funcs = {
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 0b27112ec46f..db197b865b90 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -592,12 +592,6 @@ struct psb_ops {
extern void psb_modeset_init(struct drm_device *dev);
extern void psb_modeset_cleanup(struct drm_device *dev);
-/* framebuffer */
-struct drm_framebuffer *psb_framebuffer_create(struct drm_device *dev,
- const struct drm_format_info *info,
- const struct drm_mode_fb_cmd2 *mode_cmd,
- struct drm_gem_object *obj);
-
/* fbdev */
#if defined(CONFIG_DRM_FBDEV_EMULATION)
int psb_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper,
diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c
index 4b77be94348d..11e7441de63b 100644
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -447,7 +447,7 @@ static void gud_fb_handle_damage(struct gud_device *gdrm, struct drm_framebuffer
}
/* Imported buffers are assumed to be WriteCombined with uncached reads */
- gud_flush_damage(gdrm, fb, src, !fb->obj[0]->import_attach, damage);
+ gud_flush_damage(gdrm, fb, src, !drm_gem_is_imported(fb->obj[0]), damage);
}
int gud_plane_atomic_check(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/imagination/pvr_power.c b/drivers/gpu/drm/imagination/pvr_power.c
index 006a72ed5064..7a8765c0c1ed 100644
--- a/drivers/gpu/drm/imagination/pvr_power.c
+++ b/drivers/gpu/drm/imagination/pvr_power.c
@@ -598,8 +598,8 @@ int pvr_power_domains_init(struct pvr_device *pvr_dev)
struct drm_device *drm_dev = from_pvr_device(pvr_dev);
struct device *dev = drm_dev->dev;
- struct device_link **domain_links __free(kfree) = NULL;
struct dev_pm_domain_list *domains = NULL;
+ struct device_link **domain_links = NULL;
int domain_count;
int link_count;
@@ -608,23 +608,30 @@ int pvr_power_domains_init(struct pvr_device *pvr_dev)
domain_count = of_count_phandle_with_args(dev->of_node, "power-domains",
"#power-domain-cells");
- if (domain_count < 0)
- return domain_count;
+ if (domain_count < 0) {
+ err = domain_count;
+ goto out;
+ }
- if (domain_count <= 1)
- return 0;
+ if (domain_count <= 1) {
+ err = 0;
+ goto out;
+ }
if (domain_count > ARRAY_SIZE(ROGUE_PD_NAMES)) {
drm_err(drm_dev, "%s() only supports %zu domains on Rogue",
__func__, ARRAY_SIZE(ROGUE_PD_NAMES));
- return -EOPNOTSUPP;
+ err = -EOPNOTSUPP;
+ goto out;
}
link_count = domain_count - 1;
domain_links = kzalloc_objs(*domain_links, link_count);
- if (!domain_links)
- return -ENOMEM;
+ if (!domain_links) {
+ err = -ENOMEM;
+ goto out;
+ }
const struct dev_pm_domain_attach_data pd_attach_data = {
.pd_names = ROGUE_PD_NAMES,
@@ -634,7 +641,7 @@ int pvr_power_domains_init(struct pvr_device *pvr_dev)
err = dev_pm_domain_attach_list(dev, &pd_attach_data, &domains);
if (err < 0)
- return err;
+ goto err_free_links;
for (i = 0; i < link_count; i++) {
struct device_link *link;
@@ -650,17 +657,26 @@ int pvr_power_domains_init(struct pvr_device *pvr_dev)
domain_links[i] = link;
}
- pvr_dev->power = (struct pvr_device_power){
- .domains = domains,
- .domain_links = no_free_ptr(domain_links),
- };
-
- return 0;
+ err = 0;
+ goto out;
err_unlink:
while (--i >= 0)
device_link_del(domain_links[i]);
+ dev_pm_domain_detach_list(domains);
+ domains = NULL;
+
+err_free_links:
+ kfree(domain_links);
+ domain_links = NULL;
+
+out:
+ pvr_dev->power = (struct pvr_device_power){
+ .domains = domains,
+ .domain_links = domain_links,
+ };
+
return err;
}
@@ -668,14 +684,16 @@ void pvr_power_domains_fini(struct pvr_device *pvr_dev)
{
struct pvr_device_power *pvr_power = &pvr_dev->power;
- int i = (int)pvr_power->domains->num_pds - 1;
+ if (!pvr_power->domains)
+ goto out;
- while (--i >= 0)
+ for (int i = (int)pvr_power->domains->num_pds - 2; i >= 0; --i)
device_link_del(pvr_power->domain_links[i]);
dev_pm_domain_detach_list(pvr_power->domains);
kfree(pvr_power->domain_links);
+out:
*pvr_power = (struct pvr_device_power){ 0 };
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 3c7d2e5b3850..0e8de6d4b36f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -144,7 +144,7 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
nouveau_bo_del_io_reserve_lru(bo);
nv10_bo_put_tile_region(dev, nvbo->tile, NULL);
- if (bo->base.import_attach)
+ if (drm_gem_is_imported(&bo->base))
drm_prime_gem_destroy(&bo->base, bo->sg);
/*
diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
index f5f0e2c505b6..0fce4452dbe7 100644
--- a/drivers/gpu/drm/panel/panel-edp.c
+++ b/drivers/gpu/drm/panel/panel-edp.c
@@ -1814,6 +1814,13 @@ static const struct panel_delay delay_200_500_e200 = {
.enable = 200,
};
+static const struct panel_delay delay_200_500_e200_d100 = {
+ .hpd_absent = 200,
+ .unprepare = 500,
+ .enable = 200,
+ .disable = 100,
+};
+
static const struct panel_delay delay_200_500_e200_d200 = {
.hpd_absent = 200,
.unprepare = 500,
@@ -2014,7 +2021,7 @@ static const struct edp_panel_entry edp_panels[] = {
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0c93, &delay_200_500_e200, "Unknown"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0cb6, &delay_200_500_e200, "NT116WHM-N44"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0cf2, &delay_200_500_e200, "NV156FHM-N4S"),
- EDP_PANEL_ENTRY('B', 'O', 'E', 0x0cf6, &delay_200_500_e200, "NV140WUM-N64"),
+ EDP_PANEL_ENTRY('B', 'O', 'E', 0x0cf6, &delay_200_500_e200_d100, "NV140WUM-N64"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0cfa, &delay_200_500_e50, "NV116WHM-A4D"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0d45, &delay_200_500_e80, "NV116WHM-N4B"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0d73, &delay_200_500_e80, "NE140WUM-N6S"),
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 822633da741e..3a7fce428898 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -702,7 +702,7 @@ static void panfrost_gem_debugfs_bo_print(struct panfrost_gem_object *bo,
resident_size,
drm_vma_node_start(&bo->base.base.vma_node));
- if (bo->base.base.import_attach)
+ if (drm_gem_is_imported(&bo->base.base))
gem_state_flags |= PANFROST_DEBUGFS_GEM_STATE_FLAG_IMPORTED;
if (bo->base.base.dma_buf)
gem_state_flags |= PANFROST_DEBUGFS_GEM_STATE_FLAG_EXPORTED;
diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
index 4b4575dd6e90..6d14b0269574 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.c
+++ b/drivers/gpu/drm/panthor/panthor_gem.c
@@ -666,7 +666,7 @@ static void panthor_gem_debugfs_bo_print(struct panthor_gem_object *bo,
resident_size,
drm_vma_node_start(&bo->base.base.vma_node));
- if (bo->base.base.import_attach)
+ if (drm_gem_is_imported(&bo->base.base))
gem_state_flags |= PANTHOR_DEBUGFS_GEM_STATE_FLAG_IMPORTED;
if (bo->base.base.dma_buf)
gem_state_flags |= PANTHOR_DEBUGFS_GEM_STATE_FLAG_EXPORTED;
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
index e6ee35406165..13fa55aed3da 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -1418,48 +1418,12 @@ static void drm_sched_cancel_remaining_jobs(struct drm_gpu_scheduler *sched)
*/
void drm_sched_fini(struct drm_gpu_scheduler *sched)
{
- struct drm_sched_entity *s_entity;
int i;
drm_sched_wqueue_stop(sched);
- for (i = DRM_SCHED_PRIORITY_KERNEL; i < sched->num_rqs; i++) {
- struct drm_sched_rq *rq = sched->sched_rq[i];
-
- spin_lock(&rq->lock);
- list_for_each_entry(s_entity, &rq->entities, list) {
- /*
- * Prevents reinsertion and marks job_queue as idle,
- * it will be removed from the rq in drm_sched_entity_fini()
- * eventually
- *
- * FIXME:
- * This lacks the proper spin_lock(&s_entity->lock) and
- * is, therefore, a race condition. Most notably, it
- * can race with drm_sched_entity_push_job(). The lock
- * cannot be taken here, however, because this would
- * lead to lock inversion -> deadlock.
- *
- * The best solution probably is to enforce the life
- * time rule of all entities having to be torn down
- * before their scheduler. Then, however, locking could
- * be dropped alltogether from this function.
- *
- * For now, this remains a potential race in all
- * drivers that keep entities alive for longer than
- * the scheduler.
- *
- * The READ_ONCE() is there to make the lockless read
- * (warning about the lockless write below) slightly
- * less broken...
- */
- if (!READ_ONCE(s_entity->stopped))
- dev_warn(sched->dev, "Tearing down scheduler with active entities!\n");
- s_entity->stopped = true;
- }
- spin_unlock(&rq->lock);
+ for (i = DRM_SCHED_PRIORITY_KERNEL; i < sched->num_rqs; i++)
kfree(sched->sched_rq[i]);
- }
/* Wakeup everyone stuck in drm_sched_entity_flush for this scheduler */
wake_up_all(&sched->job_scheduled);
diff --git a/drivers/gpu/drm/scheduler/tests/tests_basic.c b/drivers/gpu/drm/scheduler/tests/tests_basic.c
index 82a41a456b0a..a5a5a35a87b0 100644
--- a/drivers/gpu/drm/scheduler/tests/tests_basic.c
+++ b/drivers/gpu/drm/scheduler/tests/tests_basic.c
@@ -421,7 +421,7 @@ static void drm_sched_change_priority(struct kunit *test)
static struct kunit_case drm_sched_priority_tests[] = {
KUNIT_CASE(drm_sched_priorities),
- KUNIT_CASE(drm_sched_change_priority),
+ KUNIT_CASE_SLOW(drm_sched_change_priority),
{}
};
@@ -546,7 +546,7 @@ static void drm_sched_test_credits(struct kunit *test)
}
static struct kunit_case drm_sched_credits_tests[] = {
- KUNIT_CASE(drm_sched_test_credits),
+ KUNIT_CASE_SLOW(drm_sched_test_credits),
{}
};
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 1f93bc5a3d02..f45ba47b4ba8 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -556,7 +556,7 @@ static void vc4_free_object(struct drm_gem_object *gem_bo)
mutex_lock(&vc4->bo_lock);
/* If the object references someone else's memory, we can't cache it.
*/
- if (gem_bo->import_attach) {
+ if (drm_gem_is_imported(gem_bo)) {
vc4_bo_destroy(bo);
goto out;
}
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index ad8cbd727b80..2d3df5e621c1 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -1250,7 +1250,7 @@ int vc4_gem_madvise_ioctl(struct drm_device *dev, void *data,
/* Not sure it's safe to purge imported BOs. Let's just assume it's
* not until proven otherwise.
*/
- if (gem_obj->import_attach) {
+ if (drm_gem_is_imported(gem_obj)) {
DRM_DEBUG("madvise not supported on imported BOs\n");
ret = -EINVAL;
goto out_put_gem;
diff --git a/drivers/gpu/tests/gpu_buddy_test.c b/drivers/gpu/tests/gpu_buddy_test.c
index 450e71deed90..5429010f34d3 100644
--- a/drivers/gpu/tests/gpu_buddy_test.c
+++ b/drivers/gpu/tests/gpu_buddy_test.c
@@ -910,7 +910,7 @@ static struct kunit_case gpu_buddy_tests[] = {
KUNIT_CASE(gpu_test_buddy_alloc_contiguous),
KUNIT_CASE(gpu_test_buddy_alloc_clear),
KUNIT_CASE(gpu_test_buddy_alloc_range_bias),
- KUNIT_CASE(gpu_test_buddy_fragmentation_performance),
+ KUNIT_CASE_SLOW(gpu_test_buddy_fragmentation_performance),
KUNIT_CASE(gpu_test_buddy_alloc_exceeds_max_order),
{}
};