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
12int 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
27void hl_asid_fini(struct hl_device *hdev)
28{
29	mutex_destroy(&hdev->asid_mutex);
30	kfree(hdev->asid_bitmap);
31}
32
33unsigned 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
51void hl_asid_free(struct hl_device *hdev, unsigned long asid)
52{
53	if (WARN((asid == 0 || asid >= hdev->asic_prop.max_asid),
54						"Invalid ASID %lu", asid))
55		return;
56	clear_bit(asid, hdev->asid_bitmap);
57}
58