diff options
Diffstat (limited to 'drivers/gpu')
87 files changed, 1259 insertions, 1127 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index ec4036a09f3e..a625b9137da2 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | |||
| @@ -187,12 +187,12 @@ int init_pipelines(struct device_queue_manager *dqm, | |||
| 187 | unsigned int get_first_pipe(struct device_queue_manager *dqm); | 187 | unsigned int get_first_pipe(struct device_queue_manager *dqm); |
| 188 | unsigned int get_pipes_num(struct device_queue_manager *dqm); | 188 | unsigned int get_pipes_num(struct device_queue_manager *dqm); |
| 189 | 189 | ||
| 190 | extern inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd) | 190 | static inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd) |
| 191 | { | 191 | { |
| 192 | return (pdd->lds_base >> 16) & 0xFF; | 192 | return (pdd->lds_base >> 16) & 0xFF; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | extern inline unsigned int | 195 | static inline unsigned int |
| 196 | get_sh_mem_bases_nybble_64(struct kfd_process_device *pdd) | 196 | get_sh_mem_bases_nybble_64(struct kfd_process_device *pdd) |
| 197 | { | 197 | { |
| 198 | return (pdd->lds_base >> 60) & 0x0E; | 198 | return (pdd->lds_base >> 60) & 0x0E; |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index d0d5f4baf72d..80113c335966 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h | |||
| @@ -617,10 +617,7 @@ int kgd2kfd_resume(struct kfd_dev *kfd); | |||
| 617 | int kfd_init_apertures(struct kfd_process *process); | 617 | int kfd_init_apertures(struct kfd_process *process); |
| 618 | 618 | ||
| 619 | /* Queue Context Management */ | 619 | /* Queue Context Management */ |
| 620 | inline uint32_t lower_32(uint64_t x); | ||
| 621 | inline uint32_t upper_32(uint64_t x); | ||
| 622 | struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd); | 620 | struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd); |
| 623 | inline uint32_t get_sdma_base_addr(struct cik_sdma_rlc_registers *m); | ||
| 624 | 621 | ||
| 625 | int init_queue(struct queue **q, struct queue_properties properties); | 622 | int init_queue(struct queue **q, struct queue_properties properties); |
| 626 | void uninit_queue(struct queue *q); | 623 | void uninit_queue(struct queue *q); |
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index 381c5fcbf903..ccbdadb108dc 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c | |||
| @@ -211,15 +211,8 @@ static int arcpgu_probe(struct platform_device *pdev) | |||
| 211 | if (ret) | 211 | if (ret) |
| 212 | goto err_unload; | 212 | goto err_unload; |
| 213 | 213 | ||
| 214 | ret = drm_connector_register_all(drm); | ||
| 215 | if (ret) | ||
| 216 | goto err_unregister; | ||
| 217 | |||
| 218 | return 0; | 214 | return 0; |
| 219 | 215 | ||
| 220 | err_unregister: | ||
| 221 | drm_dev_unregister(drm); | ||
| 222 | |||
| 223 | err_unload: | 216 | err_unload: |
| 224 | arcpgu_unload(drm); | 217 | arcpgu_unload(drm); |
| 225 | 218 | ||
| @@ -233,7 +226,6 @@ static int arcpgu_remove(struct platform_device *pdev) | |||
| 233 | { | 226 | { |
| 234 | struct drm_device *drm = platform_get_drvdata(pdev); | 227 | struct drm_device *drm = platform_get_drvdata(pdev); |
| 235 | 228 | ||
| 236 | drm_connector_unregister_all(drm); | ||
| 237 | drm_dev_unregister(drm); | 229 | drm_dev_unregister(drm); |
| 238 | arcpgu_unload(drm); | 230 | arcpgu_unload(drm); |
| 239 | drm_dev_unref(drm); | 231 | drm_dev_unref(drm); |
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index cb21c0b6374a..f5ebdd681445 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c | |||
| @@ -189,7 +189,6 @@ static struct drm_driver armada_drm_driver = { | |||
| 189 | .load = armada_drm_load, | 189 | .load = armada_drm_load, |
| 190 | .lastclose = armada_drm_lastclose, | 190 | .lastclose = armada_drm_lastclose, |
| 191 | .unload = armada_drm_unload, | 191 | .unload = armada_drm_unload, |
| 192 | .set_busid = drm_platform_set_busid, | ||
| 193 | .get_vblank_counter = drm_vblank_no_hw_counter, | 192 | .get_vblank_counter = drm_vblank_no_hw_counter, |
| 194 | .enable_vblank = armada_drm_enable_vblank, | 193 | .enable_vblank = armada_drm_enable_vblank, |
| 195 | .disable_vblank = armada_drm_disable_vblank, | 194 | .disable_vblank = armada_drm_disable_vblank, |
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index 148e8a42b2c6..1ee707ef6b8d 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c | |||
| @@ -121,6 +121,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 121 | int ret; | 121 | int ret; |
| 122 | 122 | ||
| 123 | ret = drm_plane_helper_check_update(plane, crtc, fb, &src, &dest, &clip, | 123 | ret = drm_plane_helper_check_update(plane, crtc, fb, &src, &dest, &clip, |
| 124 | BIT(DRM_ROTATE_0), | ||
| 124 | 0, INT_MAX, true, false, &visible); | 125 | 0, INT_MAX, true, false, &visible); |
| 125 | if (ret) | 126 | if (ret) |
| 126 | return ret; | 127 | return ret; |
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c index 9ecf16c7911d..d4a3d61b7b06 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | |||
| @@ -691,13 +691,6 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev) | |||
| 691 | destroy_workqueue(dc->wq); | 691 | destroy_workqueue(dc->wq); |
| 692 | } | 692 | } |
| 693 | 693 | ||
| 694 | static void atmel_hlcdc_dc_connector_unplug_all(struct drm_device *dev) | ||
| 695 | { | ||
| 696 | mutex_lock(&dev->mode_config.mutex); | ||
| 697 | drm_connector_unregister_all(dev); | ||
| 698 | mutex_unlock(&dev->mode_config.mutex); | ||
| 699 | } | ||
| 700 | |||
| 701 | static void atmel_hlcdc_dc_lastclose(struct drm_device *dev) | 694 | static void atmel_hlcdc_dc_lastclose(struct drm_device *dev) |
| 702 | { | 695 | { |
| 703 | struct atmel_hlcdc_dc *dc = dev->dev_private; | 696 | struct atmel_hlcdc_dc *dc = dev->dev_private; |
| @@ -815,15 +808,8 @@ static int atmel_hlcdc_dc_drm_probe(struct platform_device *pdev) | |||
| 815 | if (ret) | 808 | if (ret) |
| 816 | goto err_unload; | 809 | goto err_unload; |
| 817 | 810 | ||
| 818 | ret = drm_connector_register_all(ddev); | ||
| 819 | if (ret) | ||
| 820 | goto err_unregister; | ||
| 821 | |||
| 822 | return 0; | 811 | return 0; |
| 823 | 812 | ||
| 824 | err_unregister: | ||
| 825 | drm_dev_unregister(ddev); | ||
| 826 | |||
| 827 | err_unload: | 813 | err_unload: |
| 828 | atmel_hlcdc_dc_unload(ddev); | 814 | atmel_hlcdc_dc_unload(ddev); |
| 829 | 815 | ||
| @@ -837,7 +823,6 @@ static int atmel_hlcdc_dc_drm_remove(struct platform_device *pdev) | |||
| 837 | { | 823 | { |
| 838 | struct drm_device *ddev = platform_get_drvdata(pdev); | 824 | struct drm_device *ddev = platform_get_drvdata(pdev); |
| 839 | 825 | ||
| 840 | atmel_hlcdc_dc_connector_unplug_all(ddev); | ||
| 841 | drm_dev_unregister(ddev); | 826 | drm_dev_unregister(ddev); |
| 842 | atmel_hlcdc_dc_unload(ddev); | 827 | atmel_hlcdc_dc_unload(ddev); |
| 843 | drm_dev_unref(ddev); | 828 | drm_dev_unref(ddev); |
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 50d0baa06db0..4153e8a193af 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c | |||
| @@ -30,25 +30,36 @@ | |||
| 30 | 30 | ||
| 31 | #include <drm/drmP.h> | 31 | #include <drm/drmP.h> |
| 32 | #include "drm_internal.h" | 32 | #include "drm_internal.h" |
| 33 | #include "drm_legacy.h" | ||
| 33 | 34 | ||
| 34 | /** | 35 | /** |
| 35 | * drm_getmagic - Get unique magic of a client | 36 | * DOC: master and authentication |
| 36 | * @dev: DRM device to operate on | ||
| 37 | * @data: ioctl data containing the drm_auth object | ||
| 38 | * @file_priv: DRM file that performs the operation | ||
| 39 | * | 37 | * |
| 40 | * This looks up the unique magic of the passed client and returns it. If the | 38 | * struct &drm_master is used to track groups of clients with open |
| 41 | * client did not have a magic assigned, yet, a new one is registered. The magic | 39 | * primary/legacy device nodes. For every struct &drm_file which has had at |
| 42 | * is stored in the passed drm_auth object. | 40 | * least once successfully became the device master (either through the |
| 41 | * SET_MASTER IOCTL, or implicitly through opening the primary device node when | ||
| 42 | * no one else is the current master that time) there exists one &drm_master. | ||
| 43 | * This is noted in the is_master member of &drm_file. All other clients have | ||
| 44 | * just a pointer to the &drm_master they are associated with. | ||
| 43 | * | 45 | * |
| 44 | * Returns: 0 on success, negative error code on failure. | 46 | * In addition only one &drm_master can be the current master for a &drm_device. |
| 47 | * It can be switched through the DROP_MASTER and SET_MASTER IOCTL, or | ||
| 48 | * implicitly through closing/openeing the primary device node. See also | ||
| 49 | * drm_is_current_master(). | ||
| 50 | * | ||
| 51 | * Clients can authenticate against the current master (if it matches their own) | ||
| 52 | * using the GETMAGIC and AUTHMAGIC IOCTLs. Together with exchanging masters, | ||
| 53 | * this allows controlled access to the device for an entire group of mutually | ||
| 54 | * trusted clients. | ||
| 45 | */ | 55 | */ |
| 56 | |||
| 46 | int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) | 57 | int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) |
| 47 | { | 58 | { |
| 48 | struct drm_auth *auth = data; | 59 | struct drm_auth *auth = data; |
| 49 | int ret = 0; | 60 | int ret = 0; |
| 50 | 61 | ||
| 51 | mutex_lock(&dev->struct_mutex); | 62 | mutex_lock(&dev->master_mutex); |
| 52 | if (!file_priv->magic) { | 63 | if (!file_priv->magic) { |
| 53 | ret = idr_alloc(&file_priv->master->magic_map, file_priv, | 64 | ret = idr_alloc(&file_priv->master->magic_map, file_priv, |
| 54 | 1, 0, GFP_KERNEL); | 65 | 1, 0, GFP_KERNEL); |
| @@ -56,23 +67,13 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
| 56 | file_priv->magic = ret; | 67 | file_priv->magic = ret; |
| 57 | } | 68 | } |
| 58 | auth->magic = file_priv->magic; | 69 | auth->magic = file_priv->magic; |
| 59 | mutex_unlock(&dev->struct_mutex); | 70 | mutex_unlock(&dev->master_mutex); |
| 60 | 71 | ||
| 61 | DRM_DEBUG("%u\n", auth->magic); | 72 | DRM_DEBUG("%u\n", auth->magic); |
| 62 | 73 | ||
| 63 | return ret < 0 ? ret : 0; | 74 | return ret < 0 ? ret : 0; |
| 64 | } | 75 | } |
| 65 | 76 | ||
| 66 | /** | ||
| 67 | * drm_authmagic - Authenticate client with a magic | ||
| 68 | * @dev: DRM device to operate on | ||
| 69 | * @data: ioctl data containing the drm_auth object | ||
| 70 | * @file_priv: DRM file that performs the operation | ||
| 71 | * | ||
| 72 | * This looks up a DRM client by the passed magic and authenticates it. | ||
| 73 | * | ||
| 74 | * Returns: 0 on success, negative error code on failure. | ||
| 75 | */ | ||
| 76 | int drm_authmagic(struct drm_device *dev, void *data, | 77 | int drm_authmagic(struct drm_device *dev, void *data, |
| 77 | struct drm_file *file_priv) | 78 | struct drm_file *file_priv) |
| 78 | { | 79 | { |
| @@ -81,13 +82,253 @@ int drm_authmagic(struct drm_device *dev, void *data, | |||
| 81 | 82 | ||
| 82 | DRM_DEBUG("%u\n", auth->magic); | 83 | DRM_DEBUG("%u\n", auth->magic); |
| 83 | 84 | ||
| 84 | mutex_lock(&dev->struct_mutex); | 85 | mutex_lock(&dev->master_mutex); |
| 85 | file = idr_find(&file_priv->master->magic_map, auth->magic); | 86 | file = idr_find(&file_priv->master->magic_map, auth->magic); |
| 86 | if (file) { | 87 | if (file) { |
| 87 | file->authenticated = 1; | 88 | file->authenticated = 1; |
| 88 | idr_replace(&file_priv->master->magic_map, NULL, auth->magic); | 89 | idr_replace(&file_priv->master->magic_map, NULL, auth->magic); |
| 89 | } | 90 | } |
| 90 | mutex_unlock(&dev->struct_mutex); | 91 | mutex_unlock(&dev->master_mutex); |
| 91 | 92 | ||
| 92 | return file ? 0 : -EINVAL; | 93 | return file ? 0 : -EINVAL; |
| 93 | } | 94 | } |
| 95 | |||
| 96 | static struct drm_master *drm_master_create(struct drm_device *dev) | ||
| 97 | { | ||
| 98 | struct drm_master *master; | ||
| 99 | |||
| 100 | master = kzalloc(sizeof(*master), GFP_KERNEL); | ||
| 101 | if (!master) | ||
| 102 | return NULL; | ||
| 103 | |||
| 104 | kref_init(&master->refcount); | ||
| 105 | spin_lock_init(&master->lock.spinlock); | ||
| 106 | init_waitqueue_head(&master->lock.lock_queue); | ||
| 107 | idr_init(&master->magic_map); | ||
| 108 | master->dev = dev; | ||
| 109 | |||
| 110 | return master; | ||
| 111 | } | ||
| 112 | |||
| 113 | static int drm_set_master(struct drm_device *dev, struct drm_file *fpriv, | ||
| 114 | bool new_master) | ||
| 115 | { | ||
| 116 | int ret = 0; | ||
| 117 | |||
| 118 | dev->master = drm_master_get(fpriv->master); | ||
| 119 | if (dev->driver->master_set) { | ||
| 120 | ret = dev->driver->master_set(dev, fpriv, new_master); | ||
| 121 | if (unlikely(ret != 0)) { | ||
| 122 | drm_master_put(&dev->master); | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | return ret; | ||
| 127 | } | ||
| 128 | |||
| 129 | static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) | ||
| 130 | { | ||
| 131 | struct drm_master *old_master; | ||
| 132 | int ret; | ||
| 133 | |||
| 134 | lockdep_assert_held_once(&dev->master_mutex); | ||
| 135 | |||
| 136 | old_master = fpriv->master; | ||
| 137 | fpriv->master = drm_master_create(dev); | ||
| 138 | if (!fpriv->master) { | ||
| 139 | fpriv->master = old_master; | ||
| 140 | return -ENOMEM; | ||
| 141 | } | ||
| 142 | |||
| 143 | if (dev->driver->master_create) { | ||
| 144 | ret = dev->driver->master_create(dev, fpriv->master); | ||
| 145 | if (ret) | ||
| 146 | goto out_err; | ||
| 147 | } | ||
| 148 | fpriv->is_master = 1; | ||
| 149 | fpriv->authenticated = 1; | ||
| 150 | |||
| 151 | ret = drm_set_master(dev, fpriv, true); | ||
| 152 | if (ret) | ||
| 153 | goto out_err; | ||
| 154 | |||
| 155 | if (old_master) | ||
| 156 | drm_master_put(&old_master); | ||
| 157 | |||
| 158 | return 0; | ||
| 159 | |||
| 160 | out_err: | ||
| 161 | /* drop references and restore old master on failure */ | ||
| 162 | drm_master_put(&fpriv->master); | ||
| 163 | fpriv->master = old_master; | ||
| 164 | |||
| 165 | return ret; | ||
| 166 | } | ||
| 167 | |||
| 168 | int drm_setmaster_ioctl(struct drm_device *dev, void *data, | ||
| 169 | struct drm_file *file_priv) | ||
| 170 | { | ||
| 171 | int ret = 0; | ||
| 172 | |||
| 173 | mutex_lock(&dev->master_mutex); | ||
| 174 | if (drm_is_current_master(file_priv)) | ||
| 175 | goto out_unlock; | ||
| 176 | |||
| 177 | if (dev->master) { | ||
| 178 | ret = -EINVAL; | ||
| 179 | goto out_unlock; | ||
| 180 | } | ||
| 181 | |||
| 182 | if (!file_priv->master) { | ||
| 183 | ret = -EINVAL; | ||
| 184 | goto out_unlock; | ||
| 185 | } | ||
| 186 | |||
| 187 | if (!file_priv->is_master) { | ||
| 188 | ret = drm_new_set_master(dev, file_priv); | ||
| 189 | goto out_unlock; | ||
| 190 | } | ||
| 191 | |||
| 192 | ret = drm_set_master(dev, file_priv, false); | ||
| 193 | out_unlock: | ||
| 194 | mutex_unlock(&dev->master_mutex); | ||
| 195 | return ret; | ||
| 196 | } | ||
| 197 | |||
| 198 | static void drm_drop_master(struct drm_device *dev, | ||
| 199 | struct drm_file *fpriv) | ||
| 200 | { | ||
| 201 | if (dev->driver->master_drop) | ||
| 202 | dev->driver->master_drop(dev, fpriv); | ||
| 203 | drm_master_put(&dev->master); | ||
| 204 | } | ||
| 205 | |||
| 206 | int drm_dropmaster_ioctl(struct drm_device *dev, void *data, | ||
| 207 | struct drm_file *file_priv) | ||
| 208 | { | ||
| 209 | int ret = -EINVAL; | ||
| 210 | |||
| 211 | mutex_lock(&dev->master_mutex); | ||
| 212 | if (!drm_is_current_master(file_priv)) | ||
| 213 | goto out_unlock; | ||
| 214 | |||
| 215 | if (!dev->master) | ||
| 216 | goto out_unlock; | ||
| 217 | |||
| 218 | ret = 0; | ||
| 219 | drm_drop_master(dev, file_priv); | ||
| 220 | out_unlock: | ||
| 221 | mutex_unlock(&dev->master_mutex); | ||
| 222 | return ret; | ||
| 223 | } | ||
| 224 | |||
| 225 | int drm_master_open(struct drm_file *file_priv) | ||
| 226 | { | ||
| 227 | struct drm_device *dev = file_priv->minor->dev; | ||
| 228 | int ret = 0; | ||
| 229 | |||
| 230 | /* if there is no current master make this fd it, but do not create | ||
| 231 | * any master object for render clients */ | ||
| 232 | mutex_lock(&dev->master_mutex); | ||
| 233 | if (!dev->master) | ||
| 234 | ret = drm_new_set_master(dev, file_priv); | ||
| 235 | else | ||
| 236 | file_priv->master = drm_master_get(dev->master); | ||
| 237 | mutex_unlock(&dev->master_mutex); | ||
| 238 | |||
| 239 | return ret; | ||
| 240 | } | ||
| 241 | |||
| 242 | void drm_master_release(struct drm_file *file_priv) | ||
| 243 | { | ||
| 244 | struct drm_device *dev = file_priv->minor->dev; | ||
| 245 | struct drm_master *master = file_priv->master; | ||
| 246 | |||
| 247 | mutex_lock(&dev->master_mutex); | ||
| 248 | if (file_priv->magic) | ||
| 249 | idr_remove(&file_priv->master->magic_map, file_priv->magic); | ||
| 250 | |||
| 251 | if (!drm_is_current_master(file_priv)) | ||
| 252 | goto out; | ||
| 253 | |||
| 254 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
| 255 | /* | ||
| 256 | * Since the master is disappearing, so is the | ||
| 257 | * possibility to lock. | ||
| 258 | */ | ||
| 259 | mutex_lock(&dev->struct_mutex); | ||
| 260 | if (master->lock.hw_lock) { | ||
| 261 | if (dev->sigdata.lock == master->lock.hw_lock) | ||
| 262 | dev->sigdata.lock = NULL; | ||
| 263 | master->lock.hw_lock = NULL; | ||
| 264 | master->lock.file_priv = NULL; | ||
| 265 | wake_up_interruptible_all(&master->lock.lock_queue); | ||
| 266 | } | ||
| 267 | mutex_unlock(&dev->struct_mutex); | ||
| 268 | } | ||
| 269 | |||
| 270 | if (dev->master == file_priv->master) | ||
| 271 | drm_drop_master(dev, file_priv); | ||
| 272 | out: | ||
| 273 | /* drop the master reference held by the file priv */ | ||
| 274 | if (file_priv->master) | ||
| 275 | drm_master_put(&file_priv->master); | ||
| 276 | mutex_unlock(&dev->master_mutex); | ||
| 277 | } | ||
| 278 | |||
| 279 | /** | ||
| 280 | * drm_is_current_master - checks whether @priv is the current master | ||
| 281 | * @fpriv: DRM file private | ||
| 282 | * | ||
| 283 | * Checks whether @fpriv is current master on its device. This decides whether a | ||
| 284 | * client is allowed to run DRM_MASTER IOCTLs. | ||
| 285 | * | ||
| 286 | * Most of the modern IOCTL which require DRM_MASTER are for kernel modesetting | ||
| 287 | * - the current master is assumed to own the non-shareable display hardware. | ||
| 288 | */ | ||
| 289 | bool drm_is_current_master(struct drm_file *fpriv) | ||
| 290 | { | ||
| 291 | return fpriv->is_master && fpriv->master == fpriv->minor->dev->master; | ||
| 292 | } | ||
| 293 | EXPORT_SYMBOL(drm_is_current_master); | ||
| 294 | |||
| 295 | /** | ||
| 296 | * drm_master_get - reference a master pointer | ||
| 297 | * @master: struct &drm_master | ||
| 298 | * | ||
| 299 | * Increments the reference count of @master and returns a pointer to @master. | ||
| 300 | */ | ||
| 301 | struct drm_master *drm_master_get(struct drm_master *master) | ||
| 302 | { | ||
| 303 | kref_get(&master->refcount); | ||
| 304 | return master; | ||
| 305 | } | ||
| 306 | EXPORT_SYMBOL(drm_master_get); | ||
| 307 | |||
| 308 | static void drm_master_destroy(struct kref *kref) | ||
| 309 | { | ||
| 310 | struct drm_master *master = container_of(kref, struct drm_master, refcount); | ||
| 311 | struct drm_device *dev = master->dev; | ||
| 312 | |||
| 313 | if (dev->driver->master_destroy) | ||
| 314 | dev->driver->master_destroy(dev, master); | ||
| 315 | |||
| 316 | drm_legacy_master_rmmaps(dev, master); | ||
| 317 | |||
| 318 | idr_destroy(&master->magic_map); | ||
| 319 | kfree(master->unique); | ||
| 320 | kfree(master); | ||
| 321 | } | ||
| 322 | |||
| 323 | /** | ||
| 324 | * drm_master_put - unreference and clear a master pointer | ||
| 325 | * @master: pointer to a pointer of struct &drm_master | ||
| 326 | * | ||
| 327 | * This decrements the &drm_master behind @master and sets it to NULL. | ||
| 328 | */ | ||
| 329 | void drm_master_put(struct drm_master **master) | ||
| 330 | { | ||
| 331 | kref_put(&(*master)->refcount, drm_master_destroy); | ||
| 332 | *master = NULL; | ||
| 333 | } | ||
| 334 | EXPORT_SYMBOL(drm_master_put); | ||
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 9b34158c0f77..c3a12cd8bd0d 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c | |||
| @@ -51,7 +51,7 @@ static struct drm_map_list *drm_find_matching_map(struct drm_device *dev, | |||
| 51 | */ | 51 | */ |
| 52 | if (!entry->map || | 52 | if (!entry->map || |
| 53 | map->type != entry->map->type || | 53 | map->type != entry->map->type || |
| 54 | entry->master != dev->primary->master) | 54 | entry->master != dev->master) |
| 55 | continue; | 55 | continue; |
| 56 | switch (map->type) { | 56 | switch (map->type) { |
| 57 | case _DRM_SHM: | 57 | case _DRM_SHM: |
| @@ -245,12 +245,12 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 245 | map->offset = (unsigned long)map->handle; | 245 | map->offset = (unsigned long)map->handle; |
| 246 | if (map->flags & _DRM_CONTAINS_LOCK) { | 246 | if (map->flags & _DRM_CONTAINS_LOCK) { |
| 247 | /* Prevent a 2nd X Server from creating a 2nd lock */ | 247 | /* Prevent a 2nd X Server from creating a 2nd lock */ |
| 248 | if (dev->primary->master->lock.hw_lock != NULL) { | 248 | if (dev->master->lock.hw_lock != NULL) { |
| 249 | vfree(map->handle); | 249 | vfree(map->handle); |
| 250 | kfree(map); | 250 | kfree(map); |
| 251 | return -EBUSY; | 251 | return -EBUSY; |
| 252 | } | 252 | } |
| 253 | dev->sigdata.lock = dev->primary->master->lock.hw_lock = map->handle; /* Pointer to lock */ | 253 | dev->sigdata.lock = dev->master->lock.hw_lock = map->handle; /* Pointer to lock */ |
| 254 | } | 254 | } |
| 255 | break; | 255 | break; |
| 256 | case _DRM_AGP: { | 256 | case _DRM_AGP: { |
| @@ -356,7 +356,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 356 | mutex_unlock(&dev->struct_mutex); | 356 | mutex_unlock(&dev->struct_mutex); |
| 357 | 357 | ||
| 358 | if (!(map->flags & _DRM_DRIVER)) | 358 | if (!(map->flags & _DRM_DRIVER)) |
| 359 | list->master = dev->primary->master; | 359 | list->master = dev->master; |
| 360 | *maplist = list; | 360 | *maplist = list; |
| 361 | return 0; | 361 | return 0; |
| 362 | } | 362 | } |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 4ec35f9e6de5..fd93e9c79d28 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <drm/drm_fourcc.h> | 39 | #include <drm/drm_fourcc.h> |
| 40 | #include <drm/drm_modeset_lock.h> | 40 | #include <drm/drm_modeset_lock.h> |
| 41 | #include <drm/drm_atomic.h> | 41 | #include <drm/drm_atomic.h> |
| 42 | #include <drm/drm_auth.h> | ||
| 42 | 43 | ||
| 43 | #include "drm_crtc_internal.h" | 44 | #include "drm_crtc_internal.h" |
| 44 | #include "drm_internal.h" | 45 | #include "drm_internal.h" |
| @@ -608,6 +609,31 @@ static unsigned int drm_num_crtcs(struct drm_device *dev) | |||
| 608 | return num; | 609 | return num; |
| 609 | } | 610 | } |
| 610 | 611 | ||
| 612 | static int drm_crtc_register_all(struct drm_device *dev) | ||
| 613 | { | ||
| 614 | struct drm_crtc *crtc; | ||
| 615 | int ret = 0; | ||
| 616 | |||
| 617 | drm_for_each_crtc(crtc, dev) { | ||
| 618 | if (crtc->funcs->late_register) | ||
| 619 | ret = crtc->funcs->late_register(crtc); | ||
| 620 | if (ret) | ||
| 621 | return ret; | ||
| 622 | } | ||
| 623 | |||
| 624 | return 0; | ||
| 625 | } | ||
| 626 | |||
| 627 | static void drm_crtc_unregister_all(struct drm_device *dev) | ||
| 628 | { | ||
| 629 | struct drm_crtc *crtc; | ||
| 630 | |||
| 631 | drm_for_each_crtc(crtc, dev) { | ||
| 632 | if (crtc->funcs->early_unregister) | ||
| 633 | crtc->funcs->early_unregister(crtc); | ||
| 634 | } | ||
| 635 | } | ||
| 636 | |||
| 611 | /** | 637 | /** |
| 612 | * drm_crtc_init_with_planes - Initialise a new CRTC object with | 638 | * drm_crtc_init_with_planes - Initialise a new CRTC object with |
| 613 | * specified primary and cursor planes. | 639 | * specified primary and cursor planes. |
| @@ -938,6 +964,12 @@ void drm_connector_cleanup(struct drm_connector *connector) | |||
| 938 | struct drm_device *dev = connector->dev; | 964 | struct drm_device *dev = connector->dev; |
| 939 | struct drm_display_mode *mode, *t; | 965 | struct drm_display_mode *mode, *t; |
| 940 | 966 | ||
| 967 | /* The connector should have been removed from userspace long before | ||
| 968 | * it is finally destroyed. | ||
| 969 | */ | ||
| 970 | if (WARN_ON(connector->registered)) | ||
| 971 | drm_connector_unregister(connector); | ||
| 972 | |||
| 941 | if (connector->tile_group) { | 973 | if (connector->tile_group) { |
| 942 | drm_mode_put_tile_group(dev, connector->tile_group); | 974 | drm_mode_put_tile_group(dev, connector->tile_group); |
| 943 | connector->tile_group = NULL; | 975 | connector->tile_group = NULL; |
| @@ -984,19 +1016,34 @@ int drm_connector_register(struct drm_connector *connector) | |||
| 984 | { | 1016 | { |
| 985 | int ret; | 1017 | int ret; |
| 986 | 1018 | ||
| 1019 | if (connector->registered) | ||
| 1020 | return 0; | ||
| 1021 | |||
| 987 | ret = drm_sysfs_connector_add(connector); | 1022 | ret = drm_sysfs_connector_add(connector); |
| 988 | if (ret) | 1023 | if (ret) |
| 989 | return ret; | 1024 | return ret; |
| 990 | 1025 | ||
| 991 | ret = drm_debugfs_connector_add(connector); | 1026 | ret = drm_debugfs_connector_add(connector); |
| 992 | if (ret) { | 1027 | if (ret) { |
| 993 | drm_sysfs_connector_remove(connector); | 1028 | goto err_sysfs; |
| 994 | return ret; | 1029 | } |
| 1030 | |||
| 1031 | if (connector->funcs->late_register) { | ||
| 1032 | ret = connector->funcs->late_register(connector); | ||
| 1033 | if (ret) | ||
| 1034 | goto err_debugfs; | ||
| 995 | } | 1035 | } |
| 996 | 1036 | ||
| 997 | drm_mode_object_register(connector->dev, &connector->base); | 1037 | drm_mode_object_register(connector->dev, &connector->base); |
| 998 | 1038 | ||
| 1039 | connector->registered = true; | ||
| 999 | return 0; | 1040 | return 0; |
| 1041 | |||
| 1042 | err_debugfs: | ||
| 1043 | drm_debugfs_connector_remove(connector); | ||
| 1044 | err_sysfs: | ||
| 1045 | drm_sysfs_connector_remove(connector); | ||
| 1046 | return ret; | ||
| 1000 | } | 1047 | } |
| 1001 | EXPORT_SYMBOL(drm_connector_register); | 1048 | EXPORT_SYMBOL(drm_connector_register); |
| 1002 | 1049 | ||
| @@ -1008,8 +1055,16 @@ EXPORT_SYMBOL(drm_connector_register); | |||
| 1008 | */ | 1055 | */ |
| 1009 | void drm_connector_unregister(struct drm_connector *connector) | 1056 | void drm_connector_unregister(struct drm_connector *connector) |
| 1010 | { | 1057 | { |
| 1058 | if (!connector->registered) | ||
| 1059 | return; | ||
| 1060 | |||
| 1061 | if (connector->funcs->early_unregister) | ||
| 1062 | connector->funcs->early_unregister(connector); | ||
| 1063 | |||
| 1011 | drm_sysfs_connector_remove(connector); | 1064 | drm_sysfs_connector_remove(connector); |
| 1012 | drm_debugfs_connector_remove(connector); | 1065 | drm_debugfs_connector_remove(connector); |
| 1066 | |||
| 1067 | connector->registered = false; | ||
| 1013 | } | 1068 | } |
| 1014 | EXPORT_SYMBOL(drm_connector_unregister); | 1069 | EXPORT_SYMBOL(drm_connector_unregister); |
| 1015 | 1070 | ||
| @@ -1018,9 +1073,9 @@ EXPORT_SYMBOL(drm_connector_unregister); | |||
| 1018 | * @dev: drm device | 1073 | * @dev: drm device |
| 1019 | * | 1074 | * |
| 1020 | * This function registers all connectors in sysfs and other places so that | 1075 | * This function registers all connectors in sysfs and other places so that |
| 1021 | * userspace can start to access them. Drivers can call it after calling | 1076 | * userspace can start to access them. drm_connector_register_all() is called |
| 1022 | * drm_dev_register() to complete the device registration, if they don't call | 1077 | * automatically from drm_dev_register() to complete the device registration, |
| 1023 | * drm_connector_register() on each connector individually. | 1078 | * if they don't call drm_connector_register() on each connector individually. |
| 1024 | * | 1079 | * |
| 1025 | * When a device is unplugged and should be removed from userspace access, | 1080 | * When a device is unplugged and should be removed from userspace access, |
| 1026 | * call drm_connector_unregister_all(), which is the inverse of this | 1081 | * call drm_connector_unregister_all(), which is the inverse of this |
| @@ -1073,6 +1128,31 @@ void drm_connector_unregister_all(struct drm_device *dev) | |||
| 1073 | } | 1128 | } |
| 1074 | EXPORT_SYMBOL(drm_connector_unregister_all); | 1129 | EXPORT_SYMBOL(drm_connector_unregister_all); |
| 1075 | 1130 | ||
| 1131 | static int drm_encoder_register_all(struct drm_device *dev) | ||
| 1132 | { | ||
| 1133 | struct drm_encoder *encoder; | ||
| 1134 | int ret = 0; | ||
| 1135 | |||
| 1136 | drm_for_each_encoder(encoder, dev) { | ||
| 1137 | if (encoder->funcs->late_register) | ||
| 1138 | ret = encoder->funcs->late_register(encoder); | ||
| 1139 | if (ret) | ||
| 1140 | return ret; | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | return 0; | ||
| 1144 | } | ||
| 1145 | |||
| 1146 | static void drm_encoder_unregister_all(struct drm_device *dev) | ||
| 1147 | { | ||
| 1148 | struct drm_encoder *encoder; | ||
| 1149 | |||
| 1150 | drm_for_each_encoder(encoder, dev) { | ||
| 1151 | if (encoder->funcs->early_unregister) | ||
| 1152 | encoder->funcs->early_unregister(encoder); | ||
| 1153 | } | ||
| 1154 | } | ||
| 1155 | |||
| 1076 | /** | 1156 | /** |
| 1077 | * drm_encoder_init - Init a preallocated encoder | 1157 | * drm_encoder_init - Init a preallocated encoder |
| 1078 | * @dev: drm device | 1158 | * @dev: drm device |
| @@ -1261,6 +1341,31 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, | |||
| 1261 | } | 1341 | } |
| 1262 | EXPORT_SYMBOL(drm_universal_plane_init); | 1342 | EXPORT_SYMBOL(drm_universal_plane_init); |
| 1263 | 1343 | ||
| 1344 | static int drm_plane_register_all(struct drm_device *dev) | ||
| 1345 | { | ||
| 1346 | struct drm_plane *plane; | ||
| 1347 | int ret = 0; | ||
| 1348 | |||
| 1349 | drm_for_each_plane(plane, dev) { | ||
| 1350 | if (plane->funcs->late_register) | ||
| 1351 | ret = plane->funcs->late_register(plane); | ||
| 1352 | if (ret) | ||
| 1353 | return ret; | ||
| 1354 | } | ||
| 1355 | |||
| 1356 | return 0; | ||
| 1357 | } | ||
| 1358 | |||
| 1359 | static void drm_plane_unregister_all(struct drm_device *dev) | ||
| 1360 | { | ||
| 1361 | struct drm_plane *plane; | ||
| 1362 | |||
| 1363 | drm_for_each_plane(plane, dev) { | ||
| 1364 | if (plane->funcs->early_unregister) | ||
| 1365 | plane->funcs->early_unregister(plane); | ||
| 1366 | } | ||
| 1367 | } | ||
| 1368 | |||
| 1264 | /** | 1369 | /** |
| 1265 | * drm_plane_init - Initialize a legacy plane | 1370 | * drm_plane_init - Initialize a legacy plane |
| 1266 | * @dev: DRM device | 1371 | * @dev: DRM device |
| @@ -1383,6 +1488,46 @@ void drm_plane_force_disable(struct drm_plane *plane) | |||
| 1383 | } | 1488 | } |
| 1384 | EXPORT_SYMBOL(drm_plane_force_disable); | 1489 | EXPORT_SYMBOL(drm_plane_force_disable); |
| 1385 | 1490 | ||
| 1491 | int drm_modeset_register_all(struct drm_device *dev) | ||
| 1492 | { | ||
| 1493 | int ret; | ||
| 1494 | |||
| 1495 | ret = drm_plane_register_all(dev); | ||
| 1496 | if (ret) | ||
| 1497 | goto err_plane; | ||
| 1498 | |||
| 1499 | ret = drm_crtc_register_all(dev); | ||
| 1500 | if (ret) | ||
| 1501 | goto err_crtc; | ||
| 1502 | |||
| 1503 | ret = drm_encoder_register_all(dev); | ||
| 1504 | if (ret) | ||
| 1505 | goto err_encoder; | ||
| 1506 | |||
| 1507 | ret = drm_connector_register_all(dev); | ||
| 1508 | if (ret) | ||
| 1509 | goto err_connector; | ||
| 1510 | |||
| 1511 | return 0; | ||
| 1512 | |||
| 1513 | err_connector: | ||
| 1514 | drm_encoder_unregister_all(dev); | ||
| 1515 | err_encoder: | ||
| 1516 | drm_crtc_unregister_all(dev); | ||
| 1517 | err_crtc: | ||
| 1518 | drm_plane_unregister_all(dev); | ||
| 1519 | err_plane: | ||
| 1520 | return ret; | ||
| 1521 | } | ||
| 1522 | |||
| 1523 | void drm_modeset_unregister_all(struct drm_device *dev) | ||
| 1524 | { | ||
| 1525 | drm_connector_unregister_all(dev); | ||
| 1526 | drm_encoder_unregister_all(dev); | ||
| 1527 | drm_crtc_unregister_all(dev); | ||
| 1528 | drm_plane_unregister_all(dev); | ||
| 1529 | } | ||
| 1530 | |||
| 1386 | static int drm_mode_create_standard_properties(struct drm_device *dev) | 1531 | static int drm_mode_create_standard_properties(struct drm_device *dev) |
| 1387 | { | 1532 | { |
| 1388 | struct drm_property *prop; | 1533 | struct drm_property *prop; |
| @@ -3499,7 +3644,7 @@ int drm_mode_getfb(struct drm_device *dev, | |||
| 3499 | r->bpp = fb->bits_per_pixel; | 3644 | r->bpp = fb->bits_per_pixel; |
| 3500 | r->pitch = fb->pitches[0]; | 3645 | r->pitch = fb->pitches[0]; |
| 3501 | if (fb->funcs->create_handle) { | 3646 | if (fb->funcs->create_handle) { |
| 3502 | if (file_priv->is_master || capable(CAP_SYS_ADMIN) || | 3647 | if (drm_is_current_master(file_priv) || capable(CAP_SYS_ADMIN) || |
| 3503 | drm_is_control_client(file_priv)) { | 3648 | drm_is_control_client(file_priv)) { |
| 3504 | ret = fb->funcs->create_handle(fb, file_priv, | 3649 | ret = fb->funcs->create_handle(fb, file_priv, |
| 3505 | &r->handle); | 3650 | &r->handle); |
| @@ -3656,6 +3801,13 @@ void drm_fb_release(struct drm_file *priv) | |||
| 3656 | } | 3801 | } |
| 3657 | } | 3802 | } |
| 3658 | 3803 | ||
| 3804 | static bool drm_property_type_valid(struct drm_property *property) | ||
| 3805 | { | ||
| 3806 | if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE) | ||
| 3807 | return !(property->flags & DRM_MODE_PROP_LEGACY_TYPE); | ||
| 3808 | return !!(property->flags & DRM_MODE_PROP_LEGACY_TYPE); | ||
| 3809 | } | ||
| 3810 | |||
| 3659 | /** | 3811 | /** |
| 3660 | * drm_property_create - create a new property type | 3812 | * drm_property_create - create a new property type |
| 3661 | * @dev: drm device | 3813 | * @dev: drm device |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index bf10d7046aa6..d61591274ff6 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
| @@ -232,6 +232,9 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev) | |||
| 232 | */ | 232 | */ |
| 233 | void drm_helper_disable_unused_functions(struct drm_device *dev) | 233 | void drm_helper_disable_unused_functions(struct drm_device *dev) |
| 234 | { | 234 | { |
| 235 | if (drm_core_check_feature(dev, DRIVER_ATOMIC)) | ||
| 236 | DRM_ERROR("Called for atomic driver, this is not what you want.\n"); | ||
| 237 | |||
| 235 | drm_modeset_lock_all(dev); | 238 | drm_modeset_lock_all(dev); |
| 236 | __drm_helper_disable_unused_functions(dev); | 239 | __drm_helper_disable_unused_functions(dev); |
| 237 | drm_modeset_unlock_all(dev); | 240 | drm_modeset_unlock_all(dev); |
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index a78c138282ea..47a500b90fd7 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h | |||
| @@ -31,14 +31,100 @@ | |||
| 31 | * and are not exported to drivers. | 31 | * and are not exported to drivers. |
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | |||
| 35 | /* drm_crtc.c */ | ||
| 36 | void drm_connector_ida_init(void); | ||
| 37 | void drm_connector_ida_destroy(void); | ||
| 34 | int drm_mode_object_get(struct drm_device *dev, | 38 | int drm_mode_object_get(struct drm_device *dev, |
| 35 | struct drm_mode_object *obj, uint32_t obj_type); | 39 | struct drm_mode_object *obj, uint32_t obj_type); |
| 36 | void drm_mode_object_unregister(struct drm_device *dev, | 40 | void drm_mode_object_unregister(struct drm_device *dev, |
| 37 | struct drm_mode_object *object); | 41 | struct drm_mode_object *object); |
| 42 | bool drm_property_change_valid_get(struct drm_property *property, | ||
| 43 | uint64_t value, | ||
| 44 | struct drm_mode_object **ref); | ||
| 45 | void drm_property_change_valid_put(struct drm_property *property, | ||
| 46 | struct drm_mode_object *ref); | ||
| 47 | |||
| 48 | int drm_plane_check_pixel_format(const struct drm_plane *plane, | ||
| 49 | u32 format); | ||
| 50 | int drm_crtc_check_viewport(const struct drm_crtc *crtc, | ||
| 51 | int x, int y, | ||
| 52 | const struct drm_display_mode *mode, | ||
| 53 | const struct drm_framebuffer *fb); | ||
| 54 | |||
| 55 | void drm_fb_release(struct drm_file *file_priv); | ||
| 56 | void drm_property_destroy_user_blobs(struct drm_device *dev, | ||
| 57 | struct drm_file *file_priv); | ||
| 58 | |||
| 59 | /* dumb buffer support IOCTLs */ | ||
| 60 | int drm_mode_create_dumb_ioctl(struct drm_device *dev, | ||
| 61 | void *data, struct drm_file *file_priv); | ||
| 62 | int drm_mode_mmap_dumb_ioctl(struct drm_device *dev, | ||
| 63 | void *data, struct drm_file *file_priv); | ||
| 64 | int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, | ||
| 65 | void *data, struct drm_file *file_priv); | ||
| 66 | |||
| 67 | /* framebuffer IOCTLs */ | ||
| 68 | extern int drm_mode_addfb(struct drm_device *dev, | ||
| 69 | void *data, struct drm_file *file_priv); | ||
| 70 | extern int drm_mode_addfb2(struct drm_device *dev, | ||
| 71 | void *data, struct drm_file *file_priv); | ||
| 72 | int drm_mode_rmfb(struct drm_device *dev, | ||
| 73 | void *data, struct drm_file *file_priv); | ||
| 74 | int drm_mode_getfb(struct drm_device *dev, | ||
| 75 | void *data, struct drm_file *file_priv); | ||
| 76 | int drm_mode_dirtyfb_ioctl(struct drm_device *dev, | ||
| 77 | void *data, struct drm_file *file_priv); | ||
| 78 | |||
| 79 | /* IOCTLs */ | ||
| 80 | int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, | ||
| 81 | struct drm_file *file_priv); | ||
| 82 | int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, | ||
| 83 | struct drm_file *file_priv); | ||
| 84 | |||
| 85 | int drm_mode_getresources(struct drm_device *dev, | ||
| 86 | void *data, struct drm_file *file_priv); | ||
| 87 | int drm_mode_getplane_res(struct drm_device *dev, void *data, | ||
| 88 | struct drm_file *file_priv); | ||
| 89 | int drm_mode_getcrtc(struct drm_device *dev, | ||
| 90 | void *data, struct drm_file *file_priv); | ||
| 91 | int drm_mode_getconnector(struct drm_device *dev, | ||
| 92 | void *data, struct drm_file *file_priv); | ||
| 93 | int drm_mode_setcrtc(struct drm_device *dev, | ||
| 94 | void *data, struct drm_file *file_priv); | ||
| 95 | int drm_mode_getplane(struct drm_device *dev, | ||
| 96 | void *data, struct drm_file *file_priv); | ||
| 97 | int drm_mode_setplane(struct drm_device *dev, | ||
| 98 | void *data, struct drm_file *file_priv); | ||
| 99 | int drm_mode_cursor_ioctl(struct drm_device *dev, | ||
| 100 | void *data, struct drm_file *file_priv); | ||
| 101 | int drm_mode_cursor2_ioctl(struct drm_device *dev, | ||
| 102 | void *data, struct drm_file *file_priv); | ||
| 103 | int drm_mode_getproperty_ioctl(struct drm_device *dev, | ||
| 104 | void *data, struct drm_file *file_priv); | ||
| 105 | int drm_mode_getblob_ioctl(struct drm_device *dev, | ||
| 106 | void *data, struct drm_file *file_priv); | ||
| 107 | int drm_mode_createblob_ioctl(struct drm_device *dev, | ||
| 108 | void *data, struct drm_file *file_priv); | ||
| 109 | int drm_mode_destroyblob_ioctl(struct drm_device *dev, | ||
| 110 | void *data, struct drm_file *file_priv); | ||
| 111 | int drm_mode_connector_property_set_ioctl(struct drm_device *dev, | ||
| 112 | void *data, struct drm_file *file_priv); | ||
| 113 | int drm_mode_getencoder(struct drm_device *dev, | ||
| 114 | void *data, struct drm_file *file_priv); | ||
| 115 | int drm_mode_gamma_get_ioctl(struct drm_device *dev, | ||
| 116 | void *data, struct drm_file *file_priv); | ||
| 117 | int drm_mode_gamma_set_ioctl(struct drm_device *dev, | ||
| 118 | void *data, struct drm_file *file_priv); | ||
| 119 | |||
| 120 | int drm_mode_page_flip_ioctl(struct drm_device *dev, | ||
| 121 | void *data, struct drm_file *file_priv); | ||
| 38 | 122 | ||
| 39 | /* drm_atomic.c */ | 123 | /* drm_atomic.c */ |
| 40 | int drm_atomic_get_property(struct drm_mode_object *obj, | 124 | int drm_atomic_get_property(struct drm_mode_object *obj, |
| 41 | struct drm_property *property, uint64_t *val); | 125 | struct drm_property *property, uint64_t *val); |
| 42 | int drm_mode_atomic_ioctl(struct drm_device *dev, | 126 | int drm_mode_atomic_ioctl(struct drm_device *dev, |
| 43 | void *data, struct drm_file *file_priv); | 127 | void *data, struct drm_file *file_priv); |
| 44 | 128 | ||
| 129 | int drm_modeset_register_all(struct drm_device *dev); | ||
| 130 | void drm_modeset_unregister_all(struct drm_device *dev); | ||
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 3bcf8e6a85b3..fa10cef2ba37 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c | |||
| @@ -46,11 +46,8 @@ | |||
| 46 | 46 | ||
| 47 | static const struct drm_info_list drm_debugfs_list[] = { | 47 | static const struct drm_info_list drm_debugfs_list[] = { |
| 48 | {"name", drm_name_info, 0}, | 48 | {"name", drm_name_info, 0}, |
| 49 | {"vm", drm_vm_info, 0}, | ||
| 50 | {"clients", drm_clients_info, 0}, | 49 | {"clients", drm_clients_info, 0}, |
| 51 | {"bufs", drm_bufs_info, 0}, | ||
| 52 | {"gem_names", drm_gem_name_info, DRIVER_GEM}, | 50 | {"gem_names", drm_gem_name_info, DRIVER_GEM}, |
| 53 | {"vma", drm_vma_info, 0}, | ||
| 54 | }; | 51 | }; |
| 55 | #define DRM_DEBUGFS_ENTRIES ARRAY_SIZE(drm_debugfs_list) | 52 | #define DRM_DEBUGFS_ENTRIES ARRAY_SIZE(drm_debugfs_list) |
| 56 | 53 | ||
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index eeaf5a7c3aa7..091053e995e5 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c | |||
| @@ -708,8 +708,6 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, | |||
| 708 | 708 | ||
| 709 | memset(&msg, 0, sizeof(msg)); | 709 | memset(&msg, 0, sizeof(msg)); |
| 710 | 710 | ||
| 711 | mutex_lock(&aux->hw_mutex); | ||
| 712 | |||
| 713 | for (i = 0; i < num; i++) { | 711 | for (i = 0; i < num; i++) { |
| 714 | msg.address = msgs[i].addr; | 712 | msg.address = msgs[i].addr; |
| 715 | drm_dp_i2c_msg_set_request(&msg, &msgs[i]); | 713 | drm_dp_i2c_msg_set_request(&msg, &msgs[i]); |
| @@ -764,8 +762,6 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, | |||
| 764 | msg.size = 0; | 762 | msg.size = 0; |
| 765 | (void)drm_dp_i2c_do_msg(aux, &msg); | 763 | (void)drm_dp_i2c_do_msg(aux, &msg); |
| 766 | 764 | ||
| 767 | mutex_unlock(&aux->hw_mutex); | ||
| 768 | |||
| 769 | return err; | 765 | return err; |
| 770 | } | 766 | } |
| 771 | 767 | ||
| @@ -774,22 +770,64 @@ static const struct i2c_algorithm drm_dp_i2c_algo = { | |||
| 774 | .master_xfer = drm_dp_i2c_xfer, | 770 | .master_xfer = drm_dp_i2c_xfer, |
| 775 | }; | 771 | }; |
| 776 | 772 | ||
| 773 | static struct drm_dp_aux *i2c_to_aux(struct i2c_adapter *i2c) | ||
| 774 | { | ||
| 775 | return container_of(i2c, struct drm_dp_aux, ddc); | ||
| 776 | } | ||
| 777 | |||
| 778 | static void lock_bus(struct i2c_adapter *i2c, unsigned int flags) | ||
| 779 | { | ||
| 780 | mutex_lock(&i2c_to_aux(i2c)->hw_mutex); | ||
| 781 | } | ||
| 782 | |||
| 783 | static int trylock_bus(struct i2c_adapter *i2c, unsigned int flags) | ||
| 784 | { | ||
| 785 | return mutex_trylock(&i2c_to_aux(i2c)->hw_mutex); | ||
| 786 | } | ||
| 787 | |||
| 788 | static void unlock_bus(struct i2c_adapter *i2c, unsigned int flags) | ||
| 789 | { | ||
| 790 | mutex_unlock(&i2c_to_aux(i2c)->hw_mutex); | ||
| 791 | } | ||
| 792 | |||
| 777 | /** | 793 | /** |
| 778 | * drm_dp_aux_register() - initialise and register aux channel | 794 | * drm_dp_aux_init() - minimally initialise an aux channel |
| 779 | * @aux: DisplayPort AUX channel | 795 | * @aux: DisplayPort AUX channel |
| 780 | * | 796 | * |
| 781 | * Returns 0 on success or a negative error code on failure. | 797 | * If you need to use the drm_dp_aux's i2c adapter prior to registering it |
| 798 | * with the outside world, call drm_dp_aux_init() first. You must still | ||
| 799 | * call drm_dp_aux_register() once the connector has been registered to | ||
| 800 | * allow userspace access to the auxiliary DP channel. | ||
| 782 | */ | 801 | */ |
| 783 | int drm_dp_aux_register(struct drm_dp_aux *aux) | 802 | void drm_dp_aux_init(struct drm_dp_aux *aux) |
| 784 | { | 803 | { |
| 785 | int ret; | ||
| 786 | |||
| 787 | mutex_init(&aux->hw_mutex); | 804 | mutex_init(&aux->hw_mutex); |
| 788 | 805 | ||
| 789 | aux->ddc.algo = &drm_dp_i2c_algo; | 806 | aux->ddc.algo = &drm_dp_i2c_algo; |
| 790 | aux->ddc.algo_data = aux; | 807 | aux->ddc.algo_data = aux; |
| 791 | aux->ddc.retries = 3; | 808 | aux->ddc.retries = 3; |
| 792 | 809 | ||
| 810 | aux->ddc.lock_bus = lock_bus; | ||
| 811 | aux->ddc.trylock_bus = trylock_bus; | ||
| 812 | aux->ddc.unlock_bus = unlock_bus; | ||
| 813 | } | ||
| 814 | EXPORT_SYMBOL(drm_dp_aux_init); | ||
| 815 | |||
| 816 | /** | ||
| 817 | * drm_dp_aux_register() - initialise and register aux channel | ||
| 818 | * @aux: DisplayPort AUX channel | ||
| 819 | * | ||
| 820 | * Automatically calls drm_dp_aux_init() if this hasn't been done yet. | ||
| 821 | * | ||
| 822 | * Returns 0 on success or a negative error code on failure. | ||
| 823 | */ | ||
| 824 | int drm_dp_aux_register(struct drm_dp_aux *aux) | ||
| 825 | { | ||
| 826 | int ret; | ||
| 827 | |||
| 828 | if (!aux->ddc.algo) | ||
| 829 | drm_dp_aux_init(aux); | ||
| 830 | |||
| 793 | aux->ddc.class = I2C_CLASS_DDC; | 831 | aux->ddc.class = I2C_CLASS_DDC; |
| 794 | aux->ddc.owner = THIS_MODULE; | 832 | aux->ddc.owner = THIS_MODULE; |
| 795 | aux->ddc.dev.parent = aux->dev; | 833 | aux->ddc.dev.parent = aux->dev; |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 8b2582aeaab6..aead9ffcbe29 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
| @@ -34,8 +34,10 @@ | |||
| 34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
| 35 | #include <drm/drmP.h> | 35 | #include <drm/drmP.h> |
| 36 | #include <drm/drm_core.h> | 36 | #include <drm/drm_core.h> |
| 37 | #include "drm_crtc_internal.h" | ||
| 37 | #include "drm_legacy.h" | 38 | #include "drm_legacy.h" |
| 38 | #include "drm_internal.h" | 39 | #include "drm_internal.h" |
| 40 | #include "drm_crtc_internal.h" | ||
| 39 | 41 | ||
| 40 | /* | 42 | /* |
| 41 | * drm_debug: Enable debug output. | 43 | * drm_debug: Enable debug output. |
| @@ -93,114 +95,6 @@ void drm_ut_debug_printk(const char *function_name, const char *format, ...) | |||
| 93 | } | 95 | } |
| 94 | EXPORT_SYMBOL(drm_ut_debug_printk); | 96 | EXPORT_SYMBOL(drm_ut_debug_printk); |
| 95 | 97 | ||
| 96 | struct drm_master *drm_master_create(struct drm_minor *minor) | ||
| 97 | { | ||
| 98 | struct drm_master *master; | ||
| 99 | |||
| 100 | master = kzalloc(sizeof(*master), GFP_KERNEL); | ||
| 101 | if (!master) | ||
| 102 | return NULL; | ||
| 103 | |||
| 104 | kref_init(&master->refcount); | ||
| 105 | spin_lock_init(&master->lock.spinlock); | ||
| 106 | init_waitqueue_head(&master->lock.lock_queue); | ||
| 107 | idr_init(&master->magic_map); | ||
| 108 | master->minor = minor; | ||
| 109 | |||
| 110 | return master; | ||
| 111 | } | ||
| 112 | |||
| 113 | struct drm_master *drm_master_get(struct drm_master *master) | ||
| 114 | { | ||
| 115 | kref_get(&master->refcount); | ||
| 116 | return master; | ||
| 117 | } | ||
| 118 | EXPORT_SYMBOL(drm_master_get); | ||
| 119 | |||
| 120 | static void drm_master_destroy(struct kref *kref) | ||
| 121 | { | ||
| 122 | struct drm_master *master = container_of(kref, struct drm_master, refcount); | ||
| 123 | struct drm_device *dev = master->minor->dev; | ||
| 124 | |||
| 125 | if (dev->driver->master_destroy) | ||
| 126 | dev->driver->master_destroy(dev, master); | ||
| 127 | |||
| 128 | drm_legacy_master_rmmaps(dev, master); | ||
| 129 | |||
| 130 | idr_destroy(&master->magic_map); | ||
| 131 | kfree(master->unique); | ||
| 132 | kfree(master); | ||
| 133 | } | ||
| 134 | |||
| 135 | void drm_master_put(struct drm_master **master) | ||
| 136 | { | ||
| 137 | kref_put(&(*master)->refcount, drm_master_destroy); | ||
| 138 | *master = NULL; | ||
| 139 | } | ||
| 140 | EXPORT_SYMBOL(drm_master_put); | ||
| 141 | |||
| 142 | int drm_setmaster_ioctl(struct drm_device *dev, void *data, | ||
| 143 | struct drm_file *file_priv) | ||
| 144 | { | ||
| 145 | int ret = 0; | ||
| 146 | |||
| 147 | mutex_lock(&dev->master_mutex); | ||
| 148 | if (file_priv->is_master) | ||
| 149 | goto out_unlock; | ||
| 150 | |||
| 151 | if (file_priv->minor->master) { | ||
| 152 | ret = -EINVAL; | ||
| 153 | goto out_unlock; | ||
| 154 | } | ||
| 155 | |||
| 156 | if (!file_priv->master) { | ||
| 157 | ret = -EINVAL; | ||
| 158 | goto out_unlock; | ||
| 159 | } | ||
| 160 | |||
| 161 | if (!file_priv->allowed_master) { | ||
| 162 | ret = drm_new_set_master(dev, file_priv); | ||
| 163 | goto out_unlock; | ||
| 164 | } | ||
| 165 | |||
| 166 | file_priv->minor->master = drm_master_get(file_priv->master); | ||
| 167 | file_priv->is_master = 1; | ||
| 168 | if (dev->driver->master_set) { | ||
| 169 | ret = dev->driver->master_set(dev, file_priv, false); | ||
| 170 | if (unlikely(ret != 0)) { | ||
| 171 | file_priv->is_master = 0; | ||
| 172 | drm_master_put(&file_priv->minor->master); | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | out_unlock: | ||
| 177 | mutex_unlock(&dev->master_mutex); | ||
| 178 | return ret; | ||
| 179 | } | ||
| 180 | |||
| 181 | int drm_dropmaster_ioctl(struct drm_device *dev, void *data, | ||
| 182 | struct drm_file *file_priv) | ||
| 183 | { | ||
| 184 | int ret = -EINVAL; | ||
| 185 | |||
| 186 | mutex_lock(&dev->master_mutex); | ||
| 187 | if (!file_priv->is_master) | ||
| 188 | goto out_unlock; | ||
| 189 | |||
| 190 | if (!file_priv->minor->master) | ||
| 191 | goto out_unlock; | ||
| 192 | |||
| 193 | ret = 0; | ||
| 194 | if (dev->driver->master_drop) | ||
| 195 | dev->driver->master_drop(dev, file_priv, false); | ||
| 196 | drm_master_put(&file_priv->minor->master); | ||
| 197 | file_priv->is_master = 0; | ||
| 198 | |||
| 199 | out_unlock: | ||
| 200 | mutex_unlock(&dev->master_mutex); | ||
| 201 | return ret; | ||
| 202 | } | ||
| 203 | |||
| 204 | /* | 98 | /* |
| 205 | * DRM Minors | 99 | * DRM Minors |
| 206 | * A DRM device can provide several char-dev interfaces on the DRM-Major. Each | 100 | * A DRM device can provide several char-dev interfaces on the DRM-Major. Each |
| @@ -405,10 +299,9 @@ void drm_minor_release(struct drm_minor *minor) | |||
| 405 | * callbacks implemented by the driver. The driver then needs to initialize all | 299 | * callbacks implemented by the driver. The driver then needs to initialize all |
| 406 | * the various subsystems for the drm device like memory management, vblank | 300 | * the various subsystems for the drm device like memory management, vblank |
| 407 | * handling, modesetting support and intial output configuration plus obviously | 301 | * handling, modesetting support and intial output configuration plus obviously |
| 408 | * initialize all the corresponding hardware bits. An important part of this is | 302 | * initialize all the corresponding hardware bits. Finally when everything is up |
| 409 | * also calling drm_dev_set_unique() to set the userspace-visible unique name of | 303 | * and running and ready for userspace the device instance can be published |
| 410 | * this device instance. Finally when everything is up and running and ready for | 304 | * using drm_dev_register(). |
| 411 | * userspace the device instance can be published using drm_dev_register(). | ||
| 412 | * | 305 | * |
| 413 | * There is also deprecated support for initalizing device instances using | 306 | * There is also deprecated support for initalizing device instances using |
| 414 | * bus-specific helpers and the ->load() callback. But due to | 307 | * bus-specific helpers and the ->load() callback. But due to |
| @@ -430,6 +323,14 @@ void drm_minor_release(struct drm_minor *minor) | |||
| 430 | * dev_priv field of &drm_device. | 323 | * dev_priv field of &drm_device. |
| 431 | */ | 324 | */ |
| 432 | 325 | ||
| 326 | static int drm_dev_set_unique(struct drm_device *dev, const char *name) | ||
| 327 | { | ||
| 328 | kfree(dev->unique); | ||
| 329 | dev->unique = kstrdup(name, GFP_KERNEL); | ||
| 330 | |||
| 331 | return dev->unique ? 0 : -ENOMEM; | ||
| 332 | } | ||
| 333 | |||
| 433 | /** | 334 | /** |
| 434 | * drm_put_dev - Unregister and release a DRM device | 335 | * drm_put_dev - Unregister and release a DRM device |
| 435 | * @dev: DRM device | 336 | * @dev: DRM device |
| @@ -549,11 +450,12 @@ static void drm_fs_inode_free(struct inode *inode) | |||
| 549 | } | 450 | } |
| 550 | 451 | ||
| 551 | /** | 452 | /** |
| 552 | * drm_dev_alloc - Allocate new DRM device | 453 | * drm_dev_init - Initialise new DRM device |
| 553 | * @driver: DRM driver to allocate device for | 454 | * @dev: DRM device |
| 455 | * @driver: DRM driver | ||
| 554 | * @parent: Parent device object | 456 | * @parent: Parent device object |
| 555 | * | 457 | * |
| 556 | * Allocate and initialize a new DRM device. No device registration is done. | 458 | * Initialize a new DRM device. No device registration is done. |
| 557 | * Call drm_dev_register() to advertice the device to user space and register it | 459 | * Call drm_dev_register() to advertice the device to user space and register it |
| 558 | * with other core subsystems. This should be done last in the device | 460 | * with other core subsystems. This should be done last in the device |
| 559 | * initialization sequence to make sure userspace can't access an inconsistent | 461 | * initialization sequence to make sure userspace can't access an inconsistent |
| @@ -564,19 +466,18 @@ static void drm_fs_inode_free(struct inode *inode) | |||
| 564 | * | 466 | * |
| 565 | * Note that for purely virtual devices @parent can be NULL. | 467 | * Note that for purely virtual devices @parent can be NULL. |
| 566 | * | 468 | * |
| 469 | * Drivers that do not want to allocate their own device struct | ||
| 470 | * embedding struct &drm_device can call drm_dev_alloc() instead. | ||
| 471 | * | ||
| 567 | * RETURNS: | 472 | * RETURNS: |
| 568 | * Pointer to new DRM device, or NULL if out of memory. | 473 | * 0 on success, or error code on failure. |
| 569 | */ | 474 | */ |
| 570 | struct drm_device *drm_dev_alloc(struct drm_driver *driver, | 475 | int drm_dev_init(struct drm_device *dev, |
| 571 | struct device *parent) | 476 | struct drm_driver *driver, |
| 477 | struct device *parent) | ||
| 572 | { | 478 | { |
| 573 | struct drm_device *dev; | ||
| 574 | int ret; | 479 | int ret; |
| 575 | 480 | ||
| 576 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 577 | if (!dev) | ||
| 578 | return NULL; | ||
| 579 | |||
| 580 | kref_init(&dev->ref); | 481 | kref_init(&dev->ref); |
| 581 | dev->dev = parent; | 482 | dev->dev = parent; |
| 582 | dev->driver = driver; | 483 | dev->driver = driver; |
| @@ -617,7 +518,8 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver, | |||
| 617 | if (ret) | 518 | if (ret) |
| 618 | goto err_minors; | 519 | goto err_minors; |
| 619 | 520 | ||
| 620 | if (drm_ht_create(&dev->map_hash, 12)) | 521 | ret = drm_ht_create(&dev->map_hash, 12); |
| 522 | if (ret) | ||
| 621 | goto err_minors; | 523 | goto err_minors; |
| 622 | 524 | ||
| 623 | drm_legacy_ctxbitmap_init(dev); | 525 | drm_legacy_ctxbitmap_init(dev); |
| @@ -630,13 +532,13 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver, | |||
| 630 | } | 532 | } |
| 631 | } | 533 | } |
| 632 | 534 | ||
| 633 | if (parent) { | 535 | /* Use the parent device name as DRM device unique identifier, but fall |
| 634 | ret = drm_dev_set_unique(dev, dev_name(parent)); | 536 | * back to the driver name for virtual devices like vgem. */ |
| 635 | if (ret) | 537 | ret = drm_dev_set_unique(dev, parent ? dev_name(parent) : driver->name); |
| 636 | goto err_setunique; | 538 | if (ret) |
| 637 | } | 539 | goto err_setunique; |
| 638 | 540 | ||
| 639 | return dev; | 541 | return 0; |
| 640 | 542 | ||
| 641 | err_setunique: | 543 | err_setunique: |
| 642 | if (drm_core_check_feature(dev, DRIVER_GEM)) | 544 | if (drm_core_check_feature(dev, DRIVER_GEM)) |
| @@ -651,8 +553,49 @@ err_minors: | |||
| 651 | drm_fs_inode_free(dev->anon_inode); | 553 | drm_fs_inode_free(dev->anon_inode); |
| 652 | err_free: | 554 | err_free: |
| 653 | mutex_destroy(&dev->master_mutex); | 555 | mutex_destroy(&dev->master_mutex); |
| 654 | kfree(dev); | 556 | return ret; |
| 655 | return NULL; | 557 | } |
| 558 | EXPORT_SYMBOL(drm_dev_init); | ||
| 559 | |||
| 560 | /** | ||
| 561 | * drm_dev_alloc - Allocate new DRM device | ||
| 562 | * @driver: DRM driver to allocate device for | ||
| 563 | * @parent: Parent device object | ||
| 564 | * | ||
| 565 | * Allocate and initialize a new DRM device. No device registration is done. | ||
| 566 | * Call drm_dev_register() to advertice the device to user space and register it | ||
| 567 | * with other core subsystems. This should be done last in the device | ||
| 568 | * initialization sequence to make sure userspace can't access an inconsistent | ||
| 569 | * state. | ||
| 570 | * | ||
| 571 | * The initial ref-count of the object is 1. Use drm_dev_ref() and | ||
| 572 | * drm_dev_unref() to take and drop further ref-counts. | ||
| 573 | * | ||
| 574 | * Note that for purely virtual devices @parent can be NULL. | ||
| 575 | * | ||
| 576 | * Drivers that wish to subclass or embed struct &drm_device into their | ||
| 577 | * own struct should look at using drm_dev_init() instead. | ||
| 578 | * | ||
| 579 | * RETURNS: | ||
| 580 | * Pointer to new DRM device, or NULL if out of memory. | ||
| 581 | */ | ||
| 582 | struct drm_device *drm_dev_alloc(struct drm_driver *driver, | ||
| 583 | struct device *parent) | ||
| 584 | { | ||
| 585 | struct drm_device *dev; | ||
| 586 | int ret; | ||
| 587 | |||
| 588 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 589 | if (!dev) | ||
| 590 | return NULL; | ||
| 591 | |||
| 592 | ret = drm_dev_init(dev, driver, parent); | ||
| 593 | if (ret) { | ||
| 594 | kfree(dev); | ||
| 595 | return NULL; | ||
| 596 | } | ||
| 597 | |||
| 598 | return dev; | ||
| 656 | } | 599 | } |
| 657 | EXPORT_SYMBOL(drm_dev_alloc); | 600 | EXPORT_SYMBOL(drm_dev_alloc); |
| 658 | 601 | ||
| @@ -716,11 +659,7 @@ EXPORT_SYMBOL(drm_dev_unref); | |||
| 716 | * | 659 | * |
| 717 | * Register the DRM device @dev with the system, advertise device to user-space | 660 | * Register the DRM device @dev with the system, advertise device to user-space |
| 718 | * and start normal device operation. @dev must be allocated via drm_dev_alloc() | 661 | * and start normal device operation. @dev must be allocated via drm_dev_alloc() |
| 719 | * previously. Right after drm_dev_register() the driver should call | 662 | * previously. |
| 720 | * drm_connector_register_all() to register all connectors in sysfs. This is | ||
| 721 | * a separate call for backward compatibility with drivers still using | ||
| 722 | * the deprecated ->load() callback, where connectors are registered from within | ||
| 723 | * the ->load() callback. | ||
| 724 | * | 663 | * |
| 725 | * Never call this twice on any device! | 664 | * Never call this twice on any device! |
| 726 | * | 665 | * |
| @@ -757,6 +696,9 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) | |||
| 757 | goto err_minors; | 696 | goto err_minors; |
| 758 | } | 697 | } |
| 759 | 698 | ||
| 699 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
| 700 | drm_modeset_register_all(dev); | ||
| 701 | |||
| 760 | ret = 0; | 702 | ret = 0; |
| 761 | goto out_unlock; | 703 | goto out_unlock; |
| 762 | 704 | ||
| @@ -787,6 +729,9 @@ void drm_dev_unregister(struct drm_device *dev) | |||
| 787 | 729 | ||
| 788 | drm_lastclose(dev); | 730 | drm_lastclose(dev); |
| 789 | 731 | ||
| 732 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
| 733 | drm_modeset_unregister_all(dev); | ||
| 734 | |||
| 790 | if (dev->driver->unload) | 735 | if (dev->driver->unload) |
| 791 | dev->driver->unload(dev); | 736 | dev->driver->unload(dev); |
| 792 | 737 | ||
| @@ -804,26 +749,6 @@ void drm_dev_unregister(struct drm_device *dev) | |||
| 804 | } | 749 | } |
| 805 | EXPORT_SYMBOL(drm_dev_unregister); | 750 | EXPORT_SYMBOL(drm_dev_unregister); |
| 806 | 751 | ||
| 807 | /** | ||
| 808 | * drm_dev_set_unique - Set the unique name of a DRM device | ||
| 809 | * @dev: device of which to set the unique name | ||
| 810 | * @name: unique name | ||
| 811 | * | ||
| 812 | * Sets the unique name of a DRM device using the specified string. Drivers | ||
| 813 | * can use this at driver probe time if the unique name of the devices they | ||
| 814 | * drive is static. | ||
| 815 | * | ||
| 816 | * Return: 0 on success or a negative error code on failure. | ||
| 817 | */ | ||
| 818 | int drm_dev_set_unique(struct drm_device *dev, const char *name) | ||
| 819 | { | ||
| 820 | kfree(dev->unique); | ||
| 821 | dev->unique = kstrdup(name, GFP_KERNEL); | ||
| 822 | |||
| 823 | return dev->unique ? 0 : -ENOMEM; | ||
| 824 | } | ||
| 825 | EXPORT_SYMBOL(drm_dev_set_unique); | ||
| 826 | |||
| 827 | /* | 752 | /* |
| 828 | * DRM Core | 753 | * DRM Core |
| 829 | * The DRM core module initializes all global DRM objects and makes them | 754 | * The DRM core module initializes all global DRM objects and makes them |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 0bac5246e5a7..ce54e985d91b 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
| @@ -464,7 +464,7 @@ static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper) | |||
| 464 | 464 | ||
| 465 | /* Sometimes user space wants everything disabled, so don't steal the | 465 | /* Sometimes user space wants everything disabled, so don't steal the |
| 466 | * display if there's a master. */ | 466 | * display if there's a master. */ |
| 467 | if (dev->primary->master) | 467 | if (lockless_dereference(dev->master)) |
| 468 | return false; | 468 | return false; |
| 469 | 469 | ||
| 470 | drm_for_each_crtc(crtc, dev) { | 470 | drm_for_each_crtc(crtc, dev) { |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index a27bc7cda975..323c238fcac7 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <linux/module.h> | 40 | #include <linux/module.h> |
| 41 | #include "drm_legacy.h" | 41 | #include "drm_legacy.h" |
| 42 | #include "drm_internal.h" | 42 | #include "drm_internal.h" |
| 43 | #include "drm_crtc_internal.h" | ||
| 43 | 44 | ||
| 44 | /* from BKL pushdown */ | 45 | /* from BKL pushdown */ |
| 45 | DEFINE_MUTEX(drm_global_mutex); | 46 | DEFINE_MUTEX(drm_global_mutex); |
| @@ -168,60 +169,6 @@ static int drm_cpu_valid(void) | |||
| 168 | } | 169 | } |
| 169 | 170 | ||
| 170 | /* | 171 | /* |
| 171 | * drm_new_set_master - Allocate a new master object and become master for the | ||
| 172 | * associated master realm. | ||
| 173 | * | ||
| 174 | * @dev: The associated device. | ||
| 175 | * @fpriv: File private identifying the client. | ||
| 176 | * | ||
| 177 | * This function must be called with dev::struct_mutex held. | ||
| 178 | * Returns negative error code on failure. Zero on success. | ||
| 179 | */ | ||
| 180 | int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) | ||
| 181 | { | ||
| 182 | struct drm_master *old_master; | ||
| 183 | int ret; | ||
| 184 | |||
| 185 | lockdep_assert_held_once(&dev->master_mutex); | ||
| 186 | |||
| 187 | /* create a new master */ | ||
| 188 | fpriv->minor->master = drm_master_create(fpriv->minor); | ||
| 189 | if (!fpriv->minor->master) | ||
| 190 | return -ENOMEM; | ||
| 191 | |||
| 192 | /* take another reference for the copy in the local file priv */ | ||
| 193 | old_master = fpriv->master; | ||
| 194 | fpriv->master = drm_master_get(fpriv->minor->master); | ||
| 195 | |||
| 196 | if (dev->driver->master_create) { | ||
| 197 | ret = dev->driver->master_create(dev, fpriv->master); | ||
| 198 | if (ret) | ||
| 199 | goto out_err; | ||
| 200 | } | ||
| 201 | if (dev->driver->master_set) { | ||
| 202 | ret = dev->driver->master_set(dev, fpriv, true); | ||
| 203 | if (ret) | ||
| 204 | goto out_err; | ||
| 205 | } | ||
| 206 | |||
| 207 | fpriv->is_master = 1; | ||
| 208 | fpriv->allowed_master = 1; | ||
| 209 | fpriv->authenticated = 1; | ||
| 210 | if (old_master) | ||
| 211 | drm_master_put(&old_master); | ||
| 212 | |||
| 213 | return 0; | ||
| 214 | |||
| 215 | out_err: | ||
| 216 | /* drop both references and restore old master on failure */ | ||
| 217 | drm_master_put(&fpriv->minor->master); | ||
| 218 | drm_master_put(&fpriv->master); | ||
| 219 | fpriv->master = old_master; | ||
| 220 | |||
| 221 | return ret; | ||
| 222 | } | ||
| 223 | |||
| 224 | /* | ||
| 225 | * Called whenever a process opens /dev/drm. | 172 | * Called whenever a process opens /dev/drm. |
| 226 | * | 173 | * |
| 227 | * \param filp file pointer. | 174 | * \param filp file pointer. |
| @@ -283,19 +230,11 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) | |||
| 283 | goto out_prime_destroy; | 230 | goto out_prime_destroy; |
| 284 | } | 231 | } |
| 285 | 232 | ||
| 286 | /* if there is no current master make this fd it, but do not create | 233 | if (drm_is_primary_client(priv)) { |
| 287 | * any master object for render clients */ | 234 | ret = drm_master_open(priv); |
| 288 | mutex_lock(&dev->master_mutex); | ||
| 289 | if (drm_is_primary_client(priv) && !priv->minor->master) { | ||
| 290 | /* create a new master */ | ||
| 291 | ret = drm_new_set_master(dev, priv); | ||
| 292 | if (ret) | 235 | if (ret) |
| 293 | goto out_close; | 236 | goto out_close; |
| 294 | } else if (drm_is_primary_client(priv)) { | ||
| 295 | /* get a reference to the master */ | ||
| 296 | priv->master = drm_master_get(priv->minor->master); | ||
| 297 | } | 237 | } |
| 298 | mutex_unlock(&dev->master_mutex); | ||
| 299 | 238 | ||
| 300 | mutex_lock(&dev->filelist_mutex); | 239 | mutex_lock(&dev->filelist_mutex); |
| 301 | list_add(&priv->lhead, &dev->filelist); | 240 | list_add(&priv->lhead, &dev->filelist); |
| @@ -324,7 +263,6 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) | |||
| 324 | return 0; | 263 | return 0; |
| 325 | 264 | ||
| 326 | out_close: | 265 | out_close: |
| 327 | mutex_unlock(&dev->master_mutex); | ||
| 328 | if (dev->driver->postclose) | 266 | if (dev->driver->postclose) |
| 329 | dev->driver->postclose(dev, priv); | 267 | dev->driver->postclose(dev, priv); |
| 330 | out_prime_destroy: | 268 | out_prime_destroy: |
| @@ -338,18 +276,6 @@ out_prime_destroy: | |||
| 338 | return ret; | 276 | return ret; |
| 339 | } | 277 | } |
| 340 | 278 | ||
| 341 | static void drm_master_release(struct drm_device *dev, struct file *filp) | ||
| 342 | { | ||
| 343 | struct drm_file *file_priv = filp->private_data; | ||
| 344 | |||
| 345 | if (drm_legacy_i_have_hw_lock(dev, file_priv)) { | ||
| 346 | DRM_DEBUG("File %p released, freeing lock for context %d\n", | ||
| 347 | filp, _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); | ||
| 348 | drm_legacy_lock_free(&file_priv->master->lock, | ||
| 349 | _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); | ||
| 350 | } | ||
| 351 | } | ||
| 352 | |||
| 353 | static void drm_events_release(struct drm_file *file_priv) | 279 | static void drm_events_release(struct drm_file *file_priv) |
| 354 | { | 280 | { |
| 355 | struct drm_device *dev = file_priv->minor->dev; | 281 | struct drm_device *dev = file_priv->minor->dev; |
| @@ -451,11 +377,6 @@ int drm_release(struct inode *inode, struct file *filp) | |||
| 451 | list_del(&file_priv->lhead); | 377 | list_del(&file_priv->lhead); |
| 452 | mutex_unlock(&dev->filelist_mutex); | 378 | mutex_unlock(&dev->filelist_mutex); |
| 453 | 379 | ||
| 454 | mutex_lock(&dev->struct_mutex); | ||
| 455 | if (file_priv->magic) | ||
| 456 | idr_remove(&file_priv->master->magic_map, file_priv->magic); | ||
| 457 | mutex_unlock(&dev->struct_mutex); | ||
| 458 | |||
| 459 | if (dev->driver->preclose) | 380 | if (dev->driver->preclose) |
| 460 | dev->driver->preclose(dev, file_priv); | 381 | dev->driver->preclose(dev, file_priv); |
| 461 | 382 | ||
| @@ -468,9 +389,8 @@ int drm_release(struct inode *inode, struct file *filp) | |||
| 468 | (long)old_encode_dev(file_priv->minor->kdev->devt), | 389 | (long)old_encode_dev(file_priv->minor->kdev->devt), |
| 469 | dev->open_count); | 390 | dev->open_count); |
| 470 | 391 | ||
| 471 | /* if the master has gone away we can't do anything with the lock */ | 392 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
| 472 | if (file_priv->minor->master) | 393 | drm_legacy_lock_release(dev, filp); |
| 473 | drm_master_release(dev, filp); | ||
| 474 | 394 | ||
| 475 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) | 395 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) |
| 476 | drm_legacy_reclaim_buffers(dev, file_priv); | 396 | drm_legacy_reclaim_buffers(dev, file_priv); |
| @@ -487,43 +407,12 @@ int drm_release(struct inode *inode, struct file *filp) | |||
| 487 | 407 | ||
| 488 | drm_legacy_ctxbitmap_flush(dev, file_priv); | 408 | drm_legacy_ctxbitmap_flush(dev, file_priv); |
| 489 | 409 | ||
| 490 | mutex_lock(&dev->master_mutex); | 410 | if (drm_is_primary_client(file_priv)) |
| 491 | 411 | drm_master_release(file_priv); | |
| 492 | if (file_priv->is_master) { | ||
| 493 | struct drm_master *master = file_priv->master; | ||
| 494 | |||
| 495 | /* | ||
| 496 | * Since the master is disappearing, so is the | ||
| 497 | * possibility to lock. | ||
| 498 | */ | ||
| 499 | mutex_lock(&dev->struct_mutex); | ||
| 500 | if (master->lock.hw_lock) { | ||
| 501 | if (dev->sigdata.lock == master->lock.hw_lock) | ||
| 502 | dev->sigdata.lock = NULL; | ||
| 503 | master->lock.hw_lock = NULL; | ||
| 504 | master->lock.file_priv = NULL; | ||
| 505 | wake_up_interruptible_all(&master->lock.lock_queue); | ||
| 506 | } | ||
| 507 | mutex_unlock(&dev->struct_mutex); | ||
| 508 | |||
| 509 | if (file_priv->minor->master == file_priv->master) { | ||
| 510 | /* drop the reference held my the minor */ | ||
| 511 | if (dev->driver->master_drop) | ||
| 512 | dev->driver->master_drop(dev, file_priv, true); | ||
| 513 | drm_master_put(&file_priv->minor->master); | ||
| 514 | } | ||
| 515 | } | ||
| 516 | |||
| 517 | /* drop the master reference held by the file priv */ | ||
| 518 | if (file_priv->master) | ||
| 519 | drm_master_put(&file_priv->master); | ||
| 520 | file_priv->is_master = 0; | ||
| 521 | mutex_unlock(&dev->master_mutex); | ||
| 522 | 412 | ||
| 523 | if (dev->driver->postclose) | 413 | if (dev->driver->postclose) |
| 524 | dev->driver->postclose(dev, file_priv); | 414 | dev->driver->postclose(dev, file_priv); |
| 525 | 415 | ||
| 526 | |||
| 527 | if (drm_core_check_feature(dev, DRIVER_PRIME)) | 416 | if (drm_core_check_feature(dev, DRIVER_PRIME)) |
| 528 | drm_prime_destroy_file_private(&file_priv->prime); | 417 | drm_prime_destroy_file_private(&file_priv->prime); |
| 529 | 418 | ||
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index 5d469b2f26f4..9ae353f4dd06 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c | |||
| @@ -50,106 +50,24 @@ int drm_name_info(struct seq_file *m, void *data) | |||
| 50 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 50 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
| 51 | struct drm_minor *minor = node->minor; | 51 | struct drm_minor *minor = node->minor; |
| 52 | struct drm_device *dev = minor->dev; | 52 | struct drm_device *dev = minor->dev; |
| 53 | struct drm_master *master = minor->master; | 53 | struct drm_master *master; |
| 54 | if (!master) | ||
| 55 | return 0; | ||
| 56 | |||
| 57 | if (master->unique) { | ||
| 58 | seq_printf(m, "%s %s %s\n", | ||
| 59 | dev->driver->name, | ||
| 60 | dev_name(dev->dev), master->unique); | ||
| 61 | } else { | ||
| 62 | seq_printf(m, "%s %s\n", | ||
| 63 | dev->driver->name, dev_name(dev->dev)); | ||
| 64 | } | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Called when "/proc/dri/.../vm" is read. | ||
| 70 | * | ||
| 71 | * Prints information about all mappings in drm_device::maplist. | ||
| 72 | */ | ||
| 73 | int drm_vm_info(struct seq_file *m, void *data) | ||
| 74 | { | ||
| 75 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
| 76 | struct drm_device *dev = node->minor->dev; | ||
| 77 | struct drm_local_map *map; | ||
| 78 | struct drm_map_list *r_list; | ||
| 79 | |||
| 80 | /* Hardcoded from _DRM_FRAME_BUFFER, | ||
| 81 | _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and | ||
| 82 | _DRM_SCATTER_GATHER and _DRM_CONSISTENT */ | ||
| 83 | const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" }; | ||
| 84 | const char *type; | ||
| 85 | int i; | ||
| 86 | |||
| 87 | mutex_lock(&dev->struct_mutex); | ||
| 88 | seq_printf(m, "slot offset size type flags address mtrr\n\n"); | ||
| 89 | i = 0; | ||
| 90 | list_for_each_entry(r_list, &dev->maplist, head) { | ||
| 91 | map = r_list->map; | ||
| 92 | if (!map) | ||
| 93 | continue; | ||
| 94 | if (map->type < 0 || map->type > 5) | ||
| 95 | type = "??"; | ||
| 96 | else | ||
| 97 | type = types[map->type]; | ||
| 98 | |||
| 99 | seq_printf(m, "%4d 0x%016llx 0x%08lx %4.4s 0x%02x 0x%08lx ", | ||
| 100 | i, | ||
| 101 | (unsigned long long)map->offset, | ||
| 102 | map->size, type, map->flags, | ||
| 103 | (unsigned long) r_list->user_token); | ||
| 104 | if (map->mtrr < 0) | ||
| 105 | seq_printf(m, "none\n"); | ||
| 106 | else | ||
| 107 | seq_printf(m, "%4d\n", map->mtrr); | ||
| 108 | i++; | ||
| 109 | } | ||
| 110 | mutex_unlock(&dev->struct_mutex); | ||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | 54 | ||
| 114 | /** | 55 | mutex_lock(&dev->master_mutex); |
| 115 | * Called when "/proc/dri/.../bufs" is read. | 56 | master = dev->master; |
| 116 | */ | 57 | if (!master) |
| 117 | int drm_bufs_info(struct seq_file *m, void *data) | 58 | goto out_unlock; |
| 118 | { | 59 | |
| 119 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 60 | seq_printf(m, "%s", dev->driver->name); |
| 120 | struct drm_device *dev = node->minor->dev; | 61 | if (dev->dev) |
| 121 | struct drm_device_dma *dma; | 62 | seq_printf(m, " dev=%s", dev_name(dev->dev)); |
| 122 | int i, seg_pages; | 63 | if (master && master->unique) |
| 123 | 64 | seq_printf(m, " master=%s", master->unique); | |
| 124 | mutex_lock(&dev->struct_mutex); | 65 | if (dev->unique) |
| 125 | dma = dev->dma; | 66 | seq_printf(m, " unique=%s", dev->unique); |
| 126 | if (!dma) { | ||
| 127 | mutex_unlock(&dev->struct_mutex); | ||
| 128 | return 0; | ||
| 129 | } | ||
| 130 | |||
| 131 | seq_printf(m, " o size count free segs pages kB\n\n"); | ||
| 132 | for (i = 0; i <= DRM_MAX_ORDER; i++) { | ||
| 133 | if (dma->bufs[i].buf_count) { | ||
| 134 | seg_pages = dma->bufs[i].seg_count * (1 << dma->bufs[i].page_order); | ||
| 135 | seq_printf(m, "%2d %8d %5d %5d %5d %5d %5ld\n", | ||
| 136 | i, | ||
| 137 | dma->bufs[i].buf_size, | ||
| 138 | dma->bufs[i].buf_count, | ||
| 139 | 0, | ||
| 140 | dma->bufs[i].seg_count, | ||
| 141 | seg_pages, | ||
| 142 | seg_pages * PAGE_SIZE / 1024); | ||
| 143 | } | ||
| 144 | } | ||
| 145 | seq_printf(m, "\n"); | ||
| 146 | for (i = 0; i < dma->buf_count; i++) { | ||
| 147 | if (i && !(i % 32)) | ||
| 148 | seq_printf(m, "\n"); | ||
| 149 | seq_printf(m, " %d", dma->buflist[i]->list); | ||
| 150 | } | ||
| 151 | seq_printf(m, "\n"); | 67 | seq_printf(m, "\n"); |
| 152 | mutex_unlock(&dev->struct_mutex); | 68 | out_unlock: |
| 69 | mutex_unlock(&dev->master_mutex); | ||
| 70 | |||
| 153 | return 0; | 71 | return 0; |
| 154 | } | 72 | } |
| 155 | 73 | ||
| @@ -184,7 +102,7 @@ int drm_clients_info(struct seq_file *m, void *data) | |||
| 184 | task ? task->comm : "<unknown>", | 102 | task ? task->comm : "<unknown>", |
| 185 | pid_vnr(priv->pid), | 103 | pid_vnr(priv->pid), |
| 186 | priv->minor->index, | 104 | priv->minor->index, |
| 187 | priv->is_master ? 'y' : 'n', | 105 | drm_is_current_master(priv) ? 'y' : 'n', |
| 188 | priv->authenticated ? 'y' : 'n', | 106 | priv->authenticated ? 'y' : 'n', |
| 189 | from_kuid_munged(seq_user_ns(m), priv->uid), | 107 | from_kuid_munged(seq_user_ns(m), priv->uid), |
| 190 | priv->magic); | 108 | priv->magic); |
| @@ -194,7 +112,6 @@ int drm_clients_info(struct seq_file *m, void *data) | |||
| 194 | return 0; | 112 | return 0; |
| 195 | } | 113 | } |
| 196 | 114 | ||
| 197 | |||
| 198 | static int drm_gem_one_name_info(int id, void *ptr, void *data) | 115 | static int drm_gem_one_name_info(int id, void *ptr, void *data) |
| 199 | { | 116 | { |
| 200 | struct drm_gem_object *obj = ptr; | 117 | struct drm_gem_object *obj = ptr; |
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 902cf6a15212..b86dc9b921a5 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h | |||
| @@ -29,15 +29,9 @@ extern struct mutex drm_global_mutex; | |||
| 29 | void drm_lastclose(struct drm_device *dev); | 29 | void drm_lastclose(struct drm_device *dev); |
| 30 | 30 | ||
| 31 | /* drm_pci.c */ | 31 | /* drm_pci.c */ |
| 32 | int drm_pci_set_unique(struct drm_device *dev, | ||
| 33 | struct drm_master *master, | ||
| 34 | struct drm_unique *u); | ||
| 35 | int drm_irq_by_busid(struct drm_device *dev, void *data, | 32 | int drm_irq_by_busid(struct drm_device *dev, void *data, |
| 36 | struct drm_file *file_priv); | 33 | struct drm_file *file_priv); |
| 37 | 34 | ||
| 38 | /* drm_vm.c */ | ||
| 39 | int drm_vma_info(struct seq_file *m, void *data); | ||
| 40 | |||
| 41 | /* drm_prime.c */ | 35 | /* drm_prime.c */ |
| 42 | int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, | 36 | int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, |
| 43 | struct drm_file *file_priv); | 37 | struct drm_file *file_priv); |
| @@ -51,8 +45,6 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr | |||
| 51 | 45 | ||
| 52 | /* drm_info.c */ | 46 | /* drm_info.c */ |
| 53 | int drm_name_info(struct seq_file *m, void *data); | 47 | int drm_name_info(struct seq_file *m, void *data); |
| 54 | int drm_vm_info(struct seq_file *m, void *data); | ||
| 55 | int drm_bufs_info(struct seq_file *m, void *data); | ||
| 56 | int drm_clients_info(struct seq_file *m, void* data); | 48 | int drm_clients_info(struct seq_file *m, void* data); |
| 57 | int drm_gem_name_info(struct seq_file *m, void *data); | 49 | int drm_gem_name_info(struct seq_file *m, void *data); |
| 58 | 50 | ||
| @@ -67,6 +59,12 @@ int drm_getmagic(struct drm_device *dev, void *data, | |||
| 67 | struct drm_file *file_priv); | 59 | struct drm_file *file_priv); |
| 68 | int drm_authmagic(struct drm_device *dev, void *data, | 60 | int drm_authmagic(struct drm_device *dev, void *data, |
| 69 | struct drm_file *file_priv); | 61 | struct drm_file *file_priv); |
| 62 | int drm_setmaster_ioctl(struct drm_device *dev, void *data, | ||
| 63 | struct drm_file *file_priv); | ||
| 64 | int drm_dropmaster_ioctl(struct drm_device *dev, void *data, | ||
| 65 | struct drm_file *file_priv); | ||
| 66 | int drm_master_open(struct drm_file *file_priv); | ||
| 67 | void drm_master_release(struct drm_file *file_priv); | ||
| 70 | 68 | ||
| 71 | /* drm_sysfs.c */ | 69 | /* drm_sysfs.c */ |
| 72 | extern struct class *drm_class; | 70 | extern struct class *drm_class; |
| @@ -92,13 +90,6 @@ int drm_gem_open_ioctl(struct drm_device *dev, void *data, | |||
| 92 | void drm_gem_open(struct drm_device *dev, struct drm_file *file_private); | 90 | void drm_gem_open(struct drm_device *dev, struct drm_file *file_private); |
| 93 | void drm_gem_release(struct drm_device *dev, struct drm_file *file_private); | 91 | void drm_gem_release(struct drm_device *dev, struct drm_file *file_private); |
| 94 | 92 | ||
| 95 | /* drm_drv.c */ | ||
| 96 | int drm_setmaster_ioctl(struct drm_device *dev, void *data, | ||
| 97 | struct drm_file *file_priv); | ||
| 98 | int drm_dropmaster_ioctl(struct drm_device *dev, void *data, | ||
| 99 | struct drm_file *file_priv); | ||
| 100 | struct drm_master *drm_master_create(struct drm_minor *minor); | ||
| 101 | |||
| 102 | /* drm_debugfs.c */ | 93 | /* drm_debugfs.c */ |
| 103 | #if defined(CONFIG_DEBUG_FS) | 94 | #if defined(CONFIG_DEBUG_FS) |
| 104 | int drm_debugfs_init(struct drm_minor *minor, int minor_id, | 95 | int drm_debugfs_init(struct drm_minor *minor, int minor_id, |
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index b7a39771c152..1f84ff5f1bf8 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | #include <drm/drmP.h> | 31 | #include <drm/drmP.h> |
| 32 | #include <drm/drm_core.h> | 32 | #include <drm/drm_core.h> |
| 33 | #include <drm/drm_auth.h> | ||
| 33 | #include "drm_legacy.h" | 34 | #include "drm_legacy.h" |
| 34 | #include "drm_internal.h" | 35 | #include "drm_internal.h" |
| 35 | #include "drm_crtc_internal.h" | 36 | #include "drm_crtc_internal.h" |
| @@ -37,6 +38,64 @@ | |||
| 37 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
| 38 | #include <linux/export.h> | 39 | #include <linux/export.h> |
| 39 | 40 | ||
| 41 | /** | ||
| 42 | * DOC: getunique and setversion story | ||
| 43 | * | ||
| 44 | * BEWARE THE DRAGONS! MIND THE TRAPDOORS! | ||
| 45 | * | ||
| 46 | * In an attempt to warn anyone else who's trying to figure out what's going | ||
| 47 | * on here, I'll try to summarize the story. First things first, let's clear up | ||
| 48 | * the names, because the kernel internals, libdrm and the ioctls are all named | ||
| 49 | * differently: | ||
| 50 | * | ||
| 51 | * - GET_UNIQUE ioctl, implemented by drm_getunique is wrapped up in libdrm | ||
| 52 | * through the drmGetBusid function. | ||
| 53 | * - The libdrm drmSetBusid function is backed by the SET_UNIQUE ioctl. All | ||
| 54 | * that code is nerved in the kernel with drm_invalid_op(). | ||
| 55 | * - The internal set_busid kernel functions and driver callbacks are | ||
| 56 | * exclusively use by the SET_VERSION ioctl, because only drm 1.0 (which is | ||
| 57 | * nerved) allowed userspace to set the busid through the above ioctl. | ||
| 58 | * - Other ioctls and functions involved are named consistently. | ||
| 59 | * | ||
| 60 | * For anyone wondering what's the difference between drm 1.1 and 1.4: Correctly | ||
| 61 | * handling pci domains in the busid on ppc. Doing this correctly was only | ||
| 62 | * implemented in libdrm in 2010, hence can't be nerved yet. No one knows what's | ||
| 63 | * special with drm 1.2 and 1.3. | ||
| 64 | * | ||
| 65 | * Now the actual horror story of how device lookup in drm works. At large, | ||
| 66 | * there's 2 different ways, either by busid, or by device driver name. | ||
| 67 | * | ||
| 68 | * Opening by busid is fairly simple: | ||
| 69 | * | ||
| 70 | * 1. First call SET_VERSION to make sure pci domains are handled properly. As a | ||
| 71 | * side-effect this fills out the unique name in the master structure. | ||
| 72 | * 2. Call GET_UNIQUE to read out the unique name from the master structure, | ||
| 73 | * which matches the busid thanks to step 1. If it doesn't, proceed to try | ||
| 74 | * the next device node. | ||
| 75 | * | ||
| 76 | * Opening by name is slightly different: | ||
| 77 | * | ||
| 78 | * 1. Directly call VERSION to get the version and to match against the driver | ||
| 79 | * name returned by that ioctl. Note that SET_VERSION is not called, which | ||
| 80 | * means the the unique name for the master node just opening is _not_ filled | ||
| 81 | * out. This despite that with current drm device nodes are always bound to | ||
| 82 | * one device, and can't be runtime assigned like with drm 1.0. | ||
| 83 | * 2. Match driver name. If it mismatches, proceed to the next device node. | ||
| 84 | * 3. Call GET_UNIQUE, and check whether the unique name has length zero (by | ||
| 85 | * checking that the first byte in the string is 0). If that's not the case | ||
| 86 | * libdrm skips and proceeds to the next device node. Probably this is just | ||
| 87 | * copypasta from drm 1.0 times where a set unique name meant that the driver | ||
| 88 | * was in use already, but that's just conjecture. | ||
| 89 | * | ||
| 90 | * Long story short: To keep the open by name logic working, GET_UNIQUE must | ||
| 91 | * _not_ return a unique string when SET_VERSION hasn't been called yet, | ||
| 92 | * otherwise libdrm breaks. Even when that unique string can't ever change, and | ||
| 93 | * is totally irrelevant for actually opening the device because runtime | ||
| 94 | * assignable device instances were only support in drm 1.0, which is long dead. | ||
| 95 | * But the libdrm code in drmOpenByName somehow survived, hence this can't be | ||
| 96 | * broken. | ||
| 97 | */ | ||
| 98 | |||
| 40 | static int drm_version(struct drm_device *dev, void *data, | 99 | static int drm_version(struct drm_device *dev, void *data, |
| 41 | struct drm_file *file_priv); | 100 | struct drm_file *file_priv); |
| 42 | 101 | ||
| @@ -75,51 +134,6 @@ drm_unset_busid(struct drm_device *dev, | |||
| 75 | master->unique_len = 0; | 134 | master->unique_len = 0; |
| 76 | } | 135 | } |
| 77 | 136 | ||
| 78 | /* | ||
| 79 | * Set the bus id. | ||
| 80 | * | ||
| 81 | * \param inode device inode. | ||
| 82 | * \param file_priv DRM file private. | ||
| 83 | * \param cmd command. | ||
| 84 | * \param arg user argument, pointing to a drm_unique structure. | ||
| 85 | * \return zero on success or a negative number on failure. | ||
| 86 | * | ||
| 87 | * Copies the bus id from userspace into drm_device::unique, and verifies that | ||
| 88 | * it matches the device this DRM is attached to (EINVAL otherwise). Deprecated | ||
| 89 | * in interface version 1.1 and will return EBUSY when setversion has requested | ||
| 90 | * version 1.1 or greater. Also note that KMS is all version 1.1 and later and | ||
| 91 | * UMS was only ever supported on pci devices. | ||
| 92 | */ | ||
| 93 | static int drm_setunique(struct drm_device *dev, void *data, | ||
| 94 | struct drm_file *file_priv) | ||
| 95 | { | ||
| 96 | struct drm_unique *u = data; | ||
| 97 | struct drm_master *master = file_priv->master; | ||
| 98 | int ret; | ||
| 99 | |||
| 100 | if (master->unique_len || master->unique) | ||
| 101 | return -EBUSY; | ||
| 102 | |||
| 103 | if (!u->unique_len || u->unique_len > 1024) | ||
| 104 | return -EINVAL; | ||
| 105 | |||
| 106 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
| 107 | return 0; | ||
| 108 | |||
| 109 | if (WARN_ON(!dev->pdev)) | ||
| 110 | return -EINVAL; | ||
| 111 | |||
| 112 | ret = drm_pci_set_unique(dev, master, u); | ||
| 113 | if (ret) | ||
| 114 | goto err; | ||
| 115 | |||
| 116 | return 0; | ||
| 117 | |||
| 118 | err: | ||
| 119 | drm_unset_busid(dev, master); | ||
| 120 | return ret; | ||
| 121 | } | ||
| 122 | |||
| 123 | static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) | 137 | static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) |
| 124 | { | 138 | { |
| 125 | struct drm_master *master = file_priv->master; | 139 | struct drm_master *master = file_priv->master; |
| @@ -135,12 +149,7 @@ static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) | |||
| 135 | return ret; | 149 | return ret; |
| 136 | } | 150 | } |
| 137 | } else { | 151 | } else { |
| 138 | if (WARN(dev->unique == NULL, | 152 | WARN_ON(!dev->unique); |
| 139 | "No drm_driver.set_busid() implementation provided by " | ||
| 140 | "%ps. Use drm_dev_set_unique() to set the unique " | ||
| 141 | "name explicitly.", dev->driver)) | ||
| 142 | return -EINVAL; | ||
| 143 | |||
| 144 | master->unique = kstrdup(dev->unique, GFP_KERNEL); | 153 | master->unique = kstrdup(dev->unique, GFP_KERNEL); |
| 145 | if (master->unique) | 154 | if (master->unique) |
| 146 | master->unique_len = strlen(dev->unique); | 155 | master->unique_len = strlen(dev->unique); |
| @@ -473,7 +482,8 @@ int drm_ioctl_permit(u32 flags, struct drm_file *file_priv) | |||
| 473 | return -EACCES; | 482 | return -EACCES; |
| 474 | 483 | ||
| 475 | /* MASTER is only for master or control clients */ | 484 | /* MASTER is only for master or control clients */ |
| 476 | if (unlikely((flags & DRM_MASTER) && !file_priv->is_master && | 485 | if (unlikely((flags & DRM_MASTER) && |
| 486 | !drm_is_current_master(file_priv) && | ||
| 477 | !drm_is_control_client(file_priv))) | 487 | !drm_is_control_client(file_priv))) |
| 478 | return -EACCES; | 488 | return -EACCES; |
| 479 | 489 | ||
| @@ -504,7 +514,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = { | |||
| 504 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, | 514 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, |
| 505 | DRM_UNLOCKED|DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW), | 515 | DRM_UNLOCKED|DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW), |
| 506 | DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), | 516 | DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), |
| 507 | DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), | 517 | DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, DRM_UNLOCKED), |
| 508 | DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), | 518 | DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), |
| 509 | DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_legacy_getmap_ioctl, DRM_UNLOCKED), | 519 | DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_legacy_getmap_ioctl, DRM_UNLOCKED), |
| 510 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED), | 520 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED), |
| @@ -513,10 +523,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = { | |||
| 513 | DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0), | 523 | DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0), |
| 514 | DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), | 524 | DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), |
| 515 | 525 | ||
| 516 | DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 526 | DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 517 | DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 527 | DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 518 | DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 528 | DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 519 | DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER), | 529 | DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_UNLOCKED|DRM_MASTER), |
| 520 | 530 | ||
| 521 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_legacy_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 531 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_legacy_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 522 | DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_legacy_rmmap_ioctl, DRM_AUTH), | 532 | DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_legacy_rmmap_ioctl, DRM_AUTH), |
| @@ -524,8 +534,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { | |||
| 524 | DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_legacy_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 534 | DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_legacy_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 525 | DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_legacy_getsareactx, DRM_AUTH), | 535 | DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_legacy_getsareactx, DRM_AUTH), |
| 526 | 536 | ||
| 527 | DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY), | 537 | DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_UNLOCKED|DRM_ROOT_ONLY), |
| 528 | DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY), | 538 | DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_UNLOCKED|DRM_ROOT_ONLY), |
| 529 | 539 | ||
| 530 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_legacy_addctx, DRM_AUTH|DRM_ROOT_ONLY), | 540 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_legacy_addctx, DRM_AUTH|DRM_ROOT_ONLY), |
| 531 | DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_legacy_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 541 | DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_legacy_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 76e39c50c90c..8ca3d2bf2bda 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -994,10 +994,10 @@ static void send_vblank_event(struct drm_device *dev, | |||
| 994 | e->event.tv_sec = now->tv_sec; | 994 | e->event.tv_sec = now->tv_sec; |
| 995 | e->event.tv_usec = now->tv_usec; | 995 | e->event.tv_usec = now->tv_usec; |
| 996 | 996 | ||
| 997 | drm_send_event_locked(dev, &e->base); | ||
| 998 | |||
| 999 | trace_drm_vblank_event_delivered(e->base.pid, e->pipe, | 997 | trace_drm_vblank_event_delivered(e->base.pid, e->pipe, |
| 1000 | e->event.sequence); | 998 | e->event.sequence); |
| 999 | |||
| 1000 | drm_send_event_locked(dev, &e->base); | ||
| 1001 | } | 1001 | } |
| 1002 | 1002 | ||
| 1003 | /** | 1003 | /** |
diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h index d3b6ee357a2b..c6f422e879dd 100644 --- a/drivers/gpu/drm/drm_legacy.h +++ b/drivers/gpu/drm/drm_legacy.h | |||
| @@ -88,14 +88,10 @@ struct drm_agp_mem { | |||
| 88 | struct list_head head; | 88 | struct list_head head; |
| 89 | }; | 89 | }; |
| 90 | 90 | ||
| 91 | /* | 91 | /* drm_lock.c */ |
| 92 | * Generic Userspace Locking-API | ||
| 93 | */ | ||
| 94 | |||
| 95 | int drm_legacy_i_have_hw_lock(struct drm_device *d, struct drm_file *f); | ||
| 96 | int drm_legacy_lock(struct drm_device *d, void *v, struct drm_file *f); | 92 | int drm_legacy_lock(struct drm_device *d, void *v, struct drm_file *f); |
| 97 | int drm_legacy_unlock(struct drm_device *d, void *v, struct drm_file *f); | 93 | int drm_legacy_unlock(struct drm_device *d, void *v, struct drm_file *f); |
| 98 | int drm_legacy_lock_free(struct drm_lock_data *lock, unsigned int ctx); | 94 | void drm_legacy_lock_release(struct drm_device *dev, struct file *filp); |
| 99 | 95 | ||
| 100 | /* DMA support */ | 96 | /* DMA support */ |
| 101 | int drm_legacy_dma_setup(struct drm_device *dev); | 97 | int drm_legacy_dma_setup(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index daa2ff12101b..48ac0ebbd663 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c | |||
| @@ -41,6 +41,110 @@ | |||
| 41 | static int drm_lock_take(struct drm_lock_data *lock_data, unsigned int context); | 41 | static int drm_lock_take(struct drm_lock_data *lock_data, unsigned int context); |
| 42 | 42 | ||
| 43 | /** | 43 | /** |
| 44 | * Take the heavyweight lock. | ||
| 45 | * | ||
| 46 | * \param lock lock pointer. | ||
| 47 | * \param context locking context. | ||
| 48 | * \return one if the lock is held, or zero otherwise. | ||
| 49 | * | ||
| 50 | * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction. | ||
| 51 | */ | ||
| 52 | static | ||
| 53 | int drm_lock_take(struct drm_lock_data *lock_data, | ||
| 54 | unsigned int context) | ||
| 55 | { | ||
| 56 | unsigned int old, new, prev; | ||
| 57 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | ||
| 58 | |||
| 59 | spin_lock_bh(&lock_data->spinlock); | ||
| 60 | do { | ||
| 61 | old = *lock; | ||
| 62 | if (old & _DRM_LOCK_HELD) | ||
| 63 | new = old | _DRM_LOCK_CONT; | ||
| 64 | else { | ||
| 65 | new = context | _DRM_LOCK_HELD | | ||
| 66 | ((lock_data->user_waiters + lock_data->kernel_waiters > 1) ? | ||
| 67 | _DRM_LOCK_CONT : 0); | ||
| 68 | } | ||
| 69 | prev = cmpxchg(lock, old, new); | ||
| 70 | } while (prev != old); | ||
| 71 | spin_unlock_bh(&lock_data->spinlock); | ||
| 72 | |||
| 73 | if (_DRM_LOCKING_CONTEXT(old) == context) { | ||
| 74 | if (old & _DRM_LOCK_HELD) { | ||
| 75 | if (context != DRM_KERNEL_CONTEXT) { | ||
| 76 | DRM_ERROR("%d holds heavyweight lock\n", | ||
| 77 | context); | ||
| 78 | } | ||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | if ((_DRM_LOCKING_CONTEXT(new)) == context && (new & _DRM_LOCK_HELD)) { | ||
| 84 | /* Have lock */ | ||
| 85 | return 1; | ||
| 86 | } | ||
| 87 | return 0; | ||
| 88 | } | ||
| 89 | |||
| 90 | /** | ||
| 91 | * This takes a lock forcibly and hands it to context. Should ONLY be used | ||
| 92 | * inside *_unlock to give lock to kernel before calling *_dma_schedule. | ||
| 93 | * | ||
| 94 | * \param dev DRM device. | ||
| 95 | * \param lock lock pointer. | ||
| 96 | * \param context locking context. | ||
| 97 | * \return always one. | ||
| 98 | * | ||
| 99 | * Resets the lock file pointer. | ||
| 100 | * Marks the lock as held by the given context, via the \p cmpxchg instruction. | ||
| 101 | */ | ||
| 102 | static int drm_lock_transfer(struct drm_lock_data *lock_data, | ||
| 103 | unsigned int context) | ||
| 104 | { | ||
| 105 | unsigned int old, new, prev; | ||
| 106 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | ||
| 107 | |||
| 108 | lock_data->file_priv = NULL; | ||
| 109 | do { | ||
| 110 | old = *lock; | ||
| 111 | new = context | _DRM_LOCK_HELD; | ||
| 112 | prev = cmpxchg(lock, old, new); | ||
| 113 | } while (prev != old); | ||
| 114 | return 1; | ||
| 115 | } | ||
| 116 | |||
| 117 | static int drm_legacy_lock_free(struct drm_lock_data *lock_data, | ||
| 118 | unsigned int context) | ||
| 119 | { | ||
| 120 | unsigned int old, new, prev; | ||
| 121 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | ||
| 122 | |||
| 123 | spin_lock_bh(&lock_data->spinlock); | ||
| 124 | if (lock_data->kernel_waiters != 0) { | ||
| 125 | drm_lock_transfer(lock_data, 0); | ||
| 126 | lock_data->idle_has_lock = 1; | ||
| 127 | spin_unlock_bh(&lock_data->spinlock); | ||
| 128 | return 1; | ||
| 129 | } | ||
| 130 | spin_unlock_bh(&lock_data->spinlock); | ||
| 131 | |||
| 132 | do { | ||
| 133 | old = *lock; | ||
| 134 | new = _DRM_LOCKING_CONTEXT(old); | ||
| 135 | prev = cmpxchg(lock, old, new); | ||
| 136 | } while (prev != old); | ||
| 137 | |||
| 138 | if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { | ||
| 139 | DRM_ERROR("%d freed heavyweight lock held by %d\n", | ||
| 140 | context, _DRM_LOCKING_CONTEXT(old)); | ||
| 141 | return 1; | ||
| 142 | } | ||
| 143 | wake_up_interruptible(&lock_data->lock_queue); | ||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | /** | ||
| 44 | * Lock ioctl. | 148 | * Lock ioctl. |
| 45 | * | 149 | * |
| 46 | * \param inode device inode. | 150 | * \param inode device inode. |
| @@ -115,7 +219,7 @@ int drm_legacy_lock(struct drm_device *dev, void *data, | |||
| 115 | /* don't set the block all signals on the master process for now | 219 | /* don't set the block all signals on the master process for now |
| 116 | * really probably not the correct answer but lets us debug xkb | 220 | * really probably not the correct answer but lets us debug xkb |
| 117 | * xserver for now */ | 221 | * xserver for now */ |
| 118 | if (!file_priv->is_master) { | 222 | if (!drm_is_current_master(file_priv)) { |
| 119 | dev->sigdata.context = lock->context; | 223 | dev->sigdata.context = lock->context; |
| 120 | dev->sigdata.lock = master->lock.hw_lock; | 224 | dev->sigdata.lock = master->lock.hw_lock; |
| 121 | } | 225 | } |
| @@ -165,120 +269,6 @@ int drm_legacy_unlock(struct drm_device *dev, void *data, struct drm_file *file_ | |||
| 165 | } | 269 | } |
| 166 | 270 | ||
| 167 | /** | 271 | /** |
| 168 | * Take the heavyweight lock. | ||
| 169 | * | ||
| 170 | * \param lock lock pointer. | ||
| 171 | * \param context locking context. | ||
| 172 | * \return one if the lock is held, or zero otherwise. | ||
| 173 | * | ||
| 174 | * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction. | ||
| 175 | */ | ||
| 176 | static | ||
| 177 | int drm_lock_take(struct drm_lock_data *lock_data, | ||
| 178 | unsigned int context) | ||
| 179 | { | ||
| 180 | unsigned int old, new, prev; | ||
| 181 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | ||
| 182 | |||
| 183 | spin_lock_bh(&lock_data->spinlock); | ||
| 184 | do { | ||
| 185 | old = *lock; | ||
| 186 | if (old & _DRM_LOCK_HELD) | ||
| 187 | new = old | _DRM_LOCK_CONT; | ||
| 188 | else { | ||
| 189 | new = context | _DRM_LOCK_HELD | | ||
| 190 | ((lock_data->user_waiters + lock_data->kernel_waiters > 1) ? | ||
| 191 | _DRM_LOCK_CONT : 0); | ||
| 192 | } | ||
| 193 | prev = cmpxchg(lock, old, new); | ||
| 194 | } while (prev != old); | ||
| 195 | spin_unlock_bh(&lock_data->spinlock); | ||
| 196 | |||
| 197 | if (_DRM_LOCKING_CONTEXT(old) == context) { | ||
| 198 | if (old & _DRM_LOCK_HELD) { | ||
| 199 | if (context != DRM_KERNEL_CONTEXT) { | ||
| 200 | DRM_ERROR("%d holds heavyweight lock\n", | ||
| 201 | context); | ||
| 202 | } | ||
| 203 | return 0; | ||
| 204 | } | ||
| 205 | } | ||
| 206 | |||
| 207 | if ((_DRM_LOCKING_CONTEXT(new)) == context && (new & _DRM_LOCK_HELD)) { | ||
| 208 | /* Have lock */ | ||
| 209 | return 1; | ||
| 210 | } | ||
| 211 | return 0; | ||
| 212 | } | ||
| 213 | |||
| 214 | /** | ||
| 215 | * This takes a lock forcibly and hands it to context. Should ONLY be used | ||
| 216 | * inside *_unlock to give lock to kernel before calling *_dma_schedule. | ||
| 217 | * | ||
| 218 | * \param dev DRM device. | ||
| 219 | * \param lock lock pointer. | ||
| 220 | * \param context locking context. | ||
| 221 | * \return always one. | ||
| 222 | * | ||
| 223 | * Resets the lock file pointer. | ||
| 224 | * Marks the lock as held by the given context, via the \p cmpxchg instruction. | ||
| 225 | */ | ||
| 226 | static int drm_lock_transfer(struct drm_lock_data *lock_data, | ||
| 227 | unsigned int context) | ||
| 228 | { | ||
| 229 | unsigned int old, new, prev; | ||
| 230 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | ||
| 231 | |||
| 232 | lock_data->file_priv = NULL; | ||
| 233 | do { | ||
| 234 | old = *lock; | ||
| 235 | new = context | _DRM_LOCK_HELD; | ||
| 236 | prev = cmpxchg(lock, old, new); | ||
| 237 | } while (prev != old); | ||
| 238 | return 1; | ||
| 239 | } | ||
| 240 | |||
| 241 | /** | ||
| 242 | * Free lock. | ||
| 243 | * | ||
| 244 | * \param dev DRM device. | ||
| 245 | * \param lock lock. | ||
| 246 | * \param context context. | ||
| 247 | * | ||
| 248 | * Resets the lock file pointer. | ||
| 249 | * Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task | ||
| 250 | * waiting on the lock queue. | ||
| 251 | */ | ||
| 252 | int drm_legacy_lock_free(struct drm_lock_data *lock_data, unsigned int context) | ||
| 253 | { | ||
| 254 | unsigned int old, new, prev; | ||
| 255 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | ||
| 256 | |||
| 257 | spin_lock_bh(&lock_data->spinlock); | ||
| 258 | if (lock_data->kernel_waiters != 0) { | ||
| 259 | drm_lock_transfer(lock_data, 0); | ||
| 260 | lock_data->idle_has_lock = 1; | ||
| 261 | spin_unlock_bh(&lock_data->spinlock); | ||
| 262 | return 1; | ||
| 263 | } | ||
| 264 | spin_unlock_bh(&lock_data->spinlock); | ||
| 265 | |||
| 266 | do { | ||
| 267 | old = *lock; | ||
| 268 | new = _DRM_LOCKING_CONTEXT(old); | ||
| 269 | prev = cmpxchg(lock, old, new); | ||
| 270 | } while (prev != old); | ||
| 271 | |||
| 272 | if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { | ||
| 273 | DRM_ERROR("%d freed heavyweight lock held by %d\n", | ||
| 274 | context, _DRM_LOCKING_CONTEXT(old)); | ||
| 275 | return 1; | ||
| 276 | } | ||
| 277 | wake_up_interruptible(&lock_data->lock_queue); | ||
| 278 | return 0; | ||
| 279 | } | ||
| 280 | |||
| 281 | /** | ||
| 282 | * This function returns immediately and takes the hw lock | 272 | * This function returns immediately and takes the hw lock |
| 283 | * with the kernel context if it is free, otherwise it gets the highest priority when and if | 273 | * with the kernel context if it is free, otherwise it gets the highest priority when and if |
| 284 | * it is eventually released. | 274 | * it is eventually released. |
| @@ -330,11 +320,27 @@ void drm_legacy_idlelock_release(struct drm_lock_data *lock_data) | |||
| 330 | } | 320 | } |
| 331 | EXPORT_SYMBOL(drm_legacy_idlelock_release); | 321 | EXPORT_SYMBOL(drm_legacy_idlelock_release); |
| 332 | 322 | ||
| 333 | int drm_legacy_i_have_hw_lock(struct drm_device *dev, | 323 | static int drm_legacy_i_have_hw_lock(struct drm_device *dev, |
| 334 | struct drm_file *file_priv) | 324 | struct drm_file *file_priv) |
| 335 | { | 325 | { |
| 336 | struct drm_master *master = file_priv->master; | 326 | struct drm_master *master = file_priv->master; |
| 337 | return (file_priv->lock_count && master->lock.hw_lock && | 327 | return (file_priv->lock_count && master->lock.hw_lock && |
| 338 | _DRM_LOCK_IS_HELD(master->lock.hw_lock->lock) && | 328 | _DRM_LOCK_IS_HELD(master->lock.hw_lock->lock) && |
| 339 | master->lock.file_priv == file_priv); | 329 | master->lock.file_priv == file_priv); |
| 340 | } | 330 | } |
| 331 | |||
| 332 | void drm_legacy_lock_release(struct drm_device *dev, struct file *filp) | ||
| 333 | { | ||
| 334 | struct drm_file *file_priv = filp->private_data; | ||
| 335 | |||
| 336 | /* if the master has gone away we can't do anything with the lock */ | ||
| 337 | if (!dev->master) | ||
| 338 | return; | ||
| 339 | |||
| 340 | if (drm_legacy_i_have_hw_lock(dev, file_priv)) { | ||
| 341 | DRM_DEBUG("File %p released, freeing lock for context %d\n", | ||
| 342 | filp, _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); | ||
| 343 | drm_legacy_lock_free(&file_priv->master->lock, | ||
| 344 | _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); | ||
| 345 | } | ||
| 346 | } | ||
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 29d5a548d07a..b2f8f1062d5f 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c | |||
| @@ -144,50 +144,6 @@ int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master) | |||
| 144 | } | 144 | } |
| 145 | EXPORT_SYMBOL(drm_pci_set_busid); | 145 | EXPORT_SYMBOL(drm_pci_set_busid); |
| 146 | 146 | ||
| 147 | int drm_pci_set_unique(struct drm_device *dev, | ||
| 148 | struct drm_master *master, | ||
| 149 | struct drm_unique *u) | ||
| 150 | { | ||
| 151 | int domain, bus, slot, func, ret; | ||
| 152 | |||
| 153 | master->unique_len = u->unique_len; | ||
| 154 | master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL); | ||
| 155 | if (!master->unique) { | ||
| 156 | ret = -ENOMEM; | ||
| 157 | goto err; | ||
| 158 | } | ||
| 159 | |||
| 160 | if (copy_from_user(master->unique, u->unique, master->unique_len)) { | ||
| 161 | ret = -EFAULT; | ||
| 162 | goto err; | ||
| 163 | } | ||
| 164 | |||
| 165 | master->unique[master->unique_len] = '\0'; | ||
| 166 | |||
| 167 | /* Return error if the busid submitted doesn't match the device's actual | ||
| 168 | * busid. | ||
| 169 | */ | ||
| 170 | ret = sscanf(master->unique, "PCI:%d:%d:%d", &bus, &slot, &func); | ||
| 171 | if (ret != 3) { | ||
| 172 | ret = -EINVAL; | ||
| 173 | goto err; | ||
| 174 | } | ||
| 175 | |||
| 176 | domain = bus >> 8; | ||
| 177 | bus &= 0xff; | ||
| 178 | |||
| 179 | if ((domain != drm_get_pci_domain(dev)) || | ||
| 180 | (bus != dev->pdev->bus->number) || | ||
| 181 | (slot != PCI_SLOT(dev->pdev->devfn)) || | ||
| 182 | (func != PCI_FUNC(dev->pdev->devfn))) { | ||
| 183 | ret = -EINVAL; | ||
| 184 | goto err; | ||
| 185 | } | ||
| 186 | return 0; | ||
| 187 | err: | ||
| 188 | return ret; | ||
| 189 | } | ||
| 190 | |||
| 191 | static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p) | 147 | static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p) |
| 192 | { | 148 | { |
| 193 | if ((p->busnum >> 8) != drm_get_pci_domain(dev) || | 149 | if ((p->busnum >> 8) != drm_get_pci_domain(dev) || |
| @@ -444,13 +400,6 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, | |||
| 444 | { | 400 | { |
| 445 | return -EINVAL; | 401 | return -EINVAL; |
| 446 | } | 402 | } |
| 447 | |||
| 448 | int drm_pci_set_unique(struct drm_device *dev, | ||
| 449 | struct drm_master *master, | ||
| 450 | struct drm_unique *u) | ||
| 451 | { | ||
| 452 | return -EINVAL; | ||
| 453 | } | ||
| 454 | #endif | 403 | #endif |
| 455 | 404 | ||
| 456 | EXPORT_SYMBOL(drm_pci_init); | 405 | EXPORT_SYMBOL(drm_pci_init); |
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index fc51306fe365..16c4a7bd7465 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c | |||
| @@ -115,6 +115,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc, | |||
| 115 | * @src: source coordinates in 16.16 fixed point | 115 | * @src: source coordinates in 16.16 fixed point |
| 116 | * @dest: integer destination coordinates | 116 | * @dest: integer destination coordinates |
| 117 | * @clip: integer clipping coordinates | 117 | * @clip: integer clipping coordinates |
| 118 | * @rotation: plane rotation | ||
| 118 | * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point | 119 | * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point |
| 119 | * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point | 120 | * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point |
| 120 | * @can_position: is it legal to position the plane such that it | 121 | * @can_position: is it legal to position the plane such that it |
| @@ -134,16 +135,17 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc, | |||
| 134 | * Zero if update appears valid, error code on failure | 135 | * Zero if update appears valid, error code on failure |
| 135 | */ | 136 | */ |
| 136 | int drm_plane_helper_check_update(struct drm_plane *plane, | 137 | int drm_plane_helper_check_update(struct drm_plane *plane, |
| 137 | struct drm_crtc *crtc, | 138 | struct drm_crtc *crtc, |
| 138 | struct drm_framebuffer *fb, | 139 | struct drm_framebuffer *fb, |
| 139 | struct drm_rect *src, | 140 | struct drm_rect *src, |
| 140 | struct drm_rect *dest, | 141 | struct drm_rect *dest, |
| 141 | const struct drm_rect *clip, | 142 | const struct drm_rect *clip, |
| 142 | int min_scale, | 143 | unsigned int rotation, |
| 143 | int max_scale, | 144 | int min_scale, |
| 144 | bool can_position, | 145 | int max_scale, |
| 145 | bool can_update_disabled, | 146 | bool can_position, |
| 146 | bool *visible) | 147 | bool can_update_disabled, |
| 148 | bool *visible) | ||
| 147 | { | 149 | { |
| 148 | int hscale, vscale; | 150 | int hscale, vscale; |
| 149 | 151 | ||
| @@ -163,6 +165,8 @@ int drm_plane_helper_check_update(struct drm_plane *plane, | |||
| 163 | return -EINVAL; | 165 | return -EINVAL; |
| 164 | } | 166 | } |
| 165 | 167 | ||
| 168 | drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation); | ||
| 169 | |||
| 166 | /* Check scaling */ | 170 | /* Check scaling */ |
| 167 | hscale = drm_rect_calc_hscale(src, dest, min_scale, max_scale); | 171 | hscale = drm_rect_calc_hscale(src, dest, min_scale, max_scale); |
| 168 | vscale = drm_rect_calc_vscale(src, dest, min_scale, max_scale); | 172 | vscale = drm_rect_calc_vscale(src, dest, min_scale, max_scale); |
| @@ -174,6 +178,9 @@ int drm_plane_helper_check_update(struct drm_plane *plane, | |||
| 174 | } | 178 | } |
| 175 | 179 | ||
| 176 | *visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale); | 180 | *visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale); |
| 181 | |||
| 182 | drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation); | ||
| 183 | |||
| 177 | if (!*visible) | 184 | if (!*visible) |
| 178 | /* | 185 | /* |
| 179 | * Plane isn't visible; some drivers can handle this | 186 | * Plane isn't visible; some drivers can handle this |
| @@ -267,6 +274,7 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 267 | 274 | ||
| 268 | ret = drm_plane_helper_check_update(plane, crtc, fb, | 275 | ret = drm_plane_helper_check_update(plane, crtc, fb, |
| 269 | &src, &dest, &clip, | 276 | &src, &dest, &clip, |
| 277 | BIT(DRM_ROTATE_0), | ||
| 270 | DRM_PLANE_HELPER_NO_SCALING, | 278 | DRM_PLANE_HELPER_NO_SCALING, |
| 271 | DRM_PLANE_HELPER_NO_SCALING, | 279 | DRM_PLANE_HELPER_NO_SCALING, |
| 272 | false, false, &visible); | 280 | false, false, &visible); |
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index 644169e1a029..2c819ef90090 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c | |||
| @@ -68,24 +68,6 @@ err_free: | |||
| 68 | return ret; | 68 | return ret; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | int drm_platform_set_busid(struct drm_device *dev, struct drm_master *master) | ||
| 72 | { | ||
| 73 | int id; | ||
| 74 | |||
| 75 | id = dev->platformdev->id; | ||
| 76 | if (id < 0) | ||
| 77 | id = 0; | ||
| 78 | |||
| 79 | master->unique = kasprintf(GFP_KERNEL, "platform:%s:%02d", | ||
| 80 | dev->platformdev->name, id); | ||
| 81 | if (!master->unique) | ||
| 82 | return -ENOMEM; | ||
| 83 | |||
| 84 | master->unique_len = strlen(master->unique); | ||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | EXPORT_SYMBOL(drm_platform_set_busid); | ||
| 88 | |||
| 89 | /** | 71 | /** |
| 90 | * drm_platform_init - Register a platform device with the DRM subsystem | 72 | * drm_platform_init - Register a platform device with the DRM subsystem |
| 91 | * @driver: DRM device driver | 73 | * @driver: DRM device driver |
diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c index b2071d495ada..0db36d27e90b 100644 --- a/drivers/gpu/drm/drm_simple_kms_helper.c +++ b/drivers/gpu/drm/drm_simple_kms_helper.c | |||
| @@ -105,6 +105,7 @@ static int drm_simple_kms_plane_atomic_check(struct drm_plane *plane, | |||
| 105 | ret = drm_plane_helper_check_update(plane, &pipe->crtc, | 105 | ret = drm_plane_helper_check_update(plane, &pipe->crtc, |
| 106 | plane_state->fb, | 106 | plane_state->fb, |
| 107 | &src, &dest, &clip, | 107 | &src, &dest, &clip, |
| 108 | plane_state->rotation, | ||
| 108 | DRM_PLANE_HELPER_NO_SCALING, | 109 | DRM_PLANE_HELPER_NO_SCALING, |
| 109 | DRM_PLANE_HELPER_NO_SCALING, | 110 | DRM_PLANE_HELPER_NO_SCALING, |
| 110 | false, true, &visible); | 111 | false, true, &visible); |
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index ac9f4b3ec615..43ff44a2b8e7 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c | |||
| @@ -670,57 +670,3 @@ void drm_legacy_vma_flush(struct drm_device *dev) | |||
| 670 | kfree(vma); | 670 | kfree(vma); |
| 671 | } | 671 | } |
| 672 | } | 672 | } |
| 673 | |||
| 674 | int drm_vma_info(struct seq_file *m, void *data) | ||
| 675 | { | ||
| 676 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
| 677 | struct drm_device *dev = node->minor->dev; | ||
| 678 | struct drm_vma_entry *pt; | ||
| 679 | struct vm_area_struct *vma; | ||
| 680 | unsigned long vma_count = 0; | ||
| 681 | #if defined(__i386__) | ||
| 682 | unsigned int pgprot; | ||
| 683 | #endif | ||
| 684 | |||
| 685 | mutex_lock(&dev->struct_mutex); | ||
| 686 | list_for_each_entry(pt, &dev->vmalist, head) | ||
| 687 | vma_count++; | ||
| 688 | |||
| 689 | seq_printf(m, "vma use count: %lu, high_memory = %pK, 0x%pK\n", | ||
| 690 | vma_count, high_memory, | ||
| 691 | (void *)(unsigned long)virt_to_phys(high_memory)); | ||
| 692 | |||
| 693 | list_for_each_entry(pt, &dev->vmalist, head) { | ||
| 694 | vma = pt->vma; | ||
| 695 | if (!vma) | ||
| 696 | continue; | ||
| 697 | seq_printf(m, | ||
| 698 | "\n%5d 0x%pK-0x%pK %c%c%c%c%c%c 0x%08lx000", | ||
| 699 | pt->pid, | ||
| 700 | (void *)vma->vm_start, (void *)vma->vm_end, | ||
| 701 | vma->vm_flags & VM_READ ? 'r' : '-', | ||
| 702 | vma->vm_flags & VM_WRITE ? 'w' : '-', | ||
| 703 | vma->vm_flags & VM_EXEC ? 'x' : '-', | ||
| 704 | vma->vm_flags & VM_MAYSHARE ? 's' : 'p', | ||
| 705 | vma->vm_flags & VM_LOCKED ? 'l' : '-', | ||
| 706 | vma->vm_flags & VM_IO ? 'i' : '-', | ||
| 707 | vma->vm_pgoff); | ||
| 708 | |||
| 709 | #if defined(__i386__) | ||
| 710 | pgprot = pgprot_val(vma->vm_page_prot); | ||
| 711 | seq_printf(m, " %c%c%c%c%c%c%c%c%c", | ||
| 712 | pgprot & _PAGE_PRESENT ? 'p' : '-', | ||
| 713 | pgprot & _PAGE_RW ? 'w' : 'r', | ||
| 714 | pgprot & _PAGE_USER ? 'u' : 's', | ||
| 715 | pgprot & _PAGE_PWT ? 't' : 'b', | ||
| 716 | pgprot & _PAGE_PCD ? 'u' : 'c', | ||
| 717 | pgprot & _PAGE_ACCESSED ? 'a' : '-', | ||
| 718 | pgprot & _PAGE_DIRTY ? 'd' : '-', | ||
| 719 | pgprot & _PAGE_PSE ? 'm' : 'k', | ||
| 720 | pgprot & _PAGE_GLOBAL ? 'g' : 'l'); | ||
| 721 | #endif | ||
| 722 | seq_printf(m, "\n"); | ||
| 723 | } | ||
| 724 | mutex_unlock(&dev->struct_mutex); | ||
| 725 | return 0; | ||
| 726 | } | ||
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 3d4f56df8359..340d390306d8 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c | |||
| @@ -496,7 +496,6 @@ static struct drm_driver etnaviv_drm_driver = { | |||
| 496 | DRIVER_RENDER, | 496 | DRIVER_RENDER, |
| 497 | .open = etnaviv_open, | 497 | .open = etnaviv_open, |
| 498 | .preclose = etnaviv_preclose, | 498 | .preclose = etnaviv_preclose, |
| 499 | .set_busid = drm_platform_set_busid, | ||
| 500 | .gem_free_object_unlocked = etnaviv_gem_free_object, | 499 | .gem_free_object_unlocked = etnaviv_gem_free_object, |
| 501 | .gem_vm_ops = &vm_ops, | 500 | .gem_vm_ops = &vm_ops, |
| 502 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, | 501 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 4a679fb9bb02..13d28d4229e2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
| @@ -407,7 +407,6 @@ static struct drm_driver exynos_drm_driver = { | |||
| 407 | .preclose = exynos_drm_preclose, | 407 | .preclose = exynos_drm_preclose, |
| 408 | .lastclose = exynos_drm_lastclose, | 408 | .lastclose = exynos_drm_lastclose, |
| 409 | .postclose = exynos_drm_postclose, | 409 | .postclose = exynos_drm_postclose, |
| 410 | .set_busid = drm_platform_set_busid, | ||
| 411 | .get_vblank_counter = drm_vblank_no_hw_counter, | 410 | .get_vblank_counter = drm_vblank_no_hw_counter, |
| 412 | .enable_vblank = exynos_drm_crtc_enable_vblank, | 411 | .enable_vblank = exynos_drm_crtc_enable_vblank, |
| 413 | .disable_vblank = exynos_drm_crtc_disable_vblank, | 412 | .disable_vblank = exynos_drm_crtc_disable_vblank, |
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c index c564ec612b59..a6e4cd591960 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c | |||
| @@ -37,23 +37,22 @@ int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device *fsl_dev) | |||
| 37 | 37 | ||
| 38 | ret = fsl_dcu_drm_crtc_create(fsl_dev); | 38 | ret = fsl_dcu_drm_crtc_create(fsl_dev); |
| 39 | if (ret) | 39 | if (ret) |
| 40 | return ret; | 40 | goto err; |
| 41 | 41 | ||
| 42 | ret = fsl_dcu_drm_encoder_create(fsl_dev, &fsl_dev->crtc); | 42 | ret = fsl_dcu_drm_encoder_create(fsl_dev, &fsl_dev->crtc); |
| 43 | if (ret) | 43 | if (ret) |
| 44 | goto fail_encoder; | 44 | goto err; |
| 45 | 45 | ||
| 46 | ret = fsl_dcu_drm_connector_create(fsl_dev, &fsl_dev->encoder); | 46 | ret = fsl_dcu_drm_connector_create(fsl_dev, &fsl_dev->encoder); |
| 47 | if (ret) | 47 | if (ret) |
| 48 | goto fail_connector; | 48 | goto err; |
| 49 | 49 | ||
| 50 | drm_mode_config_reset(fsl_dev->drm); | 50 | drm_mode_config_reset(fsl_dev->drm); |
| 51 | drm_kms_helper_poll_init(fsl_dev->drm); | 51 | drm_kms_helper_poll_init(fsl_dev->drm); |
| 52 | 52 | ||
| 53 | return 0; | 53 | return 0; |
| 54 | fail_encoder: | 54 | |
| 55 | fsl_dev->crtc.funcs->destroy(&fsl_dev->crtc); | 55 | err: |
| 56 | fail_connector: | 56 | drm_mode_config_cleanup(fsl_dev->drm); |
| 57 | fsl_dev->encoder.funcs->destroy(&fsl_dev->encoder); | ||
| 58 | return ret; | 57 | return ret; |
| 59 | } | 58 | } |
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index 193657259ee9..1edd9bc80294 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c | |||
| @@ -171,7 +171,6 @@ static struct drm_driver kirin_drm_driver = { | |||
| 171 | .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | | 171 | .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | |
| 172 | DRIVER_ATOMIC | DRIVER_HAVE_IRQ, | 172 | DRIVER_ATOMIC | DRIVER_HAVE_IRQ, |
| 173 | .fops = &kirin_drm_fops, | 173 | .fops = &kirin_drm_fops, |
| 174 | .set_busid = drm_platform_set_busid, | ||
| 175 | 174 | ||
| 176 | .gem_free_object_unlocked = drm_gem_cma_free_object, | 175 | .gem_free_object_unlocked = drm_gem_cma_free_object, |
| 177 | .gem_vm_ops = &drm_gem_cma_vm_ops, | 176 | .gem_vm_ops = &drm_gem_cma_vm_ops, |
| @@ -221,19 +220,12 @@ static int kirin_drm_bind(struct device *dev) | |||
| 221 | if (ret) | 220 | if (ret) |
| 222 | goto err_kms_cleanup; | 221 | goto err_kms_cleanup; |
| 223 | 222 | ||
| 224 | /* connectors should be registered after drm device register */ | ||
| 225 | ret = drm_connector_register_all(drm_dev); | ||
| 226 | if (ret) | ||
| 227 | goto err_drm_dev_unregister; | ||
| 228 | |||
| 229 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", | 223 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", |
| 230 | driver->name, driver->major, driver->minor, driver->patchlevel, | 224 | driver->name, driver->major, driver->minor, driver->patchlevel, |
| 231 | driver->date, drm_dev->primary->index); | 225 | driver->date, drm_dev->primary->index); |
| 232 | 226 | ||
| 233 | return 0; | 227 | return 0; |
| 234 | 228 | ||
| 235 | err_drm_dev_unregister: | ||
| 236 | drm_dev_unregister(drm_dev); | ||
| 237 | err_kms_cleanup: | 229 | err_kms_cleanup: |
| 238 | kirin_drm_kms_cleanup(drm_dev); | 230 | kirin_drm_kms_cleanup(drm_dev); |
| 239 | err_drm_dev_unref: | 231 | err_drm_dev_unref: |
| @@ -246,7 +238,6 @@ static void kirin_drm_unbind(struct device *dev) | |||
| 246 | { | 238 | { |
| 247 | struct drm_device *drm_dev = dev_get_drvdata(dev); | 239 | struct drm_device *drm_dev = dev_get_drvdata(dev); |
| 248 | 240 | ||
| 249 | drm_connector_unregister_all(drm_dev); | ||
| 250 | drm_dev_unregister(drm_dev); | 241 | drm_dev_unregister(drm_dev); |
| 251 | kirin_drm_kms_cleanup(drm_dev); | 242 | kirin_drm_kms_cleanup(drm_dev); |
| 252 | drm_dev_unref(drm_dev); | 243 | drm_dev_unref(drm_dev); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0113207967d9..ee338655f782 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #include <drm/intel-gtt.h> | 47 | #include <drm/intel-gtt.h> |
| 48 | #include <drm/drm_legacy.h> /* for struct drm_dma_handle */ | 48 | #include <drm/drm_legacy.h> /* for struct drm_dma_handle */ |
| 49 | #include <drm/drm_gem.h> | 49 | #include <drm/drm_gem.h> |
| 50 | #include <drm/drm_auth.h> | ||
| 50 | 51 | ||
| 51 | #include "i915_params.h" | 52 | #include "i915_params.h" |
| 52 | #include "i915_reg.h" | 53 | #include "i915_reg.h" |
| @@ -3673,7 +3674,7 @@ extern void intel_modeset_init_hw(struct drm_device *dev); | |||
| 3673 | extern void intel_modeset_init(struct drm_device *dev); | 3674 | extern void intel_modeset_init(struct drm_device *dev); |
| 3674 | extern void intel_modeset_gem_init(struct drm_device *dev); | 3675 | extern void intel_modeset_gem_init(struct drm_device *dev); |
| 3675 | extern void intel_modeset_cleanup(struct drm_device *dev); | 3676 | extern void intel_modeset_cleanup(struct drm_device *dev); |
| 3676 | extern void intel_connector_unregister(struct intel_connector *); | 3677 | extern void intel_connector_unregister(struct drm_connector *); |
| 3677 | extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); | 3678 | extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); |
| 3678 | extern void intel_display_resume(struct drm_device *dev); | 3679 | extern void intel_display_resume(struct drm_device *dev); |
| 3679 | extern void i915_redisable_vga(struct drm_device *dev); | 3680 | extern void i915_redisable_vga(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 8097698b9622..7941f1fe9cd2 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
| @@ -1446,7 +1446,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 1446 | 1446 | ||
| 1447 | dispatch_flags = 0; | 1447 | dispatch_flags = 0; |
| 1448 | if (args->flags & I915_EXEC_SECURE) { | 1448 | if (args->flags & I915_EXEC_SECURE) { |
| 1449 | if (!file->is_master || !capable(CAP_SYS_ADMIN)) | 1449 | if (!drm_is_current_master(file) || !capable(CAP_SYS_ADMIN)) |
| 1450 | return -EPERM; | 1450 | return -EPERM; |
| 1451 | 1451 | ||
| 1452 | dispatch_flags |= I915_DISPATCH_SECURE; | 1452 | dispatch_flags |= I915_DISPATCH_SECURE; |
| @@ -1553,7 +1553,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 1553 | batch_obj, | 1553 | batch_obj, |
| 1554 | args->batch_start_offset, | 1554 | args->batch_start_offset, |
| 1555 | args->batch_len, | 1555 | args->batch_len, |
| 1556 | file->is_master); | 1556 | drm_is_current_master(file)); |
| 1557 | if (IS_ERR(parsed_batch_obj)) { | 1557 | if (IS_ERR(parsed_batch_obj)) { |
| 1558 | ret = PTR_ERR(parsed_batch_obj); | 1558 | ret = PTR_ERR(parsed_batch_obj); |
| 1559 | goto err; | 1559 | goto err; |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 9465de4135aa..e115bcc6766f 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -743,6 +743,7 @@ static const struct drm_connector_funcs intel_crt_connector_funcs = { | |||
| 743 | .dpms = drm_atomic_helper_connector_dpms, | 743 | .dpms = drm_atomic_helper_connector_dpms, |
| 744 | .detect = intel_crt_detect, | 744 | .detect = intel_crt_detect, |
| 745 | .fill_modes = drm_helper_probe_single_connector_modes, | 745 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 746 | .early_unregister = intel_connector_unregister, | ||
| 746 | .destroy = intel_crt_destroy, | 747 | .destroy = intel_crt_destroy, |
| 747 | .set_property = intel_crt_set_property, | 748 | .set_property = intel_crt_set_property, |
| 748 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | 749 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
| @@ -875,7 +876,6 @@ void intel_crt_init(struct drm_device *dev) | |||
| 875 | crt->base.get_hw_state = intel_crt_get_hw_state; | 876 | crt->base.get_hw_state = intel_crt_get_hw_state; |
| 876 | } | 877 | } |
| 877 | intel_connector->get_hw_state = intel_connector_get_hw_state; | 878 | intel_connector->get_hw_state = intel_connector_get_hw_state; |
| 878 | intel_connector->unregister = intel_connector_unregister; | ||
| 879 | 879 | ||
| 880 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); | 880 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); |
| 881 | 881 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 49322f6cfa2b..b12085a8bfa6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -14102,6 +14102,7 @@ intel_check_primary_plane(struct drm_plane *plane, | |||
| 14102 | 14102 | ||
| 14103 | return drm_plane_helper_check_update(plane, crtc, fb, &state->src, | 14103 | return drm_plane_helper_check_update(plane, crtc, fb, &state->src, |
| 14104 | &state->dst, &state->clip, | 14104 | &state->dst, &state->clip, |
| 14105 | state->base.rotation, | ||
| 14105 | min_scale, max_scale, | 14106 | min_scale, max_scale, |
| 14106 | can_position, true, | 14107 | can_position, true, |
| 14107 | &state->visible); | 14108 | &state->visible); |
| @@ -14293,6 +14294,7 @@ intel_check_cursor_plane(struct drm_plane *plane, | |||
| 14293 | 14294 | ||
| 14294 | ret = drm_plane_helper_check_update(plane, crtc, fb, &state->src, | 14295 | ret = drm_plane_helper_check_update(plane, crtc, fb, &state->src, |
| 14295 | &state->dst, &state->clip, | 14296 | &state->dst, &state->clip, |
| 14297 | state->base.rotation, | ||
| 14296 | DRM_PLANE_HELPER_NO_SCALING, | 14298 | DRM_PLANE_HELPER_NO_SCALING, |
| 14297 | DRM_PLANE_HELPER_NO_SCALING, | 14299 | DRM_PLANE_HELPER_NO_SCALING, |
| 14298 | true, true, &state->visible); | 14300 | true, true, &state->visible); |
| @@ -16217,23 +16219,20 @@ void intel_modeset_gem_init(struct drm_device *dev) | |||
| 16217 | intel_backlight_register(dev); | 16219 | intel_backlight_register(dev); |
| 16218 | } | 16220 | } |
| 16219 | 16221 | ||
| 16220 | void intel_connector_unregister(struct intel_connector *intel_connector) | 16222 | void intel_connector_unregister(struct drm_connector *connector) |
| 16221 | { | 16223 | { |
| 16222 | struct drm_connector *connector = &intel_connector->base; | 16224 | struct intel_connector *intel_connector = to_intel_connector(connector); |
| 16223 | 16225 | ||
| 16226 | intel_backlight_device_unregister(intel_connector); | ||
| 16224 | intel_panel_destroy_backlight(connector); | 16227 | intel_panel_destroy_backlight(connector); |
| 16225 | drm_connector_unregister(connector); | ||
| 16226 | } | 16228 | } |
| 16227 | 16229 | ||
| 16228 | void intel_modeset_cleanup(struct drm_device *dev) | 16230 | void intel_modeset_cleanup(struct drm_device *dev) |
| 16229 | { | 16231 | { |
| 16230 | struct drm_i915_private *dev_priv = dev->dev_private; | 16232 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 16231 | struct intel_connector *connector; | ||
| 16232 | 16233 | ||
| 16233 | intel_disable_gt_powersave(dev_priv); | 16234 | intel_disable_gt_powersave(dev_priv); |
| 16234 | 16235 | ||
| 16235 | intel_backlight_unregister(dev); | ||
| 16236 | |||
| 16237 | /* | 16236 | /* |
| 16238 | * Interrupts and polling as the first thing to avoid creating havoc. | 16237 | * Interrupts and polling as the first thing to avoid creating havoc. |
| 16239 | * Too much stuff here (turning of connectors, ...) would | 16238 | * Too much stuff here (turning of connectors, ...) would |
| @@ -16254,9 +16253,7 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
| 16254 | /* flush any delayed tasks or pending work */ | 16253 | /* flush any delayed tasks or pending work */ |
| 16255 | flush_scheduled_work(); | 16254 | flush_scheduled_work(); |
| 16256 | 16255 | ||
| 16257 | /* destroy the backlight and sysfs files before encoders/connectors */ | 16256 | drm_connector_unregister_all(dev); |
| 16258 | for_each_intel_connector(dev, connector) | ||
| 16259 | connector->unregister(connector); | ||
| 16260 | 16257 | ||
| 16261 | drm_mode_config_cleanup(dev); | 16258 | drm_mode_config_cleanup(dev); |
| 16262 | 16259 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index be083519dac9..0b84f8e5df50 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1177,7 +1177,6 @@ static void intel_aux_reg_init(struct intel_dp *intel_dp) | |||
| 1177 | static void | 1177 | static void |
| 1178 | intel_dp_aux_fini(struct intel_dp *intel_dp) | 1178 | intel_dp_aux_fini(struct intel_dp *intel_dp) |
| 1179 | { | 1179 | { |
| 1180 | drm_dp_aux_unregister(&intel_dp->aux); | ||
| 1181 | kfree(intel_dp->aux.name); | 1180 | kfree(intel_dp->aux.name); |
| 1182 | } | 1181 | } |
| 1183 | 1182 | ||
| @@ -1212,15 +1211,6 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector) | |||
| 1212 | return 0; | 1211 | return 0; |
| 1213 | } | 1212 | } |
| 1214 | 1213 | ||
| 1215 | static void | ||
| 1216 | intel_dp_connector_unregister(struct intel_connector *intel_connector) | ||
| 1217 | { | ||
| 1218 | struct intel_dp *intel_dp = intel_attached_dp(&intel_connector->base); | ||
| 1219 | |||
| 1220 | intel_dp_aux_fini(intel_dp); | ||
| 1221 | intel_connector_unregister(intel_connector); | ||
| 1222 | } | ||
| 1223 | |||
| 1224 | static int | 1214 | static int |
| 1225 | intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) | 1215 | intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) |
| 1226 | { | 1216 | { |
| @@ -4457,6 +4447,13 @@ done: | |||
| 4457 | } | 4447 | } |
| 4458 | 4448 | ||
| 4459 | static void | 4449 | static void |
| 4450 | intel_dp_connector_unregister(struct drm_connector *connector) | ||
| 4451 | { | ||
| 4452 | drm_dp_aux_unregister(&intel_attached_dp(connector)->aux); | ||
| 4453 | intel_connector_unregister(connector); | ||
| 4454 | } | ||
| 4455 | |||
| 4456 | static void | ||
| 4460 | intel_dp_connector_destroy(struct drm_connector *connector) | 4457 | intel_dp_connector_destroy(struct drm_connector *connector) |
| 4461 | { | 4458 | { |
| 4462 | struct intel_connector *intel_connector = to_intel_connector(connector); | 4459 | struct intel_connector *intel_connector = to_intel_connector(connector); |
| @@ -4496,6 +4493,9 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) | |||
| 4496 | intel_dp->edp_notifier.notifier_call = NULL; | 4493 | intel_dp->edp_notifier.notifier_call = NULL; |
| 4497 | } | 4494 | } |
| 4498 | } | 4495 | } |
| 4496 | |||
| 4497 | intel_dp_aux_fini(intel_dp); | ||
| 4498 | |||
| 4499 | drm_encoder_cleanup(encoder); | 4499 | drm_encoder_cleanup(encoder); |
| 4500 | kfree(intel_dig_port); | 4500 | kfree(intel_dig_port); |
| 4501 | } | 4501 | } |
| @@ -4572,6 +4572,7 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = { | |||
| 4572 | .fill_modes = drm_helper_probe_single_connector_modes, | 4572 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 4573 | .set_property = intel_dp_set_property, | 4573 | .set_property = intel_dp_set_property, |
| 4574 | .atomic_get_property = intel_connector_atomic_get_property, | 4574 | .atomic_get_property = intel_connector_atomic_get_property, |
| 4575 | .early_unregister = intel_dp_connector_unregister, | ||
| 4575 | .destroy = intel_dp_connector_destroy, | 4576 | .destroy = intel_dp_connector_destroy, |
| 4576 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | 4577 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
| 4577 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | 4578 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, |
| @@ -5487,7 +5488,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, | |||
| 5487 | intel_connector->get_hw_state = intel_ddi_connector_get_hw_state; | 5488 | intel_connector->get_hw_state = intel_ddi_connector_get_hw_state; |
| 5488 | else | 5489 | else |
| 5489 | intel_connector->get_hw_state = intel_connector_get_hw_state; | 5490 | intel_connector->get_hw_state = intel_connector_get_hw_state; |
| 5490 | intel_connector->unregister = intel_dp_connector_unregister; | ||
| 5491 | 5491 | ||
| 5492 | /* Set up the hotplug pin. */ | 5492 | /* Set up the hotplug pin. */ |
| 5493 | switch (port) { | 5493 | switch (port) { |
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index f62ca9a126b3..9646816604be 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c | |||
| @@ -336,6 +336,7 @@ static const struct drm_connector_funcs intel_dp_mst_connector_funcs = { | |||
| 336 | .fill_modes = drm_helper_probe_single_connector_modes, | 336 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 337 | .set_property = intel_dp_mst_set_property, | 337 | .set_property = intel_dp_mst_set_property, |
| 338 | .atomic_get_property = intel_connector_atomic_get_property, | 338 | .atomic_get_property = intel_connector_atomic_get_property, |
| 339 | .early_unregister = intel_connector_unregister, | ||
| 339 | .destroy = intel_dp_mst_connector_destroy, | 340 | .destroy = intel_dp_mst_connector_destroy, |
| 340 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | 341 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
| 341 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | 342 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, |
| @@ -455,7 +456,6 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo | |||
| 455 | drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort); | 456 | drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort); |
| 456 | drm_connector_helper_add(connector, &intel_dp_mst_connector_helper_funcs); | 457 | drm_connector_helper_add(connector, &intel_dp_mst_connector_helper_funcs); |
| 457 | 458 | ||
| 458 | intel_connector->unregister = intel_connector_unregister; | ||
| 459 | intel_connector->get_hw_state = intel_dp_mst_get_hw_state; | 459 | intel_connector->get_hw_state = intel_dp_mst_get_hw_state; |
| 460 | intel_connector->mst_port = intel_dp; | 460 | intel_connector->mst_port = intel_dp; |
| 461 | intel_connector->port = port; | 461 | intel_connector->port = port; |
| @@ -489,7 +489,7 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
| 489 | struct intel_connector *intel_connector = to_intel_connector(connector); | 489 | struct intel_connector *intel_connector = to_intel_connector(connector); |
| 490 | struct drm_device *dev = connector->dev; | 490 | struct drm_device *dev = connector->dev; |
| 491 | 491 | ||
| 492 | intel_connector->unregister(intel_connector); | 492 | drm_connector_unregister(connector); |
| 493 | 493 | ||
| 494 | /* need to nuke the connector */ | 494 | /* need to nuke the connector */ |
| 495 | drm_modeset_lock_all(dev); | 495 | drm_modeset_lock_all(dev); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 270da8de0acf..65e60ff3b553 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -242,14 +242,6 @@ struct intel_connector { | |||
| 242 | * and active (i.e. dpms ON state). */ | 242 | * and active (i.e. dpms ON state). */ |
| 243 | bool (*get_hw_state)(struct intel_connector *); | 243 | bool (*get_hw_state)(struct intel_connector *); |
| 244 | 244 | ||
| 245 | /* | ||
| 246 | * Removes all interfaces through which the connector is accessible | ||
| 247 | * - like sysfs, debugfs entries -, so that no new operations can be | ||
| 248 | * started on the connector. Also makes sure all currently pending | ||
| 249 | * operations finish before returing. | ||
| 250 | */ | ||
| 251 | void (*unregister)(struct intel_connector *); | ||
| 252 | |||
| 253 | /* Panel info for eDP and LVDS */ | 245 | /* Panel info for eDP and LVDS */ |
| 254 | struct intel_panel panel; | 246 | struct intel_panel panel; |
| 255 | 247 | ||
| @@ -1496,7 +1488,14 @@ extern struct drm_display_mode *intel_find_panel_downclock( | |||
| 1496 | struct drm_display_mode *fixed_mode, | 1488 | struct drm_display_mode *fixed_mode, |
| 1497 | struct drm_connector *connector); | 1489 | struct drm_connector *connector); |
| 1498 | void intel_backlight_register(struct drm_device *dev); | 1490 | void intel_backlight_register(struct drm_device *dev); |
| 1499 | void intel_backlight_unregister(struct drm_device *dev); | 1491 | |
| 1492 | #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) | ||
| 1493 | void intel_backlight_device_unregister(struct intel_connector *connector); | ||
| 1494 | #else /* CONFIG_BACKLIGHT_CLASS_DEVICE */ | ||
| 1495 | static inline void intel_backlight_device_unregister(struct intel_connector *connector) | ||
| 1496 | { | ||
| 1497 | } | ||
| 1498 | #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ | ||
| 1500 | 1499 | ||
| 1501 | 1500 | ||
| 1502 | /* intel_psr.c */ | 1501 | /* intel_psr.c */ |
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index a2ead5eac336..e9eda691e8be 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c | |||
| @@ -1384,6 +1384,7 @@ static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs | |||
| 1384 | static const struct drm_connector_funcs intel_dsi_connector_funcs = { | 1384 | static const struct drm_connector_funcs intel_dsi_connector_funcs = { |
| 1385 | .dpms = drm_atomic_helper_connector_dpms, | 1385 | .dpms = drm_atomic_helper_connector_dpms, |
| 1386 | .detect = intel_dsi_detect, | 1386 | .detect = intel_dsi_detect, |
| 1387 | .early_unregister = intel_connector_unregister, | ||
| 1387 | .destroy = intel_dsi_connector_destroy, | 1388 | .destroy = intel_dsi_connector_destroy, |
| 1388 | .fill_modes = drm_helper_probe_single_connector_modes, | 1389 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 1389 | .set_property = intel_dsi_set_property, | 1390 | .set_property = intel_dsi_set_property, |
| @@ -1460,7 +1461,6 @@ void intel_dsi_init(struct drm_device *dev) | |||
| 1460 | intel_encoder->get_config = intel_dsi_get_config; | 1461 | intel_encoder->get_config = intel_dsi_get_config; |
| 1461 | 1462 | ||
| 1462 | intel_connector->get_hw_state = intel_connector_get_hw_state; | 1463 | intel_connector->get_hw_state = intel_connector_get_hw_state; |
| 1463 | intel_connector->unregister = intel_connector_unregister; | ||
| 1464 | 1464 | ||
| 1465 | /* | 1465 | /* |
| 1466 | * On BYT/CHV, pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI | 1466 | * On BYT/CHV, pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index c86f88ed92fd..60e4ddf2ec6d 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
| @@ -341,6 +341,7 @@ static void intel_dvo_destroy(struct drm_connector *connector) | |||
| 341 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { | 341 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { |
| 342 | .dpms = drm_atomic_helper_connector_dpms, | 342 | .dpms = drm_atomic_helper_connector_dpms, |
| 343 | .detect = intel_dvo_detect, | 343 | .detect = intel_dvo_detect, |
| 344 | .early_unregister = intel_connector_unregister, | ||
| 344 | .destroy = intel_dvo_destroy, | 345 | .destroy = intel_dvo_destroy, |
| 345 | .fill_modes = drm_helper_probe_single_connector_modes, | 346 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 346 | .atomic_get_property = intel_connector_atomic_get_property, | 347 | .atomic_get_property = intel_connector_atomic_get_property, |
| @@ -447,7 +448,6 @@ void intel_dvo_init(struct drm_device *dev) | |||
| 447 | intel_encoder->compute_config = intel_dvo_compute_config; | 448 | intel_encoder->compute_config = intel_dvo_compute_config; |
| 448 | intel_encoder->pre_enable = intel_dvo_pre_enable; | 449 | intel_encoder->pre_enable = intel_dvo_pre_enable; |
| 449 | intel_connector->get_hw_state = intel_dvo_connector_get_hw_state; | 450 | intel_connector->get_hw_state = intel_dvo_connector_get_hw_state; |
| 450 | intel_connector->unregister = intel_connector_unregister; | ||
| 451 | 451 | ||
| 452 | /* Now, try to find a controller */ | 452 | /* Now, try to find a controller */ |
| 453 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { | 453 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 6b29da9bba38..d4fc3d436d52 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
| @@ -1774,6 +1774,7 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = { | |||
| 1774 | .fill_modes = drm_helper_probe_single_connector_modes, | 1774 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 1775 | .set_property = intel_hdmi_set_property, | 1775 | .set_property = intel_hdmi_set_property, |
| 1776 | .atomic_get_property = intel_connector_atomic_get_property, | 1776 | .atomic_get_property = intel_connector_atomic_get_property, |
| 1777 | .early_unregister = intel_connector_unregister, | ||
| 1777 | .destroy = intel_hdmi_destroy, | 1778 | .destroy = intel_hdmi_destroy, |
| 1778 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | 1779 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
| 1779 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | 1780 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, |
| @@ -1906,7 +1907,6 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, | |||
| 1906 | intel_connector->get_hw_state = intel_ddi_connector_get_hw_state; | 1907 | intel_connector->get_hw_state = intel_ddi_connector_get_hw_state; |
| 1907 | else | 1908 | else |
| 1908 | intel_connector->get_hw_state = intel_connector_get_hw_state; | 1909 | intel_connector->get_hw_state = intel_connector_get_hw_state; |
| 1909 | intel_connector->unregister = intel_connector_unregister; | ||
| 1910 | 1910 | ||
| 1911 | intel_hdmi_add_properties(intel_hdmi, connector); | 1911 | intel_hdmi_add_properties(intel_hdmi, connector); |
| 1912 | 1912 | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index e06b9036bebc..e9082185a375 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -555,6 +555,7 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = { | |||
| 555 | .fill_modes = drm_helper_probe_single_connector_modes, | 555 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 556 | .set_property = intel_lvds_set_property, | 556 | .set_property = intel_lvds_set_property, |
| 557 | .atomic_get_property = intel_connector_atomic_get_property, | 557 | .atomic_get_property = intel_connector_atomic_get_property, |
| 558 | .early_unregister = intel_connector_unregister, | ||
| 558 | .destroy = intel_lvds_destroy, | 559 | .destroy = intel_lvds_destroy, |
| 559 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | 560 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
| 560 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | 561 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, |
| @@ -991,7 +992,6 @@ void intel_lvds_init(struct drm_device *dev) | |||
| 991 | intel_encoder->get_hw_state = intel_lvds_get_hw_state; | 992 | intel_encoder->get_hw_state = intel_lvds_get_hw_state; |
| 992 | intel_encoder->get_config = intel_lvds_get_config; | 993 | intel_encoder->get_config = intel_lvds_get_config; |
| 993 | intel_connector->get_hw_state = intel_connector_get_hw_state; | 994 | intel_connector->get_hw_state = intel_connector_get_hw_state; |
| 994 | intel_connector->unregister = intel_connector_unregister; | ||
| 995 | 995 | ||
| 996 | intel_connector_attach_encoder(intel_connector, intel_encoder); | 996 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
| 997 | intel_encoder->type = INTEL_OUTPUT_LVDS; | 997 | intel_encoder->type = INTEL_OUTPUT_LVDS; |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index f0b1602c3258..bf721781c259 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -1216,7 +1216,7 @@ static int intel_backlight_device_register(struct intel_connector *connector) | |||
| 1216 | return 0; | 1216 | return 0; |
| 1217 | } | 1217 | } |
| 1218 | 1218 | ||
| 1219 | static void intel_backlight_device_unregister(struct intel_connector *connector) | 1219 | void intel_backlight_device_unregister(struct intel_connector *connector) |
| 1220 | { | 1220 | { |
| 1221 | struct intel_panel *panel = &connector->panel; | 1221 | struct intel_panel *panel = &connector->panel; |
| 1222 | 1222 | ||
| @@ -1230,9 +1230,6 @@ static int intel_backlight_device_register(struct intel_connector *connector) | |||
| 1230 | { | 1230 | { |
| 1231 | return 0; | 1231 | return 0; |
| 1232 | } | 1232 | } |
| 1233 | static void intel_backlight_device_unregister(struct intel_connector *connector) | ||
| 1234 | { | ||
| 1235 | } | ||
| 1236 | #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ | 1233 | #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ |
| 1237 | 1234 | ||
| 1238 | /* | 1235 | /* |
| @@ -1820,11 +1817,3 @@ void intel_backlight_register(struct drm_device *dev) | |||
| 1820 | for_each_intel_connector(dev, connector) | 1817 | for_each_intel_connector(dev, connector) |
| 1821 | intel_backlight_device_register(connector); | 1818 | intel_backlight_device_register(connector); |
| 1822 | } | 1819 | } |
| 1823 | |||
| 1824 | void intel_backlight_unregister(struct drm_device *dev) | ||
| 1825 | { | ||
| 1826 | struct intel_connector *connector; | ||
| 1827 | |||
| 1828 | for_each_intel_connector(dev, connector) | ||
| 1829 | intel_backlight_device_unregister(connector); | ||
| 1830 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index ab2d0658abe6..02b4a6695528 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -2177,12 +2177,23 @@ done: | |||
| 2177 | #undef CHECK_PROPERTY | 2177 | #undef CHECK_PROPERTY |
| 2178 | } | 2178 | } |
| 2179 | 2179 | ||
| 2180 | static void | ||
| 2181 | intel_sdvo_connector_unregister(struct drm_connector *connector) | ||
| 2182 | { | ||
| 2183 | struct intel_sdvo *sdvo = intel_attached_sdvo(connector); | ||
| 2184 | |||
| 2185 | sysfs_remove_link(&connector->kdev->kobj, | ||
| 2186 | sdvo->ddc.dev.kobj.name); | ||
| 2187 | intel_connector_unregister(connector); | ||
| 2188 | } | ||
| 2189 | |||
| 2180 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | 2190 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { |
| 2181 | .dpms = drm_atomic_helper_connector_dpms, | 2191 | .dpms = drm_atomic_helper_connector_dpms, |
| 2182 | .detect = intel_sdvo_detect, | 2192 | .detect = intel_sdvo_detect, |
| 2183 | .fill_modes = drm_helper_probe_single_connector_modes, | 2193 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 2184 | .set_property = intel_sdvo_set_property, | 2194 | .set_property = intel_sdvo_set_property, |
| 2185 | .atomic_get_property = intel_connector_atomic_get_property, | 2195 | .atomic_get_property = intel_connector_atomic_get_property, |
| 2196 | .early_unregister = intel_sdvo_connector_unregister, | ||
| 2186 | .destroy = intel_sdvo_destroy, | 2197 | .destroy = intel_sdvo_destroy, |
| 2187 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | 2198 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
| 2188 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | 2199 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, |
| @@ -2345,20 +2356,6 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, struct intel_sdvo *sdvo) | |||
| 2345 | return 0x72; | 2356 | return 0x72; |
| 2346 | } | 2357 | } |
| 2347 | 2358 | ||
| 2348 | static void | ||
| 2349 | intel_sdvo_connector_unregister(struct intel_connector *intel_connector) | ||
| 2350 | { | ||
| 2351 | struct drm_connector *drm_connector; | ||
| 2352 | struct intel_sdvo *sdvo_encoder; | ||
| 2353 | |||
| 2354 | drm_connector = &intel_connector->base; | ||
| 2355 | sdvo_encoder = intel_attached_sdvo(&intel_connector->base); | ||
| 2356 | |||
| 2357 | sysfs_remove_link(&drm_connector->kdev->kobj, | ||
| 2358 | sdvo_encoder->ddc.dev.kobj.name); | ||
| 2359 | intel_connector_unregister(intel_connector); | ||
| 2360 | } | ||
| 2361 | |||
| 2362 | static int | 2359 | static int |
| 2363 | intel_sdvo_connector_init(struct intel_sdvo_connector *connector, | 2360 | intel_sdvo_connector_init(struct intel_sdvo_connector *connector, |
| 2364 | struct intel_sdvo *encoder) | 2361 | struct intel_sdvo *encoder) |
| @@ -2381,7 +2378,6 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector, | |||
| 2381 | connector->base.base.doublescan_allowed = 0; | 2378 | connector->base.base.doublescan_allowed = 0; |
| 2382 | connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; | 2379 | connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; |
| 2383 | connector->base.get_hw_state = intel_sdvo_connector_get_hw_state; | 2380 | connector->base.get_hw_state = intel_sdvo_connector_get_hw_state; |
| 2384 | connector->base.unregister = intel_sdvo_connector_unregister; | ||
| 2385 | 2381 | ||
| 2386 | intel_connector_attach_encoder(&connector->base, &encoder->base); | 2382 | intel_connector_attach_encoder(&connector->base, &encoder->base); |
| 2387 | ret = drm_connector_register(drm_connector); | 2383 | ret = drm_connector_register(drm_connector); |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 7ac9e9b0e2c3..4ce70a9f9df2 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
| @@ -1501,6 +1501,7 @@ out: | |||
| 1501 | static const struct drm_connector_funcs intel_tv_connector_funcs = { | 1501 | static const struct drm_connector_funcs intel_tv_connector_funcs = { |
| 1502 | .dpms = drm_atomic_helper_connector_dpms, | 1502 | .dpms = drm_atomic_helper_connector_dpms, |
| 1503 | .detect = intel_tv_detect, | 1503 | .detect = intel_tv_detect, |
| 1504 | .early_unregister = intel_connector_unregister, | ||
| 1504 | .destroy = intel_tv_destroy, | 1505 | .destroy = intel_tv_destroy, |
| 1505 | .set_property = intel_tv_set_property, | 1506 | .set_property = intel_tv_set_property, |
| 1506 | .atomic_get_property = intel_connector_atomic_get_property, | 1507 | .atomic_get_property = intel_connector_atomic_get_property, |
| @@ -1599,7 +1600,6 @@ intel_tv_init(struct drm_device *dev) | |||
| 1599 | intel_encoder->disable = intel_disable_tv; | 1600 | intel_encoder->disable = intel_disable_tv; |
| 1600 | intel_encoder->get_hw_state = intel_tv_get_hw_state; | 1601 | intel_encoder->get_hw_state = intel_tv_get_hw_state; |
| 1601 | intel_connector->get_hw_state = intel_connector_get_hw_state; | 1602 | intel_connector->get_hw_state = intel_connector_get_hw_state; |
| 1602 | intel_connector->unregister = intel_connector_unregister; | ||
| 1603 | 1603 | ||
| 1604 | intel_connector_attach_encoder(intel_connector, intel_encoder); | 1604 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
| 1605 | intel_encoder->type = INTEL_OUTPUT_TVOUT; | 1605 | intel_encoder->type = INTEL_OUTPUT_TVOUT; |
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 82656654fb21..7746418a4c08 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c | |||
| @@ -407,7 +407,6 @@ static struct drm_driver imx_drm_driver = { | |||
| 407 | .load = imx_drm_driver_load, | 407 | .load = imx_drm_driver_load, |
| 408 | .unload = imx_drm_driver_unload, | 408 | .unload = imx_drm_driver_unload, |
| 409 | .lastclose = imx_drm_driver_lastclose, | 409 | .lastclose = imx_drm_driver_lastclose, |
| 410 | .set_busid = drm_platform_set_busid, | ||
| 411 | .gem_free_object_unlocked = drm_gem_cma_free_object, | 410 | .gem_free_object_unlocked = drm_gem_cma_free_object, |
| 412 | .gem_vm_ops = &drm_gem_cma_vm_ops, | 411 | .gem_vm_ops = &drm_gem_cma_vm_ops, |
| 413 | .dumb_create = drm_gem_cma_dumb_create, | 412 | .dumb_create = drm_gem_cma_dumb_create, |
diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig index eeefc971801a..9eefecedc3da 100644 --- a/drivers/gpu/drm/mediatek/Kconfig +++ b/drivers/gpu/drm/mediatek/Kconfig | |||
| @@ -6,7 +6,6 @@ config DRM_MEDIATEK | |||
| 6 | select DRM_KMS_HELPER | 6 | select DRM_KMS_HELPER |
| 7 | select DRM_MIPI_DSI | 7 | select DRM_MIPI_DSI |
| 8 | select DRM_PANEL | 8 | select DRM_PANEL |
| 9 | select IOMMU_DMA | ||
| 10 | select MEMORY | 9 | select MEMORY |
| 11 | select MTK_SMI | 10 | select MTK_SMI |
| 12 | help | 11 | help |
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index c33bf98c5d5e..eebb7d881c2b 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c | |||
| @@ -280,8 +280,6 @@ static int mtk_drm_bind(struct device *dev) | |||
| 280 | if (!drm) | 280 | if (!drm) |
| 281 | return -ENOMEM; | 281 | return -ENOMEM; |
| 282 | 282 | ||
| 283 | drm_dev_set_unique(drm, dev_name(dev)); | ||
| 284 | |||
| 285 | drm->dev_private = private; | 283 | drm->dev_private = private; |
| 286 | private->drm = drm; | 284 | private->drm = drm; |
| 287 | 285 | ||
| @@ -293,14 +291,8 @@ static int mtk_drm_bind(struct device *dev) | |||
| 293 | if (ret < 0) | 291 | if (ret < 0) |
| 294 | goto err_deinit; | 292 | goto err_deinit; |
| 295 | 293 | ||
| 296 | ret = drm_connector_register_all(drm); | ||
| 297 | if (ret < 0) | ||
| 298 | goto err_unregister; | ||
| 299 | |||
| 300 | return 0; | 294 | return 0; |
| 301 | 295 | ||
| 302 | err_unregister: | ||
| 303 | drm_dev_unregister(drm); | ||
| 304 | err_deinit: | 296 | err_deinit: |
| 305 | mtk_drm_kms_deinit(drm); | 297 | mtk_drm_kms_deinit(drm); |
| 306 | err_free: | 298 | err_free: |
| @@ -455,7 +447,6 @@ static int mtk_drm_remove(struct platform_device *pdev) | |||
| 455 | struct drm_device *drm = private->drm; | 447 | struct drm_device *drm = private->drm; |
| 456 | int i; | 448 | int i; |
| 457 | 449 | ||
| 458 | drm_connector_unregister_all(drm); | ||
| 459 | drm_dev_unregister(drm); | 450 | drm_dev_unregister(drm); |
| 460 | mtk_drm_kms_deinit(drm); | 451 | mtk_drm_kms_deinit(drm); |
| 461 | drm_dev_unref(drm); | 452 | drm_dev_unref(drm); |
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c index 51bc8988fc26..3995765a90dc 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c | |||
| @@ -170,6 +170,7 @@ static int mtk_plane_atomic_check(struct drm_plane *plane, | |||
| 170 | 170 | ||
| 171 | return drm_plane_helper_check_update(plane, state->crtc, fb, | 171 | return drm_plane_helper_check_update(plane, state->crtc, fb, |
| 172 | &src, &dest, &clip, | 172 | &src, &dest, &clip, |
| 173 | state->rotation, | ||
| 173 | DRM_PLANE_HELPER_NO_SCALING, | 174 | DRM_PLANE_HELPER_NO_SCALING, |
| 174 | DRM_PLANE_HELPER_NO_SCALING, | 175 | DRM_PLANE_HELPER_NO_SCALING, |
| 175 | true, true, &visible); | 176 | true, true, &visible); |
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 9c654092ef78..a02dc2b27739 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c | |||
| @@ -197,8 +197,6 @@ static int msm_drm_uninit(struct device *dev) | |||
| 197 | 197 | ||
| 198 | drm_kms_helper_poll_fini(ddev); | 198 | drm_kms_helper_poll_fini(ddev); |
| 199 | 199 | ||
| 200 | drm_connector_unregister_all(ddev); | ||
| 201 | |||
| 202 | drm_dev_unregister(ddev); | 200 | drm_dev_unregister(ddev); |
| 203 | 201 | ||
| 204 | #ifdef CONFIG_DRM_FBDEV_EMULATION | 202 | #ifdef CONFIG_DRM_FBDEV_EMULATION |
| @@ -431,12 +429,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) | |||
| 431 | if (ret) | 429 | if (ret) |
| 432 | goto fail; | 430 | goto fail; |
| 433 | 431 | ||
| 434 | ret = drm_connector_register_all(ddev); | ||
| 435 | if (ret) { | ||
| 436 | dev_err(dev, "failed to register connectors\n"); | ||
| 437 | goto fail; | ||
| 438 | } | ||
| 439 | |||
| 440 | drm_mode_config_reset(ddev); | 432 | drm_mode_config_reset(ddev); |
| 441 | 433 | ||
| 442 | #ifdef CONFIG_DRM_FBDEV_EMULATION | 434 | #ifdef CONFIG_DRM_FBDEV_EMULATION |
| @@ -730,7 +722,6 @@ static struct drm_driver msm_driver = { | |||
| 730 | .open = msm_open, | 722 | .open = msm_open, |
| 731 | .preclose = msm_preclose, | 723 | .preclose = msm_preclose, |
| 732 | .lastclose = msm_lastclose, | 724 | .lastclose = msm_lastclose, |
| 733 | .set_busid = drm_platform_set_busid, | ||
| 734 | .irq_handler = msm_irq, | 725 | .irq_handler = msm_irq, |
| 735 | .irq_preinstall = msm_irq_preinstall, | 726 | .irq_preinstall = msm_irq_preinstall, |
| 736 | .irq_postinstall = msm_irq_postinstall, | 727 | .irq_postinstall = msm_irq_postinstall, |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index c00ff6e786a3..295e7621cc68 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
| @@ -1070,7 +1070,6 @@ nouveau_drm_init(void) | |||
| 1070 | driver_pci = driver_stub; | 1070 | driver_pci = driver_stub; |
| 1071 | driver_pci.set_busid = drm_pci_set_busid; | 1071 | driver_pci.set_busid = drm_pci_set_busid; |
| 1072 | driver_platform = driver_stub; | 1072 | driver_platform = driver_stub; |
| 1073 | driver_platform.set_busid = drm_platform_set_busid; | ||
| 1074 | 1073 | ||
| 1075 | nouveau_display_options(); | 1074 | nouveau_display_options(); |
| 1076 | 1075 | ||
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 6b97011154bf..26c6134eb744 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c | |||
| @@ -801,7 +801,6 @@ static struct drm_driver omap_drm_driver = { | |||
| 801 | .unload = dev_unload, | 801 | .unload = dev_unload, |
| 802 | .open = dev_open, | 802 | .open = dev_open, |
| 803 | .lastclose = dev_lastclose, | 803 | .lastclose = dev_lastclose, |
| 804 | .set_busid = drm_platform_set_busid, | ||
| 805 | .get_vblank_counter = drm_vblank_no_hw_counter, | 804 | .get_vblank_counter = drm_vblank_no_hw_counter, |
| 806 | .enable_vblank = omap_irq_enable_vblank, | 805 | .enable_vblank = omap_irq_enable_vblank, |
| 807 | .disable_vblank = omap_irq_disable_vblank, | 806 | .disable_vblank = omap_irq_disable_vblank, |
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index 31dfa0893416..adb10fbe918d 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c | |||
| @@ -279,9 +279,6 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev) | |||
| 279 | if (ret) | 279 | if (ret) |
| 280 | goto fini; | 280 | goto fini; |
| 281 | 281 | ||
| 282 | /* disable all the possible outputs/crtcs before entering KMS mode */ | ||
| 283 | drm_helper_disable_unused_functions(dev); | ||
| 284 | |||
| 285 | ret = drm_fb_helper_initial_config(helper, 32); | 282 | ret = drm_fb_helper_initial_config(helper, 32); |
| 286 | if (ret) | 283 | if (ret) |
| 287 | goto fini; | 284 | goto fini; |
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 48ec4b6e8b26..d1c0512e4a9e 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c | |||
| @@ -278,7 +278,6 @@ static int rcar_du_remove(struct platform_device *pdev) | |||
| 278 | struct rcar_du_device *rcdu = platform_get_drvdata(pdev); | 278 | struct rcar_du_device *rcdu = platform_get_drvdata(pdev); |
| 279 | struct drm_device *ddev = rcdu->ddev; | 279 | struct drm_device *ddev = rcdu->ddev; |
| 280 | 280 | ||
| 281 | drm_connector_unregister_all(ddev); | ||
| 282 | drm_dev_unregister(ddev); | 281 | drm_dev_unregister(ddev); |
| 283 | 282 | ||
| 284 | if (rcdu->fbdev) | 283 | if (rcdu->fbdev) |
| @@ -320,8 +319,6 @@ static int rcar_du_probe(struct platform_device *pdev) | |||
| 320 | if (!ddev) | 319 | if (!ddev) |
| 321 | return -ENOMEM; | 320 | return -ENOMEM; |
| 322 | 321 | ||
| 323 | drm_dev_set_unique(ddev, dev_name(&pdev->dev)); | ||
| 324 | |||
| 325 | rcdu->ddev = ddev; | 322 | rcdu->ddev = ddev; |
| 326 | ddev->dev_private = rcdu; | 323 | ddev->dev_private = rcdu; |
| 327 | 324 | ||
| @@ -360,10 +357,6 @@ static int rcar_du_probe(struct platform_device *pdev) | |||
| 360 | if (ret) | 357 | if (ret) |
| 361 | goto error; | 358 | goto error; |
| 362 | 359 | ||
| 363 | ret = drm_connector_register_all(ddev); | ||
| 364 | if (ret < 0) | ||
| 365 | goto error; | ||
| 366 | |||
| 367 | DRM_INFO("Device %s probed\n", dev_name(&pdev->dev)); | 360 | DRM_INFO("Device %s probed\n", dev_name(&pdev->dev)); |
| 368 | 361 | ||
| 369 | return 0; | 362 | return 0; |
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig index d30bdc38a760..e48611e83c03 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig | |||
| @@ -2,6 +2,7 @@ config DRM_ROCKCHIP | |||
| 2 | tristate "DRM Support for Rockchip" | 2 | tristate "DRM Support for Rockchip" |
| 3 | depends on DRM && ROCKCHIP_IOMMU | 3 | depends on DRM && ROCKCHIP_IOMMU |
| 4 | depends on RESET_CONTROLLER | 4 | depends on RESET_CONTROLLER |
| 5 | select DRM_GEM_CMA_HELPER | ||
| 5 | select DRM_KMS_HELPER | 6 | select DRM_KMS_HELPER |
| 6 | select DRM_KMS_FB_HELPER | 7 | select DRM_KMS_FB_HELPER |
| 7 | select DRM_PANEL | 8 | select DRM_PANEL |
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index c2bcc5ea1abe..d665fb04d264 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c | |||
| @@ -146,16 +146,12 @@ static int rockchip_drm_bind(struct device *dev) | |||
| 146 | if (!drm_dev) | 146 | if (!drm_dev) |
| 147 | return -ENOMEM; | 147 | return -ENOMEM; |
| 148 | 148 | ||
| 149 | ret = drm_dev_register(drm_dev, 0); | ||
| 150 | if (ret) | ||
| 151 | goto err_free; | ||
| 152 | |||
| 153 | dev_set_drvdata(dev, drm_dev); | 149 | dev_set_drvdata(dev, drm_dev); |
| 154 | 150 | ||
| 155 | private = devm_kzalloc(drm_dev->dev, sizeof(*private), GFP_KERNEL); | 151 | private = devm_kzalloc(drm_dev->dev, sizeof(*private), GFP_KERNEL); |
| 156 | if (!private) { | 152 | if (!private) { |
| 157 | ret = -ENOMEM; | 153 | ret = -ENOMEM; |
| 158 | goto err_unregister; | 154 | goto err_free; |
| 159 | } | 155 | } |
| 160 | 156 | ||
| 161 | drm_dev->dev_private = private; | 157 | drm_dev->dev_private = private; |
| @@ -197,12 +193,6 @@ static int rockchip_drm_bind(struct device *dev) | |||
| 197 | if (ret) | 193 | if (ret) |
| 198 | goto err_detach_device; | 194 | goto err_detach_device; |
| 199 | 195 | ||
| 200 | ret = drm_connector_register_all(drm_dev); | ||
| 201 | if (ret) { | ||
| 202 | dev_err(dev, "failed to register connectors\n"); | ||
| 203 | goto err_unbind; | ||
| 204 | } | ||
| 205 | |||
| 206 | /* init kms poll for handling hpd */ | 196 | /* init kms poll for handling hpd */ |
| 207 | drm_kms_helper_poll_init(drm_dev); | 197 | drm_kms_helper_poll_init(drm_dev); |
| 208 | 198 | ||
| @@ -222,14 +212,19 @@ static int rockchip_drm_bind(struct device *dev) | |||
| 222 | if (ret) | 212 | if (ret) |
| 223 | goto err_vblank_cleanup; | 213 | goto err_vblank_cleanup; |
| 224 | 214 | ||
| 215 | ret = drm_dev_register(drm_dev, 0); | ||
| 216 | if (ret) | ||
| 217 | goto err_fbdev_fini; | ||
| 218 | |||
| 225 | if (is_support_iommu) | 219 | if (is_support_iommu) |
| 226 | arm_iommu_release_mapping(mapping); | 220 | arm_iommu_release_mapping(mapping); |
| 227 | return 0; | 221 | return 0; |
| 222 | err_fbdev_fini: | ||
| 223 | rockchip_drm_fbdev_fini(drm_dev); | ||
| 228 | err_vblank_cleanup: | 224 | err_vblank_cleanup: |
| 229 | drm_vblank_cleanup(drm_dev); | 225 | drm_vblank_cleanup(drm_dev); |
| 230 | err_kms_helper_poll_fini: | 226 | err_kms_helper_poll_fini: |
| 231 | drm_kms_helper_poll_fini(drm_dev); | 227 | drm_kms_helper_poll_fini(drm_dev); |
| 232 | err_unbind: | ||
| 233 | component_unbind_all(dev, drm_dev); | 228 | component_unbind_all(dev, drm_dev); |
| 234 | err_detach_device: | 229 | err_detach_device: |
| 235 | if (is_support_iommu) | 230 | if (is_support_iommu) |
| @@ -240,8 +235,6 @@ err_release_mapping: | |||
| 240 | err_config_cleanup: | 235 | err_config_cleanup: |
| 241 | drm_mode_config_cleanup(drm_dev); | 236 | drm_mode_config_cleanup(drm_dev); |
| 242 | drm_dev->dev_private = NULL; | 237 | drm_dev->dev_private = NULL; |
| 243 | err_unregister: | ||
| 244 | drm_dev_unregister(drm_dev); | ||
| 245 | err_free: | 238 | err_free: |
| 246 | drm_dev_unref(drm_dev); | 239 | drm_dev_unref(drm_dev); |
| 247 | return ret; | 240 | return ret; |
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 8cd840f602b7..6255e5bcd954 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c | |||
| @@ -626,6 +626,7 @@ static int vop_plane_atomic_check(struct drm_plane *plane, | |||
| 626 | 626 | ||
| 627 | ret = drm_plane_helper_check_update(plane, crtc, state->fb, | 627 | ret = drm_plane_helper_check_update(plane, crtc, state->fb, |
| 628 | src, dest, &clip, | 628 | src, dest, &clip, |
| 629 | state->rotation, | ||
| 629 | min_scale, | 630 | min_scale, |
| 630 | max_scale, | 631 | max_scale, |
| 631 | true, true, &visible); | 632 | true, true, &visible); |
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c index ee79264b5b6a..f0492603ea88 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c | |||
| @@ -259,7 +259,6 @@ static struct drm_driver shmob_drm_driver = { | |||
| 259 | | DRIVER_PRIME, | 259 | | DRIVER_PRIME, |
| 260 | .load = shmob_drm_load, | 260 | .load = shmob_drm_load, |
| 261 | .unload = shmob_drm_unload, | 261 | .unload = shmob_drm_unload, |
| 262 | .set_busid = drm_platform_set_busid, | ||
| 263 | .irq_handler = shmob_drm_irq, | 262 | .irq_handler = shmob_drm_irq, |
| 264 | .get_vblank_counter = drm_vblank_no_hw_counter, | 263 | .get_vblank_counter = drm_vblank_no_hw_counter, |
| 265 | .enable_vblank = shmob_drm_enable_vblank, | 264 | .enable_vblank = shmob_drm_enable_vblank, |
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c index 93ad8a5704d1..03defda77766 100644 --- a/drivers/gpu/drm/sis/sis_mm.c +++ b/drivers/gpu/drm/sis/sis_mm.c | |||
| @@ -316,7 +316,7 @@ void sis_reclaim_buffers_locked(struct drm_device *dev, | |||
| 316 | struct sis_file_private *file_priv = file->driver_priv; | 316 | struct sis_file_private *file_priv = file->driver_priv; |
| 317 | struct sis_memblock *entry, *next; | 317 | struct sis_memblock *entry, *next; |
| 318 | 318 | ||
| 319 | if (!(file->minor->master && file->master->lock.hw_lock)) | 319 | if (!(dev->master && file->master->lock.hw_lock)) |
| 320 | return; | 320 | return; |
| 321 | 321 | ||
| 322 | drm_legacy_idlelock_take(&file->master->lock); | 322 | drm_legacy_idlelock_take(&file->master->lock); |
diff --git a/drivers/gpu/drm/sti/sti_compositor.c b/drivers/gpu/drm/sti/sti_compositor.c index 3d2fa3ab33df..794148ff0e57 100644 --- a/drivers/gpu/drm/sti/sti_compositor.c +++ b/drivers/gpu/drm/sti/sti_compositor.c | |||
| @@ -55,6 +55,26 @@ struct sti_compositor_data stih416_compositor_data = { | |||
| 55 | }, | 55 | }, |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | int sti_compositor_debufs_init(struct sti_compositor *compo, | ||
| 59 | struct drm_minor *minor) | ||
| 60 | { | ||
| 61 | int ret = 0, i; | ||
| 62 | |||
| 63 | for (i = 0; compo->vid[i]; i++) { | ||
| 64 | ret = vid_debugfs_init(compo->vid[i], minor); | ||
| 65 | if (ret) | ||
| 66 | return ret; | ||
| 67 | } | ||
| 68 | |||
| 69 | for (i = 0; compo->mixer[i]; i++) { | ||
| 70 | ret = sti_mixer_debugfs_init(compo->mixer[i], minor); | ||
| 71 | if (ret) | ||
| 72 | return ret; | ||
| 73 | } | ||
| 74 | |||
| 75 | return 0; | ||
| 76 | } | ||
| 77 | |||
| 58 | static int sti_compositor_bind(struct device *dev, | 78 | static int sti_compositor_bind(struct device *dev, |
| 59 | struct device *master, | 79 | struct device *master, |
| 60 | void *data) | 80 | void *data) |
diff --git a/drivers/gpu/drm/sti/sti_compositor.h b/drivers/gpu/drm/sti/sti_compositor.h index 1a4a73dab11e..24444ef42a98 100644 --- a/drivers/gpu/drm/sti/sti_compositor.h +++ b/drivers/gpu/drm/sti/sti_compositor.h | |||
| @@ -81,4 +81,7 @@ struct sti_compositor { | |||
| 81 | struct notifier_block vtg_vblank_nb; | 81 | struct notifier_block vtg_vblank_nb; |
| 82 | }; | 82 | }; |
| 83 | 83 | ||
| 84 | int sti_compositor_debufs_init(struct sti_compositor *compo, | ||
| 85 | struct drm_minor *minor); | ||
| 86 | |||
| 84 | #endif | 87 | #endif |
diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c index e04deedabd4a..7fab3af7473b 100644 --- a/drivers/gpu/drm/sti/sti_crtc.c +++ b/drivers/gpu/drm/sti/sti_crtc.c | |||
| @@ -331,6 +331,17 @@ void sti_crtc_disable_vblank(struct drm_device *drm_dev, unsigned int pipe) | |||
| 331 | } | 331 | } |
| 332 | } | 332 | } |
| 333 | 333 | ||
| 334 | static int sti_crtc_late_register(struct drm_crtc *crtc) | ||
| 335 | { | ||
| 336 | struct sti_mixer *mixer = to_sti_mixer(crtc); | ||
| 337 | struct sti_compositor *compo = dev_get_drvdata(mixer->dev); | ||
| 338 | |||
| 339 | if (drm_crtc_index(crtc) == 0) | ||
| 340 | return sti_compositor_debufs_init(compo, crtc->dev->primary); | ||
| 341 | |||
| 342 | return 0; | ||
| 343 | } | ||
| 344 | |||
| 334 | static const struct drm_crtc_funcs sti_crtc_funcs = { | 345 | static const struct drm_crtc_funcs sti_crtc_funcs = { |
| 335 | .set_config = drm_atomic_helper_set_config, | 346 | .set_config = drm_atomic_helper_set_config, |
| 336 | .page_flip = drm_atomic_helper_page_flip, | 347 | .page_flip = drm_atomic_helper_page_flip, |
| @@ -339,6 +350,7 @@ static const struct drm_crtc_funcs sti_crtc_funcs = { | |||
| 339 | .reset = drm_atomic_helper_crtc_reset, | 350 | .reset = drm_atomic_helper_crtc_reset, |
| 340 | .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, | 351 | .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, |
| 341 | .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, | 352 | .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, |
| 353 | .late_register = sti_crtc_late_register, | ||
| 342 | }; | 354 | }; |
| 343 | 355 | ||
| 344 | bool sti_crtc_is_main(struct drm_crtc *crtc) | 356 | bool sti_crtc_is_main(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/sti/sti_cursor.c b/drivers/gpu/drm/sti/sti_cursor.c index 53aa0029295b..a263bbba4119 100644 --- a/drivers/gpu/drm/sti/sti_cursor.c +++ b/drivers/gpu/drm/sti/sti_cursor.c | |||
| @@ -329,6 +329,33 @@ static const struct drm_plane_helper_funcs sti_cursor_helpers_funcs = { | |||
| 329 | .atomic_disable = sti_cursor_atomic_disable, | 329 | .atomic_disable = sti_cursor_atomic_disable, |
| 330 | }; | 330 | }; |
| 331 | 331 | ||
| 332 | static void sti_cursor_destroy(struct drm_plane *drm_plane) | ||
| 333 | { | ||
| 334 | DRM_DEBUG_DRIVER("\n"); | ||
| 335 | |||
| 336 | drm_plane_helper_disable(drm_plane); | ||
| 337 | drm_plane_cleanup(drm_plane); | ||
| 338 | } | ||
| 339 | |||
| 340 | static int sti_cursor_late_register(struct drm_plane *drm_plane) | ||
| 341 | { | ||
| 342 | struct sti_plane *plane = to_sti_plane(drm_plane); | ||
| 343 | struct sti_cursor *cursor = to_sti_cursor(plane); | ||
| 344 | |||
| 345 | return cursor_debugfs_init(cursor, drm_plane->dev->primary); | ||
| 346 | } | ||
| 347 | |||
| 348 | struct drm_plane_funcs sti_cursor_plane_helpers_funcs = { | ||
| 349 | .update_plane = drm_atomic_helper_update_plane, | ||
| 350 | .disable_plane = drm_atomic_helper_disable_plane, | ||
| 351 | .destroy = sti_cursor_destroy, | ||
| 352 | .set_property = sti_plane_set_property, | ||
| 353 | .reset = drm_atomic_helper_plane_reset, | ||
| 354 | .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, | ||
| 355 | .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, | ||
| 356 | .late_register = sti_cursor_late_register, | ||
| 357 | }; | ||
| 358 | |||
| 332 | struct drm_plane *sti_cursor_create(struct drm_device *drm_dev, | 359 | struct drm_plane *sti_cursor_create(struct drm_device *drm_dev, |
| 333 | struct device *dev, int desc, | 360 | struct device *dev, int desc, |
| 334 | void __iomem *baseaddr, | 361 | void __iomem *baseaddr, |
| @@ -363,7 +390,7 @@ struct drm_plane *sti_cursor_create(struct drm_device *drm_dev, | |||
| 363 | 390 | ||
| 364 | res = drm_universal_plane_init(drm_dev, &cursor->plane.drm_plane, | 391 | res = drm_universal_plane_init(drm_dev, &cursor->plane.drm_plane, |
| 365 | possible_crtcs, | 392 | possible_crtcs, |
| 366 | &sti_plane_helpers_funcs, | 393 | &sti_cursor_plane_helpers_funcs, |
| 367 | cursor_supported_formats, | 394 | cursor_supported_formats, |
| 368 | ARRAY_SIZE(cursor_supported_formats), | 395 | ARRAY_SIZE(cursor_supported_formats), |
| 369 | DRM_PLANE_TYPE_CURSOR, NULL); | 396 | DRM_PLANE_TYPE_CURSOR, NULL); |
| @@ -377,9 +404,6 @@ struct drm_plane *sti_cursor_create(struct drm_device *drm_dev, | |||
| 377 | 404 | ||
| 378 | sti_plane_init_property(&cursor->plane, DRM_PLANE_TYPE_CURSOR); | 405 | sti_plane_init_property(&cursor->plane, DRM_PLANE_TYPE_CURSOR); |
| 379 | 406 | ||
| 380 | if (cursor_debugfs_init(cursor, drm_dev->primary)) | ||
| 381 | DRM_ERROR("CURSOR debugfs setup failed\n"); | ||
| 382 | |||
| 383 | return &cursor->plane.drm_plane; | 407 | return &cursor->plane.drm_plane; |
| 384 | 408 | ||
| 385 | err_plane: | 409 | err_plane: |
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c index dd2c400c4a46..96bd3d08b2d4 100644 --- a/drivers/gpu/drm/sti/sti_drv.c +++ b/drivers/gpu/drm/sti/sti_drv.c | |||
| @@ -226,8 +226,28 @@ static int sti_atomic_commit(struct drm_device *drm, | |||
| 226 | return 0; | 226 | return 0; |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | static void sti_output_poll_changed(struct drm_device *ddev) | ||
| 230 | { | ||
| 231 | struct sti_private *private = ddev->dev_private; | ||
| 232 | |||
| 233 | if (!ddev->mode_config.num_connector) | ||
| 234 | return; | ||
| 235 | |||
| 236 | if (private->fbdev) { | ||
| 237 | drm_fbdev_cma_hotplug_event(private->fbdev); | ||
| 238 | return; | ||
| 239 | } | ||
| 240 | |||
| 241 | private->fbdev = drm_fbdev_cma_init(ddev, 32, | ||
| 242 | ddev->mode_config.num_crtc, | ||
| 243 | ddev->mode_config.num_connector); | ||
| 244 | if (IS_ERR(private->fbdev)) | ||
| 245 | private->fbdev = NULL; | ||
| 246 | } | ||
| 247 | |||
| 229 | static const struct drm_mode_config_funcs sti_mode_config_funcs = { | 248 | static const struct drm_mode_config_funcs sti_mode_config_funcs = { |
| 230 | .fb_create = drm_fb_cma_create, | 249 | .fb_create = drm_fb_cma_create, |
| 250 | .output_poll_changed = sti_output_poll_changed, | ||
| 231 | .atomic_check = drm_atomic_helper_check, | 251 | .atomic_check = drm_atomic_helper_check, |
| 232 | .atomic_commit = sti_atomic_commit, | 252 | .atomic_commit = sti_atomic_commit, |
| 233 | }; | 253 | }; |
| @@ -248,45 +268,6 @@ static void sti_mode_config_init(struct drm_device *dev) | |||
| 248 | dev->mode_config.funcs = &sti_mode_config_funcs; | 268 | dev->mode_config.funcs = &sti_mode_config_funcs; |
| 249 | } | 269 | } |
| 250 | 270 | ||
| 251 | static int sti_load(struct drm_device *dev, unsigned long flags) | ||
| 252 | { | ||
| 253 | struct sti_private *private; | ||
| 254 | int ret; | ||
| 255 | |||
| 256 | private = kzalloc(sizeof(*private), GFP_KERNEL); | ||
| 257 | if (!private) { | ||
| 258 | DRM_ERROR("Failed to allocate private\n"); | ||
| 259 | return -ENOMEM; | ||
| 260 | } | ||
| 261 | dev->dev_private = (void *)private; | ||
| 262 | private->drm_dev = dev; | ||
| 263 | |||
| 264 | mutex_init(&private->commit.lock); | ||
| 265 | INIT_WORK(&private->commit.work, sti_atomic_work); | ||
| 266 | |||
| 267 | drm_mode_config_init(dev); | ||
| 268 | drm_kms_helper_poll_init(dev); | ||
| 269 | |||
| 270 | sti_mode_config_init(dev); | ||
| 271 | |||
| 272 | ret = component_bind_all(dev->dev, dev); | ||
| 273 | if (ret) { | ||
| 274 | drm_kms_helper_poll_fini(dev); | ||
| 275 | drm_mode_config_cleanup(dev); | ||
| 276 | kfree(private); | ||
| 277 | return ret; | ||
| 278 | } | ||
| 279 | |||
| 280 | drm_mode_config_reset(dev); | ||
| 281 | |||
| 282 | drm_helper_disable_unused_functions(dev); | ||
| 283 | drm_fbdev_cma_init(dev, 32, | ||
| 284 | dev->mode_config.num_crtc, | ||
| 285 | dev->mode_config.num_connector); | ||
| 286 | |||
| 287 | return 0; | ||
| 288 | } | ||
| 289 | |||
| 290 | static const struct file_operations sti_driver_fops = { | 271 | static const struct file_operations sti_driver_fops = { |
| 291 | .owner = THIS_MODULE, | 272 | .owner = THIS_MODULE, |
| 292 | .open = drm_open, | 273 | .open = drm_open, |
| @@ -303,7 +284,6 @@ static const struct file_operations sti_driver_fops = { | |||
| 303 | static struct drm_driver sti_driver = { | 284 | static struct drm_driver sti_driver = { |
| 304 | .driver_features = DRIVER_HAVE_IRQ | DRIVER_MODESET | | 285 | .driver_features = DRIVER_HAVE_IRQ | DRIVER_MODESET | |
| 305 | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC, | 286 | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC, |
| 306 | .load = sti_load, | ||
| 307 | .gem_free_object_unlocked = drm_gem_cma_free_object, | 287 | .gem_free_object_unlocked = drm_gem_cma_free_object, |
| 308 | .gem_vm_ops = &drm_gem_cma_vm_ops, | 288 | .gem_vm_ops = &drm_gem_cma_vm_ops, |
| 309 | .dumb_create = drm_gem_cma_dumb_create, | 289 | .dumb_create = drm_gem_cma_dumb_create, |
| @@ -340,14 +320,88 @@ static int compare_of(struct device *dev, void *data) | |||
| 340 | return dev->of_node == data; | 320 | return dev->of_node == data; |
| 341 | } | 321 | } |
| 342 | 322 | ||
| 323 | static int sti_init(struct drm_device *ddev) | ||
| 324 | { | ||
| 325 | struct sti_private *private; | ||
| 326 | |||
| 327 | private = kzalloc(sizeof(*private), GFP_KERNEL); | ||
| 328 | if (!private) | ||
| 329 | return -ENOMEM; | ||
| 330 | |||
| 331 | ddev->dev_private = (void *)private; | ||
| 332 | dev_set_drvdata(ddev->dev, ddev); | ||
| 333 | private->drm_dev = ddev; | ||
| 334 | |||
| 335 | mutex_init(&private->commit.lock); | ||
| 336 | INIT_WORK(&private->commit.work, sti_atomic_work); | ||
| 337 | |||
| 338 | drm_mode_config_init(ddev); | ||
| 339 | |||
| 340 | sti_mode_config_init(ddev); | ||
| 341 | |||
| 342 | drm_kms_helper_poll_init(ddev); | ||
| 343 | |||
| 344 | return 0; | ||
| 345 | } | ||
| 346 | |||
| 347 | static void sti_cleanup(struct drm_device *ddev) | ||
| 348 | { | ||
| 349 | struct sti_private *private = ddev->dev_private; | ||
| 350 | |||
| 351 | if (private->fbdev) { | ||
| 352 | drm_fbdev_cma_fini(private->fbdev); | ||
| 353 | private->fbdev = NULL; | ||
| 354 | } | ||
| 355 | |||
| 356 | drm_kms_helper_poll_fini(ddev); | ||
| 357 | drm_vblank_cleanup(ddev); | ||
| 358 | kfree(private); | ||
| 359 | ddev->dev_private = NULL; | ||
| 360 | } | ||
| 361 | |||
| 343 | static int sti_bind(struct device *dev) | 362 | static int sti_bind(struct device *dev) |
| 344 | { | 363 | { |
| 345 | return drm_platform_init(&sti_driver, to_platform_device(dev)); | 364 | struct drm_device *ddev; |
| 365 | int ret; | ||
| 366 | |||
| 367 | ddev = drm_dev_alloc(&sti_driver, dev); | ||
| 368 | if (!ddev) | ||
| 369 | return -ENOMEM; | ||
| 370 | |||
| 371 | ddev->platformdev = to_platform_device(dev); | ||
| 372 | |||
| 373 | ret = sti_init(ddev); | ||
| 374 | if (ret) | ||
| 375 | goto err_drm_dev_unref; | ||
| 376 | |||
| 377 | ret = component_bind_all(ddev->dev, ddev); | ||
| 378 | if (ret) | ||
| 379 | goto err_cleanup; | ||
| 380 | |||
| 381 | ret = drm_dev_register(ddev, 0); | ||
| 382 | if (ret) | ||
| 383 | goto err_register; | ||
| 384 | |||
| 385 | drm_mode_config_reset(ddev); | ||
| 386 | |||
| 387 | return 0; | ||
| 388 | |||
| 389 | err_register: | ||
| 390 | drm_mode_config_cleanup(ddev); | ||
| 391 | err_cleanup: | ||
| 392 | sti_cleanup(ddev); | ||
| 393 | err_drm_dev_unref: | ||
| 394 | drm_dev_unref(ddev); | ||
| 395 | return ret; | ||
| 346 | } | 396 | } |
| 347 | 397 | ||
| 348 | static void sti_unbind(struct device *dev) | 398 | static void sti_unbind(struct device *dev) |
| 349 | { | 399 | { |
| 350 | drm_put_dev(dev_get_drvdata(dev)); | 400 | struct drm_device *ddev = dev_get_drvdata(dev); |
| 401 | |||
| 402 | drm_dev_unregister(ddev); | ||
| 403 | sti_cleanup(ddev); | ||
| 404 | drm_dev_unref(ddev); | ||
| 351 | } | 405 | } |
| 352 | 406 | ||
| 353 | static const struct component_master_ops sti_ops = { | 407 | static const struct component_master_ops sti_ops = { |
diff --git a/drivers/gpu/drm/sti/sti_drv.h b/drivers/gpu/drm/sti/sti_drv.h index 30ddc20841c3..78ebe5e30f53 100644 --- a/drivers/gpu/drm/sti/sti_drv.h +++ b/drivers/gpu/drm/sti/sti_drv.h | |||
| @@ -24,6 +24,7 @@ struct sti_private { | |||
| 24 | struct sti_compositor *compo; | 24 | struct sti_compositor *compo; |
| 25 | struct drm_property *plane_zorder_property; | 25 | struct drm_property *plane_zorder_property; |
| 26 | struct drm_device *drm_dev; | 26 | struct drm_device *drm_dev; |
| 27 | struct drm_fbdev_cma *fbdev; | ||
| 27 | 28 | ||
| 28 | struct { | 29 | struct { |
| 29 | struct drm_atomic_state *state; | 30 | struct drm_atomic_state *state; |
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c index e2901667eceb..ec3108074350 100644 --- a/drivers/gpu/drm/sti/sti_dvo.c +++ b/drivers/gpu/drm/sti/sti_dvo.c | |||
| @@ -404,24 +404,29 @@ sti_dvo_connector_detect(struct drm_connector *connector, bool force) | |||
| 404 | return connector_status_disconnected; | 404 | return connector_status_disconnected; |
| 405 | } | 405 | } |
| 406 | 406 | ||
| 407 | static void sti_dvo_connector_destroy(struct drm_connector *connector) | 407 | static int sti_dvo_late_register(struct drm_connector *connector) |
| 408 | { | 408 | { |
| 409 | struct sti_dvo_connector *dvo_connector | 409 | struct sti_dvo_connector *dvo_connector |
| 410 | = to_sti_dvo_connector(connector); | 410 | = to_sti_dvo_connector(connector); |
| 411 | struct sti_dvo *dvo = dvo_connector->dvo; | ||
| 412 | |||
| 413 | if (dvo_debugfs_init(dvo, dvo->drm_dev->primary)) { | ||
| 414 | DRM_ERROR("DVO debugfs setup failed\n"); | ||
| 415 | return -EINVAL; | ||
| 416 | } | ||
| 411 | 417 | ||
| 412 | drm_connector_unregister(connector); | 418 | return 0; |
| 413 | drm_connector_cleanup(connector); | ||
| 414 | kfree(dvo_connector); | ||
| 415 | } | 419 | } |
| 416 | 420 | ||
| 417 | static const struct drm_connector_funcs sti_dvo_connector_funcs = { | 421 | static const struct drm_connector_funcs sti_dvo_connector_funcs = { |
| 418 | .dpms = drm_atomic_helper_connector_dpms, | 422 | .dpms = drm_atomic_helper_connector_dpms, |
| 419 | .fill_modes = drm_helper_probe_single_connector_modes, | 423 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 420 | .detect = sti_dvo_connector_detect, | 424 | .detect = sti_dvo_connector_detect, |
| 421 | .destroy = sti_dvo_connector_destroy, | 425 | .destroy = drm_connector_cleanup, |
| 422 | .reset = drm_atomic_helper_connector_reset, | 426 | .reset = drm_atomic_helper_connector_reset, |
| 423 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | 427 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, |
| 424 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | 428 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
| 429 | .late_register = sti_dvo_late_register, | ||
| 425 | }; | 430 | }; |
| 426 | 431 | ||
| 427 | static struct drm_encoder *sti_dvo_find_encoder(struct drm_device *dev) | 432 | static struct drm_encoder *sti_dvo_find_encoder(struct drm_device *dev) |
| @@ -492,26 +497,16 @@ static int sti_dvo_bind(struct device *dev, struct device *master, void *data) | |||
| 492 | drm_connector_helper_add(drm_connector, | 497 | drm_connector_helper_add(drm_connector, |
| 493 | &sti_dvo_connector_helper_funcs); | 498 | &sti_dvo_connector_helper_funcs); |
| 494 | 499 | ||
| 495 | err = drm_connector_register(drm_connector); | ||
| 496 | if (err) | ||
| 497 | goto err_connector; | ||
| 498 | |||
| 499 | err = drm_mode_connector_attach_encoder(drm_connector, encoder); | 500 | err = drm_mode_connector_attach_encoder(drm_connector, encoder); |
| 500 | if (err) { | 501 | if (err) { |
| 501 | DRM_ERROR("Failed to attach a connector to a encoder\n"); | 502 | DRM_ERROR("Failed to attach a connector to a encoder\n"); |
| 502 | goto err_sysfs; | 503 | goto err_sysfs; |
| 503 | } | 504 | } |
| 504 | 505 | ||
| 505 | if (dvo_debugfs_init(dvo, drm_dev->primary)) | ||
| 506 | DRM_ERROR("DVO debugfs setup failed\n"); | ||
| 507 | |||
| 508 | return 0; | 506 | return 0; |
| 509 | 507 | ||
| 510 | err_sysfs: | 508 | err_sysfs: |
| 511 | drm_connector_unregister(drm_connector); | ||
| 512 | err_connector: | ||
| 513 | drm_bridge_remove(bridge); | 509 | drm_bridge_remove(bridge); |
| 514 | drm_connector_cleanup(drm_connector); | ||
| 515 | return -EINVAL; | 510 | return -EINVAL; |
| 516 | } | 511 | } |
| 517 | 512 | ||
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c index fdf69b5a041b..bf63086a3dc8 100644 --- a/drivers/gpu/drm/sti/sti_gdp.c +++ b/drivers/gpu/drm/sti/sti_gdp.c | |||
| @@ -866,6 +866,33 @@ static const struct drm_plane_helper_funcs sti_gdp_helpers_funcs = { | |||
| 866 | .atomic_disable = sti_gdp_atomic_disable, | 866 | .atomic_disable = sti_gdp_atomic_disable, |
| 867 | }; | 867 | }; |
| 868 | 868 | ||
| 869 | static void sti_gdp_destroy(struct drm_plane *drm_plane) | ||
| 870 | { | ||
| 871 | DRM_DEBUG_DRIVER("\n"); | ||
| 872 | |||
| 873 | drm_plane_helper_disable(drm_plane); | ||
| 874 | drm_plane_cleanup(drm_plane); | ||
| 875 | } | ||
| 876 | |||
| 877 | static int sti_gdp_late_register(struct drm_plane *drm_plane) | ||
| 878 | { | ||
| 879 | struct sti_plane *plane = to_sti_plane(drm_plane); | ||
| 880 | struct sti_gdp *gdp = to_sti_gdp(plane); | ||
| 881 | |||
| 882 | return gdp_debugfs_init(gdp, drm_plane->dev->primary); | ||
| 883 | } | ||
| 884 | |||
| 885 | struct drm_plane_funcs sti_gdp_plane_helpers_funcs = { | ||
| 886 | .update_plane = drm_atomic_helper_update_plane, | ||
| 887 | .disable_plane = drm_atomic_helper_disable_plane, | ||
| 888 | .destroy = sti_gdp_destroy, | ||
| 889 | .set_property = sti_plane_set_property, | ||
| 890 | .reset = drm_atomic_helper_plane_reset, | ||
| 891 | .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, | ||
| 892 | .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, | ||
| 893 | .late_register = sti_gdp_late_register, | ||
| 894 | }; | ||
| 895 | |||
| 869 | struct drm_plane *sti_gdp_create(struct drm_device *drm_dev, | 896 | struct drm_plane *sti_gdp_create(struct drm_device *drm_dev, |
| 870 | struct device *dev, int desc, | 897 | struct device *dev, int desc, |
| 871 | void __iomem *baseaddr, | 898 | void __iomem *baseaddr, |
| @@ -892,7 +919,7 @@ struct drm_plane *sti_gdp_create(struct drm_device *drm_dev, | |||
| 892 | 919 | ||
| 893 | res = drm_universal_plane_init(drm_dev, &gdp->plane.drm_plane, | 920 | res = drm_universal_plane_init(drm_dev, &gdp->plane.drm_plane, |
| 894 | possible_crtcs, | 921 | possible_crtcs, |
| 895 | &sti_plane_helpers_funcs, | 922 | &sti_gdp_plane_helpers_funcs, |
| 896 | gdp_supported_formats, | 923 | gdp_supported_formats, |
| 897 | ARRAY_SIZE(gdp_supported_formats), | 924 | ARRAY_SIZE(gdp_supported_formats), |
| 898 | type, NULL); | 925 | type, NULL); |
| @@ -905,9 +932,6 @@ struct drm_plane *sti_gdp_create(struct drm_device *drm_dev, | |||
| 905 | 932 | ||
| 906 | sti_plane_init_property(&gdp->plane, type); | 933 | sti_plane_init_property(&gdp->plane, type); |
| 907 | 934 | ||
| 908 | if (gdp_debugfs_init(gdp, drm_dev->primary)) | ||
| 909 | DRM_ERROR("GDP debugfs setup failed\n"); | ||
| 910 | |||
| 911 | return &gdp->plane.drm_plane; | 935 | return &gdp->plane.drm_plane; |
| 912 | 936 | ||
| 913 | err: | 937 | err: |
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c index dcec5a8eda59..8505569f75de 100644 --- a/drivers/gpu/drm/sti/sti_hda.c +++ b/drivers/gpu/drm/sti/sti_hda.c | |||
| @@ -681,24 +681,29 @@ sti_hda_connector_detect(struct drm_connector *connector, bool force) | |||
| 681 | return connector_status_connected; | 681 | return connector_status_connected; |
| 682 | } | 682 | } |
| 683 | 683 | ||
| 684 | static void sti_hda_connector_destroy(struct drm_connector *connector) | 684 | static int sti_hda_late_register(struct drm_connector *connector) |
| 685 | { | 685 | { |
| 686 | struct sti_hda_connector *hda_connector | 686 | struct sti_hda_connector *hda_connector |
| 687 | = to_sti_hda_connector(connector); | 687 | = to_sti_hda_connector(connector); |
| 688 | struct sti_hda *hda = hda_connector->hda; | ||
| 689 | |||
| 690 | if (hda_debugfs_init(hda, hda->drm_dev->primary)) { | ||
| 691 | DRM_ERROR("HDA debugfs setup failed\n"); | ||
| 692 | return -EINVAL; | ||
| 693 | } | ||
| 688 | 694 | ||
| 689 | drm_connector_unregister(connector); | 695 | return 0; |
| 690 | drm_connector_cleanup(connector); | ||
| 691 | kfree(hda_connector); | ||
| 692 | } | 696 | } |
| 693 | 697 | ||
| 694 | static const struct drm_connector_funcs sti_hda_connector_funcs = { | 698 | static const struct drm_connector_funcs sti_hda_connector_funcs = { |
| 695 | .dpms = drm_atomic_helper_connector_dpms, | 699 | .dpms = drm_atomic_helper_connector_dpms, |
| 696 | .fill_modes = drm_helper_probe_single_connector_modes, | 700 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 697 | .detect = sti_hda_connector_detect, | 701 | .detect = sti_hda_connector_detect, |
| 698 | .destroy = sti_hda_connector_destroy, | 702 | .destroy = drm_connector_cleanup, |
| 699 | .reset = drm_atomic_helper_connector_reset, | 703 | .reset = drm_atomic_helper_connector_reset, |
| 700 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | 704 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, |
| 701 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | 705 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
| 706 | .late_register = sti_hda_late_register, | ||
| 702 | }; | 707 | }; |
| 703 | 708 | ||
| 704 | static struct drm_encoder *sti_hda_find_encoder(struct drm_device *dev) | 709 | static struct drm_encoder *sti_hda_find_encoder(struct drm_device *dev) |
| @@ -756,10 +761,6 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data) | |||
| 756 | drm_connector_helper_add(drm_connector, | 761 | drm_connector_helper_add(drm_connector, |
| 757 | &sti_hda_connector_helper_funcs); | 762 | &sti_hda_connector_helper_funcs); |
| 758 | 763 | ||
| 759 | err = drm_connector_register(drm_connector); | ||
| 760 | if (err) | ||
| 761 | goto err_connector; | ||
| 762 | |||
| 763 | err = drm_mode_connector_attach_encoder(drm_connector, encoder); | 764 | err = drm_mode_connector_attach_encoder(drm_connector, encoder); |
| 764 | if (err) { | 765 | if (err) { |
| 765 | DRM_ERROR("Failed to attach a connector to a encoder\n"); | 766 | DRM_ERROR("Failed to attach a connector to a encoder\n"); |
| @@ -769,15 +770,10 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data) | |||
| 769 | /* force to disable hd dacs at startup */ | 770 | /* force to disable hd dacs at startup */ |
| 770 | hda_enable_hd_dacs(hda, false); | 771 | hda_enable_hd_dacs(hda, false); |
| 771 | 772 | ||
| 772 | if (hda_debugfs_init(hda, drm_dev->primary)) | ||
| 773 | DRM_ERROR("HDA debugfs setup failed\n"); | ||
| 774 | |||
| 775 | return 0; | 773 | return 0; |
| 776 | 774 | ||
| 777 | err_sysfs: | 775 | err_sysfs: |
| 778 | drm_connector_unregister(drm_connector); | 776 | drm_bridge_remove(bridge); |
| 779 | err_connector: | ||
| 780 | drm_connector_cleanup(drm_connector); | ||
| 781 | return -EINVAL; | 777 | return -EINVAL; |
| 782 | } | 778 | } |
| 783 | 779 | ||
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c index 36d9d6635784..8d1402b245bf 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.c +++ b/drivers/gpu/drm/sti/sti_hdmi.c | |||
| @@ -915,16 +915,6 @@ sti_hdmi_connector_detect(struct drm_connector *connector, bool force) | |||
| 915 | return connector_status_disconnected; | 915 | return connector_status_disconnected; |
| 916 | } | 916 | } |
| 917 | 917 | ||
| 918 | static void sti_hdmi_connector_destroy(struct drm_connector *connector) | ||
| 919 | { | ||
| 920 | struct sti_hdmi_connector *hdmi_connector | ||
| 921 | = to_sti_hdmi_connector(connector); | ||
| 922 | |||
| 923 | drm_connector_unregister(connector); | ||
| 924 | drm_connector_cleanup(connector); | ||
| 925 | kfree(hdmi_connector); | ||
| 926 | } | ||
| 927 | |||
| 928 | static void sti_hdmi_connector_init_property(struct drm_device *drm_dev, | 918 | static void sti_hdmi_connector_init_property(struct drm_device *drm_dev, |
| 929 | struct drm_connector *connector) | 919 | struct drm_connector *connector) |
| 930 | { | 920 | { |
| @@ -1007,17 +997,31 @@ sti_hdmi_connector_get_property(struct drm_connector *connector, | |||
| 1007 | return -EINVAL; | 997 | return -EINVAL; |
| 1008 | } | 998 | } |
| 1009 | 999 | ||
| 1000 | static int sti_hdmi_late_register(struct drm_connector *connector) | ||
| 1001 | { | ||
| 1002 | struct sti_hdmi_connector *hdmi_connector | ||
| 1003 | = to_sti_hdmi_connector(connector); | ||
| 1004 | struct sti_hdmi *hdmi = hdmi_connector->hdmi; | ||
| 1005 | |||
| 1006 | if (hdmi_debugfs_init(hdmi, hdmi->drm_dev->primary)) { | ||
| 1007 | DRM_ERROR("HDMI debugfs setup failed\n"); | ||
| 1008 | return -EINVAL; | ||
| 1009 | } | ||
| 1010 | |||
| 1011 | return 0; | ||
| 1012 | } | ||
| 1013 | |||
| 1010 | static const struct drm_connector_funcs sti_hdmi_connector_funcs = { | 1014 | static const struct drm_connector_funcs sti_hdmi_connector_funcs = { |
| 1011 | .dpms = drm_atomic_helper_connector_dpms, | ||
| 1012 | .fill_modes = drm_helper_probe_single_connector_modes, | 1015 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 1013 | .detect = sti_hdmi_connector_detect, | 1016 | .detect = sti_hdmi_connector_detect, |
| 1014 | .destroy = sti_hdmi_connector_destroy, | 1017 | .destroy = drm_connector_cleanup, |
| 1015 | .reset = drm_atomic_helper_connector_reset, | 1018 | .reset = drm_atomic_helper_connector_reset, |
| 1016 | .set_property = drm_atomic_helper_connector_set_property, | 1019 | .set_property = drm_atomic_helper_connector_set_property, |
| 1017 | .atomic_set_property = sti_hdmi_connector_set_property, | 1020 | .atomic_set_property = sti_hdmi_connector_set_property, |
| 1018 | .atomic_get_property = sti_hdmi_connector_get_property, | 1021 | .atomic_get_property = sti_hdmi_connector_get_property, |
| 1019 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | 1022 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, |
| 1020 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | 1023 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
| 1024 | .late_register = sti_hdmi_late_register, | ||
| 1021 | }; | 1025 | }; |
| 1022 | 1026 | ||
| 1023 | static struct drm_encoder *sti_hdmi_find_encoder(struct drm_device *dev) | 1027 | static struct drm_encoder *sti_hdmi_find_encoder(struct drm_device *dev) |
| @@ -1078,10 +1082,6 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data) | |||
| 1078 | /* initialise property */ | 1082 | /* initialise property */ |
| 1079 | sti_hdmi_connector_init_property(drm_dev, drm_connector); | 1083 | sti_hdmi_connector_init_property(drm_dev, drm_connector); |
| 1080 | 1084 | ||
| 1081 | err = drm_connector_register(drm_connector); | ||
| 1082 | if (err) | ||
| 1083 | goto err_connector; | ||
| 1084 | |||
| 1085 | err = drm_mode_connector_attach_encoder(drm_connector, encoder); | 1085 | err = drm_mode_connector_attach_encoder(drm_connector, encoder); |
| 1086 | if (err) { | 1086 | if (err) { |
| 1087 | DRM_ERROR("Failed to attach a connector to a encoder\n"); | 1087 | DRM_ERROR("Failed to attach a connector to a encoder\n"); |
| @@ -1091,16 +1091,10 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data) | |||
| 1091 | /* Enable default interrupts */ | 1091 | /* Enable default interrupts */ |
| 1092 | hdmi_write(hdmi, HDMI_DEFAULT_INT, HDMI_INT_EN); | 1092 | hdmi_write(hdmi, HDMI_DEFAULT_INT, HDMI_INT_EN); |
| 1093 | 1093 | ||
| 1094 | if (hdmi_debugfs_init(hdmi, drm_dev->primary)) | ||
| 1095 | DRM_ERROR("HDMI debugfs setup failed\n"); | ||
| 1096 | |||
| 1097 | return 0; | 1094 | return 0; |
| 1098 | 1095 | ||
| 1099 | err_sysfs: | 1096 | err_sysfs: |
| 1100 | drm_connector_unregister(drm_connector); | 1097 | drm_bridge_remove(bridge); |
| 1101 | err_connector: | ||
| 1102 | drm_connector_cleanup(drm_connector); | ||
| 1103 | |||
| 1104 | return -EINVAL; | 1098 | return -EINVAL; |
| 1105 | } | 1099 | } |
| 1106 | 1100 | ||
diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c index 1c06a50fddca..33d2f42550cc 100644 --- a/drivers/gpu/drm/sti/sti_hqvdp.c +++ b/drivers/gpu/drm/sti/sti_hqvdp.c | |||
| @@ -1234,6 +1234,33 @@ static const struct drm_plane_helper_funcs sti_hqvdp_helpers_funcs = { | |||
| 1234 | .atomic_disable = sti_hqvdp_atomic_disable, | 1234 | .atomic_disable = sti_hqvdp_atomic_disable, |
| 1235 | }; | 1235 | }; |
| 1236 | 1236 | ||
| 1237 | static void sti_hqvdp_destroy(struct drm_plane *drm_plane) | ||
| 1238 | { | ||
| 1239 | DRM_DEBUG_DRIVER("\n"); | ||
| 1240 | |||
| 1241 | drm_plane_helper_disable(drm_plane); | ||
| 1242 | drm_plane_cleanup(drm_plane); | ||
| 1243 | } | ||
| 1244 | |||
| 1245 | static int sti_hqvdp_late_register(struct drm_plane *drm_plane) | ||
| 1246 | { | ||
| 1247 | struct sti_plane *plane = to_sti_plane(drm_plane); | ||
| 1248 | struct sti_hqvdp *hqvdp = to_sti_hqvdp(plane); | ||
| 1249 | |||
| 1250 | return hqvdp_debugfs_init(hqvdp, drm_plane->dev->primary); | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | struct drm_plane_funcs sti_hqvdp_plane_helpers_funcs = { | ||
| 1254 | .update_plane = drm_atomic_helper_update_plane, | ||
| 1255 | .disable_plane = drm_atomic_helper_disable_plane, | ||
| 1256 | .destroy = sti_hqvdp_destroy, | ||
| 1257 | .set_property = sti_plane_set_property, | ||
| 1258 | .reset = drm_atomic_helper_plane_reset, | ||
| 1259 | .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, | ||
| 1260 | .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, | ||
| 1261 | .late_register = sti_hqvdp_late_register, | ||
| 1262 | }; | ||
| 1263 | |||
| 1237 | static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev, | 1264 | static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev, |
| 1238 | struct device *dev, int desc) | 1265 | struct device *dev, int desc) |
| 1239 | { | 1266 | { |
| @@ -1246,7 +1273,7 @@ static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev, | |||
| 1246 | sti_hqvdp_init(hqvdp); | 1273 | sti_hqvdp_init(hqvdp); |
| 1247 | 1274 | ||
| 1248 | res = drm_universal_plane_init(drm_dev, &hqvdp->plane.drm_plane, 1, | 1275 | res = drm_universal_plane_init(drm_dev, &hqvdp->plane.drm_plane, 1, |
| 1249 | &sti_plane_helpers_funcs, | 1276 | &sti_hqvdp_plane_helpers_funcs, |
| 1250 | hqvdp_supported_formats, | 1277 | hqvdp_supported_formats, |
| 1251 | ARRAY_SIZE(hqvdp_supported_formats), | 1278 | ARRAY_SIZE(hqvdp_supported_formats), |
| 1252 | DRM_PLANE_TYPE_OVERLAY, NULL); | 1279 | DRM_PLANE_TYPE_OVERLAY, NULL); |
| @@ -1259,9 +1286,6 @@ static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev, | |||
| 1259 | 1286 | ||
| 1260 | sti_plane_init_property(&hqvdp->plane, DRM_PLANE_TYPE_OVERLAY); | 1287 | sti_plane_init_property(&hqvdp->plane, DRM_PLANE_TYPE_OVERLAY); |
| 1261 | 1288 | ||
| 1262 | if (hqvdp_debugfs_init(hqvdp, drm_dev->primary)) | ||
| 1263 | DRM_ERROR("HQVDP debugfs setup failed\n"); | ||
| 1264 | |||
| 1265 | return &hqvdp->plane.drm_plane; | 1289 | return &hqvdp->plane.drm_plane; |
| 1266 | } | 1290 | } |
| 1267 | 1291 | ||
diff --git a/drivers/gpu/drm/sti/sti_mixer.c b/drivers/gpu/drm/sti/sti_mixer.c index 6f86f2b2b6a5..1885c7ab5a8b 100644 --- a/drivers/gpu/drm/sti/sti_mixer.c +++ b/drivers/gpu/drm/sti/sti_mixer.c | |||
| @@ -181,7 +181,7 @@ static struct drm_info_list mixer1_debugfs_files[] = { | |||
| 181 | { "mixer_aux", mixer_dbg_show, 0, NULL }, | 181 | { "mixer_aux", mixer_dbg_show, 0, NULL }, |
| 182 | }; | 182 | }; |
| 183 | 183 | ||
| 184 | static int mixer_debugfs_init(struct sti_mixer *mixer, struct drm_minor *minor) | 184 | int sti_mixer_debugfs_init(struct sti_mixer *mixer, struct drm_minor *minor) |
| 185 | { | 185 | { |
| 186 | unsigned int i; | 186 | unsigned int i; |
| 187 | struct drm_info_list *mixer_debugfs_files; | 187 | struct drm_info_list *mixer_debugfs_files; |
| @@ -393,8 +393,5 @@ struct sti_mixer *sti_mixer_create(struct device *dev, | |||
| 393 | DRM_DEBUG_DRIVER("%s created. Regs=%p\n", | 393 | DRM_DEBUG_DRIVER("%s created. Regs=%p\n", |
| 394 | sti_mixer_to_str(mixer), mixer->regs); | 394 | sti_mixer_to_str(mixer), mixer->regs); |
| 395 | 395 | ||
| 396 | if (mixer_debugfs_init(mixer, drm_dev->primary)) | ||
| 397 | DRM_ERROR("MIXER debugfs setup failed\n"); | ||
| 398 | |||
| 399 | return mixer; | 396 | return mixer; |
| 400 | } | 397 | } |
diff --git a/drivers/gpu/drm/sti/sti_mixer.h b/drivers/gpu/drm/sti/sti_mixer.h index 6f35fc086873..830a3c42d886 100644 --- a/drivers/gpu/drm/sti/sti_mixer.h +++ b/drivers/gpu/drm/sti/sti_mixer.h | |||
| @@ -55,6 +55,8 @@ int sti_mixer_active_video_area(struct sti_mixer *mixer, | |||
| 55 | 55 | ||
| 56 | void sti_mixer_set_background_status(struct sti_mixer *mixer, bool enable); | 56 | void sti_mixer_set_background_status(struct sti_mixer *mixer, bool enable); |
| 57 | 57 | ||
| 58 | int sti_mixer_debugfs_init(struct sti_mixer *mixer, struct drm_minor *minor); | ||
| 59 | |||
| 58 | /* depth in Cross-bar control = z order */ | 60 | /* depth in Cross-bar control = z order */ |
| 59 | #define GAM_MIXER_NB_DEPTH_LEVEL 6 | 61 | #define GAM_MIXER_NB_DEPTH_LEVEL 6 |
| 60 | 62 | ||
diff --git a/drivers/gpu/drm/sti/sti_plane.c b/drivers/gpu/drm/sti/sti_plane.c index f10c98d3f012..85cee9098439 100644 --- a/drivers/gpu/drm/sti/sti_plane.c +++ b/drivers/gpu/drm/sti/sti_plane.c | |||
| @@ -106,17 +106,9 @@ void sti_plane_update_fps(struct sti_plane *plane, | |||
| 106 | plane->fps_info.fips_str); | 106 | plane->fps_info.fips_str); |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | static void sti_plane_destroy(struct drm_plane *drm_plane) | 109 | int sti_plane_set_property(struct drm_plane *drm_plane, |
| 110 | { | 110 | struct drm_property *property, |
| 111 | DRM_DEBUG_DRIVER("\n"); | 111 | uint64_t val) |
| 112 | |||
| 113 | drm_plane_helper_disable(drm_plane); | ||
| 114 | drm_plane_cleanup(drm_plane); | ||
| 115 | } | ||
| 116 | |||
| 117 | static int sti_plane_set_property(struct drm_plane *drm_plane, | ||
| 118 | struct drm_property *property, | ||
| 119 | uint64_t val) | ||
| 120 | { | 112 | { |
| 121 | struct drm_device *dev = drm_plane->dev; | 113 | struct drm_device *dev = drm_plane->dev; |
| 122 | struct sti_private *private = dev->dev_private; | 114 | struct sti_private *private = dev->dev_private; |
| @@ -170,13 +162,3 @@ void sti_plane_init_property(struct sti_plane *plane, | |||
| 170 | plane->drm_plane.base.id, | 162 | plane->drm_plane.base.id, |
| 171 | sti_plane_to_str(plane), plane->zorder); | 163 | sti_plane_to_str(plane), plane->zorder); |
| 172 | } | 164 | } |
| 173 | |||
| 174 | struct drm_plane_funcs sti_plane_helpers_funcs = { | ||
| 175 | .update_plane = drm_atomic_helper_update_plane, | ||
| 176 | .disable_plane = drm_atomic_helper_disable_plane, | ||
| 177 | .destroy = sti_plane_destroy, | ||
| 178 | .set_property = sti_plane_set_property, | ||
| 179 | .reset = drm_atomic_helper_plane_reset, | ||
| 180 | .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, | ||
| 181 | .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, | ||
| 182 | }; | ||
diff --git a/drivers/gpu/drm/sti/sti_plane.h b/drivers/gpu/drm/sti/sti_plane.h index c50a3b9f5d37..39d39f5b7dd9 100644 --- a/drivers/gpu/drm/sti/sti_plane.h +++ b/drivers/gpu/drm/sti/sti_plane.h | |||
| @@ -11,8 +11,6 @@ | |||
| 11 | #include <drm/drm_atomic_helper.h> | 11 | #include <drm/drm_atomic_helper.h> |
| 12 | #include <drm/drm_plane_helper.h> | 12 | #include <drm/drm_plane_helper.h> |
| 13 | 13 | ||
| 14 | extern struct drm_plane_funcs sti_plane_helpers_funcs; | ||
| 15 | |||
| 16 | #define to_sti_plane(x) container_of(x, struct sti_plane, drm_plane) | 14 | #define to_sti_plane(x) container_of(x, struct sti_plane, drm_plane) |
| 17 | 15 | ||
| 18 | #define STI_PLANE_TYPE_SHIFT 8 | 16 | #define STI_PLANE_TYPE_SHIFT 8 |
| @@ -83,6 +81,11 @@ const char *sti_plane_to_str(struct sti_plane *plane); | |||
| 83 | void sti_plane_update_fps(struct sti_plane *plane, | 81 | void sti_plane_update_fps(struct sti_plane *plane, |
| 84 | bool new_frame, | 82 | bool new_frame, |
| 85 | bool new_field); | 83 | bool new_field); |
| 84 | |||
| 85 | int sti_plane_set_property(struct drm_plane *drm_plane, | ||
| 86 | struct drm_property *property, | ||
| 87 | uint64_t val); | ||
| 88 | |||
| 86 | void sti_plane_init_property(struct sti_plane *plane, | 89 | void sti_plane_init_property(struct sti_plane *plane, |
| 87 | enum drm_plane_type type); | 90 | enum drm_plane_type type); |
| 88 | #endif | 91 | #endif |
diff --git a/drivers/gpu/drm/sti/sti_tvout.c b/drivers/gpu/drm/sti/sti_tvout.c index 60fe0afa5644..e25995b35715 100644 --- a/drivers/gpu/drm/sti/sti_tvout.c +++ b/drivers/gpu/drm/sti/sti_tvout.c | |||
| @@ -112,6 +112,7 @@ struct sti_tvout { | |||
| 112 | struct drm_encoder *hdmi; | 112 | struct drm_encoder *hdmi; |
| 113 | struct drm_encoder *hda; | 113 | struct drm_encoder *hda; |
| 114 | struct drm_encoder *dvo; | 114 | struct drm_encoder *dvo; |
| 115 | bool debugfs_registered; | ||
| 115 | }; | 116 | }; |
| 116 | 117 | ||
| 117 | struct sti_tvout_encoder { | 118 | struct sti_tvout_encoder { |
| @@ -625,8 +626,37 @@ static void sti_tvout_encoder_destroy(struct drm_encoder *encoder) | |||
| 625 | kfree(sti_encoder); | 626 | kfree(sti_encoder); |
| 626 | } | 627 | } |
| 627 | 628 | ||
| 629 | static int sti_tvout_late_register(struct drm_encoder *encoder) | ||
| 630 | { | ||
| 631 | struct sti_tvout *tvout = to_sti_tvout(encoder); | ||
| 632 | int ret; | ||
| 633 | |||
| 634 | if (tvout->debugfs_registered) | ||
| 635 | return 0; | ||
| 636 | |||
| 637 | ret = tvout_debugfs_init(tvout, encoder->dev->primary); | ||
| 638 | if (ret) | ||
| 639 | return ret; | ||
| 640 | |||
| 641 | tvout->debugfs_registered = true; | ||
| 642 | return 0; | ||
| 643 | } | ||
| 644 | |||
| 645 | static void sti_tvout_early_unregister(struct drm_encoder *encoder) | ||
| 646 | { | ||
| 647 | struct sti_tvout *tvout = to_sti_tvout(encoder); | ||
| 648 | |||
| 649 | if (!tvout->debugfs_registered) | ||
| 650 | return; | ||
| 651 | |||
| 652 | tvout_debugfs_exit(tvout, encoder->dev->primary); | ||
| 653 | tvout->debugfs_registered = false; | ||
| 654 | } | ||
| 655 | |||
| 628 | static const struct drm_encoder_funcs sti_tvout_encoder_funcs = { | 656 | static const struct drm_encoder_funcs sti_tvout_encoder_funcs = { |
| 629 | .destroy = sti_tvout_encoder_destroy, | 657 | .destroy = sti_tvout_encoder_destroy, |
| 658 | .late_register = sti_tvout_late_register, | ||
| 659 | .early_unregister = sti_tvout_early_unregister, | ||
| 630 | }; | 660 | }; |
| 631 | 661 | ||
| 632 | static void sti_dvo_encoder_enable(struct drm_encoder *encoder) | 662 | static void sti_dvo_encoder_enable(struct drm_encoder *encoder) |
| @@ -813,9 +843,6 @@ static int sti_tvout_bind(struct device *dev, struct device *master, void *data) | |||
| 813 | 843 | ||
| 814 | sti_tvout_create_encoders(drm_dev, tvout); | 844 | sti_tvout_create_encoders(drm_dev, tvout); |
| 815 | 845 | ||
| 816 | if (tvout_debugfs_init(tvout, drm_dev->primary)) | ||
| 817 | DRM_ERROR("TVOUT debugfs setup failed\n"); | ||
| 818 | |||
| 819 | return 0; | 846 | return 0; |
| 820 | } | 847 | } |
| 821 | 848 | ||
| @@ -823,11 +850,8 @@ static void sti_tvout_unbind(struct device *dev, struct device *master, | |||
| 823 | void *data) | 850 | void *data) |
| 824 | { | 851 | { |
| 825 | struct sti_tvout *tvout = dev_get_drvdata(dev); | 852 | struct sti_tvout *tvout = dev_get_drvdata(dev); |
| 826 | struct drm_device *drm_dev = data; | ||
| 827 | 853 | ||
| 828 | sti_tvout_destroy_encoders(tvout); | 854 | sti_tvout_destroy_encoders(tvout); |
| 829 | |||
| 830 | tvout_debugfs_exit(tvout, drm_dev->primary); | ||
| 831 | } | 855 | } |
| 832 | 856 | ||
| 833 | static const struct component_ops sti_tvout_ops = { | 857 | static const struct component_ops sti_tvout_ops = { |
diff --git a/drivers/gpu/drm/sti/sti_vid.c b/drivers/gpu/drm/sti/sti_vid.c index 0132aaebe598..47634a0251fc 100644 --- a/drivers/gpu/drm/sti/sti_vid.c +++ b/drivers/gpu/drm/sti/sti_vid.c | |||
| @@ -123,7 +123,7 @@ static struct drm_info_list vid_debugfs_files[] = { | |||
| 123 | { "vid", vid_dbg_show, 0, NULL }, | 123 | { "vid", vid_dbg_show, 0, NULL }, |
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | static int vid_debugfs_init(struct sti_vid *vid, struct drm_minor *minor) | 126 | int vid_debugfs_init(struct sti_vid *vid, struct drm_minor *minor) |
| 127 | { | 127 | { |
| 128 | unsigned int i; | 128 | unsigned int i; |
| 129 | 129 | ||
| @@ -220,8 +220,5 @@ struct sti_vid *sti_vid_create(struct device *dev, struct drm_device *drm_dev, | |||
| 220 | 220 | ||
| 221 | sti_vid_init(vid); | 221 | sti_vid_init(vid); |
| 222 | 222 | ||
| 223 | if (vid_debugfs_init(vid, drm_dev->primary)) | ||
| 224 | DRM_ERROR("VID debugfs setup failed\n"); | ||
| 225 | |||
| 226 | return vid; | 223 | return vid; |
| 227 | } | 224 | } |
diff --git a/drivers/gpu/drm/sti/sti_vid.h b/drivers/gpu/drm/sti/sti_vid.h index 6c842344f3d8..fdc90f922a05 100644 --- a/drivers/gpu/drm/sti/sti_vid.h +++ b/drivers/gpu/drm/sti/sti_vid.h | |||
| @@ -26,4 +26,6 @@ void sti_vid_disable(struct sti_vid *vid); | |||
| 26 | struct sti_vid *sti_vid_create(struct device *dev, struct drm_device *drm_dev, | 26 | struct sti_vid *sti_vid_create(struct device *dev, struct drm_device *drm_dev, |
| 27 | int id, void __iomem *baseaddr); | 27 | int id, void __iomem *baseaddr); |
| 28 | 28 | ||
| 29 | int vid_debugfs_init(struct sti_vid *vid, struct drm_minor *minor); | ||
| 30 | |||
| 29 | #endif | 31 | #endif |
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index 68e9d85085fb..9a67f927a53e 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c | |||
| @@ -24,34 +24,6 @@ | |||
| 24 | #include "sun4i_layer.h" | 24 | #include "sun4i_layer.h" |
| 25 | #include "sun4i_tcon.h" | 25 | #include "sun4i_tcon.h" |
| 26 | 26 | ||
| 27 | static int sun4i_drv_connector_plug_all(struct drm_device *drm) | ||
| 28 | { | ||
| 29 | struct drm_connector *connector, *failed; | ||
| 30 | int ret; | ||
| 31 | |||
| 32 | mutex_lock(&drm->mode_config.mutex); | ||
| 33 | list_for_each_entry(connector, &drm->mode_config.connector_list, head) { | ||
| 34 | ret = drm_connector_register(connector); | ||
| 35 | if (ret) { | ||
| 36 | failed = connector; | ||
| 37 | goto err; | ||
| 38 | } | ||
| 39 | } | ||
| 40 | mutex_unlock(&drm->mode_config.mutex); | ||
| 41 | return 0; | ||
| 42 | |||
| 43 | err: | ||
| 44 | list_for_each_entry(connector, &drm->mode_config.connector_list, head) { | ||
| 45 | if (failed == connector) | ||
| 46 | break; | ||
| 47 | |||
| 48 | drm_connector_unregister(connector); | ||
| 49 | } | ||
| 50 | mutex_unlock(&drm->mode_config.mutex); | ||
| 51 | |||
| 52 | return ret; | ||
| 53 | } | ||
| 54 | |||
| 55 | static int sun4i_drv_enable_vblank(struct drm_device *drm, unsigned int pipe) | 27 | static int sun4i_drv_enable_vblank(struct drm_device *drm, unsigned int pipe) |
| 56 | { | 28 | { |
| 57 | struct sun4i_drv *drv = drm->dev_private; | 29 | struct sun4i_drv *drv = drm->dev_private; |
| @@ -135,10 +107,6 @@ static int sun4i_drv_bind(struct device *dev) | |||
| 135 | if (!drm) | 107 | if (!drm) |
| 136 | return -ENOMEM; | 108 | return -ENOMEM; |
| 137 | 109 | ||
| 138 | ret = drm_dev_set_unique(drm, dev_name(drm->dev)); | ||
| 139 | if (ret) | ||
| 140 | goto free_drm; | ||
| 141 | |||
| 142 | drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL); | 110 | drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL); |
| 143 | if (!drv) { | 111 | if (!drv) { |
| 144 | ret = -ENOMEM; | 112 | ret = -ENOMEM; |
| @@ -187,14 +155,8 @@ static int sun4i_drv_bind(struct device *dev) | |||
| 187 | if (ret) | 155 | if (ret) |
| 188 | goto free_drm; | 156 | goto free_drm; |
| 189 | 157 | ||
| 190 | ret = sun4i_drv_connector_plug_all(drm); | ||
| 191 | if (ret) | ||
| 192 | goto unregister_drm; | ||
| 193 | |||
| 194 | return 0; | 158 | return 0; |
| 195 | 159 | ||
| 196 | unregister_drm: | ||
| 197 | drm_dev_unregister(drm); | ||
| 198 | free_drm: | 160 | free_drm: |
| 199 | drm_dev_unref(drm); | 161 | drm_dev_unref(drm); |
| 200 | return ret; | 162 | return ret; |
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 308e197908fc..d27809372d54 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c | |||
| @@ -541,7 +541,6 @@ static struct drm_driver tilcdc_driver = { | |||
| 541 | .load = tilcdc_load, | 541 | .load = tilcdc_load, |
| 542 | .unload = tilcdc_unload, | 542 | .unload = tilcdc_unload, |
| 543 | .lastclose = tilcdc_lastclose, | 543 | .lastclose = tilcdc_lastclose, |
| 544 | .set_busid = drm_platform_set_busid, | ||
| 545 | .irq_handler = tilcdc_irq, | 544 | .irq_handler = tilcdc_irq, |
| 546 | .irq_preinstall = tilcdc_irq_preinstall, | 545 | .irq_preinstall = tilcdc_irq_preinstall, |
| 547 | .irq_postinstall = tilcdc_irq_postinstall, | 546 | .irq_postinstall = tilcdc_irq_postinstall, |
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 58b8fc036332..9e88231b8906 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c | |||
| @@ -176,7 +176,6 @@ static int vc4_drm_bind(struct device *dev) | |||
| 176 | { | 176 | { |
| 177 | struct platform_device *pdev = to_platform_device(dev); | 177 | struct platform_device *pdev = to_platform_device(dev); |
| 178 | struct drm_device *drm; | 178 | struct drm_device *drm; |
| 179 | struct drm_connector *connector; | ||
| 180 | struct vc4_dev *vc4; | 179 | struct vc4_dev *vc4; |
| 181 | int ret = 0; | 180 | int ret = 0; |
| 182 | 181 | ||
| @@ -211,22 +210,10 @@ static int vc4_drm_bind(struct device *dev) | |||
| 211 | if (ret < 0) | 210 | if (ret < 0) |
| 212 | goto unbind_all; | 211 | goto unbind_all; |
| 213 | 212 | ||
| 214 | /* Connector registration has to occur after DRM device | ||
| 215 | * registration, because it creates sysfs entries based on the | ||
| 216 | * DRM device. | ||
| 217 | */ | ||
| 218 | list_for_each_entry(connector, &drm->mode_config.connector_list, head) { | ||
| 219 | ret = drm_connector_register(connector); | ||
| 220 | if (ret) | ||
| 221 | goto unregister; | ||
| 222 | } | ||
| 223 | |||
| 224 | vc4_kms_load(drm); | 213 | vc4_kms_load(drm); |
| 225 | 214 | ||
| 226 | return 0; | 215 | return 0; |
| 227 | 216 | ||
| 228 | unregister: | ||
| 229 | drm_dev_unregister(drm); | ||
| 230 | unbind_all: | 217 | unbind_all: |
| 231 | component_unbind_all(dev, drm); | 218 | component_unbind_all(dev, drm); |
| 232 | gem_destroy: | 219 | gem_destroy: |
diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index 1b4cc8b27080..35ea5d02a827 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c | |||
| @@ -260,8 +260,6 @@ static int __init vgem_init(void) | |||
| 260 | goto out; | 260 | goto out; |
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | drm_dev_set_unique(vgem_device, "vgem"); | ||
| 264 | |||
| 265 | ret = drm_dev_register(vgem_device, 0); | 263 | ret = drm_dev_register(vgem_device, 0); |
| 266 | 264 | ||
| 267 | if (ret) | 265 | if (ret) |
diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c index 4f20742e7788..a04ef1c992d9 100644 --- a/drivers/gpu/drm/via/via_mm.c +++ b/drivers/gpu/drm/via/via_mm.c | |||
| @@ -208,7 +208,7 @@ void via_reclaim_buffers_locked(struct drm_device *dev, | |||
| 208 | struct via_file_private *file_priv = file->driver_priv; | 208 | struct via_file_private *file_priv = file->driver_priv; |
| 209 | struct via_memblock *entry, *next; | 209 | struct via_memblock *entry, *next; |
| 210 | 210 | ||
| 211 | if (!(file->minor->master && file->master->lock.hw_lock)) | 211 | if (!(dev->master && file->master->lock.hw_lock)) |
| 212 | return; | 212 | return; |
| 213 | 213 | ||
| 214 | drm_legacy_idlelock_take(&file->master->lock); | 214 | drm_legacy_idlelock_take(&file->master->lock); |
diff --git a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c index 88a39165edd5..7f0e93f87a55 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c +++ b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c | |||
| @@ -27,16 +27,6 @@ | |||
| 27 | 27 | ||
| 28 | #include "virtgpu_drv.h" | 28 | #include "virtgpu_drv.h" |
| 29 | 29 | ||
| 30 | int drm_virtio_set_busid(struct drm_device *dev, struct drm_master *master) | ||
| 31 | { | ||
| 32 | struct pci_dev *pdev = dev->pdev; | ||
| 33 | |||
| 34 | if (pdev) { | ||
| 35 | return drm_pci_set_busid(dev, master); | ||
| 36 | } | ||
| 37 | return 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | static void virtio_pci_kick_out_firmware_fb(struct pci_dev *pci_dev) | 30 | static void virtio_pci_kick_out_firmware_fb(struct pci_dev *pci_dev) |
| 41 | { | 31 | { |
| 42 | struct apertures_struct *ap; | 32 | struct apertures_struct *ap; |
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 5820b7020ae5..c13f70cfc461 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c | |||
| @@ -117,7 +117,6 @@ static const struct file_operations virtio_gpu_driver_fops = { | |||
| 117 | 117 | ||
| 118 | static struct drm_driver driver = { | 118 | static struct drm_driver driver = { |
| 119 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC, | 119 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC, |
| 120 | .set_busid = drm_virtio_set_busid, | ||
| 121 | .load = virtio_gpu_driver_load, | 120 | .load = virtio_gpu_driver_load, |
| 122 | .unload = virtio_gpu_driver_unload, | 121 | .unload = virtio_gpu_driver_unload, |
| 123 | .open = virtio_gpu_driver_open, | 122 | .open = virtio_gpu_driver_open, |
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index acf556a35cb2..b18ef3111f0c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h | |||
| @@ -49,7 +49,6 @@ | |||
| 49 | #define DRIVER_PATCHLEVEL 1 | 49 | #define DRIVER_PATCHLEVEL 1 |
| 50 | 50 | ||
| 51 | /* virtgpu_drm_bus.c */ | 51 | /* virtgpu_drm_bus.c */ |
| 52 | int drm_virtio_set_busid(struct drm_device *dev, struct drm_master *master); | ||
| 53 | int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev); | 52 | int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev); |
| 54 | 53 | ||
| 55 | struct virtio_gpu_object { | 54 | struct virtio_gpu_object { |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 9fcd8200d485..60646644bef3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
| @@ -1049,7 +1049,7 @@ static struct vmw_master *vmw_master_check(struct drm_device *dev, | |||
| 1049 | if (unlikely(ret != 0)) | 1049 | if (unlikely(ret != 0)) |
| 1050 | return ERR_PTR(-ERESTARTSYS); | 1050 | return ERR_PTR(-ERESTARTSYS); |
| 1051 | 1051 | ||
| 1052 | if (file_priv->is_master) { | 1052 | if (drm_is_current_master(file_priv)) { |
| 1053 | mutex_unlock(&dev->master_mutex); | 1053 | mutex_unlock(&dev->master_mutex); |
| 1054 | return NULL; | 1054 | return NULL; |
| 1055 | } | 1055 | } |
| @@ -1228,8 +1228,7 @@ static int vmw_master_set(struct drm_device *dev, | |||
| 1228 | } | 1228 | } |
| 1229 | 1229 | ||
| 1230 | static void vmw_master_drop(struct drm_device *dev, | 1230 | static void vmw_master_drop(struct drm_device *dev, |
| 1231 | struct drm_file *file_priv, | 1231 | struct drm_file *file_priv) |
| 1232 | bool from_release) | ||
| 1233 | { | 1232 | { |
| 1234 | struct vmw_private *dev_priv = vmw_priv(dev); | 1233 | struct vmw_private *dev_priv = vmw_priv(dev); |
| 1235 | struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); | 1234 | struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 1980e2a28265..9a90f824814e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <drm/drmP.h> | 32 | #include <drm/drmP.h> |
| 33 | #include <drm/vmwgfx_drm.h> | 33 | #include <drm/vmwgfx_drm.h> |
| 34 | #include <drm/drm_hashtab.h> | 34 | #include <drm/drm_hashtab.h> |
| 35 | #include <drm/drm_auth.h> | ||
| 35 | #include <linux/suspend.h> | 36 | #include <linux/suspend.h> |
| 36 | #include <drm/ttm/ttm_bo_driver.h> | 37 | #include <drm/ttm/ttm_bo_driver.h> |
| 37 | #include <drm/ttm/ttm_object.h> | 38 | #include <drm/ttm/ttm_object.h> |
