diff options
author | Paul Mundt <lethal@linux-sh.org> | 2012-03-28 06:53:10 +0200 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2012-03-28 06:53:10 +0200 |
commit | 18af30e259c25a64ad69bb749c661564bc886275 (patch) | |
tree | 996c89594fd20f25fcc15b5843625d99473f6982 /arch/s390/include/asm/system.h | |
parent | arch/sh/drivers/dma/{dma-g2,dmabrg}.c: ensure arguments to request_irq and fr... (diff) | |
parent | Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s39... (diff) | |
download | linux-18af30e259c25a64ad69bb749c661564bc886275.tar.xz linux-18af30e259c25a64ad69bb749c661564bc886275.zip |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux into sh-latest
Diffstat (limited to 'arch/s390/include/asm/system.h')
-rw-r--r-- | arch/s390/include/asm/system.h | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index d73cc6b60000..2e0bb7f0f9b2 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h @@ -7,8 +7,10 @@ #ifndef __ASM_SYSTEM_H #define __ASM_SYSTEM_H +#include <linux/preempt.h> #include <linux/kernel.h> #include <linux/errno.h> +#include <linux/string.h> #include <asm/types.h> #include <asm/ptrace.h> #include <asm/setup.h> @@ -248,6 +250,38 @@ static inline int test_facility(unsigned long nr) return (*ptr & (0x80 >> (nr & 7))) != 0; } +/** + * stfle - Store facility list extended + * @stfle_fac_list: array where facility list can be stored + * @size: size of passed in array in double words + */ +static inline void stfle(u64 *stfle_fac_list, int size) +{ + unsigned long nr; + + preempt_disable(); + S390_lowcore.stfl_fac_list = 0; + asm volatile( + " .insn s,0xb2b10000,0(0)\n" /* stfl */ + "0:\n" + EX_TABLE(0b, 0b) + : "=m" (S390_lowcore.stfl_fac_list)); + nr = 4; /* bytes stored by stfl */ + memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); + if (S390_lowcore.stfl_fac_list & 0x01000000) { + /* More facility bits available with stfle */ + register unsigned long reg0 asm("0") = size - 1; + + asm volatile(".insn s,0xb2b00000,0(%1)" /* stfle */ + : "+d" (reg0) + : "a" (stfle_fac_list) + : "memory", "cc"); + nr = (reg0 + 1) * 8; /* # bytes stored by stfle */ + } + memset((char *) stfle_fac_list + nr, 0, size * 8 - nr); + preempt_enable(); +} + static inline unsigned short stap(void) { unsigned short cpu_address; |