18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2006 Atmark Techno, Inc.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef _ASM_MICROBLAZE_IRQFLAGS_H
78c2ecf20Sopenharmony_ci#define _ASM_MICROBLAZE_IRQFLAGS_H
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/types.h>
108c2ecf20Sopenharmony_ci#include <asm/registers.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_cistatic inline notrace unsigned long arch_local_irq_save(void)
158c2ecf20Sopenharmony_ci{
168c2ecf20Sopenharmony_ci	unsigned long flags;
178c2ecf20Sopenharmony_ci	asm volatile("	msrclr %0, %1	\n"
188c2ecf20Sopenharmony_ci		     "	nop		\n"
198c2ecf20Sopenharmony_ci		     : "=r"(flags)
208c2ecf20Sopenharmony_ci		     : "i"(MSR_IE)
218c2ecf20Sopenharmony_ci		     : "memory");
228c2ecf20Sopenharmony_ci	return flags;
238c2ecf20Sopenharmony_ci}
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistatic inline notrace void arch_local_irq_disable(void)
268c2ecf20Sopenharmony_ci{
278c2ecf20Sopenharmony_ci	/* this uses r0 without declaring it - is that correct? */
288c2ecf20Sopenharmony_ci	asm volatile("	msrclr r0, %0	\n"
298c2ecf20Sopenharmony_ci		     "	nop		\n"
308c2ecf20Sopenharmony_ci		     :
318c2ecf20Sopenharmony_ci		     : "i"(MSR_IE)
328c2ecf20Sopenharmony_ci		     : "memory");
338c2ecf20Sopenharmony_ci}
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_cistatic inline notrace void arch_local_irq_enable(void)
368c2ecf20Sopenharmony_ci{
378c2ecf20Sopenharmony_ci	/* this uses r0 without declaring it - is that correct? */
388c2ecf20Sopenharmony_ci	asm volatile("	msrset	r0, %0	\n"
398c2ecf20Sopenharmony_ci		     "	nop		\n"
408c2ecf20Sopenharmony_ci		     :
418c2ecf20Sopenharmony_ci		     : "i"(MSR_IE)
428c2ecf20Sopenharmony_ci		     : "memory");
438c2ecf20Sopenharmony_ci}
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci#else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_cistatic inline notrace unsigned long arch_local_irq_save(void)
488c2ecf20Sopenharmony_ci{
498c2ecf20Sopenharmony_ci	unsigned long flags, tmp;
508c2ecf20Sopenharmony_ci	asm volatile ("	mfs	%0, rmsr	\n"
518c2ecf20Sopenharmony_ci		      "	nop			\n"
528c2ecf20Sopenharmony_ci		      "	andi	%1, %0, %2	\n"
538c2ecf20Sopenharmony_ci		      "	mts	rmsr, %1	\n"
548c2ecf20Sopenharmony_ci		      "	nop			\n"
558c2ecf20Sopenharmony_ci		      : "=r"(flags), "=r"(tmp)
568c2ecf20Sopenharmony_ci		      : "i"(~MSR_IE)
578c2ecf20Sopenharmony_ci		      : "memory");
588c2ecf20Sopenharmony_ci	return flags;
598c2ecf20Sopenharmony_ci}
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_cistatic inline notrace void arch_local_irq_disable(void)
628c2ecf20Sopenharmony_ci{
638c2ecf20Sopenharmony_ci	unsigned long tmp;
648c2ecf20Sopenharmony_ci	asm volatile("	mfs	%0, rmsr	\n"
658c2ecf20Sopenharmony_ci		     "	nop			\n"
668c2ecf20Sopenharmony_ci		     "	andi	%0, %0, %1	\n"
678c2ecf20Sopenharmony_ci		     "	mts	rmsr, %0	\n"
688c2ecf20Sopenharmony_ci		     "	nop			\n"
698c2ecf20Sopenharmony_ci		     : "=r"(tmp)
708c2ecf20Sopenharmony_ci		     : "i"(~MSR_IE)
718c2ecf20Sopenharmony_ci		     : "memory");
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_cistatic inline notrace void arch_local_irq_enable(void)
758c2ecf20Sopenharmony_ci{
768c2ecf20Sopenharmony_ci	unsigned long tmp;
778c2ecf20Sopenharmony_ci	asm volatile("	mfs	%0, rmsr	\n"
788c2ecf20Sopenharmony_ci		     "	nop			\n"
798c2ecf20Sopenharmony_ci		     "	ori	%0, %0, %1	\n"
808c2ecf20Sopenharmony_ci		     "	mts	rmsr, %0	\n"
818c2ecf20Sopenharmony_ci		     "	nop			\n"
828c2ecf20Sopenharmony_ci		     : "=r"(tmp)
838c2ecf20Sopenharmony_ci		     : "i"(MSR_IE)
848c2ecf20Sopenharmony_ci		     : "memory");
858c2ecf20Sopenharmony_ci}
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci#endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_cistatic inline notrace unsigned long arch_local_save_flags(void)
908c2ecf20Sopenharmony_ci{
918c2ecf20Sopenharmony_ci	unsigned long flags;
928c2ecf20Sopenharmony_ci	asm volatile("	mfs	%0, rmsr	\n"
938c2ecf20Sopenharmony_ci		     "	nop			\n"
948c2ecf20Sopenharmony_ci		     : "=r"(flags)
958c2ecf20Sopenharmony_ci		     :
968c2ecf20Sopenharmony_ci		     : "memory");
978c2ecf20Sopenharmony_ci	return flags;
988c2ecf20Sopenharmony_ci}
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistatic inline notrace void arch_local_irq_restore(unsigned long flags)
1018c2ecf20Sopenharmony_ci{
1028c2ecf20Sopenharmony_ci	asm volatile("	mts	rmsr, %0	\n"
1038c2ecf20Sopenharmony_ci		     "	nop			\n"
1048c2ecf20Sopenharmony_ci		     :
1058c2ecf20Sopenharmony_ci		     : "r"(flags)
1068c2ecf20Sopenharmony_ci		     : "memory");
1078c2ecf20Sopenharmony_ci}
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_cistatic inline notrace bool arch_irqs_disabled_flags(unsigned long flags)
1108c2ecf20Sopenharmony_ci{
1118c2ecf20Sopenharmony_ci	return (flags & MSR_IE) == 0;
1128c2ecf20Sopenharmony_ci}
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_cistatic inline notrace bool arch_irqs_disabled(void)
1158c2ecf20Sopenharmony_ci{
1168c2ecf20Sopenharmony_ci	return arch_irqs_disabled_flags(arch_local_save_flags());
1178c2ecf20Sopenharmony_ci}
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci#endif /* _ASM_MICROBLAZE_IRQFLAGS_H */
120