162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2006 Atmark Techno, Inc.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef _ASM_MICROBLAZE_IRQFLAGS_H
762306a36Sopenharmony_ci#define _ASM_MICROBLAZE_IRQFLAGS_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/types.h>
1062306a36Sopenharmony_ci#include <asm/registers.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cistatic inline notrace unsigned long arch_local_irq_save(void)
1562306a36Sopenharmony_ci{
1662306a36Sopenharmony_ci	unsigned long flags;
1762306a36Sopenharmony_ci	asm volatile("	msrclr %0, %1	\n"
1862306a36Sopenharmony_ci		     "	nop		\n"
1962306a36Sopenharmony_ci		     : "=r"(flags)
2062306a36Sopenharmony_ci		     : "i"(MSR_IE)
2162306a36Sopenharmony_ci		     : "memory");
2262306a36Sopenharmony_ci	return flags;
2362306a36Sopenharmony_ci}
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_cistatic inline notrace void arch_local_irq_disable(void)
2662306a36Sopenharmony_ci{
2762306a36Sopenharmony_ci	/* this uses r0 without declaring it - is that correct? */
2862306a36Sopenharmony_ci	asm volatile("	msrclr r0, %0	\n"
2962306a36Sopenharmony_ci		     "	nop		\n"
3062306a36Sopenharmony_ci		     :
3162306a36Sopenharmony_ci		     : "i"(MSR_IE)
3262306a36Sopenharmony_ci		     : "memory");
3362306a36Sopenharmony_ci}
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistatic inline notrace void arch_local_irq_enable(void)
3662306a36Sopenharmony_ci{
3762306a36Sopenharmony_ci	/* this uses r0 without declaring it - is that correct? */
3862306a36Sopenharmony_ci	asm volatile("	msrset	r0, %0	\n"
3962306a36Sopenharmony_ci		     "	nop		\n"
4062306a36Sopenharmony_ci		     :
4162306a36Sopenharmony_ci		     : "i"(MSR_IE)
4262306a36Sopenharmony_ci		     : "memory");
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic inline notrace unsigned long arch_local_irq_save(void)
4862306a36Sopenharmony_ci{
4962306a36Sopenharmony_ci	unsigned long flags, tmp;
5062306a36Sopenharmony_ci	asm volatile ("	mfs	%0, rmsr	\n"
5162306a36Sopenharmony_ci		      "	nop			\n"
5262306a36Sopenharmony_ci		      "	andi	%1, %0, %2	\n"
5362306a36Sopenharmony_ci		      "	mts	rmsr, %1	\n"
5462306a36Sopenharmony_ci		      "	nop			\n"
5562306a36Sopenharmony_ci		      : "=r"(flags), "=r"(tmp)
5662306a36Sopenharmony_ci		      : "i"(~MSR_IE)
5762306a36Sopenharmony_ci		      : "memory");
5862306a36Sopenharmony_ci	return flags;
5962306a36Sopenharmony_ci}
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cistatic inline notrace void arch_local_irq_disable(void)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	unsigned long tmp;
6462306a36Sopenharmony_ci	asm volatile("	mfs	%0, rmsr	\n"
6562306a36Sopenharmony_ci		     "	nop			\n"
6662306a36Sopenharmony_ci		     "	andi	%0, %0, %1	\n"
6762306a36Sopenharmony_ci		     "	mts	rmsr, %0	\n"
6862306a36Sopenharmony_ci		     "	nop			\n"
6962306a36Sopenharmony_ci		     : "=r"(tmp)
7062306a36Sopenharmony_ci		     : "i"(~MSR_IE)
7162306a36Sopenharmony_ci		     : "memory");
7262306a36Sopenharmony_ci}
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistatic inline notrace void arch_local_irq_enable(void)
7562306a36Sopenharmony_ci{
7662306a36Sopenharmony_ci	unsigned long tmp;
7762306a36Sopenharmony_ci	asm volatile("	mfs	%0, rmsr	\n"
7862306a36Sopenharmony_ci		     "	nop			\n"
7962306a36Sopenharmony_ci		     "	ori	%0, %0, %1	\n"
8062306a36Sopenharmony_ci		     "	mts	rmsr, %0	\n"
8162306a36Sopenharmony_ci		     "	nop			\n"
8262306a36Sopenharmony_ci		     : "=r"(tmp)
8362306a36Sopenharmony_ci		     : "i"(MSR_IE)
8462306a36Sopenharmony_ci		     : "memory");
8562306a36Sopenharmony_ci}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci#endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_cistatic inline notrace unsigned long arch_local_save_flags(void)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci	unsigned long flags;
9262306a36Sopenharmony_ci	asm volatile("	mfs	%0, rmsr	\n"
9362306a36Sopenharmony_ci		     "	nop			\n"
9462306a36Sopenharmony_ci		     : "=r"(flags)
9562306a36Sopenharmony_ci		     :
9662306a36Sopenharmony_ci		     : "memory");
9762306a36Sopenharmony_ci	return flags;
9862306a36Sopenharmony_ci}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_cistatic inline notrace void arch_local_irq_restore(unsigned long flags)
10162306a36Sopenharmony_ci{
10262306a36Sopenharmony_ci	asm volatile("	mts	rmsr, %0	\n"
10362306a36Sopenharmony_ci		     "	nop			\n"
10462306a36Sopenharmony_ci		     :
10562306a36Sopenharmony_ci		     : "r"(flags)
10662306a36Sopenharmony_ci		     : "memory");
10762306a36Sopenharmony_ci}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_cistatic inline notrace bool arch_irqs_disabled_flags(unsigned long flags)
11062306a36Sopenharmony_ci{
11162306a36Sopenharmony_ci	return (flags & MSR_IE) == 0;
11262306a36Sopenharmony_ci}
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_cistatic inline notrace bool arch_irqs_disabled(void)
11562306a36Sopenharmony_ci{
11662306a36Sopenharmony_ci	return arch_irqs_disabled_flags(arch_local_save_flags());
11762306a36Sopenharmony_ci}
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#endif /* _ASM_MICROBLAZE_IRQFLAGS_H */
120