diff options
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/drm_atomic_helper.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_ioctl.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_mode_config.c | 111 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_plane.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_drv.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/mediatek/mtk_drm_drv.c | 3 |
11 files changed, 80 insertions, 104 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 583f47f27b36..23767df72615 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1117,7 +1117,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, * vblank wait) in the ->enable boolean. */ old_crtc_state->enable = false; - if (!crtc->state->enable) + if (!crtc->state->active) continue; /* Legacy cursor ioctls are completely unsynced, and userspace diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index e75f62cd8a65..14c58072651b 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -357,7 +357,10 @@ int drm_mode_getcrtc(struct drm_device *dev, drm_modeset_lock_crtc(crtc, crtc->primary); crtc_resp->gamma_size = crtc->gamma_size; - if (crtc->primary->fb) + + if (crtc->primary->state && crtc->primary->state->fb) + crtc_resp->fb_id = crtc->primary->state->fb->base.id; + else if (!crtc->primary->state && crtc->primary->fb) crtc_resp->fb_id = crtc->primary->fb->base.id; else crtc_resp->fb_id = 0; diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index a525751b4559..4a7b3e98d586 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -323,9 +323,8 @@ void drm_minor_release(struct drm_minor *minor) * historical baggage. Hence use the reference counting provided by * drm_dev_ref() and drm_dev_unref() only carefully. * - * Also note that embedding of &drm_device is currently not (yet) supported (but - * it would be easy to add). Drivers can store driver-private data in the - * dev_priv field of &drm_device. + * It is recommended that drivers embed struct &drm_device into their own device + * structure, which is supported through drm_dev_init(). */ /** @@ -462,7 +461,11 @@ static void drm_fs_inode_free(struct inode *inode) * Note that for purely virtual devices @parent can be NULL. * * Drivers that do not want to allocate their own device struct - * embedding struct &drm_device can call drm_dev_alloc() instead. + * 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. * * RETURNS: * 0 on success, or error code on failure. diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index fed22c2b98b6..59b691146033 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -115,11 +115,15 @@ static int drm_getunique(struct drm_device *dev, void *data, struct drm_unique *u = data; struct drm_master *master = file_priv->master; + mutex_lock(&master->dev->master_mutex); if (u->unique_len >= master->unique_len) { - if (copy_to_user(u->unique, master->unique, master->unique_len)) + if (copy_to_user(u->unique, master->unique, master->unique_len)) { + mutex_unlock(&master->dev->master_mutex); return -EFAULT; + } } u->unique_len = master->unique_len; + mutex_unlock(&master->dev->master_mutex); return 0; } @@ -340,6 +344,7 @@ static int drm_setversion(struct drm_device *dev, void *data, struct drm_file *f struct drm_set_version *sv = data; int if_version, retcode = 0; + mutex_lock(&dev->master_mutex); if (sv->drm_di_major != -1) { if (sv->drm_di_major != DRM_IF_MAJOR || sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) { @@ -374,6 +379,7 @@ done: sv->drm_di_minor = DRM_IF_MINOR; sv->drm_dd_major = dev->driver->major; sv->drm_dd_minor = dev->driver->minor; + mutex_unlock(&dev->master_mutex); return retcode; } @@ -528,15 +534,15 @@ EXPORT_SYMBOL(drm_ioctl_permit); static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED|DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), + DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_legacy_getmap_ioctl, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0), - DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), + DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_UNLOCKED | DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), @@ -729,9 +735,8 @@ long drm_ioctl(struct file *filp, if (ksize > in_size) memset(kdata + in_size, 0, ksize - in_size); - /* Enforce sane locking for modern driver ioctls. Core ioctls are - * too messy still. */ - if ((!drm_core_check_feature(dev, DRIVER_LEGACY) && is_driver_ioctl) || + /* Enforce sane locking for modern driver ioctls. */ + if (!drm_core_check_feature(dev, DRIVER_LEGACY) || (ioctl->flags & DRM_UNLOCKED)) retcode = func(dev, kdata, file_priv); else { diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 2735a5847ffa..b1e8bbceaf39 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -84,17 +84,11 @@ int drm_mode_getresources(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_mode_card_res *card_res = data; - struct list_head *lh; struct drm_framebuffer *fb; struct drm_connector *connector; struct drm_crtc *crtc; struct drm_encoder *encoder; - int ret = 0; - int connector_count = 0; - int crtc_count = 0; - int fb_count = 0; - int encoder_count = 0; - int copied = 0; + int count, ret = 0; uint32_t __user *fb_id; uint32_t __user *crtc_id; uint32_t __user *connector_id; @@ -105,89 +99,62 @@ int drm_mode_getresources(struct drm_device *dev, void *data, mutex_lock(&file_priv->fbs_lock); - /* - * For the non-control nodes we need to limit the list of resources - * by IDs in the group list for this node - */ - list_for_each(lh, &file_priv->fbs) - fb_count++; - - /* handle this in 4 parts */ - /* FBs */ - if (card_res->count_fbs >= fb_count) { - copied = 0; - fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr; - list_for_each_entry(fb, &file_priv->fbs, filp_head) { - if (put_user(fb->base.id, fb_id + copied)) { - mutex_unlock(&file_priv->fbs_lock); - return -EFAULT; - } - copied++; + count = 0; + fb_id = u64_to_user_ptr(card_res->fb_id_ptr); + list_for_each_entry(fb, &file_priv->fbs, filp_head) { + if (count < card_res->count_fbs && + put_user(fb->base.id, fb_id + count)) { + mutex_unlock(&file_priv->fbs_lock); + return -EFAULT; } + count++; } - card_res->count_fbs = fb_count; + card_res->count_fbs = count; mutex_unlock(&file_priv->fbs_lock); /* mode_config.mutex protects the connector list against e.g. DP MST * connector hot-adding. CRTC/Plane lists are invariant. */ mutex_lock(&dev->mode_config.mutex); - drm_for_each_crtc(crtc, dev) - crtc_count++; - - drm_for_each_connector(connector, dev) - connector_count++; - - drm_for_each_encoder(encoder, dev) - encoder_count++; - card_res->max_height = dev->mode_config.max_height; card_res->min_height = dev->mode_config.min_height; card_res->max_width = dev->mode_config.max_width; card_res->min_width = dev->mode_config.min_width; - /* CRTCs */ - if (card_res->count_crtcs >= crtc_count) { - copied = 0; - crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr; - drm_for_each_crtc(crtc, dev) { - if (put_user(crtc->base.id, crtc_id + copied)) { - ret = -EFAULT; - goto out; - } - copied++; + count = 0; + crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr); + drm_for_each_crtc(crtc, dev) { + if (count < card_res->count_crtcs && + put_user(crtc->base.id, crtc_id + count)) { + ret = -EFAULT; + goto out; } + count++; } - card_res->count_crtcs = crtc_count; - - /* Encoders */ - if (card_res->count_encoders >= encoder_count) { - copied = 0; - encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr; - drm_for_each_encoder(encoder, dev) { - if (put_user(encoder->base.id, encoder_id + - copied)) { - ret = -EFAULT; - goto out; - } - copied++; + card_res->count_crtcs = count; + + count = 0; + encoder_id = u64_to_user_ptr(card_res->encoder_id_ptr); + drm_for_each_encoder(encoder, dev) { + if (count < card_res->count_encoders && + put_user(encoder->base.id, encoder_id + count)) { + ret = -EFAULT; + goto out; } + count++; } - card_res->count_encoders = encoder_count; - - /* Connectors */ - if (card_res->count_connectors >= connector_count) { - copied = 0; - connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr; - drm_for_each_connector(connector, dev) { - if (put_user(connector->base.id, - connector_id + copied)) { - ret = -EFAULT; - goto out; - } - copied++; + card_res->count_encoders = count; + + count = 0; + connector_id = u64_to_user_ptr(card_res->connector_id_ptr); + drm_for_each_connector(connector, dev) { + if (count < card_res->count_connectors && + put_user(connector->base.id, connector_id + count)) { + ret = -EFAULT; + goto out; } + count++; } - card_res->count_connectors = connector_count; + card_res->count_connectors = count; out: mutex_unlock(&dev->mode_config.mutex); diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 62b98f386fd1..c2dc8e6f80ff 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -392,12 +392,16 @@ int drm_mode_getplane(struct drm_device *dev, void *data, return -ENOENT; drm_modeset_lock(&plane->mutex, NULL); - if (plane->crtc) + if (plane->state && plane->state->crtc) + plane_resp->crtc_id = plane->state->crtc->base.id; + else if (!plane->state && plane->crtc) plane_resp->crtc_id = plane->crtc->base.id; else plane_resp->crtc_id = 0; - if (plane->fb) + if (plane->state && plane->state->fb) + plane_resp->fb_id = plane->state->fb->base.id; + else if (!plane->state && plane->fb) plane_resp->fb_id = plane->fb->base.id; else plane_resp->fb_id = 0; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 00368b14d08d..30d70ed143f7 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -592,7 +592,7 @@ static void etnaviv_unbind(struct device *dev) drm->dev_private = NULL; kfree(priv); - drm_put_dev(drm); + drm_dev_unref(drm); } static const struct component_master_ops etnaviv_master_ops = { diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c index afc2b5d2d5f0..3ea70459b901 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c @@ -973,9 +973,9 @@ static int ade_dts_parse(struct platform_device *pdev, struct ade_hw_ctx *ctx) return 0; } -static int ade_drm_init(struct drm_device *dev) +static int ade_drm_init(struct platform_device *pdev) { - struct platform_device *pdev = dev->platformdev; + struct drm_device *dev = platform_get_drvdata(pdev); struct ade_data *ade; struct ade_hw_ctx *ctx; struct ade_crtc *acrtc; @@ -1034,13 +1034,8 @@ static int ade_drm_init(struct drm_device *dev) return 0; } -static void ade_drm_cleanup(struct drm_device *dev) +static void ade_drm_cleanup(struct platform_device *pdev) { - struct platform_device *pdev = dev->platformdev; - struct ade_data *ade = platform_get_drvdata(pdev); - struct drm_crtc *crtc = &ade->acrtc.base; - - drm_crtc_cleanup(crtc); } const struct kirin_dc_ops ade_dc_ops = { diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index ebd5f4fe4c23..fa228b7b022c 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -42,7 +42,7 @@ static int kirin_drm_kms_cleanup(struct drm_device *dev) #endif drm_kms_helper_poll_fini(dev); drm_vblank_cleanup(dev); - dc_ops->cleanup(dev); + dc_ops->cleanup(to_platform_device(dev->dev)); drm_mode_config_cleanup(dev); devm_kfree(dev->dev, priv); dev->dev_private = NULL; @@ -104,7 +104,7 @@ static int kirin_drm_kms_init(struct drm_device *dev) kirin_drm_mode_config_init(dev); /* display controller init */ - ret = dc_ops->init(dev); + ret = dc_ops->init(to_platform_device(dev->dev)); if (ret) goto err_mode_config_cleanup; @@ -138,7 +138,7 @@ static int kirin_drm_kms_init(struct drm_device *dev) err_unbind_all: component_unbind_all(dev->dev, dev); err_dc_cleanup: - dc_ops->cleanup(dev); + dc_ops->cleanup(to_platform_device(dev->dev)); err_mode_config_cleanup: drm_mode_config_cleanup(dev); devm_kfree(dev->dev, priv); @@ -209,8 +209,6 @@ static int kirin_drm_bind(struct device *dev) if (IS_ERR(drm_dev)) return PTR_ERR(drm_dev); - drm_dev->platformdev = to_platform_device(dev); - ret = kirin_drm_kms_init(drm_dev); if (ret) goto err_drm_dev_unref; diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h index 1a07caf8e7f4..a0bb217c4c64 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h @@ -15,8 +15,8 @@ /* display controller init/cleanup ops */ struct kirin_dc_ops { - int (*init)(struct drm_device *dev); - void (*cleanup)(struct drm_device *dev); + int (*init)(struct platform_device *pdev); + void (*cleanup)(struct platform_device *pdev); }; struct kirin_drm_private { diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 4b7fe7eaec01..b5f88e6d078e 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -321,7 +321,8 @@ static void mtk_drm_unbind(struct device *dev) { struct mtk_drm_private *private = dev_get_drvdata(dev); - drm_put_dev(private->drm); + drm_dev_unregister(private->drm); + drm_dev_unref(private->drm); private->drm = NULL; } |