1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2001  Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto
7 * Copyright (C) 2004, 2006  Hirokazu Takata <takata at linux-m32r.org>
8 */
9
10#ifndef _ASM_M32R_IRQFLAGS_H
11#define _ASM_M32R_IRQFLAGS_H
12
13#include <linux/types.h>
14
15static inline unsigned long arch_local_save_flags(void)
16{
17	unsigned long flags;
18	asm volatile("mvfc %0,psw" : "=r"(flags));
19	return flags;
20}
21
22static inline void arch_local_irq_disable(void)
23{
24#if !defined(CONFIG_CHIP_M32102) && !defined(CONFIG_CHIP_M32104)
25	asm volatile (
26		"clrpsw #0x40 -> nop"
27		: : : "memory");
28#else
29	unsigned long tmpreg0, tmpreg1;
30	asm volatile (
31		"ld24	%0, #0	; Use 32-bit insn.			\n\t"
32		"mvfc	%1, psw	; No interrupt can be accepted here.	\n\t"
33		"mvtc	%0, psw						\n\t"
34		"and3	%0, %1, #0xffbf					\n\t"
35		"mvtc	%0, psw						\n\t"
36		: "=&r" (tmpreg0), "=&r" (tmpreg1)
37		:
38		: "cbit", "memory");
39#endif
40}
41
42static inline void arch_local_irq_enable(void)
43{
44#if !defined(CONFIG_CHIP_M32102) && !defined(CONFIG_CHIP_M32104)
45	asm volatile (
46		"setpsw #0x40 -> nop"
47		: : : "memory");
48#else
49	unsigned long tmpreg;
50	asm volatile (
51		"mvfc	%0, psw;		\n\t"
52		"or3	%0, %0, #0x0040;	\n\t"
53		"mvtc	%0, psw;		\n\t"
54		: "=&r" (tmpreg)
55		:
56		: "cbit", "memory");
57#endif
58}
59
60static inline unsigned long arch_local_irq_save(void)
61{
62	unsigned long flags;
63
64#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
65	asm volatile (
66		"mvfc	%0, psw;	\n\t"
67		"clrpsw	#0x40 -> nop;	\n\t"
68		: "=r" (flags)
69		:
70		: "memory");
71#else
72	unsigned long tmpreg;
73	asm volatile (
74		"ld24	%1, #0		\n\t"
75		"mvfc	%0, psw		\n\t"
76		"mvtc	%1, psw		\n\t"
77		"and3	%1, %0, #0xffbf	\n\t"
78		"mvtc	%1, psw		\n\t"
79		: "=r" (flags), "=&r" (tmpreg)
80		:
81		: "cbit", "memory");
82#endif
83	return flags;
84}
85
86static inline void arch_local_irq_restore(unsigned long flags)
87{
88	asm volatile("mvtc %0,psw"
89		     :
90		     : "r" (flags)
91		     : "cbit", "memory");
92}
93
94static inline bool arch_irqs_disabled_flags(unsigned long flags)
95{
96	return !(flags & 0x40);
97}
98
99static inline bool arch_irqs_disabled(void)
100{
101	return arch_irqs_disabled_flags(arch_local_save_flags());
102}
103
104#endif /* _ASM_M32R_IRQFLAGS_H */
105