summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_drv.c')
-rw-r--r--drivers/gpu/drm/drm_drv.c66
1 files changed, 32 insertions, 34 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index c760dc0f814a..0feaaf74abc3 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -55,7 +55,7 @@ MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl");
MODULE_DESCRIPTION("DRM shared core routines");
MODULE_LICENSE("GPL and additional rights");
-static DEFINE_XARRAY_ALLOC(drm_minors_xa);
+DEFINE_XARRAY_ALLOC(drm_minors_xa);
/*
* If the drm core fails to init for whatever reason,
@@ -83,6 +83,18 @@ DEFINE_STATIC_SRCU(drm_unplug_srcu);
* registered and unregistered dynamically according to device-state.
*/
+static struct xarray *drm_minor_get_xa(enum drm_minor_type type)
+{
+ if (type == DRM_MINOR_PRIMARY || type == DRM_MINOR_RENDER)
+ return &drm_minors_xa;
+#if IS_ENABLED(CONFIG_DRM_ACCEL)
+ else if (type == DRM_MINOR_ACCEL)
+ return &accel_minors_xa;
+#endif
+ else
+ return ERR_PTR(-EOPNOTSUPP);
+}
+
static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
enum drm_minor_type type)
{
@@ -106,18 +118,18 @@ static void drm_minor_alloc_release(struct drm_device *dev, void *data)
put_device(minor->kdev);
- if (minor->type == DRM_MINOR_ACCEL)
- accel_minor_remove(minor->index);
- else
- xa_erase(&drm_minors_xa, minor->index);
+ xa_erase(drm_minor_get_xa(minor->type), minor->index);
}
-#define DRM_MINOR_LIMIT(t) ({ typeof(t) _t = (t); XA_LIMIT(64 * _t, 64 * _t + 63); })
+#define DRM_MINOR_LIMIT(t) ({ \
+ typeof(t) _t = (t); \
+ _t == DRM_MINOR_ACCEL ? XA_LIMIT(0, ACCEL_MAX_MINORS) : XA_LIMIT(64 * _t, 64 * _t + 63); \
+})
static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type)
{
struct drm_minor *minor;
- int index, r;
+ int r;
minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
if (!minor)
@@ -126,18 +138,11 @@ static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type)
minor->type = type;
minor->dev = dev;
- if (type == DRM_MINOR_ACCEL) {
- r = accel_minor_alloc();
- index = r;
- } else {
- r = xa_alloc(&drm_minors_xa, &index, NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL);
- }
-
+ r = xa_alloc(drm_minor_get_xa(type), &minor->index,
+ NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL);
if (r < 0)
return r;
- minor->index = index;
-
r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor);
if (r)
return r;
@@ -176,16 +181,12 @@ static int drm_minor_register(struct drm_device *dev, enum drm_minor_type type)
goto err_debugfs;
/* replace NULL with @minor so lookups will succeed from now on */
- if (minor->type == DRM_MINOR_ACCEL) {
- accel_minor_replace(minor, minor->index);
- } else {
- entry = xa_store(&drm_minors_xa, minor->index, minor, GFP_KERNEL);
- if (xa_is_err(entry)) {
- ret = xa_err(entry);
- goto err_debugfs;
- }
- WARN_ON(entry);
+ entry = xa_store(drm_minor_get_xa(type), minor->index, minor, GFP_KERNEL);
+ if (xa_is_err(entry)) {
+ ret = xa_err(entry);
+ goto err_debugfs;
}
+ WARN_ON(entry);
DRM_DEBUG("new minor registered %d\n", minor->index);
return 0;
@@ -204,10 +205,7 @@ static void drm_minor_unregister(struct drm_device *dev, enum drm_minor_type typ
return;
/* replace @minor with NULL so lookups will fail from now on */
- if (minor->type == DRM_MINOR_ACCEL)
- accel_minor_replace(NULL, minor->index);
- else
- xa_store(&drm_minors_xa, minor->index, NULL, GFP_KERNEL);
+ xa_store(drm_minor_get_xa(type), minor->index, NULL, GFP_KERNEL);
device_del(minor->kdev);
dev_set_drvdata(minor->kdev, NULL); /* safety belt */
@@ -223,15 +221,15 @@ static void drm_minor_unregister(struct drm_device *dev, enum drm_minor_type typ
* minor->dev pointer will stay valid! However, the device may get unplugged and
* unregistered while you hold the minor.
*/
-struct drm_minor *drm_minor_acquire(unsigned int minor_id)
+struct drm_minor *drm_minor_acquire(struct xarray *minor_xa, unsigned int minor_id)
{
struct drm_minor *minor;
- xa_lock(&drm_minors_xa);
- minor = xa_load(&drm_minors_xa, minor_id);
+ xa_lock(minor_xa);
+ minor = xa_load(minor_xa, minor_id);
if (minor)
drm_dev_get(minor->dev);
- xa_unlock(&drm_minors_xa);
+ xa_unlock(minor_xa);
if (!minor) {
return ERR_PTR(-ENODEV);
@@ -1024,7 +1022,7 @@ static int drm_stub_open(struct inode *inode, struct file *filp)
DRM_DEBUG("\n");
- minor = drm_minor_acquire(iminor(inode));
+ minor = drm_minor_acquire(&drm_minors_xa, iminor(inode));
if (IS_ERR(minor))
return PTR_ERR(minor);