Merge tag 'drm-misc-fixes-2025-07-03' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes
drm-misc-fixes for v6.16-rc5: - Replace simple panel lookup hack with proper fix. - nullpointer deref in vesadrm fix. - fix dma_resv_wait_timeout. - fix error handling in ttm_buffer_object_transfer. - bridge fixes. - Fix vmwgfx accidentally allocating encrypted memory. - Fix race in spsc_queue_push() - Add refcount on backing GEM objects during fb creation. - Fix v3d irq's being enabled during gpu reset. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://lore.kernel.org/r/a7461418-08dc-4b7c-b2fa-264155f66d5e@linux.intel.com
This commit is contained in:
@@ -685,11 +685,13 @@ long dma_resv_wait_timeout(struct dma_resv *obj, enum dma_resv_usage usage,
|
||||
dma_resv_iter_begin(&cursor, obj, usage);
|
||||
dma_resv_for_each_fence_unlocked(&cursor, fence) {
|
||||
|
||||
ret = dma_fence_wait_timeout(fence, intr, ret);
|
||||
if (ret <= 0) {
|
||||
dma_resv_iter_end(&cursor);
|
||||
return ret;
|
||||
}
|
||||
ret = dma_fence_wait_timeout(fence, intr, timeout);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
|
||||
/* Even for zero timeout the return value is 1 */
|
||||
if (timeout)
|
||||
timeout = ret;
|
||||
}
|
||||
dma_resv_iter_end(&cursor);
|
||||
|
||||
|
||||
@@ -64,10 +64,11 @@ struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent, str
|
||||
adev->id = ret;
|
||||
adev->name = "dp_hpd_bridge";
|
||||
adev->dev.parent = parent;
|
||||
adev->dev.of_node = of_node_get(parent->of_node);
|
||||
adev->dev.release = drm_aux_hpd_bridge_release;
|
||||
adev->dev.platform_data = of_node_get(np);
|
||||
|
||||
device_set_of_node_from_dev(&adev->dev, parent);
|
||||
|
||||
ret = auxiliary_device_init(adev);
|
||||
if (ret) {
|
||||
of_node_put(adev->dev.platform_data);
|
||||
|
||||
@@ -299,6 +299,7 @@ struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel,
|
||||
panel_bridge->bridge.of_node = panel->dev->of_node;
|
||||
panel_bridge->bridge.ops = DRM_BRIDGE_OP_MODES;
|
||||
panel_bridge->bridge.type = connector_type;
|
||||
panel_bridge->bridge.pre_enable_prev_first = panel->prepare_prev_first;
|
||||
|
||||
drm_bridge_add(&panel_bridge->bridge);
|
||||
|
||||
@@ -413,8 +414,6 @@ struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev,
|
||||
return bridge;
|
||||
}
|
||||
|
||||
bridge->pre_enable_prev_first = panel->prepare_prev_first;
|
||||
|
||||
*ptr = bridge;
|
||||
devres_add(dev, ptr);
|
||||
|
||||
@@ -456,8 +455,6 @@ struct drm_bridge *drmm_panel_bridge_add(struct drm_device *drm,
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
bridge->pre_enable_prev_first = panel->prepare_prev_first;
|
||||
|
||||
return bridge;
|
||||
}
|
||||
EXPORT_SYMBOL(drmm_panel_bridge_add);
|
||||
|
||||
@@ -212,6 +212,35 @@ void drm_gem_private_object_fini(struct drm_gem_object *obj)
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_private_object_fini);
|
||||
|
||||
static void drm_gem_object_handle_get(struct drm_gem_object *obj)
|
||||
{
|
||||
struct drm_device *dev = obj->dev;
|
||||
|
||||
drm_WARN_ON(dev, !mutex_is_locked(&dev->object_name_lock));
|
||||
|
||||
if (obj->handle_count++ == 0)
|
||||
drm_gem_object_get(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_gem_object_handle_get_unlocked - acquire reference on user-space handles
|
||||
* @obj: GEM object
|
||||
*
|
||||
* Acquires a reference on the GEM buffer object's handle. Required
|
||||
* to keep the GEM object alive. Call drm_gem_object_handle_put_unlocked()
|
||||
* to release the reference.
|
||||
*/
|
||||
void drm_gem_object_handle_get_unlocked(struct drm_gem_object *obj)
|
||||
{
|
||||
struct drm_device *dev = obj->dev;
|
||||
|
||||
guard(mutex)(&dev->object_name_lock);
|
||||
|
||||
drm_WARN_ON(dev, !obj->handle_count); /* first ref taken in create-tail helper */
|
||||
drm_gem_object_handle_get(obj);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_object_handle_get_unlocked);
|
||||
|
||||
/**
|
||||
* drm_gem_object_handle_free - release resources bound to userspace handles
|
||||
* @obj: GEM object to clean up.
|
||||
@@ -242,8 +271,14 @@ static void drm_gem_object_exported_dma_buf_free(struct drm_gem_object *obj)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
|
||||
/**
|
||||
* drm_gem_object_handle_put_unlocked - releases reference on user-space handles
|
||||
* @obj: GEM object
|
||||
*
|
||||
* Releases a reference on the GEM buffer object's handle. Possibly releases
|
||||
* the GEM buffer object and associated dma-buf objects.
|
||||
*/
|
||||
void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
|
||||
{
|
||||
struct drm_device *dev = obj->dev;
|
||||
bool final = false;
|
||||
@@ -268,6 +303,7 @@ drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
|
||||
if (final)
|
||||
drm_gem_object_put(obj);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_object_handle_put_unlocked);
|
||||
|
||||
/*
|
||||
* Called at device or object close to release the file's
|
||||
@@ -389,8 +425,8 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
|
||||
int ret;
|
||||
|
||||
WARN_ON(!mutex_is_locked(&dev->object_name_lock));
|
||||
if (obj->handle_count++ == 0)
|
||||
drm_gem_object_get(obj);
|
||||
|
||||
drm_gem_object_handle_get(obj);
|
||||
|
||||
/*
|
||||
* Get the user-visible handle using idr. Preload and perform
|
||||
|
||||
@@ -99,7 +99,7 @@ void drm_gem_fb_destroy(struct drm_framebuffer *fb)
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < fb->format->num_planes; i++)
|
||||
drm_gem_object_put(fb->obj[i]);
|
||||
drm_gem_object_handle_put_unlocked(fb->obj[i]);
|
||||
|
||||
drm_framebuffer_cleanup(fb);
|
||||
kfree(fb);
|
||||
@@ -182,8 +182,10 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
|
||||
if (!objs[i]) {
|
||||
drm_dbg_kms(dev, "Failed to lookup GEM object\n");
|
||||
ret = -ENOENT;
|
||||
goto err_gem_object_put;
|
||||
goto err_gem_object_handle_put_unlocked;
|
||||
}
|
||||
drm_gem_object_handle_get_unlocked(objs[i]);
|
||||
drm_gem_object_put(objs[i]);
|
||||
|
||||
min_size = (height - 1) * mode_cmd->pitches[i]
|
||||
+ drm_format_info_min_pitch(info, i, width)
|
||||
@@ -193,22 +195,22 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
|
||||
drm_dbg_kms(dev,
|
||||
"GEM object size (%zu) smaller than minimum size (%u) for plane %d\n",
|
||||
objs[i]->size, min_size, i);
|
||||
drm_gem_object_put(objs[i]);
|
||||
drm_gem_object_handle_put_unlocked(objs[i]);
|
||||
ret = -EINVAL;
|
||||
goto err_gem_object_put;
|
||||
goto err_gem_object_handle_put_unlocked;
|
||||
}
|
||||
}
|
||||
|
||||
ret = drm_gem_fb_init(dev, fb, mode_cmd, objs, i, funcs);
|
||||
if (ret)
|
||||
goto err_gem_object_put;
|
||||
goto err_gem_object_handle_put_unlocked;
|
||||
|
||||
return 0;
|
||||
|
||||
err_gem_object_put:
|
||||
err_gem_object_handle_put_unlocked:
|
||||
while (i > 0) {
|
||||
--i;
|
||||
drm_gem_object_put(objs[i]);
|
||||
drm_gem_object_handle_put_unlocked(objs[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -161,6 +161,8 @@ void drm_sysfs_lease_event(struct drm_device *dev);
|
||||
|
||||
/* drm_gem.c */
|
||||
int drm_gem_init(struct drm_device *dev);
|
||||
void drm_gem_object_handle_get_unlocked(struct drm_gem_object *obj);
|
||||
void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj);
|
||||
int drm_gem_handle_create_tail(struct drm_file *file_priv,
|
||||
struct drm_gem_object *obj,
|
||||
u32 *handlep);
|
||||
|
||||
@@ -91,12 +91,13 @@ static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
|
||||
.restore = pm_generic_restore,
|
||||
};
|
||||
|
||||
static const struct bus_type mipi_dsi_bus_type = {
|
||||
const struct bus_type mipi_dsi_bus_type = {
|
||||
.name = "mipi-dsi",
|
||||
.match = mipi_dsi_device_match,
|
||||
.uevent = mipi_dsi_uevent,
|
||||
.pm = &mipi_dsi_device_pm_ops,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mipi_dsi_bus_type);
|
||||
|
||||
/**
|
||||
* of_find_mipi_dsi_device_by_node() - find the MIPI DSI device matching a
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/media-bus-format.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
@@ -136,6 +137,14 @@ struct panel_desc {
|
||||
int connector_type;
|
||||
};
|
||||
|
||||
struct panel_desc_dsi {
|
||||
struct panel_desc desc;
|
||||
|
||||
unsigned long flags;
|
||||
enum mipi_dsi_pixel_format format;
|
||||
unsigned int lanes;
|
||||
};
|
||||
|
||||
struct panel_simple {
|
||||
struct drm_panel base;
|
||||
|
||||
@@ -430,10 +439,7 @@ static const struct drm_panel_funcs panel_simple_funcs = {
|
||||
.get_timings = panel_simple_get_timings,
|
||||
};
|
||||
|
||||
static struct panel_desc panel_dpi;
|
||||
|
||||
static int panel_dpi_probe(struct device *dev,
|
||||
struct panel_simple *panel)
|
||||
static struct panel_desc *panel_dpi_probe(struct device *dev)
|
||||
{
|
||||
struct display_timing *timing;
|
||||
const struct device_node *np;
|
||||
@@ -445,17 +451,17 @@ static int panel_dpi_probe(struct device *dev,
|
||||
np = dev->of_node;
|
||||
desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
|
||||
if (!desc)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
timing = devm_kzalloc(dev, sizeof(*timing), GFP_KERNEL);
|
||||
if (!timing)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = of_get_display_timing(np, "panel-timing", timing);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%pOF: no panel-timing node found for \"panel-dpi\" binding\n",
|
||||
np);
|
||||
return ret;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
desc->timings = timing;
|
||||
@@ -473,9 +479,7 @@ static int panel_dpi_probe(struct device *dev,
|
||||
/* We do not know the connector for the DT node, so guess it */
|
||||
desc->connector_type = DRM_MODE_CONNECTOR_DPI;
|
||||
|
||||
panel->desc = desc;
|
||||
|
||||
return 0;
|
||||
return desc;
|
||||
}
|
||||
|
||||
#define PANEL_SIMPLE_BOUNDS_CHECK(to_check, bounds, field) \
|
||||
@@ -570,8 +574,44 @@ static int panel_simple_override_nondefault_lvds_datamapping(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
|
||||
static const struct panel_desc *panel_simple_get_desc(struct device *dev)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_DRM_MIPI_DSI) &&
|
||||
dev_is_mipi_dsi(dev)) {
|
||||
const struct panel_desc_dsi *dsi_desc;
|
||||
|
||||
dsi_desc = of_device_get_match_data(dev);
|
||||
if (!dsi_desc)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
return &dsi_desc->desc;
|
||||
}
|
||||
|
||||
if (dev_is_platform(dev)) {
|
||||
const struct panel_desc *desc;
|
||||
|
||||
desc = of_device_get_match_data(dev);
|
||||
if (!desc) {
|
||||
/*
|
||||
* panel-dpi probes without a descriptor and
|
||||
* panel_dpi_probe() will initialize one for us
|
||||
* based on the device tree.
|
||||
*/
|
||||
if (of_device_is_compatible(dev->of_node, "panel-dpi"))
|
||||
return panel_dpi_probe(dev);
|
||||
else
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static struct panel_simple *panel_simple_probe(struct device *dev)
|
||||
{
|
||||
const struct panel_desc *desc;
|
||||
struct panel_simple *panel;
|
||||
struct display_timing dt;
|
||||
struct device_node *ddc;
|
||||
@@ -579,27 +619,31 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
|
||||
u32 bus_flags;
|
||||
int err;
|
||||
|
||||
desc = panel_simple_get_desc(dev);
|
||||
if (IS_ERR(desc))
|
||||
return ERR_CAST(desc);
|
||||
|
||||
panel = devm_drm_panel_alloc(dev, struct panel_simple, base,
|
||||
&panel_simple_funcs, desc->connector_type);
|
||||
if (IS_ERR(panel))
|
||||
return PTR_ERR(panel);
|
||||
return ERR_CAST(panel);
|
||||
|
||||
panel->desc = desc;
|
||||
|
||||
panel->supply = devm_regulator_get(dev, "power");
|
||||
if (IS_ERR(panel->supply))
|
||||
return PTR_ERR(panel->supply);
|
||||
return ERR_CAST(panel->supply);
|
||||
|
||||
panel->enable_gpio = devm_gpiod_get_optional(dev, "enable",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(panel->enable_gpio))
|
||||
return dev_err_probe(dev, PTR_ERR(panel->enable_gpio),
|
||||
"failed to request GPIO\n");
|
||||
return dev_err_cast_probe(dev, panel->enable_gpio,
|
||||
"failed to request GPIO\n");
|
||||
|
||||
err = of_drm_get_panel_orientation(dev->of_node, &panel->orientation);
|
||||
if (err) {
|
||||
dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err);
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
|
||||
@@ -608,19 +652,12 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
|
||||
of_node_put(ddc);
|
||||
|
||||
if (!panel->ddc)
|
||||
return -EPROBE_DEFER;
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
}
|
||||
|
||||
if (desc == &panel_dpi) {
|
||||
/* Handle the generic panel-dpi binding */
|
||||
err = panel_dpi_probe(dev, panel);
|
||||
if (err)
|
||||
goto free_ddc;
|
||||
desc = panel->desc;
|
||||
} else {
|
||||
if (!of_get_display_timing(dev->of_node, "panel-timing", &dt))
|
||||
panel_simple_parse_panel_timing_node(dev, panel, &dt);
|
||||
}
|
||||
if (!of_device_is_compatible(dev->of_node, "panel-dpi") &&
|
||||
!of_get_display_timing(dev->of_node, "panel-timing", &dt))
|
||||
panel_simple_parse_panel_timing_node(dev, panel, &dt);
|
||||
|
||||
if (desc->connector_type == DRM_MODE_CONNECTOR_LVDS) {
|
||||
/* Optional data-mapping property for overriding bus format */
|
||||
@@ -703,7 +740,7 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
|
||||
|
||||
drm_panel_add(&panel->base);
|
||||
|
||||
return 0;
|
||||
return panel;
|
||||
|
||||
disable_pm_runtime:
|
||||
pm_runtime_dont_use_autosuspend(dev);
|
||||
@@ -712,7 +749,7 @@ free_ddc:
|
||||
if (panel->ddc)
|
||||
put_device(&panel->ddc->dev);
|
||||
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static void panel_simple_shutdown(struct device *dev)
|
||||
@@ -5367,7 +5404,12 @@ static const struct of_device_id platform_of_match[] = {
|
||||
}, {
|
||||
/* Must be the last entry */
|
||||
.compatible = "panel-dpi",
|
||||
.data = &panel_dpi,
|
||||
|
||||
/*
|
||||
* Explicitly NULL, the panel_desc structure will be
|
||||
* allocated by panel_dpi_probe().
|
||||
*/
|
||||
.data = NULL,
|
||||
}, {
|
||||
/* sentinel */
|
||||
}
|
||||
@@ -5376,13 +5418,13 @@ MODULE_DEVICE_TABLE(of, platform_of_match);
|
||||
|
||||
static int panel_simple_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct panel_desc *desc;
|
||||
struct panel_simple *panel;
|
||||
|
||||
desc = of_device_get_match_data(&pdev->dev);
|
||||
if (!desc)
|
||||
return -ENODEV;
|
||||
panel = panel_simple_probe(&pdev->dev);
|
||||
if (IS_ERR(panel))
|
||||
return PTR_ERR(panel);
|
||||
|
||||
return panel_simple_probe(&pdev->dev, desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void panel_simple_platform_remove(struct platform_device *pdev)
|
||||
@@ -5412,14 +5454,6 @@ static struct platform_driver panel_simple_platform_driver = {
|
||||
.shutdown = panel_simple_platform_shutdown,
|
||||
};
|
||||
|
||||
struct panel_desc_dsi {
|
||||
struct panel_desc desc;
|
||||
|
||||
unsigned long flags;
|
||||
enum mipi_dsi_pixel_format format;
|
||||
unsigned int lanes;
|
||||
};
|
||||
|
||||
static const struct drm_display_mode auo_b080uan01_mode = {
|
||||
.clock = 154500,
|
||||
.hdisplay = 1200,
|
||||
@@ -5653,16 +5687,14 @@ MODULE_DEVICE_TABLE(of, dsi_of_match);
|
||||
static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
const struct panel_desc_dsi *desc;
|
||||
struct panel_simple *panel;
|
||||
int err;
|
||||
|
||||
desc = of_device_get_match_data(&dsi->dev);
|
||||
if (!desc)
|
||||
return -ENODEV;
|
||||
|
||||
err = panel_simple_probe(&dsi->dev, &desc->desc);
|
||||
if (err < 0)
|
||||
return err;
|
||||
panel = panel_simple_probe(&dsi->dev);
|
||||
if (IS_ERR(panel))
|
||||
return PTR_ERR(panel);
|
||||
|
||||
desc = container_of(panel->desc, struct panel_desc_dsi, desc);
|
||||
dsi->mode_flags = desc->flags;
|
||||
dsi->format = desc->format;
|
||||
dsi->lanes = desc->lanes;
|
||||
|
||||
@@ -362,14 +362,19 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv,
|
||||
|
||||
if (!__screen_info_vbe_mode_nonvga(si)) {
|
||||
vesa->cmap_write = vesadrm_vga_cmap_write;
|
||||
#if defined(CONFIG_X86_32)
|
||||
} else {
|
||||
#if defined(CONFIG_X86_32)
|
||||
phys_addr_t pmi_base = __screen_info_vesapm_info_base(si);
|
||||
const u16 *pmi_addr = phys_to_virt(pmi_base);
|
||||
|
||||
vesa->pmi.PrimaryPalette = (u8 *)pmi_addr + pmi_addr[2];
|
||||
vesa->cmap_write = vesadrm_pmi_cmap_write;
|
||||
if (pmi_base) {
|
||||
const u16 *pmi_addr = phys_to_virt(pmi_base);
|
||||
|
||||
vesa->pmi.PrimaryPalette = (u8 *)pmi_addr + pmi_addr[2];
|
||||
vesa->cmap_write = vesadrm_pmi_cmap_write;
|
||||
} else
|
||||
#endif
|
||||
if (format->is_color_indexed)
|
||||
drm_warn(dev, "hardware palette is unchangeable, colors may be incorrect\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
|
||||
@@ -254,6 +254,13 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
|
||||
ret = dma_resv_trylock(&fbo->base.base._resv);
|
||||
WARN_ON(!ret);
|
||||
|
||||
ret = dma_resv_reserve_fences(&fbo->base.base._resv, 1);
|
||||
if (ret) {
|
||||
dma_resv_unlock(&fbo->base.base._resv);
|
||||
kfree(fbo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (fbo->base.resource) {
|
||||
ttm_resource_set_bo(fbo->base.resource, &fbo->base);
|
||||
bo->resource = NULL;
|
||||
@@ -262,12 +269,6 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
|
||||
fbo->base.bulk_move = NULL;
|
||||
}
|
||||
|
||||
ret = dma_resv_reserve_fences(&fbo->base.base._resv, 1);
|
||||
if (ret) {
|
||||
kfree(fbo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ttm_bo_get(bo);
|
||||
fbo->bo = bo;
|
||||
|
||||
|
||||
@@ -101,6 +101,12 @@ enum v3d_gen {
|
||||
V3D_GEN_71 = 71,
|
||||
};
|
||||
|
||||
enum v3d_irq {
|
||||
V3D_CORE_IRQ,
|
||||
V3D_HUB_IRQ,
|
||||
V3D_MAX_IRQS,
|
||||
};
|
||||
|
||||
struct v3d_dev {
|
||||
struct drm_device drm;
|
||||
|
||||
@@ -112,6 +118,8 @@ struct v3d_dev {
|
||||
|
||||
bool single_irq_line;
|
||||
|
||||
int irq[V3D_MAX_IRQS];
|
||||
|
||||
struct v3d_perfmon_info perfmon_info;
|
||||
|
||||
void __iomem *hub_regs;
|
||||
|
||||
@@ -134,6 +134,8 @@ v3d_reset(struct v3d_dev *v3d)
|
||||
if (false)
|
||||
v3d_idle_axi(v3d, 0);
|
||||
|
||||
v3d_irq_disable(v3d);
|
||||
|
||||
v3d_idle_gca(v3d);
|
||||
v3d_reset_sms(v3d);
|
||||
v3d_reset_v3d(v3d);
|
||||
|
||||
@@ -260,7 +260,7 @@ v3d_hub_irq(int irq, void *arg)
|
||||
int
|
||||
v3d_irq_init(struct v3d_dev *v3d)
|
||||
{
|
||||
int irq1, ret, core;
|
||||
int irq, ret, core;
|
||||
|
||||
INIT_WORK(&v3d->overflow_mem_work, v3d_overflow_mem_work);
|
||||
|
||||
@@ -271,17 +271,24 @@ v3d_irq_init(struct v3d_dev *v3d)
|
||||
V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS(v3d->ver));
|
||||
V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS(v3d->ver));
|
||||
|
||||
irq1 = platform_get_irq_optional(v3d_to_pdev(v3d), 1);
|
||||
if (irq1 == -EPROBE_DEFER)
|
||||
return irq1;
|
||||
if (irq1 > 0) {
|
||||
ret = devm_request_irq(v3d->drm.dev, irq1,
|
||||
irq = platform_get_irq_optional(v3d_to_pdev(v3d), 1);
|
||||
if (irq == -EPROBE_DEFER)
|
||||
return irq;
|
||||
if (irq > 0) {
|
||||
v3d->irq[V3D_CORE_IRQ] = irq;
|
||||
|
||||
ret = devm_request_irq(v3d->drm.dev, v3d->irq[V3D_CORE_IRQ],
|
||||
v3d_irq, IRQF_SHARED,
|
||||
"v3d_core0", v3d);
|
||||
if (ret)
|
||||
goto fail;
|
||||
ret = devm_request_irq(v3d->drm.dev,
|
||||
platform_get_irq(v3d_to_pdev(v3d), 0),
|
||||
|
||||
irq = platform_get_irq(v3d_to_pdev(v3d), 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
v3d->irq[V3D_HUB_IRQ] = irq;
|
||||
|
||||
ret = devm_request_irq(v3d->drm.dev, v3d->irq[V3D_HUB_IRQ],
|
||||
v3d_hub_irq, IRQF_SHARED,
|
||||
"v3d_hub", v3d);
|
||||
if (ret)
|
||||
@@ -289,8 +296,12 @@ v3d_irq_init(struct v3d_dev *v3d)
|
||||
} else {
|
||||
v3d->single_irq_line = true;
|
||||
|
||||
ret = devm_request_irq(v3d->drm.dev,
|
||||
platform_get_irq(v3d_to_pdev(v3d), 0),
|
||||
irq = platform_get_irq(v3d_to_pdev(v3d), 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
v3d->irq[V3D_CORE_IRQ] = irq;
|
||||
|
||||
ret = devm_request_irq(v3d->drm.dev, v3d->irq[V3D_CORE_IRQ],
|
||||
v3d_irq, IRQF_SHARED,
|
||||
"v3d", v3d);
|
||||
if (ret)
|
||||
@@ -331,6 +342,12 @@ v3d_irq_disable(struct v3d_dev *v3d)
|
||||
V3D_CORE_WRITE(core, V3D_CTL_INT_MSK_SET, ~0);
|
||||
V3D_WRITE(V3D_HUB_INT_MSK_SET, ~0);
|
||||
|
||||
/* Finish any interrupt handler still in flight. */
|
||||
for (int i = 0; i < V3D_MAX_IRQS; i++) {
|
||||
if (v3d->irq[i])
|
||||
synchronize_irq(v3d->irq[i]);
|
||||
}
|
||||
|
||||
/* Clear any pending interrupts we might have left. */
|
||||
for (core = 0; core < v3d->cores; core++)
|
||||
V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS(v3d->ver));
|
||||
|
||||
@@ -749,7 +749,7 @@ static int vmw_setup_pci_resources(struct vmw_private *dev,
|
||||
dev->fifo_mem = devm_memremap(dev->drm.dev,
|
||||
fifo_start,
|
||||
fifo_size,
|
||||
MEMREMAP_WB);
|
||||
MEMREMAP_WB | MEMREMAP_DEC);
|
||||
|
||||
if (IS_ERR(dev->fifo_mem)) {
|
||||
drm_err(&dev->drm,
|
||||
|
||||
@@ -223,6 +223,9 @@ struct mipi_dsi_multi_context {
|
||||
|
||||
#define to_mipi_dsi_device(__dev) container_of_const(__dev, struct mipi_dsi_device, dev)
|
||||
|
||||
extern const struct bus_type mipi_dsi_bus_type;
|
||||
#define dev_is_mipi_dsi(dev) ((dev)->bus == &mipi_dsi_bus_type)
|
||||
|
||||
/**
|
||||
* mipi_dsi_pixel_format_to_bpp - obtain the number of bits per pixel for any
|
||||
* given pixel format defined by the MIPI DSI
|
||||
|
||||
@@ -70,9 +70,11 @@ static inline bool spsc_queue_push(struct spsc_queue *queue, struct spsc_node *n
|
||||
|
||||
preempt_disable();
|
||||
|
||||
atomic_inc(&queue->job_count);
|
||||
smp_mb__after_atomic();
|
||||
|
||||
tail = (struct spsc_node **)atomic_long_xchg(&queue->tail, (long)&node->next);
|
||||
WRITE_ONCE(*tail, node);
|
||||
atomic_inc(&queue->job_count);
|
||||
|
||||
/*
|
||||
* In case of first element verify new node will be visible to the consumer
|
||||
|
||||
Reference in New Issue
Block a user