xref: /rk3399_ARM-atf/drivers/ti/pd/ti_device_prepare.c (revision a28114d66a6d43db4accef5fd5d6dab6c059e584)
1 /*
2  * Copyright (c) 2025-2026 Texas Instruments Incorporated - https://www.ti.com
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /*
8  * Device Preparation and Validation
9  *
10  * This module prepares and validates devices for operations by performing
11  * initialization checks and handling exclusive access constraints before device operations.
12  */
13 
14 #include <assert.h>
15 #include <errno.h>
16 #include <common/debug.h>
17 
18 #include <ti_device.h>
19 #include <ti_device_prepare.h>
20 #include <ti_host_idx_mapping.h>
21 
22 /**
23  * device_prepare() - Look up a device and host, and validate access.
24  * @host_id: Host ID making the request.
25  * @id: Device ID to look up.
26  * @host_idx: If non-NULL, filled with the resolved host index on success.
27  * @dev: If non-NULL, filled with the device pointer on success.
28  * @exclusive: If true, enforce exclusive ownership — fails if the device is
29  *             marked exclusive and the caller is not the owner.
30  *
31  * Return: 0 on success, negative error code otherwise.
32  */
device_prepare(uint8_t host_id,uint32_t id,uint8_t * host_idx,struct ti_device ** dev,bool exclusive)33 static int32_t device_prepare(uint8_t host_id, uint32_t id, uint8_t *host_idx,
34 			      struct ti_device **dev, bool exclusive)
35 {
36 	struct ti_device *local_device;
37 	uint8_t local_host_idx;
38 
39 	assert(dev != NULL || host_idx != NULL);
40 
41 	local_device = ti_device_api_lookup(id);
42 	if (local_device == NULL) {
43 		VERBOSE("BAD_DEVICE: dev_id=%d\n", id);
44 		return -EINVAL;
45 	}
46 
47 	if (local_device->initialized == 0U) {
48 		return -EINVAL;
49 	}
50 
51 	local_host_idx = ti_host_idx_lookup(host_id);
52 	if (local_host_idx == TI_HOST_IDX_NONE) {
53 		return -EINVAL;
54 	}
55 
56 	if (exclusive && (local_device->exclusive != 0U) &&
57 	    (local_device->exclusive != local_host_idx)) {
58 		VERBOSE("EXCLUSIVE_DEVICE: dev_id=%d holder=%d requester=%d\n",
59 			id, local_device->exclusive, host_id);
60 		return -EINVAL;
61 	}
62 
63 	if (dev != NULL) {
64 		*dev = local_device;
65 	}
66 	if (host_idx != NULL) {
67 		*host_idx = local_host_idx;
68 	}
69 
70 	return 0;
71 }
72 
ti_device_prepare_exclusive(uint8_t host_id,uint32_t id,uint8_t * host_idx,struct ti_device ** device_ptr)73 int32_t ti_device_prepare_exclusive(uint8_t host_id, uint32_t id, uint8_t *host_idx,
74 				    struct ti_device **device_ptr)
75 {
76 	int32_t ret;
77 
78 	/* Ensure devices are fully initialized to allow modification */
79 	ret = ti_devices_init_rw();
80 	if (ret != 0) {
81 		return ret;
82 	}
83 
84 	return device_prepare(host_id, id, host_idx, device_ptr, true);
85 }
86 
ti_device_prepare_nonexclusive(uint8_t host_id,uint32_t id,uint8_t * host_idx,struct ti_device ** device_ptr)87 int32_t ti_device_prepare_nonexclusive(uint8_t host_id, uint32_t id, uint8_t *host_idx,
88 				       struct ti_device **device_ptr)
89 {
90 	return device_prepare(host_id, id, host_idx, device_ptr, false);
91 }
92