1 /*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "hardware/sync.h"
8 #include "hardware/claim.h"
9
10 static_assert(PICO_SPINLOCK_ID_STRIPED_LAST >= PICO_SPINLOCK_ID_STRIPED_FIRST, "");
11 static uint8_t striped_spin_lock_num = PICO_SPINLOCK_ID_STRIPED_FIRST;
12 static uint32_t claimed;
13
check_lock_num(uint __unused lock_num)14 static void check_lock_num(uint __unused lock_num) {
15 invalid_params_if(HARDWARE_SYNC, lock_num >= 32);
16 }
17
next_striped_spin_lock_num(void)18 uint next_striped_spin_lock_num(void) {
19 uint rc = striped_spin_lock_num++;
20 if (striped_spin_lock_num > PICO_SPINLOCK_ID_STRIPED_LAST) {
21 striped_spin_lock_num = PICO_SPINLOCK_ID_STRIPED_FIRST;
22 }
23 return rc;
24 }
25
spin_lock_claim(uint lock_num)26 void spin_lock_claim(uint lock_num) {
27 check_lock_num(lock_num);
28 hw_claim_or_assert((uint8_t *) &claimed, lock_num, "Spinlock %d is already claimed");
29 }
30
spin_lock_claim_mask(uint32_t mask)31 void spin_lock_claim_mask(uint32_t mask) {
32 for(uint i = 0; mask; i++, mask >>= 1u) {
33 if (mask & 1u) spin_lock_claim(i);
34 }
35 }
36
spin_lock_unclaim(uint lock_num)37 void spin_lock_unclaim(uint lock_num) {
38 check_lock_num(lock_num);
39 spin_unlock_unsafe(spin_lock_instance(lock_num));
40 hw_claim_clear((uint8_t *) &claimed, lock_num);
41 }
42
spin_lock_claim_unused(bool required)43 int spin_lock_claim_unused(bool required) {
44 return hw_claim_unused_from_range((uint8_t*)&claimed, required, PICO_SPINLOCK_ID_CLAIM_FREE_FIRST, PICO_SPINLOCK_ID_CLAIM_FREE_LAST, "No spinlocks are available");
45 }
46
spin_lock_is_claimed(uint lock_num)47 bool spin_lock_is_claimed(uint lock_num) {
48 check_lock_num(lock_num);
49 return hw_is_claimed((uint8_t *) &claimed, lock_num);
50 }
51
52