Merge tag 'for-5.14-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[linux-2.6-microblaze.git] / drivers / misc / habanalabs / common / asid.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 /*
4  * Copyright 2016-2019 HabanaLabs, Ltd.
5  * All Rights Reserved.
6  */
7
8 #include "habanalabs.h"
9
10 #include <linux/slab.h>
11
12 int hl_asid_init(struct hl_device *hdev)
13 {
14         hdev->asid_bitmap = kcalloc(BITS_TO_LONGS(hdev->asic_prop.max_asid),
15                                         sizeof(*hdev->asid_bitmap), GFP_KERNEL);
16         if (!hdev->asid_bitmap)
17                 return -ENOMEM;
18
19         mutex_init(&hdev->asid_mutex);
20
21         /* ASID 0 is reserved for the kernel driver and device CPU */
22         set_bit(0, hdev->asid_bitmap);
23
24         return 0;
25 }
26
27 void hl_asid_fini(struct hl_device *hdev)
28 {
29         mutex_destroy(&hdev->asid_mutex);
30         kfree(hdev->asid_bitmap);
31 }
32
33 unsigned long hl_asid_alloc(struct hl_device *hdev)
34 {
35         unsigned long found;
36
37         mutex_lock(&hdev->asid_mutex);
38
39         found = find_first_zero_bit(hdev->asid_bitmap,
40                                         hdev->asic_prop.max_asid);
41         if (found == hdev->asic_prop.max_asid)
42                 found = 0;
43         else
44                 set_bit(found, hdev->asid_bitmap);
45
46         mutex_unlock(&hdev->asid_mutex);
47
48         return found;
49 }
50
51 void hl_asid_free(struct hl_device *hdev, unsigned long asid)
52 {
53         if (asid == HL_KERNEL_ASID_ID || asid >= hdev->asic_prop.max_asid) {
54                 dev_crit(hdev->dev, "Invalid ASID %lu", asid);
55                 return;
56         }
57
58         clear_bit(asid, hdev->asid_bitmap);
59 }