diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/core/client.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/include/core/client.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvif/notify.c | 25 |
3 files changed, 20 insertions, 11 deletions
diff --git a/drivers/gpu/drm/nouveau/core/core/client.c b/drivers/gpu/drm/nouveau/core/core/client.c index 10598dede9e9..68bf06768123 100644 --- a/drivers/gpu/drm/nouveau/core/core/client.c +++ b/drivers/gpu/drm/nouveau/core/core/client.c | |||
| @@ -132,12 +132,12 @@ nvkm_client_notify_new(struct nouveau_client *client, | |||
| 132 | if (ret == 0) { | 132 | if (ret == 0) { |
| 133 | client->notify[index] = notify; | 133 | client->notify[index] = notify; |
| 134 | notify->client = client; | 134 | notify->client = client; |
| 135 | return 0; | 135 | return index; |
| 136 | } | 136 | } |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | kfree(notify); | 139 | kfree(notify); |
| 140 | return 0; | 140 | return ret; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | static int | 143 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/client.h b/drivers/gpu/drm/nouveau/core/include/core/client.h index 4fc6ab12382d..1794a05205d8 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/client.h +++ b/drivers/gpu/drm/nouveau/core/include/core/client.h | |||
| @@ -14,7 +14,7 @@ struct nouveau_client { | |||
| 14 | void *data; | 14 | void *data; |
| 15 | 15 | ||
| 16 | int (*ntfy)(const void *, u32, const void *, u32); | 16 | int (*ntfy)(const void *, u32, const void *, u32); |
| 17 | struct nvkm_client_notify *notify[8]; | 17 | struct nvkm_client_notify *notify[16]; |
| 18 | }; | 18 | }; |
| 19 | 19 | ||
| 20 | static inline struct nouveau_client * | 20 | static inline struct nouveau_client * |
diff --git a/drivers/gpu/drm/nouveau/nvif/notify.c b/drivers/gpu/drm/nouveau/nvif/notify.c index 7c06123a559c..7e03cdd17827 100644 --- a/drivers/gpu/drm/nouveau/nvif/notify.c +++ b/drivers/gpu/drm/nouveau/nvif/notify.c | |||
| @@ -87,12 +87,25 @@ nvif_notify_get(struct nvif_notify *notify) | |||
| 87 | return 0; | 87 | return 0; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | static inline int | ||
| 91 | nvif_notify_func(struct nvif_notify *notify, bool keep) | ||
| 92 | { | ||
| 93 | int ret = notify->func(notify); | ||
| 94 | if (ret == NVIF_NOTIFY_KEEP || | ||
| 95 | !test_and_clear_bit(NVKM_NOTIFY_USER, ¬ify->flags)) { | ||
| 96 | if (!keep) | ||
| 97 | atomic_dec(¬ify->putcnt); | ||
| 98 | else | ||
| 99 | nvif_notify_get_(notify); | ||
| 100 | } | ||
| 101 | return ret; | ||
| 102 | } | ||
| 103 | |||
| 90 | static void | 104 | static void |
| 91 | nvif_notify_work(struct work_struct *work) | 105 | nvif_notify_work(struct work_struct *work) |
| 92 | { | 106 | { |
| 93 | struct nvif_notify *notify = container_of(work, typeof(*notify), work); | 107 | struct nvif_notify *notify = container_of(work, typeof(*notify), work); |
| 94 | if (notify->func(notify) == NVIF_NOTIFY_KEEP) | 108 | nvif_notify_func(notify, true); |
| 95 | nvif_notify_get_(notify); | ||
| 96 | } | 109 | } |
| 97 | 110 | ||
| 98 | int | 111 | int |
| @@ -113,19 +126,15 @@ nvif_notify(const void *header, u32 length, const void *data, u32 size) | |||
| 113 | if (!WARN_ON(notify == NULL)) { | 126 | if (!WARN_ON(notify == NULL)) { |
| 114 | struct nvif_client *client = nvif_client(notify->object); | 127 | struct nvif_client *client = nvif_client(notify->object); |
| 115 | if (!WARN_ON(notify->size != size)) { | 128 | if (!WARN_ON(notify->size != size)) { |
| 129 | atomic_inc(¬ify->putcnt); | ||
| 116 | if (test_bit(NVIF_NOTIFY_WORK, ¬ify->flags)) { | 130 | if (test_bit(NVIF_NOTIFY_WORK, ¬ify->flags)) { |
| 117 | atomic_inc(¬ify->putcnt); | ||
| 118 | memcpy((void *)notify->data, data, size); | 131 | memcpy((void *)notify->data, data, size); |
| 119 | schedule_work(¬ify->work); | 132 | schedule_work(¬ify->work); |
| 120 | return NVIF_NOTIFY_DROP; | 133 | return NVIF_NOTIFY_DROP; |
| 121 | } | 134 | } |
| 122 | notify->data = data; | 135 | notify->data = data; |
| 123 | ret = notify->func(notify); | 136 | ret = nvif_notify_func(notify, client->driver->keep); |
| 124 | notify->data = NULL; | 137 | notify->data = NULL; |
| 125 | if (ret != NVIF_NOTIFY_DROP && client->driver->keep) { | ||
| 126 | atomic_inc(¬ify->putcnt); | ||
| 127 | nvif_notify_get_(notify); | ||
| 128 | } | ||
| 129 | } | 138 | } |
| 130 | } | 139 | } |
| 131 | 140 | ||
