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

pid

pid of the task

comm

command name of the task

enum switch_power_state

power state of drm device

Constants

DRM_SWITCH_POWER_ON

Power state is ON

DRM_SWITCH_POWER_OFF

Power state is OFF

DRM_SWITCH_POWER_CHANGING

Power state is changing

DRM_SWITCH_POWER_DYNAMIC_OFF

Suspended

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_version

Highest interface version set

ref

Object ref-count

dev

Device structure of bus-device

dma_dev

Device 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. Call drm_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.

managed

Managed resources linked to the lifetime of this drm_device as tracked by ref.

driver

DRM driver managing the device

dev_private

DRM 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 struct drm_device in their larger per-device structure.

primary

Primary 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 device dev.

render

Render node. Drivers should not interact with this directly ever. Drivers should not expose any additional interfaces in debugfs or sysfs on this node.

accel

Compute Acceleration node

registered

Internally used by drm_dev_register() and drm_connector_register().

master

Currently active master for this device. Protected by master_mutex

driver_features

per-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_driver instance across all devices.

unplugged

Flag to tell if the device has been unplugged. See drm_dev_enter() and drm_dev_is_unplugged().

anon_inode

inode for private address-space

unique

Unique name of the device

master_mutex

Lock for drm_minor.master and drm_file.is_master

open_count

Usage counter for outstanding files open, protected by drm_global_mutex

filelist_mutex

Protects filelist.

filelist

List of userspace clients, linked through drm_file.lhead.

filelist_internal

List of open DRM files for in-kernel clients. Protected by filelist_mutex.

clientlist_mutex

Protects clientlist access.

clientlist

List of in-kernel clients. Protected by clientlist_mutex.

vblank_disable_immediate

If 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() and drm_crtc_vblank_off() appropriately. Also, see max_vblank_count, drm_crtc_funcs.get_vblank_counter and drm_vblank_crtc_config.disable_immediate.

vblank

Array of vblank tracking structures, one per struct drm_crtc. For historical reasons (vblank support predates kernel modesetting) this is free-standing and not part of struct drm_crtc itself. It must be initialized explicitly by calling drm_vblank_init().

vblank_time_lock

Protects vblank count and time updates during vblank enable/disable

vbl_lock

Top-level vblank references lock, wraps the low-level vblank_time_lock.

max_vblank_count

Maximum 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. See drm_crtc_set_max_vblank_count() on how to use the per-crtc value.

If non-zero, drm_crtc_funcs.get_vblank_counter must be set.

vblank_event_list

List of vblank events

event_lock

Protects vblank_event_list and event delivery in general. See drm_send_event() and drm_send_event_locked().

num_crtcs

Number of CRTCs on this device

mode_config

Current mode config

object_name_lock

GEM information

object_name_idr

GEM information

vma_offset_manager

GEM information

vram_mm

VRAM MM memory manager

switch_power_state

Power state of the client. Used by drivers supporting the switcheroo driver. The state is maintained in the vga_switcheroo_client_ops.set_gpu_state callback

fb_helper

Pointer to the fbdev emulation structure. Set by drm_fb_helper_init() and cleared by drm_fb_helper_fini().

debugfs_root

Root 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 *dev

DRM 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_GEM

Driver use the GEM memory manager. This should be set for all modern drivers.

DRIVER_MODESET

Driver supports mode setting interfaces (KMS).

DRIVER_RENDER

Driver supports dedicated render nodes. See also the section on render nodes for details.

DRIVER_ATOMIC

Driver 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_SYNCOBJ

Driver supports drm_syncobj for explicit synchronization of command submission.

DRIVER_SYNCOBJ_TIMELINE

Driver supports the timeline flavor of drm_syncobj for explicit synchronization of command submission.

DRIVER_COMPUTE_ACCEL

Driver 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_GPUVA

Driver supports user defined GPU VA bindings for GEM objects.

DRIVER_CURSOR_HOTSPOT

Driver 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_AGP

Set up DRM AGP support, see drm_agp_init(), the DRM core will manage AGP resources. New drivers don’t need this.

DRIVER_LEGACY

Denote a legacy driver using shadow attach. Do not use.

DRIVER_PCI_DMA

Driver is capable of PCI DMA, mapping of PCI DMA buffers to userspace will be enabled. Only for legacy drivers. Do not use.

DRIVER_SG

Driver can perform scatter/gather DMA, allocation and mapping of scatter/gather buffers will be enabled. Only for legacy drivers. Do not use.

DRIVER_HAVE_DMA

Driver supports DMA, the userspace DMA API will be supported. Only for legacy drivers. Do not use.

DRIVER_HAVE_IRQ

Legacy 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

load

Backward-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() and drm_dev_register() for proper and race-free way to set up a struct drm_device.

This is deprecated, do not use!

Returns:

Zero on success, non-zero value on failure.

open

Driver callback when a new struct drm_file is 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 (see drm_file.is_master and drm_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.

postclose

One of the driver callbacks when a new struct drm_file is 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 (see drm_file.is_master and drm_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.

unload

Reverse 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() and drm_dev_put() for the proper way to remove a struct drm_device.

The unload() hook is called right after unregistering the device.

release

Optional 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_device using drmm_add_action(), drmm_kmalloc() and related managed resources functions.

master_set

Called whenever the minor master is set. Only used by vmwgfx.

master_drop

Called whenever the minor master is dropped. Only used by vmwgfx.

debugfs_init

Allows drivers to create driver-specific debugfs files.

gem_create_object

constructor 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_fd

PRIME export function. Only used by vmwgfx.

prime_fd_to_handle

PRIME import function. Only used by vmwgfx.

gem_prime_import

Import hook for GEM drivers.

This defaults to drm_gem_prime_import() if not set.

gem_prime_import_sg_table

Optional hook used by the PRIME helper functions drm_gem_prime_import() respectively drm_gem_prime_import_dev().

dumb_create

This 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_dumb argument. 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_offset

Allocate 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_probe

Allocates 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_fdinfo

Print device specific fdinfo. See Documentation/gpu/drm-usage-stats.rst.

major

driver major number

minor

driver minor number

patchlevel

driver patch level

name

driver name

desc

driver description

driver_features

Driver features, see enum drm_driver_feature. Drivers can disable some features on a per-instance basis using drm_device.driver_features.

ioctls

Array of driver-private IOCTL description entries. See the chapter on IOCTL support in the userland interfaces chapter for the full details.

num_ioctls

Number of entries in ioctls.

fops

File 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_device instance

Parameters

parent

Parent device object

driver

DRM driver

type

the type of the struct which contains struct drm_device

member

the name of the drm_device within 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 *dev

DRM 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 *dev

DRM device to check

u32 features

feature 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 *dev

DRM device to check

enum drm_driver_feature feature

feature 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 *dev

DRM 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 *dev

DRM 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 *dev

DRM device

int *idx

Pointer 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 idx

index 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)