diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/drm/drmP.h | 5 | ||||
| -rw-r--r-- | include/drm/drm_crtc.h | 15 | ||||
| -rw-r--r-- | include/drm/drm_modeset_lock.h | 126 |
3 files changed, 135 insertions, 11 deletions
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 76ccaabd0418..475ca5cf3c20 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
| @@ -1186,11 +1186,6 @@ static inline int drm_device_is_unplugged(struct drm_device *dev) | |||
| 1186 | return ret; | 1186 | return ret; |
| 1187 | } | 1187 | } |
| 1188 | 1188 | ||
| 1189 | static inline bool drm_modeset_is_locked(struct drm_device *dev) | ||
| 1190 | { | ||
| 1191 | return mutex_is_locked(&dev->mode_config.mutex); | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | static inline bool drm_is_render_client(const struct drm_file *file_priv) | 1189 | static inline bool drm_is_render_client(const struct drm_file *file_priv) |
| 1195 | { | 1190 | { |
| 1196 | return file_priv->minor->type == DRM_MINOR_RENDER; | 1191 | return file_priv->minor->type == DRM_MINOR_RENDER; |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 6c295df7b0df..a7fac5686915 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/hdmi.h> | 33 | #include <linux/hdmi.h> |
| 34 | #include <drm/drm_mode.h> | 34 | #include <drm/drm_mode.h> |
| 35 | #include <drm/drm_fourcc.h> | 35 | #include <drm/drm_fourcc.h> |
| 36 | #include <drm/drm_modeset_lock.h> | ||
| 36 | 37 | ||
| 37 | struct drm_device; | 38 | struct drm_device; |
| 38 | struct drm_mode_set; | 39 | struct drm_mode_set; |
| @@ -205,6 +206,10 @@ struct drm_property { | |||
| 205 | struct list_head enum_blob_list; | 206 | struct list_head enum_blob_list; |
| 206 | }; | 207 | }; |
| 207 | 208 | ||
| 209 | void drm_modeset_lock_all(struct drm_device *dev); | ||
| 210 | void drm_modeset_unlock_all(struct drm_device *dev); | ||
| 211 | void drm_warn_on_modeset_not_all_locked(struct drm_device *dev); | ||
| 212 | |||
| 208 | struct drm_crtc; | 213 | struct drm_crtc; |
| 209 | struct drm_connector; | 214 | struct drm_connector; |
| 210 | struct drm_encoder; | 215 | struct drm_encoder; |
| @@ -280,6 +285,7 @@ struct drm_crtc_funcs { | |||
| 280 | * drm_crtc - central CRTC control structure | 285 | * drm_crtc - central CRTC control structure |
| 281 | * @dev: parent DRM device | 286 | * @dev: parent DRM device |
| 282 | * @head: list management | 287 | * @head: list management |
| 288 | * @mutex: per-CRTC locking | ||
| 283 | * @base: base KMS object for ID tracking etc. | 289 | * @base: base KMS object for ID tracking etc. |
| 284 | * @primary: primary plane for this CRTC | 290 | * @primary: primary plane for this CRTC |
| 285 | * @cursor: cursor plane for this CRTC | 291 | * @cursor: cursor plane for this CRTC |
| @@ -314,7 +320,7 @@ struct drm_crtc { | |||
| 314 | * state, ...) and a write lock for everything which can be update | 320 | * state, ...) and a write lock for everything which can be update |
| 315 | * without a full modeset (fb, cursor data, ...) | 321 | * without a full modeset (fb, cursor data, ...) |
| 316 | */ | 322 | */ |
| 317 | struct mutex mutex; | 323 | struct drm_modeset_lock mutex; |
| 318 | 324 | ||
| 319 | struct drm_mode_object base; | 325 | struct drm_mode_object base; |
| 320 | 326 | ||
| @@ -738,7 +744,8 @@ struct drm_mode_group { | |||
| 738 | */ | 744 | */ |
| 739 | struct drm_mode_config { | 745 | struct drm_mode_config { |
| 740 | struct mutex mutex; /* protects configuration (mode lists etc.) */ | 746 | struct mutex mutex; /* protects configuration (mode lists etc.) */ |
| 741 | struct mutex connection_mutex; /* protects connector->encoder and encoder->crtc links */ | 747 | struct drm_modeset_lock connection_mutex; /* protects connector->encoder and encoder->crtc links */ |
| 748 | struct drm_modeset_acquire_ctx *acquire_ctx; /* for legacy _lock_all() / _unlock_all() */ | ||
| 742 | struct mutex idr_mutex; /* for IDR management */ | 749 | struct mutex idr_mutex; /* for IDR management */ |
| 743 | struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ | 750 | struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ |
| 744 | /* this is limited to one for now */ | 751 | /* this is limited to one for now */ |
| @@ -839,10 +846,6 @@ struct drm_prop_enum_list { | |||
| 839 | char *name; | 846 | char *name; |
| 840 | }; | 847 | }; |
| 841 | 848 | ||
| 842 | extern void drm_modeset_lock_all(struct drm_device *dev); | ||
| 843 | extern void drm_modeset_unlock_all(struct drm_device *dev); | ||
| 844 | extern void drm_warn_on_modeset_not_all_locked(struct drm_device *dev); | ||
| 845 | |||
| 846 | extern int drm_crtc_init_with_planes(struct drm_device *dev, | 849 | extern int drm_crtc_init_with_planes(struct drm_device *dev, |
| 847 | struct drm_crtc *crtc, | 850 | struct drm_crtc *crtc, |
| 848 | struct drm_plane *primary, | 851 | struct drm_plane *primary, |
diff --git a/include/drm/drm_modeset_lock.h b/include/drm/drm_modeset_lock.h new file mode 100644 index 000000000000..402aa7a6a058 --- /dev/null +++ b/include/drm/drm_modeset_lock.h | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2014 Red Hat | ||
| 3 | * Author: Rob Clark <robdclark@gmail.com> | ||
| 4 | * | ||
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 6 | * copy of this software and associated documentation files (the "Software"), | ||
| 7 | * to deal in the Software without restriction, including without limitation | ||
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 10 | * Software is furnished to do so, subject to the following conditions: | ||
| 11 | * | ||
| 12 | * The above copyright notice and this permission notice shall be included in | ||
| 13 | * all copies or substantial portions of the Software. | ||
| 14 | * | ||
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 18 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 21 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #ifndef DRM_MODESET_LOCK_H_ | ||
| 25 | #define DRM_MODESET_LOCK_H_ | ||
| 26 | |||
| 27 | #include <linux/ww_mutex.h> | ||
| 28 | |||
| 29 | struct drm_modeset_lock; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * drm_modeset_acquire_ctx - locking context (see ww_acquire_ctx) | ||
| 33 | * @ww_ctx: base acquire ctx | ||
| 34 | * @contended: used internally for -EDEADLK handling | ||
| 35 | * @locked: list of held locks | ||
| 36 | * | ||
| 37 | * Each thread competing for a set of locks must use one acquire | ||
| 38 | * ctx. And if any lock fxn returns -EDEADLK, it must backoff and | ||
| 39 | * retry. | ||
| 40 | */ | ||
| 41 | struct drm_modeset_acquire_ctx { | ||
| 42 | |||
| 43 | struct ww_acquire_ctx ww_ctx; | ||
| 44 | |||
| 45 | /** | ||
| 46 | * Contended lock: if a lock is contended you should only call | ||
| 47 | * drm_modeset_backoff() which drops locks and slow-locks the | ||
| 48 | * contended lock. | ||
| 49 | */ | ||
| 50 | struct drm_modeset_lock *contended; | ||
| 51 | |||
| 52 | /** | ||
| 53 | * list of held locks (drm_modeset_lock) | ||
| 54 | */ | ||
| 55 | struct list_head locked; | ||
| 56 | }; | ||
| 57 | |||
| 58 | /** | ||
| 59 | * drm_modeset_lock - used for locking modeset resources. | ||
| 60 | * @mutex: resource locking | ||
| 61 | * @head: used to hold it's place on state->locked list when | ||
| 62 | * part of an atomic update | ||
| 63 | * | ||
| 64 | * Used for locking CRTCs and other modeset resources. | ||
| 65 | */ | ||
| 66 | struct drm_modeset_lock { | ||
| 67 | /** | ||
| 68 | * modeset lock | ||
| 69 | */ | ||
| 70 | struct ww_mutex mutex; | ||
| 71 | |||
| 72 | /** | ||
| 73 | * Resources that are locked as part of an atomic update are added | ||
| 74 | * to a list (so we know what to unlock at the end). | ||
| 75 | */ | ||
| 76 | struct list_head head; | ||
| 77 | }; | ||
| 78 | |||
| 79 | extern struct ww_class crtc_ww_class; | ||
| 80 | |||
| 81 | void drm_modeset_acquire_init(struct drm_modeset_acquire_ctx *ctx, | ||
| 82 | uint32_t flags); | ||
| 83 | void drm_modeset_acquire_fini(struct drm_modeset_acquire_ctx *ctx); | ||
| 84 | void drm_modeset_drop_locks(struct drm_modeset_acquire_ctx *ctx); | ||
| 85 | void drm_modeset_backoff(struct drm_modeset_acquire_ctx *ctx); | ||
| 86 | int drm_modeset_backoff_interruptible(struct drm_modeset_acquire_ctx *ctx); | ||
| 87 | |||
| 88 | /** | ||
| 89 | * drm_modeset_lock_init - initialize lock | ||
| 90 | * @lock: lock to init | ||
| 91 | */ | ||
| 92 | static inline void drm_modeset_lock_init(struct drm_modeset_lock *lock) | ||
| 93 | { | ||
| 94 | ww_mutex_init(&lock->mutex, &crtc_ww_class); | ||
| 95 | INIT_LIST_HEAD(&lock->head); | ||
| 96 | } | ||
| 97 | |||
| 98 | /** | ||
| 99 | * drm_modeset_lock_fini - cleanup lock | ||
| 100 | * @lock: lock to cleanup | ||
| 101 | */ | ||
| 102 | static inline void drm_modeset_lock_fini(struct drm_modeset_lock *lock) | ||
| 103 | { | ||
| 104 | WARN_ON(!list_empty(&lock->head)); | ||
| 105 | } | ||
| 106 | |||
| 107 | /** | ||
| 108 | * drm_modeset_is_locked - equivalent to mutex_is_locked() | ||
| 109 | * @lock: lock to check | ||
| 110 | */ | ||
| 111 | static inline bool drm_modeset_is_locked(struct drm_modeset_lock *lock) | ||
| 112 | { | ||
| 113 | return ww_mutex_is_locked(&lock->mutex); | ||
| 114 | } | ||
| 115 | |||
| 116 | int drm_modeset_lock(struct drm_modeset_lock *lock, | ||
| 117 | struct drm_modeset_acquire_ctx *ctx); | ||
| 118 | int drm_modeset_lock_interruptible(struct drm_modeset_lock *lock, | ||
| 119 | struct drm_modeset_acquire_ctx *ctx); | ||
| 120 | void drm_modeset_unlock(struct drm_modeset_lock *lock); | ||
| 121 | |||
| 122 | struct drm_device; | ||
| 123 | int drm_modeset_lock_all_crtcs(struct drm_device *dev, | ||
| 124 | struct drm_modeset_acquire_ctx *ctx); | ||
| 125 | |||
| 126 | #endif /* DRM_MODESET_LOCK_H_ */ | ||
