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