18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __ASM_SH_ATOMIC_IRQ_H 38c2ecf20Sopenharmony_ci#define __ASM_SH_ATOMIC_IRQ_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/irqflags.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci/* 88c2ecf20Sopenharmony_ci * To get proper branch prediction for the main line, we must branch 98c2ecf20Sopenharmony_ci * forward to code at the end of this object's .text section, then 108c2ecf20Sopenharmony_ci * branch back to restart the operation. 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#define ATOMIC_OP(op, c_op) \ 148c2ecf20Sopenharmony_cistatic inline void atomic_##op(int i, atomic_t *v) \ 158c2ecf20Sopenharmony_ci{ \ 168c2ecf20Sopenharmony_ci unsigned long flags; \ 178c2ecf20Sopenharmony_ci \ 188c2ecf20Sopenharmony_ci raw_local_irq_save(flags); \ 198c2ecf20Sopenharmony_ci v->counter c_op i; \ 208c2ecf20Sopenharmony_ci raw_local_irq_restore(flags); \ 218c2ecf20Sopenharmony_ci} 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#define ATOMIC_OP_RETURN(op, c_op) \ 248c2ecf20Sopenharmony_cistatic inline int atomic_##op##_return(int i, atomic_t *v) \ 258c2ecf20Sopenharmony_ci{ \ 268c2ecf20Sopenharmony_ci unsigned long temp, flags; \ 278c2ecf20Sopenharmony_ci \ 288c2ecf20Sopenharmony_ci raw_local_irq_save(flags); \ 298c2ecf20Sopenharmony_ci temp = v->counter; \ 308c2ecf20Sopenharmony_ci temp c_op i; \ 318c2ecf20Sopenharmony_ci v->counter = temp; \ 328c2ecf20Sopenharmony_ci raw_local_irq_restore(flags); \ 338c2ecf20Sopenharmony_ci \ 348c2ecf20Sopenharmony_ci return temp; \ 358c2ecf20Sopenharmony_ci} 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#define ATOMIC_FETCH_OP(op, c_op) \ 388c2ecf20Sopenharmony_cistatic inline int atomic_fetch_##op(int i, atomic_t *v) \ 398c2ecf20Sopenharmony_ci{ \ 408c2ecf20Sopenharmony_ci unsigned long temp, flags; \ 418c2ecf20Sopenharmony_ci \ 428c2ecf20Sopenharmony_ci raw_local_irq_save(flags); \ 438c2ecf20Sopenharmony_ci temp = v->counter; \ 448c2ecf20Sopenharmony_ci v->counter c_op i; \ 458c2ecf20Sopenharmony_ci raw_local_irq_restore(flags); \ 468c2ecf20Sopenharmony_ci \ 478c2ecf20Sopenharmony_ci return temp; \ 488c2ecf20Sopenharmony_ci} 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci#define ATOMIC_OPS(op, c_op) \ 518c2ecf20Sopenharmony_ci ATOMIC_OP(op, c_op) \ 528c2ecf20Sopenharmony_ci ATOMIC_OP_RETURN(op, c_op) \ 538c2ecf20Sopenharmony_ci ATOMIC_FETCH_OP(op, c_op) 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ciATOMIC_OPS(add, +=) 568c2ecf20Sopenharmony_ciATOMIC_OPS(sub, -=) 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci#undef ATOMIC_OPS 598c2ecf20Sopenharmony_ci#define ATOMIC_OPS(op, c_op) \ 608c2ecf20Sopenharmony_ci ATOMIC_OP(op, c_op) \ 618c2ecf20Sopenharmony_ci ATOMIC_FETCH_OP(op, c_op) 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ciATOMIC_OPS(and, &=) 648c2ecf20Sopenharmony_ciATOMIC_OPS(or, |=) 658c2ecf20Sopenharmony_ciATOMIC_OPS(xor, ^=) 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#undef ATOMIC_OPS 688c2ecf20Sopenharmony_ci#undef ATOMIC_FETCH_OP 698c2ecf20Sopenharmony_ci#undef ATOMIC_OP_RETURN 708c2ecf20Sopenharmony_ci#undef ATOMIC_OP 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci#endif /* __ASM_SH_ATOMIC_IRQ_H */ 73