|  | // SPDX-License-Identifier: GPL-2.0 | 
|  |  | 
|  | /* | 
|  | * Copyright 2016-2019 HabanaLabs, Ltd. | 
|  | * All Rights Reserved. | 
|  | */ | 
|  |  | 
|  | #include "habanalabs.h" | 
|  |  | 
|  | #include <linux/slab.h> | 
|  |  | 
|  | int hl_asid_init(struct hl_device *hdev) | 
|  | { | 
|  | hdev->asid_bitmap = kcalloc(BITS_TO_LONGS(hdev->asic_prop.max_asid), | 
|  | sizeof(*hdev->asid_bitmap), GFP_KERNEL); | 
|  | if (!hdev->asid_bitmap) | 
|  | return -ENOMEM; | 
|  |  | 
|  | mutex_init(&hdev->asid_mutex); | 
|  |  | 
|  | /* ASID 0 is reserved for KMD */ | 
|  | set_bit(0, hdev->asid_bitmap); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | void hl_asid_fini(struct hl_device *hdev) | 
|  | { | 
|  | mutex_destroy(&hdev->asid_mutex); | 
|  | kfree(hdev->asid_bitmap); | 
|  | } | 
|  |  | 
|  | unsigned long hl_asid_alloc(struct hl_device *hdev) | 
|  | { | 
|  | unsigned long found; | 
|  |  | 
|  | mutex_lock(&hdev->asid_mutex); | 
|  |  | 
|  | found = find_first_zero_bit(hdev->asid_bitmap, | 
|  | hdev->asic_prop.max_asid); | 
|  | if (found == hdev->asic_prop.max_asid) | 
|  | found = 0; | 
|  | else | 
|  | set_bit(found, hdev->asid_bitmap); | 
|  |  | 
|  | mutex_unlock(&hdev->asid_mutex); | 
|  |  | 
|  | return found; | 
|  | } | 
|  |  | 
|  | void hl_asid_free(struct hl_device *hdev, unsigned long asid) | 
|  | { | 
|  | if (WARN((asid == 0 || asid >= hdev->asic_prop.max_asid), | 
|  | "Invalid ASID %lu", asid)) | 
|  | return; | 
|  | clear_bit(asid, hdev->asid_bitmap); | 
|  | } |