From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
kernel/drivers/gpu/drm/drm_drv.c | 567 ++++++++++++++++++++++++++++++--------------------------
1 files changed, 303 insertions(+), 264 deletions(-)
diff --git a/kernel/drivers/gpu/drm/drm_drv.c b/kernel/drivers/gpu/drm/drm_drv.c
index 2f1fc1f..879fccd 100644
--- a/kernel/drivers/gpu/drm/drm_drv.c
+++ b/kernel/drivers/gpu/drm/drm_drv.c
@@ -31,38 +31,25 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/mount.h>
+#include <linux/pseudo_fs.h>
#include <linux/slab.h>
#include <linux/srcu.h>
#include <drm/drm_client.h>
+#include <drm/drm_color_mgmt.h>
#include <drm/drm_drv.h>
-#include <drm/drmP.h>
+#include <drm/drm_file.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_mode_object.h>
+#include <drm/drm_print.h>
#include "drm_crtc_internal.h"
-#include "drm_legacy.h"
#include "drm_internal.h"
-#include "drm_crtc_internal.h"
-
-/*
- * drm_debug: Enable debug output.
- * Bitmask of DRM_UT_x. See include/drm/drmP.h for details.
- */
-unsigned int drm_debug = 0;
-EXPORT_SYMBOL(drm_debug);
+#include "drm_legacy.h"
MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl");
MODULE_DESCRIPTION("DRM shared core routines");
MODULE_LICENSE("GPL and additional rights");
-MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug category.\n"
-"\t\tBit 0 (0x01) will enable CORE messages (drm core code)\n"
-"\t\tBit 1 (0x02) will enable DRIVER messages (drm controller code)\n"
-"\t\tBit 2 (0x04) will enable KMS messages (modesetting code)\n"
-"\t\tBit 3 (0x08) will enable PRIME messages (prime code)\n"
-"\t\tBit 4 (0x10) will enable ATOMIC messages (atomic code)\n"
-"\t\tBit 5 (0x20) will enable VBL messages (vblank code)\n"
-"\t\tBit 7 (0x80) will enable LEASE messages (leasing code)\n"
-"\t\tBit 8 (0x100) will enable DP messages (displayport code)");
-module_param_named(debug, drm_debug, int, 0600);
static DEFINE_SPINLOCK(drm_minor_lock);
static struct idr drm_minors_idr;
@@ -106,13 +93,27 @@
}
}
+static void drm_minor_alloc_release(struct drm_device *dev, void *data)
+{
+ struct drm_minor *minor = data;
+ unsigned long flags;
+
+ WARN_ON(dev != minor->dev);
+
+ put_device(minor->kdev);
+
+ spin_lock_irqsave(&drm_minor_lock, flags);
+ idr_remove(&drm_minors_idr, minor->index);
+ spin_unlock_irqrestore(&drm_minor_lock, flags);
+}
+
static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
{
struct drm_minor *minor;
unsigned long flags;
int r;
- minor = kzalloc(sizeof(*minor), GFP_KERNEL);
+ minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
if (!minor)
return -ENOMEM;
@@ -130,46 +131,20 @@
idr_preload_end();
if (r < 0)
- goto err_free;
+ return r;
minor->index = r;
+ r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor);
+ if (r)
+ return r;
+
minor->kdev = drm_sysfs_minor_alloc(minor);
- if (IS_ERR(minor->kdev)) {
- r = PTR_ERR(minor->kdev);
- goto err_index;
- }
+ if (IS_ERR(minor->kdev))
+ return PTR_ERR(minor->kdev);
*drm_minor_get_slot(dev, type) = minor;
return 0;
-
-err_index:
- spin_lock_irqsave(&drm_minor_lock, flags);
- idr_remove(&drm_minors_idr, minor->index);
- spin_unlock_irqrestore(&drm_minor_lock, flags);
-err_free:
- kfree(minor);
- return r;
-}
-
-static void drm_minor_free(struct drm_device *dev, unsigned int type)
-{
- struct drm_minor **slot, *minor;
- unsigned long flags;
-
- slot = drm_minor_get_slot(dev, type);
- minor = *slot;
- if (!minor)
- return;
-
- put_device(minor->kdev);
-
- spin_lock_irqsave(&drm_minor_lock, flags);
- idr_remove(&drm_minors_idr, minor->index);
- spin_unlock_irqrestore(&drm_minor_lock, flags);
-
- kfree(minor);
- *slot = NULL;
}
static int drm_minor_register(struct drm_device *dev, unsigned int type)
@@ -261,40 +236,17 @@
drm_dev_put(minor->dev);
}
-struct drm_device *drm_device_get_by_name(const char *name)
-{
- int i;
-
- for (i = 0; i < 64; i++) {
- struct drm_minor *minor;
-
- minor = drm_minor_acquire(i + DRM_MINOR_PRIMARY);
- if (IS_ERR(minor))
- continue;
- if (!minor->dev || !minor->dev->driver ||
- !minor->dev->driver->name)
- continue;
- if (!name)
- return minor->dev;
- if (!strcmp(name, minor->dev->driver->name))
- return minor->dev;
- }
-
- return NULL;
-}
-
/**
* DOC: driver instance overview
*
* A device instance for a drm driver is represented by &struct drm_device. This
- * is allocated with drm_dev_alloc(), usually from bus-specific ->probe()
- * callbacks implemented by the driver. The driver then needs to initialize all
- * the various subsystems for the drm device like memory management, vblank
- * handling, modesetting support and intial output configuration plus obviously
- * initialize all the corresponding hardware bits. An important part of this is
- * also calling drm_dev_set_unique() to set the userspace-visible unique name of
- * this device instance. Finally when everything is up and running and ready for
- * userspace the device instance can be published using drm_dev_register().
+ * is allocated and initialized with devm_drm_dev_alloc(), usually from
+ * bus-specific ->probe() callbacks implemented by the driver. The driver then
+ * needs to initialize all the various subsystems for the drm device like memory
+ * management, vblank handling, modesetting support and initial output
+ * configuration plus obviously initialize all the corresponding hardware bits.
+ * Finally when everything is up and running and ready for userspace the device
+ * instance can be published using drm_dev_register().
*
* There is also deprecated support for initalizing device instances using
* bus-specific helpers and the &drm_driver.load callback. But due to
@@ -307,12 +259,126 @@
* any other resources allocated at device initialization and drop the driver's
* reference to &drm_device using drm_dev_put().
*
- * Note that the lifetime rules for &drm_device instance has still a lot of
- * historical baggage. Hence use the reference counting provided by
- * drm_dev_get() and drm_dev_put() only carefully.
+ * Note that any allocation or resource which is visible to userspace must be
+ * released only when the final drm_dev_put() is called, and not when the
+ * driver is unbound from the underlying physical struct &device. Best to use
+ * &drm_device managed resources with drmm_add_action(), drmm_kmalloc() and
+ * related functions.
*
- * It is recommended that drivers embed &struct drm_device into their own device
- * structure, which is supported through drm_dev_init().
+ * devres managed resources like devm_kmalloc() can only be used for resources
+ * directly related to the underlying hardware device, and only used in code
+ * paths fully protected by drm_dev_enter() and drm_dev_exit().
+ *
+ * Display driver example
+ * ~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The following example shows a typical structure of a DRM display driver.
+ * The example focus on the probe() function and the other functions that is
+ * almost always present and serves as a demonstration of devm_drm_dev_alloc().
+ *
+ * .. code-block:: c
+ *
+ * struct driver_device {
+ * struct drm_device drm;
+ * void *userspace_facing;
+ * struct clk *pclk;
+ * };
+ *
+ * static struct drm_driver driver_drm_driver = {
+ * [...]
+ * };
+ *
+ * static int driver_probe(struct platform_device *pdev)
+ * {
+ * struct driver_device *priv;
+ * struct drm_device *drm;
+ * int ret;
+ *
+ * priv = devm_drm_dev_alloc(&pdev->dev, &driver_drm_driver,
+ * struct driver_device, drm);
+ * if (IS_ERR(priv))
+ * return PTR_ERR(priv);
+ * drm = &priv->drm;
+ *
+ * ret = drmm_mode_config_init(drm);
+ * if (ret)
+ * return ret;
+ *
+ * priv->userspace_facing = drmm_kzalloc(..., GFP_KERNEL);
+ * if (!priv->userspace_facing)
+ * return -ENOMEM;
+ *
+ * priv->pclk = devm_clk_get(dev, "PCLK");
+ * if (IS_ERR(priv->pclk))
+ * return PTR_ERR(priv->pclk);
+ *
+ * // Further setup, display pipeline etc
+ *
+ * platform_set_drvdata(pdev, drm);
+ *
+ * drm_mode_config_reset(drm);
+ *
+ * ret = drm_dev_register(drm);
+ * if (ret)
+ * return ret;
+ *
+ * drm_fbdev_generic_setup(drm, 32);
+ *
+ * return 0;
+ * }
+ *
+ * // This function is called before the devm_ resources are released
+ * static int driver_remove(struct platform_device *pdev)
+ * {
+ * struct drm_device *drm = platform_get_drvdata(pdev);
+ *
+ * drm_dev_unregister(drm);
+ * drm_atomic_helper_shutdown(drm)
+ *
+ * return 0;
+ * }
+ *
+ * // This function is called on kernel restart and shutdown
+ * static void driver_shutdown(struct platform_device *pdev)
+ * {
+ * drm_atomic_helper_shutdown(platform_get_drvdata(pdev));
+ * }
+ *
+ * static int __maybe_unused driver_pm_suspend(struct device *dev)
+ * {
+ * return drm_mode_config_helper_suspend(dev_get_drvdata(dev));
+ * }
+ *
+ * static int __maybe_unused driver_pm_resume(struct device *dev)
+ * {
+ * drm_mode_config_helper_resume(dev_get_drvdata(dev));
+ *
+ * return 0;
+ * }
+ *
+ * static const struct dev_pm_ops driver_pm_ops = {
+ * SET_SYSTEM_SLEEP_PM_OPS(driver_pm_suspend, driver_pm_resume)
+ * };
+ *
+ * static struct platform_driver driver_driver = {
+ * .driver = {
+ * [...]
+ * .pm = &driver_pm_ops,
+ * },
+ * .probe = driver_probe,
+ * .remove = driver_remove,
+ * .shutdown = driver_shutdown,
+ * };
+ * module_platform_driver(driver_driver);
+ *
+ * Drivers that want to support device unplugging (USB, DT overlay unload) should
+ * use drm_dev_unplug() instead of drm_dev_unregister(). The driver must protect
+ * regions that is accessing device resources to prevent use after they're
+ * released. This is done using drm_dev_enter() and drm_dev_exit(). There is one
+ * shortcoming however, drm_dev_unplug() marks the drm_device as unplugged before
+ * drm_atomic_helper_shutdown() is called. This means that if the disable code
+ * paths are protected, they will not run on regular driver module unload,
+ * possibily leaving the hardware enabled.
*/
/**
@@ -403,7 +469,6 @@
synchronize_srcu(&drm_unplug_srcu);
drm_dev_unregister(dev);
- drm_dev_put(dev);
}
EXPORT_SYMBOL(drm_dev_unplug);
@@ -428,28 +493,15 @@
static int drm_fs_cnt;
static struct vfsmount *drm_fs_mnt;
-static const struct dentry_operations drm_fs_dops = {
- .d_dname = simple_dname,
-};
-
-static const struct super_operations drm_fs_sops = {
- .statfs = simple_statfs,
-};
-
-static struct dentry *drm_fs_mount(struct file_system_type *fs_type, int flags,
- const char *dev_name, void *data)
+static int drm_fs_init_fs_context(struct fs_context *fc)
{
- return mount_pseudo(fs_type,
- "drm:",
- &drm_fs_sops,
- &drm_fs_dops,
- 0x010203ff);
+ return init_pseudo(fc, 0x010203ff) ? 0 : -ENOMEM;
}
static struct file_system_type drm_fs_type = {
.name = "drm",
.owner = THIS_MODULE,
- .mount = drm_fs_mount,
+ .init_fs_context = drm_fs_init_fs_context,
.kill_sb = kill_anon_super,
};
@@ -480,39 +532,52 @@
}
/**
- * drm_dev_init - Initialise new DRM device
- * @dev: DRM device
- * @driver: DRM driver
- * @parent: Parent device object
+ * DOC: component helper usage recommendations
*
- * Initialize a new DRM device. No device registration is done.
- * Call drm_dev_register() to advertice the device to user space and register it
- * with other core subsystems. This should be done last in the device
- * initialization sequence to make sure userspace can't access an inconsistent
- * state.
+ * DRM drivers that drive hardware where a logical device consists of a pile of
+ * independent hardware blocks are recommended to use the :ref:`component helper
+ * library<component>`. For consistency and better options for code reuse the
+ * following guidelines apply:
*
- * The initial ref-count of the object is 1. Use drm_dev_get() and
- * drm_dev_put() to take and drop further ref-counts.
+ * - The entire device initialization procedure should be run from the
+ * &component_master_ops.master_bind callback, starting with
+ * devm_drm_dev_alloc(), then binding all components with
+ * component_bind_all() and finishing with drm_dev_register().
*
- * Note that for purely virtual devices @parent can be NULL.
+ * - The opaque pointer passed to all components through component_bind_all()
+ * should point at &struct drm_device of the device instance, not some driver
+ * specific private structure.
*
- * Drivers that do not want to allocate their own device struct
- * embedding &struct drm_device can call drm_dev_alloc() instead. For drivers
- * that do embed &struct drm_device it must be placed first in the overall
- * structure, and the overall structure must be allocated using kmalloc(): The
- * drm core's release function unconditionally calls kfree() on the @dev pointer
- * when the final reference is released. To override this behaviour, and so
- * allow embedding of the drm_device inside the driver's device struct at an
- * arbitrary offset, you must supply a &drm_driver.release callback and control
- * the finalization explicitly.
- *
- * RETURNS:
- * 0 on success, or error code on failure.
+ * - The component helper fills the niche where further standardization of
+ * interfaces is not practical. When there already is, or will be, a
+ * standardized interface like &drm_bridge or &drm_panel, providing its own
+ * functions to find such components at driver load time, like
+ * drm_of_find_panel_or_bridge(), then the component helper should not be
+ * used.
*/
-int drm_dev_init(struct drm_device *dev,
- struct drm_driver *driver,
- struct device *parent)
+
+static void drm_dev_init_release(struct drm_device *dev, void *res)
{
+ drm_legacy_ctxbitmap_cleanup(dev);
+ drm_legacy_remove_map_hash(dev);
+ drm_fs_inode_free(dev->anon_inode);
+
+ put_device(dev->dev);
+ /* Prevent use-after-free in drm_managed_release when debugging is
+ * enabled. Slightly awkward, but can't really be helped. */
+ dev->dev = NULL;
+ mutex_destroy(&dev->master_mutex);
+ mutex_destroy(&dev->clientlist_mutex);
+ mutex_destroy(&dev->filelist_mutex);
+ mutex_destroy(&dev->struct_mutex);
+ drm_legacy_destroy_members(dev);
+}
+
+static int drm_dev_init(struct drm_device *dev,
+ struct drm_driver *driver,
+ struct device *parent)
+{
+ struct inode *inode;
int ret;
if (!drm_core_init_complete) {
@@ -520,46 +585,57 @@
return -ENODEV;
}
+ if (WARN_ON(!parent))
+ return -EINVAL;
+
kref_init(&dev->ref);
dev->dev = get_device(parent);
dev->driver = driver;
+ INIT_LIST_HEAD(&dev->managed.resources);
+ spin_lock_init(&dev->managed.lock);
+
+ /* no per-device feature limits by default */
+ dev->driver_features = ~0u;
+
+ drm_legacy_init_members(dev);
INIT_LIST_HEAD(&dev->filelist);
INIT_LIST_HEAD(&dev->filelist_internal);
INIT_LIST_HEAD(&dev->clientlist);
- INIT_LIST_HEAD(&dev->ctxlist);
- INIT_LIST_HEAD(&dev->vmalist);
- INIT_LIST_HEAD(&dev->maplist);
INIT_LIST_HEAD(&dev->vblank_event_list);
- spin_lock_init(&dev->buf_lock);
spin_lock_init(&dev->event_lock);
mutex_init(&dev->struct_mutex);
mutex_init(&dev->filelist_mutex);
mutex_init(&dev->clientlist_mutex);
- mutex_init(&dev->ctxlist_mutex);
mutex_init(&dev->master_mutex);
- dev->anon_inode = drm_fs_inode_new();
- if (IS_ERR(dev->anon_inode)) {
- ret = PTR_ERR(dev->anon_inode);
+ ret = drmm_add_action_or_reset(dev, drm_dev_init_release, NULL);
+ if (ret)
+ return ret;
+
+ inode = drm_fs_inode_new();
+ if (IS_ERR(inode)) {
+ ret = PTR_ERR(inode);
DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret);
- goto err_free;
+ goto err;
}
+
+ dev->anon_inode = inode;
if (drm_core_check_feature(dev, DRIVER_RENDER)) {
ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
if (ret)
- goto err_minors;
+ goto err;
}
ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY);
if (ret)
- goto err_minors;
+ goto err;
- ret = drm_ht_create(&dev->map_hash, 12);
+ ret = drm_legacy_create_map_hash(dev);
if (ret)
- goto err_minors;
+ goto err;
drm_legacy_ctxbitmap_init(dev);
@@ -567,94 +643,75 @@
ret = drm_gem_init(dev);
if (ret) {
DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
- goto err_ctxbitmap;
+ goto err;
}
}
- /* Use the parent device name as DRM device unique identifier, but fall
- * back to the driver name for virtual devices like vgem. */
- ret = drm_dev_set_unique(dev, parent ? dev_name(parent) : driver->name);
+ ret = drm_dev_set_unique(dev, dev_name(parent));
if (ret)
- goto err_setunique;
+ goto err;
return 0;
-err_setunique:
- if (drm_core_check_feature(dev, DRIVER_GEM))
- drm_gem_destroy(dev);
-err_ctxbitmap:
- drm_legacy_ctxbitmap_cleanup(dev);
- drm_ht_remove(&dev->map_hash);
-err_minors:
- drm_minor_free(dev, DRM_MINOR_PRIMARY);
- drm_minor_free(dev, DRM_MINOR_RENDER);
- drm_fs_inode_free(dev->anon_inode);
-err_free:
- put_device(dev->dev);
- mutex_destroy(&dev->master_mutex);
- mutex_destroy(&dev->ctxlist_mutex);
- mutex_destroy(&dev->clientlist_mutex);
- mutex_destroy(&dev->filelist_mutex);
- mutex_destroy(&dev->struct_mutex);
+err:
+ drm_managed_release(dev);
+
return ret;
}
-EXPORT_SYMBOL(drm_dev_init);
-/**
- * drm_dev_fini - Finalize a dead DRM device
- * @dev: DRM device
- *
- * Finalize a dead DRM device. This is the converse to drm_dev_init() and
- * frees up all data allocated by it. All driver private data should be
- * finalized first. Note that this function does not free the @dev, that is
- * left to the caller.
- *
- * The ref-count of @dev must be zero, and drm_dev_fini() should only be called
- * from a &drm_driver.release callback.
- */
-void drm_dev_fini(struct drm_device *dev)
+static void devm_drm_dev_init_release(void *data)
{
- drm_vblank_cleanup(dev);
-
- if (drm_core_check_feature(dev, DRIVER_GEM))
- drm_gem_destroy(dev);
-
- drm_legacy_ctxbitmap_cleanup(dev);
- drm_ht_remove(&dev->map_hash);
- drm_fs_inode_free(dev->anon_inode);
-
- drm_minor_free(dev, DRM_MINOR_PRIMARY);
- drm_minor_free(dev, DRM_MINOR_RENDER);
-
- put_device(dev->dev);
-
- mutex_destroy(&dev->master_mutex);
- mutex_destroy(&dev->ctxlist_mutex);
- mutex_destroy(&dev->clientlist_mutex);
- mutex_destroy(&dev->filelist_mutex);
- mutex_destroy(&dev->struct_mutex);
- kfree(dev->unique);
+ drm_dev_put(data);
}
-EXPORT_SYMBOL(drm_dev_fini);
+
+static int devm_drm_dev_init(struct device *parent,
+ struct drm_device *dev,
+ struct drm_driver *driver)
+{
+ int ret;
+
+ ret = drm_dev_init(dev, driver, parent);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action(parent, devm_drm_dev_init_release, dev);
+ if (ret)
+ devm_drm_dev_init_release(dev);
+
+ return ret;
+}
+
+void *__devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver,
+ size_t size, size_t offset)
+{
+ void *container;
+ struct drm_device *drm;
+ int ret;
+
+ container = kzalloc(size, GFP_KERNEL);
+ if (!container)
+ return ERR_PTR(-ENOMEM);
+
+ drm = container + offset;
+ ret = devm_drm_dev_init(parent, drm, driver);
+ if (ret) {
+ kfree(container);
+ return ERR_PTR(ret);
+ }
+ drmm_add_final_kfree(drm, container);
+
+ return container;
+}
+EXPORT_SYMBOL(__devm_drm_dev_alloc);
/**
* drm_dev_alloc - Allocate new DRM device
* @driver: DRM driver to allocate device for
* @parent: Parent device object
*
- * Allocate and initialize a new DRM device. No device registration is done.
- * Call drm_dev_register() to advertice the device to user space and register it
- * with other core subsystems. This should be done last in the device
- * initialization sequence to make sure userspace can't access an inconsistent
- * state.
- *
- * The initial ref-count of the object is 1. Use drm_dev_get() and
- * drm_dev_put() to take and drop further ref-counts.
- *
- * Note that for purely virtual devices @parent can be NULL.
- *
- * Drivers that wish to subclass or embed &struct drm_device into their
- * own struct should look at using drm_dev_init() instead.
+ * This is the deprecated version of devm_drm_dev_alloc(), which does not support
+ * subclassing through embedding the struct &drm_device in a driver private
+ * structure, and which does not support automatic cleanup through devres.
*
* RETURNS:
* Pointer to new DRM device, or ERR_PTR on failure.
@@ -675,6 +732,8 @@
return ERR_PTR(ret);
}
+ drmm_add_final_kfree(dev, dev);
+
return dev;
}
EXPORT_SYMBOL(drm_dev_alloc);
@@ -683,12 +742,12 @@
{
struct drm_device *dev = container_of(ref, struct drm_device, ref);
- if (dev->driver->release) {
+ if (dev->driver->release)
dev->driver->release(dev);
- } else {
- drm_dev_fini(dev);
- kfree(dev);
- }
+
+ drm_managed_release(dev);
+
+ kfree(dev->managed.final_kfree);
}
/**
@@ -723,19 +782,6 @@
kref_put(&dev->ref, drm_dev_release);
}
EXPORT_SYMBOL(drm_dev_put);
-
-/**
- * drm_dev_unref - Drop reference of a DRM device
- * @dev: device to drop reference of or NULL
- *
- * This is a compatibility alias for drm_dev_put() and should not be used by new
- * code.
- */
-void drm_dev_unref(struct drm_device *dev)
-{
- drm_dev_put(dev);
-}
-EXPORT_SYMBOL(drm_dev_unref);
static int create_compat_control_link(struct drm_device *dev)
{
@@ -799,7 +845,7 @@
* @flags: Flags passed to the driver's .load() function
*
* Register the DRM device @dev with the system, advertise device to user-space
- * and start normal device operation. @dev must be allocated via drm_dev_alloc()
+ * and start normal device operation. @dev must be initialized via drm_dev_init()
* previously.
*
* Never call this twice on any device!
@@ -818,7 +864,13 @@
struct drm_driver *driver = dev->driver;
int ret;
- mutex_lock(&drm_global_mutex);
+ if (!driver->load)
+ drm_mode_config_validate(dev);
+
+ WARN_ON(!dev->managed.final_kfree);
+
+ if (drm_dev_needs_global_mutex(dev))
+ mutex_lock(&drm_global_mutex);
ret = drm_minor_register(dev, DRM_MINOR_RENDER);
if (ret)
@@ -858,7 +910,8 @@
drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
drm_minor_unregister(dev, DRM_MINOR_RENDER);
out_unlock:
- mutex_unlock(&drm_global_mutex);
+ if (drm_dev_needs_global_mutex(dev))
+ mutex_unlock(&drm_global_mutex);
return ret;
}
EXPORT_SYMBOL(drm_dev_register);
@@ -879,8 +932,6 @@
*/
void drm_dev_unregister(struct drm_device *dev)
{
- struct drm_map_list *r_list, *list_temp;
-
if (drm_core_check_feature(dev, DRIVER_LEGACY))
drm_lastclose(dev);
@@ -897,8 +948,7 @@
if (dev->agp)
drm_pci_agp_destroy(dev);
- list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
- drm_legacy_rmmap(dev, r_list->map);
+ drm_legacy_rmmaps(dev);
remove_compat_control_link(dev);
drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
@@ -911,16 +961,16 @@
* @dev: device of which to set the unique name
* @name: unique name
*
- * Sets the unique name of a DRM device using the specified string. Drivers
- * can use this at driver probe time if the unique name of the devices they
- * drive is static.
+ * Sets the unique name of a DRM device using the specified string. This is
+ * already done by drm_dev_init(), drivers should only override the default
+ * unique name for backwards compatibility reasons.
*
* Return: 0 on success or a negative error code on failure.
*/
int drm_dev_set_unique(struct drm_device *dev, const char *name)
{
- kfree(dev->unique);
- dev->unique = kstrdup(name, GFP_KERNEL);
+ drmm_kfree(dev, dev->unique);
+ dev->unique = drmm_kstrdup(dev, name, GFP_KERNEL);
return dev->unique ? 0 : -ENOMEM;
}
@@ -954,17 +1004,14 @@
DRM_DEBUG("\n");
- mutex_lock(&drm_global_mutex);
minor = drm_minor_acquire(iminor(inode));
- if (IS_ERR(minor)) {
- err = PTR_ERR(minor);
- goto out_unlock;
- }
+ if (IS_ERR(minor))
+ return PTR_ERR(minor);
new_fops = fops_get(minor->dev->driver->fops);
if (!new_fops) {
err = -ENODEV;
- goto out_release;
+ goto out;
}
replace_fops(filp, new_fops);
@@ -973,10 +1020,9 @@
else
err = 0;
-out_release:
+out:
drm_minor_release(minor);
-out_unlock:
- mutex_unlock(&drm_global_mutex);
+
return err;
}
@@ -993,14 +1039,12 @@
drm_sysfs_destroy();
idr_destroy(&drm_minors_idr);
drm_connector_ida_destroy();
- drm_global_release();
}
static int __init drm_core_init(void)
{
int ret;
- drm_global_init();
drm_connector_ida_init();
idr_init(&drm_minors_idr);
@@ -1011,11 +1055,6 @@
}
drm_debugfs_root = debugfs_create_dir("dri", NULL);
- if (!drm_debugfs_root) {
- ret = -ENOMEM;
- DRM_ERROR("Cannot create debugfs-root: %d\n", ret);
- goto error;
- }
ret = register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops);
if (ret < 0)
@@ -1031,8 +1070,8 @@
return ret;
}
-#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
-subsys_initcall(drm_core_init);
+#ifdef CONFIG_VIDEO_REVERSE_IMAGE
+fs_initcall(drm_core_init);
#else
module_init(drm_core_init);
#endif
--
Gitblit v1.6.2