diff options
Diffstat (limited to 'drivers/gpu/drm/drm_drv.c')
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 66 |
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); |