DRM Internals¶
This chapter documents DRM internals relevant to driver authors and developers working to add support for the latest features to existing drivers.
First, we go over some typical driver initialization requirements, like setting up command buffers, creating an initial output configuration, and initializing core services. Subsequent sections cover core internals in more detail, providing implementation notes and examples.
The DRM layer provides several services to graphics drivers, many of them driven by the application interfaces it provides through libdrm, the library that wraps most of the DRM ioctls. These include vblank event handling, memory management, output management, framebuffer management, command submission & fencing, suspend/resume support, and DMA services.
Driver Initialization¶
At the core of every DRM driver is a struct drm_driver structure. Drivers typically statically initialize
a drm_driver structure, and then pass it to
drm_dev_alloc() to allocate a device instance. After the
device instance is fully initialized it can be registered (which makes
it accessible from userspace) using drm_dev_register().
The struct drm_driver structure
contains static information that describes the driver and features it
supports, and pointers to methods that the DRM core will call to
implement the DRM API. We will first go through the struct
drm_driver static information fields, and will
then describe individual operations in details as they get used in later
sections.
Driver Information¶
Major, Minor and Patchlevel¶
int major; int minor; int patchlevel; The DRM core identifies driver versions by a major, minor and patch level triplet. The information is printed to the kernel log at initialization time and passed to userspace through the DRM_IOCTL_VERSION ioctl.
The major and minor numbers are also used to verify the requested driver API version passed to DRM_IOCTL_SET_VERSION. When the driver API changes between minor versions, applications can call DRM_IOCTL_SET_VERSION to select a specific version of the API. If the requested major isn’t equal to the driver major, or the requested minor is larger than the driver minor, the DRM_IOCTL_SET_VERSION call will return an error. Otherwise the driver’s set_version() method will be called with the requested version.
Name, Description and Date¶
char *name; char *desc; char *date; The driver name is printed to the kernel log at initialization time, used for IRQ registration and passed to userspace through DRM_IOCTL_VERSION.
The driver description is a purely informative string passed to userspace through the DRM_IOCTL_VERSION ioctl and otherwise unused by the kernel.
The driver date, formatted as YYYYMMDD, is meant to identify the date of the latest modification to the driver. However, as most drivers fail to update it, its value is mostly useless. The DRM core prints it to the kernel log at initialization time and passes it to userspace through the DRM_IOCTL_VERSION ioctl.
Managing Ownership of the Framebuffer Aperture¶
Error
kernel-doc missing
Error
kernel-doc missing
Error
kernel-doc missing
Device Instance and Driver Handling¶
A device instance for a drm driver is represented by struct drm_device. This
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 initializing device instances using
bus-specific helpers and the drm_driver.load callback. But due to
backwards-compatibility needs the device instance have to be published too
early, which requires unpretty global locking to make safe and is therefore
only support for existing drivers not yet converted to the new scheme.
When cleaning up a device instance everything needs to be done in reverse:
First unpublish the device instance with drm_dev_unregister(). Then clean up
any other resources allocated at device initialization and drop the driver’s
reference to drm_device using drm_dev_put().
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.
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().
struct driver_device {
struct drm_device drm;
void *userspace_facing;
struct clk *pclk;
};
static const 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_{...}_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,
possibly leaving the hardware enabled.
-
struct
drm_wedge_task_info¶ information about the guilty task of a wedge dev
Definition
struct drm_wedge_task_info {
pid_t pid;
char comm[TASK_COMM_LEN];
};
Members
pidpid of the task
commcommand name of the task
-
enum
switch_power_state¶ power state of drm device
Constants
DRM_SWITCH_POWER_ONPower state is ON
DRM_SWITCH_POWER_OFFPower state is OFF
DRM_SWITCH_POWER_CHANGINGPower state is changing
DRM_SWITCH_POWER_DYNAMIC_OFFSuspended
-
struct
drm_device¶ DRM device structure
Definition
struct drm_device {
int if_version;
struct kref ref;
struct device *dev;
struct device *dma_dev;
struct {
struct list_head resources;
void *final_kfree;
spinlock_t lock;
} managed;
const struct drm_driver *driver;
void *dev_private;
struct drm_minor *primary;
struct drm_minor *render;
struct drm_minor *accel;
bool registered;
struct drm_master *master;
u32 driver_features;
bool unplugged;
struct inode *anon_inode;
char *unique;
struct mutex master_mutex;
atomic_t open_count;
struct mutex filelist_mutex;
struct list_head filelist;
struct list_head filelist_internal;
struct mutex clientlist_mutex;
struct list_head clientlist;
bool vblank_disable_immediate;
struct drm_vblank_crtc *vblank;
spinlock_t vblank_time_lock;
spinlock_t vbl_lock;
u32 max_vblank_count;
struct list_head vblank_event_list;
spinlock_t event_lock;
unsigned int num_crtcs;
struct drm_mode_config mode_config;
struct mutex object_name_lock;
struct idr object_name_idr;
struct drm_vma_offset_manager *vma_offset_manager;
struct drm_vram_mm *vram_mm;
enum switch_power_state switch_power_state;
struct drm_fb_helper *fb_helper;
struct dentry *debugfs_root;
};
Members
if_versionHighest interface version set
refObject ref-count
devDevice structure of bus-device
dma_devDevice for DMA operations. Only required if the device dev cannot perform DMA by itself. Should be NULL otherwise. Call
drm_dev_dma_dev()to get the DMA device instead of using this field directly. Calldrm_dev_set_dma_dev()to set this field.DRM devices are sometimes bound to virtual devices that cannot perform DMA by themselves. Drivers should set this field to the respective DMA controller.
Devices on USB and other peripheral busses also cannot perform DMA by themselves. The dma_dev field should point the bus controller that does DMA on behalve of such a device. Required for importing buffers via dma-buf.
If set, the DRM core automatically releases the reference on the device.
managedManaged resources linked to the lifetime of this
drm_deviceas tracked by ref.driverDRM driver managing the device
dev_privateDRM driver private data. This is deprecated and should be left set to NULL.
Instead of using this pointer it is recommended that drivers use
devm_drm_dev_alloc()and embed structdrm_devicein their larger per-device structure.primaryPrimary node. Drivers should not interact with this directly. debugfs interfaces can be registered with
drm_debugfs_add_file(), and sysfs should be directly added on the hardware (and not character device node)struct devicedev.renderRender node. Drivers should not interact with this directly ever. Drivers should not expose any additional interfaces in debugfs or sysfs on this node.
accelCompute Acceleration node
registeredInternally used by
drm_dev_register()anddrm_connector_register().masterCurrently active master for this device. Protected by
master_mutexdriver_featuresper-device driver features
Drivers can clear specific flags here to disallow certain features on a per-device basis while still sharing a single
struct drm_driverinstance across all devices.unpluggedFlag to tell if the device has been unplugged. See
drm_dev_enter()anddrm_dev_is_unplugged().anon_inodeinode for private address-space
uniqueUnique name of the device
master_mutexLock for
drm_minor.masteranddrm_file.is_masteropen_countUsage counter for outstanding files open, protected by drm_global_mutex
filelist_mutexProtects filelist.
filelistList of userspace clients, linked through
drm_file.lhead.filelist_internalList of open DRM files for in-kernel clients. Protected by
filelist_mutex.clientlist_mutexProtects
clientlistaccess.clientlistList of in-kernel clients. Protected by
clientlist_mutex.vblank_disable_immediateIf true, vblank interrupt will be disabled immediately when the refcount drops to zero, as opposed to via the vblank disable timer.
This can be set to true it the hardware has a working vblank counter with high-precision timestamping (otherwise there are races) and the driver uses
drm_crtc_vblank_on()anddrm_crtc_vblank_off()appropriately. Also, see max_vblank_count,drm_crtc_funcs.get_vblank_counteranddrm_vblank_crtc_config.disable_immediate.vblankArray of vblank tracking structures, one per
struct drm_crtc. For historical reasons (vblank support predates kernel modesetting) this is free-standing and not part ofstruct drm_crtcitself. It must be initialized explicitly by callingdrm_vblank_init().vblank_time_lockProtects vblank count and time updates during vblank enable/disable
vbl_lockTop-level vblank references lock, wraps the low-level vblank_time_lock.
max_vblank_countMaximum value of the vblank registers. This value +1 will result in a wrap-around of the vblank register. It is used by the vblank core to handle wrap-arounds.
If set to zero the vblank core will try to guess the elapsed vblanks between times when the vblank interrupt is disabled through high-precision timestamps. That approach is suffering from small races and imprecision over longer time periods, hence exposing a hardware vblank counter is always recommended.
This is the statically configured device wide maximum. The driver can instead choose to use a runtime configurable per-crtc value
drm_vblank_crtc.max_vblank_count, in which case max_vblank_count must be left at zero. Seedrm_crtc_set_max_vblank_count()on how to use the per-crtc value.If non-zero,
drm_crtc_funcs.get_vblank_countermust be set.vblank_event_listList of vblank events
event_lockProtects vblank_event_list and event delivery in general. See
drm_send_event()anddrm_send_event_locked().num_crtcsNumber of CRTCs on this device
mode_configCurrent mode config
object_name_lockGEM information
object_name_idrGEM information
vma_offset_managerGEM information
vram_mmVRAM MM memory manager
switch_power_statePower state of the client. Used by drivers supporting the switcheroo driver. The state is maintained in the
vga_switcheroo_client_ops.set_gpu_statecallbackfb_helperPointer to the fbdev emulation structure. Set by
drm_fb_helper_init()and cleared bydrm_fb_helper_fini().debugfs_rootRoot directory for debugfs files.
Description
This structure represent a complete card that may contain multiple heads.
-
struct device *
drm_dev_dma_dev(struct drm_device *dev)¶ returns the DMA device for a DRM device
Parameters
struct drm_device *devDRM device
Description
Returns the DMA device of the given DRM device. By default, this
the DRM device’s parent. See drm_dev_set_dma_dev().
Return
A DMA-capable device for the DRM device.
-
enum
drm_driver_feature¶ feature flags
Constants
DRIVER_GEMDriver use the GEM memory manager. This should be set for all modern drivers.
DRIVER_MODESETDriver supports mode setting interfaces (KMS).
DRIVER_RENDERDriver supports dedicated render nodes. See also the section on render nodes for details.
DRIVER_ATOMICDriver supports the full atomic modesetting userspace API. Drivers which only use atomic internally, but do not support the full userspace API (e.g. not all properties converted to atomic, or multi-plane updates are not guaranteed to be tear-free) should not set this flag.
DRIVER_SYNCOBJDriver supports
drm_syncobjfor explicit synchronization of command submission.DRIVER_SYNCOBJ_TIMELINEDriver supports the timeline flavor of
drm_syncobjfor explicit synchronization of command submission.DRIVER_COMPUTE_ACCELDriver supports compute acceleration devices. This flag is mutually exclusive with DRIVER_RENDER and DRIVER_MODESET. Devices that support both graphics and compute acceleration should be handled by two drivers that are connected using auxiliary bus.
DRIVER_GEM_GPUVADriver supports user defined GPU VA bindings for GEM objects.
DRIVER_CURSOR_HOTSPOTDriver supports and requires cursor hotspot information in the cursor plane (e.g. cursor plane has to actually track the mouse cursor and the clients are required to set hotspot in order for the cursor planes to work correctly).
DRIVER_USE_AGPSet up DRM AGP support, see drm_agp_init(), the DRM core will manage AGP resources. New drivers don’t need this.
DRIVER_LEGACYDenote a legacy driver using shadow attach. Do not use.
DRIVER_PCI_DMADriver is capable of PCI DMA, mapping of PCI DMA buffers to userspace will be enabled. Only for legacy drivers. Do not use.
DRIVER_SGDriver can perform scatter/gather DMA, allocation and mapping of scatter/gather buffers will be enabled. Only for legacy drivers. Do not use.
DRIVER_HAVE_DMADriver supports DMA, the userspace DMA API will be supported. Only for legacy drivers. Do not use.
DRIVER_HAVE_IRQLegacy irq support. Only for legacy drivers. Do not use.
Description
See drm_driver.driver_features, drm_device.driver_features and
drm_core_check_feature().
-
struct
drm_driver¶ DRM driver structure
Definition
struct drm_driver {
int (*load) (struct drm_device *, unsigned long flags);
int (*open) (struct drm_device *, struct drm_file *);
void (*postclose) (struct drm_device *, struct drm_file *);
void (*unload) (struct drm_device *);
void (*release) (struct drm_device *);
void (*master_set)(struct drm_device *dev, struct drm_file *file_priv, bool from_open);
void (*master_drop)(struct drm_device *dev, struct drm_file *file_priv);
void (*debugfs_init)(struct drm_minor *minor);
struct drm_gem_object *(*gem_create_object)(struct drm_device *dev, size_t size);
int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv, uint32_t handle, uint32_t flags, int *prime_fd);
int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv, int prime_fd, uint32_t *handle);
struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev, struct dma_buf *dma_buf);
struct drm_gem_object *(*gem_prime_import_sg_table)(struct drm_device *dev,struct dma_buf_attachment *attach, struct sg_table *sgt);
int (*dumb_create)(struct drm_file *file_priv,struct drm_device *dev, struct drm_mode_create_dumb *args);
int (*dumb_map_offset)(struct drm_file *file_priv,struct drm_device *dev, uint32_t handle, uint64_t *offset);
int (*fbdev_probe)(struct drm_fb_helper *fbdev_helper, struct drm_fb_helper_surface_size *sizes);
void (*show_fdinfo)(struct drm_printer *p, struct drm_file *f);
int major;
int minor;
int patchlevel;
char *name;
char *desc;
u32 driver_features;
const struct drm_ioctl_desc *ioctls;
int num_ioctls;
const struct file_operations *fops;
};
Members
loadBackward-compatible driver callback to complete initialization steps after the driver is registered. For this reason, may suffer from race conditions and its use is deprecated for new drivers. It is therefore only supported for existing drivers not yet converted to the new scheme. See
devm_drm_dev_alloc()anddrm_dev_register()for proper and race-free way to set up astruct drm_device.This is deprecated, do not use!
Returns:
Zero on success, non-zero value on failure.
openDriver callback when a new
struct drm_fileis opened. Useful for setting up driver-private data structures like buffer allocators, execution contexts or similar things. Such driver-private resources must be released again in postclose.Since the display/modeset side of DRM can only be owned by exactly one
struct drm_file(seedrm_file.is_masteranddrm_device.master) there should never be a need to set up any modeset related resources in this callback. Doing so would be a driver design bug.Returns:
0 on success, a negative error code on failure, which will be promoted to userspace as the result of the open() system call.
postcloseOne of the driver callbacks when a new
struct drm_fileis closed. Useful for tearing down driver-private data structures allocated in open like buffer allocators, execution contexts or similar things.Since the display/modeset side of DRM can only be owned by exactly one
struct drm_file(seedrm_file.is_masteranddrm_device.master) there should never be a need to tear down any modeset related resources in this callback. Doing so would be a driver design bug.unloadReverse the effects of the driver load callback. Ideally, the clean up performed by the driver should happen in the reverse order of the initialization. Similarly to the load hook, this handler is deprecated and its usage should be dropped in favor of an open-coded teardown function at the driver layer. See
drm_dev_unregister()anddrm_dev_put()for the proper way to remove astruct drm_device.The unload() hook is called right after unregistering the device.
releaseOptional callback for destroying device data after the final reference is released, i.e. the device is being destroyed.
This is deprecated, clean up all memory allocations associated with a
drm_deviceusingdrmm_add_action(),drmm_kmalloc()and related managed resources functions.master_setCalled whenever the minor master is set. Only used by vmwgfx.
master_dropCalled whenever the minor master is dropped. Only used by vmwgfx.
debugfs_initAllows drivers to create driver-specific debugfs files.
gem_create_objectconstructor for gem objects
Hook for allocating the GEM object struct, for use by the CMA and SHMEM GEM helpers. Returns a GEM object on success, or an ERR_PTR()-encoded error code otherwise.
prime_handle_to_fdPRIME export function. Only used by vmwgfx.
prime_fd_to_handlePRIME import function. Only used by vmwgfx.
gem_prime_importImport hook for GEM drivers.
This defaults to
drm_gem_prime_import()if not set.gem_prime_import_sg_tableOptional hook used by the PRIME helper functions
drm_gem_prime_import()respectivelydrm_gem_prime_import_dev().dumb_createThis creates a new dumb buffer in the driver’s backing storage manager (GEM, TTM or something else entirely) and returns the resulting buffer handle. This handle can then be wrapped up into a framebuffer modeset object.
Note that userspace is not allowed to use such objects for render acceleration - drivers must create their own private ioctls for such a use case.
Width, height and depth are specified in the
drm_mode_create_dumbargument. The callback needs to fill the handle, pitch and size for the created buffer.Called by the user via ioctl.
Returns:
Zero on success, negative errno on failure.
dumb_map_offsetAllocate an offset in the drm device node’s address space to be able to memory map a dumb buffer.
The default implementation is
drm_gem_create_mmap_offset(). GEM based drivers must not overwrite this.Called by the user via ioctl.
Returns:
Zero on success, negative errno on failure.
fbdev_probeAllocates and initialize the fb_info structure for fbdev emulation. Furthermore it also needs to allocate the DRM framebuffer used to back the fbdev.
This callback is mandatory for fbdev support.
Returns:
0 on success ot a negative error code otherwise.
show_fdinfoPrint device specific fdinfo. See Documentation/gpu/drm-usage-stats.rst.
majordriver major number
minordriver minor number
patchleveldriver patch level
namedriver name
descdriver description
driver_featuresDriver features, see
enum drm_driver_feature. Drivers can disable some features on a per-instance basis usingdrm_device.driver_features.ioctlsArray of driver-private IOCTL description entries. See the chapter on IOCTL support in the userland interfaces chapter for the full details.
num_ioctlsNumber of entries in ioctls.
fopsFile operations for the DRM device node. See the discussion in file operations for in-depth coverage and some examples.
Description
This structure represent the common code for a family of cards. There will be
one struct drm_device for each card present in this family. It contains lots
of vfunc entries, and a pile of those probably should be moved to more
appropriate places like drm_mode_config_funcs or into a new operations
structure for GEM drivers.
-
devm_drm_dev_alloc¶
devm_drm_dev_alloc (parent, driver, type, member)
Resource managed allocation of a
drm_deviceinstance
Parameters
parentParent device object
driverDRM driver
typethe type of the struct which contains struct
drm_devicememberthe name of the
drm_devicewithin type.
Description
This allocates 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.
It is recommended that drivers embed struct drm_device into their own device
structure.
Note that this manages the lifetime of the resulting drm_device
automatically using devres. The DRM device initialized with this function is
automatically put on driver detach using drm_dev_put().
Return
Pointer to new DRM device, or ERR_PTR on failure.
-
bool
drm_dev_is_unplugged(struct drm_device *dev)¶ is a DRM device unplugged
Parameters
struct drm_device *devDRM device
Description
This function can be called to check whether a hotpluggable is unplugged.
Unplugging itself is singalled through drm_dev_unplug(). If a device is
unplugged, these two functions guarantee that any store before calling
drm_dev_unplug() is visible to callers of this function after it completes
WARNING: This function fundamentally races against drm_dev_unplug(). It is
recommended that drivers instead use the underlying drm_dev_enter() and
drm_dev_exit() function pairs.
-
bool
drm_core_check_all_features(const struct drm_device *dev, u32 features)¶ check driver feature flags mask
Parameters
const struct drm_device *devDRM device to check
u32 featuresfeature flag(s) mask
Description
This checks dev for driver features, see drm_driver.driver_features,
drm_device.driver_features, and the various enum drm_driver_feature flags.
Returns true if all features in the features mask are supported, false otherwise.
-
bool
drm_core_check_feature(const struct drm_device *dev, enum drm_driver_feature feature)¶ check driver feature flags
Parameters
const struct drm_device *devDRM device to check
enum drm_driver_feature featurefeature flag
Description
This checks dev for driver features, see drm_driver.driver_features,
drm_device.driver_features, and the various enum drm_driver_feature flags.
Returns true if the feature is supported, false otherwise.
-
bool
drm_drv_uses_atomic_modeset(struct drm_device *dev)¶ check if the driver implements atomic_commit()
Parameters
struct drm_device *devDRM device
Description
This check is useful if drivers do not have DRIVER_ATOMIC set but have atomic modesetting internally implemented.
-
void
drm_put_dev(struct drm_device *dev)¶ Unregister and release a DRM device
Parameters
struct drm_device *devDRM device
Description
Called at module unload time or when a PCI device is unplugged.
Cleans up all DRM device, calling drm_lastclose().
Note
Use of this function is deprecated. It will eventually go away
completely. Please use drm_dev_unregister() and drm_dev_put() explicitly
instead to make sure that the device isn’t userspace accessible any more
while teardown is in progress, ensuring that userspace can’t access an
inconsistent state.
-
bool
drm_dev_enter(struct drm_device *dev, int *idx)¶ Enter device critical section
Parameters
struct drm_device *devDRM device
int *idxPointer to index that will be passed to the matching
drm_dev_exit()
Description
This function marks and protects the beginning of a section that should not
be entered after the device has been unplugged. The section end is marked
with drm_dev_exit(). Calls to this function can be nested.
Return
True if it is OK to enter the section, false otherwise.
-
void
drm_dev_exit(int idx)¶ Exit device critical section
Parameters
int idxindex returned from
drm_dev_enter()
Description
This function marks the end of a section that should not be entered after the device has been unplugged.
-
void
drm_dev_unplug(struct drm_device *dev)