diff options
Diffstat (limited to 'drivers/misc/cxl/main.c')
-rw-r--r-- | drivers/misc/cxl/main.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c index d9be23b24aa3..62e0dfb5f15b 100644 --- a/drivers/misc/cxl/main.c +++ b/drivers/misc/cxl/main.c | |||
@@ -243,8 +243,10 @@ struct cxl *cxl_alloc_adapter(void) | |||
243 | if (dev_set_name(&adapter->dev, "card%i", adapter->adapter_num)) | 243 | if (dev_set_name(&adapter->dev, "card%i", adapter->adapter_num)) |
244 | goto err2; | 244 | goto err2; |
245 | 245 | ||
246 | return adapter; | 246 | /* start with context lock taken */ |
247 | atomic_set(&adapter->contexts_num, -1); | ||
247 | 248 | ||
249 | return adapter; | ||
248 | err2: | 250 | err2: |
249 | cxl_remove_adapter_nr(adapter); | 251 | cxl_remove_adapter_nr(adapter); |
250 | err1: | 252 | err1: |
@@ -286,6 +288,44 @@ int cxl_afu_select_best_mode(struct cxl_afu *afu) | |||
286 | return 0; | 288 | return 0; |
287 | } | 289 | } |
288 | 290 | ||
291 | int cxl_adapter_context_get(struct cxl *adapter) | ||
292 | { | ||
293 | int rc; | ||
294 | |||
295 | rc = atomic_inc_unless_negative(&adapter->contexts_num); | ||
296 | return rc >= 0 ? 0 : -EBUSY; | ||
297 | } | ||
298 | |||
299 | void cxl_adapter_context_put(struct cxl *adapter) | ||
300 | { | ||
301 | atomic_dec_if_positive(&adapter->contexts_num); | ||
302 | } | ||
303 | |||
304 | int cxl_adapter_context_lock(struct cxl *adapter) | ||
305 | { | ||
306 | int rc; | ||
307 | /* no active contexts -> contexts_num == 0 */ | ||
308 | rc = atomic_cmpxchg(&adapter->contexts_num, 0, -1); | ||
309 | return rc ? -EBUSY : 0; | ||
310 | } | ||
311 | |||
312 | void cxl_adapter_context_unlock(struct cxl *adapter) | ||
313 | { | ||
314 | int val = atomic_cmpxchg(&adapter->contexts_num, -1, 0); | ||
315 | |||
316 | /* | ||
317 | * contexts lock taken -> contexts_num == -1 | ||
318 | * If not true then show a warning and force reset the lock. | ||
319 | * This will happen when context_unlock was requested without | ||
320 | * doing a context_lock. | ||
321 | */ | ||
322 | if (val != -1) { | ||
323 | atomic_set(&adapter->contexts_num, 0); | ||
324 | WARN(1, "Adapter context unlocked with %d active contexts", | ||
325 | val); | ||
326 | } | ||
327 | } | ||
328 | |||
289 | static int __init init_cxl(void) | 329 | static int __init init_cxl(void) |
290 | { | 330 | { |
291 | int rc = 0; | 331 | int rc = 0; |