diff options
| author | Ingo Molnar <mingo@kernel.org> | 2018-10-23 06:30:19 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2018-10-23 06:30:19 -0400 |
| commit | dda93b45389f025fd3422d22cc31cc1ea6040305 (patch) | |
| tree | 44a856744843e24ed1baf6ca4edb1be04809a606 /drivers/media/v4l2-core/v4l2-event.c | |
| parent | 2e62024c265aa69315ed02835623740030435380 (diff) | |
| parent | b61b8bba18fe2b63d38fdaf9b83de25e2d787dfe (diff) | |
Merge branch 'x86/cache' into perf/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-event.c')
| -rw-r--r-- | drivers/media/v4l2-core/v4l2-event.c | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/drivers/media/v4l2-core/v4l2-event.c b/drivers/media/v4l2-core/v4l2-event.c index 127fe6eb91d9..a3ef1f50a4b3 100644 --- a/drivers/media/v4l2-core/v4l2-event.c +++ b/drivers/media/v4l2-core/v4l2-event.c | |||
| @@ -115,14 +115,6 @@ static void __v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *e | |||
| 115 | if (sev == NULL) | 115 | if (sev == NULL) |
| 116 | return; | 116 | return; |
| 117 | 117 | ||
| 118 | /* | ||
| 119 | * If the event has been added to the fh->subscribed list, but its | ||
| 120 | * add op has not completed yet elems will be 0, treat this as | ||
| 121 | * not being subscribed. | ||
| 122 | */ | ||
| 123 | if (!sev->elems) | ||
| 124 | return; | ||
| 125 | |||
| 126 | /* Increase event sequence number on fh. */ | 118 | /* Increase event sequence number on fh. */ |
| 127 | fh->sequence++; | 119 | fh->sequence++; |
| 128 | 120 | ||
| @@ -208,6 +200,7 @@ int v4l2_event_subscribe(struct v4l2_fh *fh, | |||
| 208 | struct v4l2_subscribed_event *sev, *found_ev; | 200 | struct v4l2_subscribed_event *sev, *found_ev; |
| 209 | unsigned long flags; | 201 | unsigned long flags; |
| 210 | unsigned i; | 202 | unsigned i; |
| 203 | int ret = 0; | ||
| 211 | 204 | ||
| 212 | if (sub->type == V4L2_EVENT_ALL) | 205 | if (sub->type == V4L2_EVENT_ALL) |
| 213 | return -EINVAL; | 206 | return -EINVAL; |
| @@ -225,31 +218,36 @@ int v4l2_event_subscribe(struct v4l2_fh *fh, | |||
| 225 | sev->flags = sub->flags; | 218 | sev->flags = sub->flags; |
| 226 | sev->fh = fh; | 219 | sev->fh = fh; |
| 227 | sev->ops = ops; | 220 | sev->ops = ops; |
| 221 | sev->elems = elems; | ||
| 222 | |||
| 223 | mutex_lock(&fh->subscribe_lock); | ||
| 228 | 224 | ||
| 229 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); | 225 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); |
| 230 | found_ev = v4l2_event_subscribed(fh, sub->type, sub->id); | 226 | found_ev = v4l2_event_subscribed(fh, sub->type, sub->id); |
| 231 | if (!found_ev) | ||
| 232 | list_add(&sev->list, &fh->subscribed); | ||
| 233 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); | 227 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); |
| 234 | 228 | ||
| 235 | if (found_ev) { | 229 | if (found_ev) { |
| 230 | /* Already listening */ | ||
| 236 | kvfree(sev); | 231 | kvfree(sev); |
| 237 | return 0; /* Already listening */ | 232 | goto out_unlock; |
| 238 | } | 233 | } |
| 239 | 234 | ||
| 240 | if (sev->ops && sev->ops->add) { | 235 | if (sev->ops && sev->ops->add) { |
| 241 | int ret = sev->ops->add(sev, elems); | 236 | ret = sev->ops->add(sev, elems); |
| 242 | if (ret) { | 237 | if (ret) { |
| 243 | sev->ops = NULL; | 238 | kvfree(sev); |
| 244 | v4l2_event_unsubscribe(fh, sub); | 239 | goto out_unlock; |
| 245 | return ret; | ||
| 246 | } | 240 | } |
| 247 | } | 241 | } |
| 248 | 242 | ||
| 249 | /* Mark as ready for use */ | 243 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); |
| 250 | sev->elems = elems; | 244 | list_add(&sev->list, &fh->subscribed); |
| 245 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); | ||
| 251 | 246 | ||
| 252 | return 0; | 247 | out_unlock: |
| 248 | mutex_unlock(&fh->subscribe_lock); | ||
| 249 | |||
| 250 | return ret; | ||
| 253 | } | 251 | } |
| 254 | EXPORT_SYMBOL_GPL(v4l2_event_subscribe); | 252 | EXPORT_SYMBOL_GPL(v4l2_event_subscribe); |
| 255 | 253 | ||
| @@ -288,6 +286,8 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh, | |||
| 288 | return 0; | 286 | return 0; |
| 289 | } | 287 | } |
| 290 | 288 | ||
| 289 | mutex_lock(&fh->subscribe_lock); | ||
| 290 | |||
| 291 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); | 291 | spin_lock_irqsave(&fh->vdev->fh_lock, flags); |
| 292 | 292 | ||
| 293 | sev = v4l2_event_subscribed(fh, sub->type, sub->id); | 293 | sev = v4l2_event_subscribed(fh, sub->type, sub->id); |
| @@ -305,6 +305,8 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh, | |||
| 305 | if (sev && sev->ops && sev->ops->del) | 305 | if (sev && sev->ops && sev->ops->del) |
| 306 | sev->ops->del(sev); | 306 | sev->ops->del(sev); |
| 307 | 307 | ||
| 308 | mutex_unlock(&fh->subscribe_lock); | ||
| 309 | |||
| 308 | kvfree(sev); | 310 | kvfree(sev); |
| 309 | 311 | ||
| 310 | return 0; | 312 | return 0; |
