blob: 586df4c9e2f2d44ac42e363c8099ff4173f13f88 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Heiko Carstens1f194a42006-07-03 00:24:46 -07002/*
Heiko Carstensa53c8fa2012-07-20 11:15:04 +02003 * Copyright IBM Corp. 2006, 2010
Heiko Carstens428aecf2010-01-27 10:12:36 +01004 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
Heiko Carstens1f194a42006-07-03 00:24:46 -07005 */
6
7#ifndef __ASM_IRQFLAGS_H
8#define __ASM_IRQFLAGS_H
9
Heiko Carstens428aecf2010-01-27 10:12:36 +010010#include <linux/types.h>
Heiko Carstens1f194a42006-07-03 00:24:46 -070011
Christian Borntraeger204ee2c2016-01-11 09:17:18 +010012#define ARCH_IRQ_ENABLED (3UL << (BITS_PER_LONG - 8))
13
David Howellsdf9ee292010-10-07 14:08:55 +010014/* store then OR system mask. */
15#define __arch_local_irq_stosm(__or) \
Martin Schwidefsky94c12cc2006-09-28 16:56:43 +020016({ \
17 unsigned long __mask; \
18 asm volatile( \
19 " stosm %0,%1" \
20 : "=Q" (__mask) : "i" (__or) : "memory"); \
21 __mask; \
Heiko Carstens1f194a42006-07-03 00:24:46 -070022})
23
David Howellsdf9ee292010-10-07 14:08:55 +010024/* store then AND system mask. */
25#define __arch_local_irq_stnsm(__and) \
Martin Schwidefsky94c12cc2006-09-28 16:56:43 +020026({ \
27 unsigned long __mask; \
28 asm volatile( \
29 " stnsm %0,%1" \
30 : "=Q" (__mask) : "i" (__and) : "memory"); \
31 __mask; \
32})
33
34/* set system mask. */
Steven Rostedtf433c4a2011-07-24 10:47:58 +020035static inline notrace void __arch_local_irq_ssm(unsigned long flags)
Martin Schwidefsky94c12cc2006-09-28 16:56:43 +020036{
David Howellsdf9ee292010-10-07 14:08:55 +010037 asm volatile("ssm %0" : : "Q" (flags) : "memory");
Martin Schwidefsky94c12cc2006-09-28 16:56:43 +020038}
39
Steven Rostedtf433c4a2011-07-24 10:47:58 +020040static inline notrace unsigned long arch_local_save_flags(void)
Martin Schwidefsky94c12cc2006-09-28 16:56:43 +020041{
Christian Borntraeger81fc77f2014-12-16 10:25:37 +010042 return __arch_local_irq_stnsm(0xff);
Martin Schwidefsky94c12cc2006-09-28 16:56:43 +020043}
44
Steven Rostedtf433c4a2011-07-24 10:47:58 +020045static inline notrace unsigned long arch_local_irq_save(void)
Martin Schwidefsky94c12cc2006-09-28 16:56:43 +020046{
David Howellsdf9ee292010-10-07 14:08:55 +010047 return __arch_local_irq_stnsm(0xfc);
Martin Schwidefsky94c12cc2006-09-28 16:56:43 +020048}
49
Steven Rostedtf433c4a2011-07-24 10:47:58 +020050static inline notrace void arch_local_irq_disable(void)
David Howellsdf9ee292010-10-07 14:08:55 +010051{
52 arch_local_irq_save();
53}
54
Steven Rostedtf433c4a2011-07-24 10:47:58 +020055static inline notrace void arch_local_irq_enable(void)
David Howellsdf9ee292010-10-07 14:08:55 +010056{
57 __arch_local_irq_stosm(0x03);
58}
59
Christian Borntraeger204ee2c2016-01-11 09:17:18 +010060/* This only restores external and I/O interrupt state */
Steven Rostedtf433c4a2011-07-24 10:47:58 +020061static inline notrace void arch_local_irq_restore(unsigned long flags)
David Howellsdf9ee292010-10-07 14:08:55 +010062{
Christian Borntraeger204ee2c2016-01-11 09:17:18 +010063 /* only disabled->disabled and disabled->enabled is valid */
64 if (flags & ARCH_IRQ_ENABLED)
65 arch_local_irq_enable();
David Howellsdf9ee292010-10-07 14:08:55 +010066}
67
Steven Rostedtf433c4a2011-07-24 10:47:58 +020068static inline notrace bool arch_irqs_disabled_flags(unsigned long flags)
Heiko Carstens1f194a42006-07-03 00:24:46 -070069{
Christian Borntraeger204ee2c2016-01-11 09:17:18 +010070 return !(flags & ARCH_IRQ_ENABLED);
Heiko Carstens1f194a42006-07-03 00:24:46 -070071}
72
Steven Rostedtf433c4a2011-07-24 10:47:58 +020073static inline notrace bool arch_irqs_disabled(void)
David Howellsdf9ee292010-10-07 14:08:55 +010074{
75 return arch_irqs_disabled_flags(arch_local_save_flags());
76}
Heiko Carstens1f194a42006-07-03 00:24:46 -070077
Heiko Carstens1f194a42006-07-03 00:24:46 -070078#endif /* __ASM_IRQFLAGS_H */