From d576a9561a1c80ae593539fb0ce0743d66825ac2 Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Sat, 22 Aug 2026 14:19:12 +0200 Subject: Merge tag 'rust-i2c-for-7.3' into i2c/i2c i2c: rust: mark I2cAdapter methods as inline A single cleanup for the Rust I2C abstractions, targeting 7.3. `I2cAdapter::get`, `inc_ref`, and `dec_ref` are trivial wrappers around `i2c_get_adapter`/`i2c_put_adapter` and were showing up as their own symbols in the build. Mark them `#[inline]` so they get folded into their callers instead. Signed-off-by: Igor Korotin * tag 'rust-i2c-for-7.3': i2c: rust: mark I2cAdapter methods as inline --- lib/dec_and_lock.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 lib/dec_and_lock.c (limited to 'lib/dec_and_lock.c') diff --git a/lib/dec_and_lock.c b/lib/dec_and_lock.c new file mode 100644 index 000000000..8c7c398fd --- /dev/null +++ b/lib/dec_and_lock.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + +/* + * This is an implementation of the notion of "decrement a + * reference count, and return locked if it decremented to zero". + * + * NOTE NOTE NOTE! This is _not_ equivalent to + * + * if (atomic_dec_and_test(&atomic)) { + * spin_lock(&lock); + * return 1; + * } + * return 0; + * + * because the spin-lock and the decrement must be + * "atomic". + */ +int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) +{ + /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ + if (atomic_add_unless(atomic, -1, 1)) + return 0; + + /* Otherwise do it the slow way */ + spin_lock(lock); + if (atomic_dec_and_test(atomic)) + return 1; + spin_unlock(lock); + return 0; +} + +EXPORT_SYMBOL(atomic_dec_and_lock); + +int _atomic_dec_and_lock_irqsave(atomic_t *atomic, spinlock_t *lock, + unsigned long *flags) +{ + /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ + if (atomic_add_unless(atomic, -1, 1)) + return 0; + + /* Otherwise do it the slow way */ + spin_lock_irqsave(lock, *flags); + if (atomic_dec_and_test(atomic)) + return 1; + spin_unlock_irqrestore(lock, *flags); + return 0; +} +EXPORT_SYMBOL(_atomic_dec_and_lock_irqsave); + +int atomic_dec_and_raw_lock(atomic_t *atomic, raw_spinlock_t *lock) +{ + /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ + if (atomic_add_unless(atomic, -1, 1)) + return 0; + + /* Otherwise do it the slow way */ + raw_spin_lock(lock); + if (atomic_dec_and_test(atomic)) + return 1; + raw_spin_unlock(lock); + return 0; +} +EXPORT_SYMBOL(atomic_dec_and_raw_lock); + +int _atomic_dec_and_raw_lock_irqsave(atomic_t *atomic, raw_spinlock_t *lock, + unsigned long *flags) +{ + /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ + if (atomic_add_unless(atomic, -1, 1)) + return 0; + + /* Otherwise do it the slow way */ + raw_spin_lock_irqsave(lock, *flags); + if (atomic_dec_and_test(atomic)) + return 1; + raw_spin_unlock_irqrestore(lock, *flags); + return 0; +} +EXPORT_SYMBOL(_atomic_dec_and_raw_lock_irqsave); -- cgit v1.3.1