aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/configs/default_defconfig5
-rw-r--r--arch/s390/configs/gcov_defconfig5
-rw-r--r--arch/s390/configs/performance_defconfig5
-rw-r--r--arch/s390/configs/zfcpdump_defconfig3
-rw-r--r--arch/s390/defconfig8
-rw-r--r--arch/s390/include/asm/mmu_context.h33
-rw-r--r--arch/s390/include/asm/switch_to.h4
-rw-r--r--arch/s390/include/uapi/asm/ucontext.h8
-rw-r--r--arch/s390/kernel/compat_linux.h4
-rw-r--r--drivers/s390/block/dcssblk.c2
-rw-r--r--drivers/s390/char/Makefile1
-rw-r--r--drivers/s390/char/sclp_vt220.c2
-rw-r--r--drivers/s390/char/vmlogrdr.c2
-rw-r--r--drivers/s390/char/vmwatchdog.c338
-rw-r--r--drivers/s390/cio/airq.c13
-rw-r--r--drivers/s390/cio/ccwgroup.c28
-rw-r--r--drivers/s390/cio/cio.c2
-rw-r--r--drivers/s390/cio/device.c71
-rw-r--r--drivers/s390/cio/qdio_debug.c79
-rw-r--r--drivers/s390/cio/qdio_debug.h2
-rw-r--r--drivers/s390/cio/qdio_main.c16
-rw-r--r--drivers/s390/crypto/ap_bus.c4
-rw-r--r--drivers/s390/crypto/zcrypt_api.c2
-rw-r--r--drivers/watchdog/Kconfig7
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/diag288_wdt.c316
26 files changed, 505 insertions, 456 deletions
diff --git a/arch/s390/configs/default_defconfig b/arch/s390/configs/default_defconfig
index 8df022c43af7..fd09a10a2b53 100644
--- a/arch/s390/configs/default_defconfig
+++ b/arch/s390/configs/default_defconfig
@@ -45,7 +45,8 @@ CONFIG_SOLARIS_X86_PARTITION=y
45CONFIG_UNIXWARE_DISKLABEL=y 45CONFIG_UNIXWARE_DISKLABEL=y
46CONFIG_CFQ_GROUP_IOSCHED=y 46CONFIG_CFQ_GROUP_IOSCHED=y
47CONFIG_DEFAULT_DEADLINE=y 47CONFIG_DEFAULT_DEADLINE=y
48CONFIG_MARCH_Z9_109=y 48CONFIG_MARCH_Z196=y
49CONFIG_TUNE_ZEC12=y
49CONFIG_NR_CPUS=256 50CONFIG_NR_CPUS=256
50CONFIG_PREEMPT=y 51CONFIG_PREEMPT=y
51CONFIG_HZ_100=y 52CONFIG_HZ_100=y
@@ -240,7 +241,6 @@ CONFIG_IP_VS_PE_SIP=m
240CONFIG_NF_CONNTRACK_IPV4=m 241CONFIG_NF_CONNTRACK_IPV4=m
241# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set 242# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
242CONFIG_NF_TABLES_IPV4=m 243CONFIG_NF_TABLES_IPV4=m
243CONFIG_NFT_REJECT_IPV4=m
244CONFIG_NFT_CHAIN_ROUTE_IPV4=m 244CONFIG_NFT_CHAIN_ROUTE_IPV4=m
245CONFIG_NFT_CHAIN_NAT_IPV4=m 245CONFIG_NFT_CHAIN_NAT_IPV4=m
246CONFIG_NF_TABLES_ARP=m 246CONFIG_NF_TABLES_ARP=m
@@ -456,6 +456,7 @@ CONFIG_TN3270_FS=y
456CONFIG_WATCHDOG=y 456CONFIG_WATCHDOG=y
457CONFIG_WATCHDOG_NOWAYOUT=y 457CONFIG_WATCHDOG_NOWAYOUT=y
458CONFIG_SOFT_WATCHDOG=m 458CONFIG_SOFT_WATCHDOG=m
459CONFIG_DIAG288_WATCHDOG=m
459# CONFIG_HID is not set 460# CONFIG_HID is not set
460# CONFIG_USB_SUPPORT is not set 461# CONFIG_USB_SUPPORT is not set
461CONFIG_INFINIBAND=m 462CONFIG_INFINIBAND=m
diff --git a/arch/s390/configs/gcov_defconfig b/arch/s390/configs/gcov_defconfig
index c81a74e3e25a..b061180d3544 100644
--- a/arch/s390/configs/gcov_defconfig
+++ b/arch/s390/configs/gcov_defconfig
@@ -45,7 +45,8 @@ CONFIG_SOLARIS_X86_PARTITION=y
45CONFIG_UNIXWARE_DISKLABEL=y 45CONFIG_UNIXWARE_DISKLABEL=y
46CONFIG_CFQ_GROUP_IOSCHED=y 46CONFIG_CFQ_GROUP_IOSCHED=y
47CONFIG_DEFAULT_DEADLINE=y 47CONFIG_DEFAULT_DEADLINE=y
48CONFIG_MARCH_Z9_109=y 48CONFIG_MARCH_Z196=y
49CONFIG_TUNE_ZEC12=y
49CONFIG_NR_CPUS=256 50CONFIG_NR_CPUS=256
50CONFIG_HZ_100=y 51CONFIG_HZ_100=y
51CONFIG_MEMORY_HOTPLUG=y 52CONFIG_MEMORY_HOTPLUG=y
@@ -238,7 +239,6 @@ CONFIG_IP_VS_PE_SIP=m
238CONFIG_NF_CONNTRACK_IPV4=m 239CONFIG_NF_CONNTRACK_IPV4=m
239# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set 240# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
240CONFIG_NF_TABLES_IPV4=m 241CONFIG_NF_TABLES_IPV4=m
241CONFIG_NFT_REJECT_IPV4=m
242CONFIG_NFT_CHAIN_ROUTE_IPV4=m 242CONFIG_NFT_CHAIN_ROUTE_IPV4=m
243CONFIG_NFT_CHAIN_NAT_IPV4=m 243CONFIG_NFT_CHAIN_NAT_IPV4=m
244CONFIG_NF_TABLES_ARP=m 244CONFIG_NF_TABLES_ARP=m
@@ -453,6 +453,7 @@ CONFIG_TN3270_FS=y
453CONFIG_WATCHDOG=y 453CONFIG_WATCHDOG=y
454CONFIG_WATCHDOG_NOWAYOUT=y 454CONFIG_WATCHDOG_NOWAYOUT=y
455CONFIG_SOFT_WATCHDOG=m 455CONFIG_SOFT_WATCHDOG=m
456CONFIG_DIAG288_WATCHDOG=m
456# CONFIG_HID is not set 457# CONFIG_HID is not set
457# CONFIG_USB_SUPPORT is not set 458# CONFIG_USB_SUPPORT is not set
458CONFIG_INFINIBAND=m 459CONFIG_INFINIBAND=m
diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig
index b5ba8fe1cc64..d279baa08014 100644
--- a/arch/s390/configs/performance_defconfig
+++ b/arch/s390/configs/performance_defconfig
@@ -43,7 +43,8 @@ CONFIG_SOLARIS_X86_PARTITION=y
43CONFIG_UNIXWARE_DISKLABEL=y 43CONFIG_UNIXWARE_DISKLABEL=y
44CONFIG_CFQ_GROUP_IOSCHED=y 44CONFIG_CFQ_GROUP_IOSCHED=y
45CONFIG_DEFAULT_DEADLINE=y 45CONFIG_DEFAULT_DEADLINE=y
46CONFIG_MARCH_Z9_109=y 46CONFIG_MARCH_Z196=y
47CONFIG_TUNE_ZEC12=y
47CONFIG_NR_CPUS=256 48CONFIG_NR_CPUS=256
48CONFIG_HZ_100=y 49CONFIG_HZ_100=y
49CONFIG_MEMORY_HOTPLUG=y 50CONFIG_MEMORY_HOTPLUG=y
@@ -236,7 +237,6 @@ CONFIG_IP_VS_PE_SIP=m
236CONFIG_NF_CONNTRACK_IPV4=m 237CONFIG_NF_CONNTRACK_IPV4=m
237# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set 238# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
238CONFIG_NF_TABLES_IPV4=m 239CONFIG_NF_TABLES_IPV4=m
239CONFIG_NFT_REJECT_IPV4=m
240CONFIG_NFT_CHAIN_ROUTE_IPV4=m 240CONFIG_NFT_CHAIN_ROUTE_IPV4=m
241CONFIG_NFT_CHAIN_NAT_IPV4=m 241CONFIG_NFT_CHAIN_NAT_IPV4=m
242CONFIG_NF_TABLES_ARP=m 242CONFIG_NF_TABLES_ARP=m
@@ -451,6 +451,7 @@ CONFIG_TN3270_FS=y
451CONFIG_WATCHDOG=y 451CONFIG_WATCHDOG=y
452CONFIG_WATCHDOG_NOWAYOUT=y 452CONFIG_WATCHDOG_NOWAYOUT=y
453CONFIG_SOFT_WATCHDOG=m 453CONFIG_SOFT_WATCHDOG=m
454CONFIG_DIAG288_WATCHDOG=m
454# CONFIG_HID is not set 455# CONFIG_HID is not set
455# CONFIG_USB_SUPPORT is not set 456# CONFIG_USB_SUPPORT is not set
456CONFIG_INFINIBAND=m 457CONFIG_INFINIBAND=m
diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig
index cef073ca1f07..948e0e057a23 100644
--- a/arch/s390/configs/zfcpdump_defconfig
+++ b/arch/s390/configs/zfcpdump_defconfig
@@ -8,7 +8,8 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
8CONFIG_PARTITION_ADVANCED=y 8CONFIG_PARTITION_ADVANCED=y
9CONFIG_IBM_PARTITION=y 9CONFIG_IBM_PARTITION=y
10CONFIG_DEFAULT_DEADLINE=y 10CONFIG_DEFAULT_DEADLINE=y
11CONFIG_MARCH_Z9_109=y 11CONFIG_MARCH_Z196=y
12CONFIG_TUNE_ZEC12=y
12# CONFIG_COMPAT is not set 13# CONFIG_COMPAT is not set
13CONFIG_NR_CPUS=2 14CONFIG_NR_CPUS=2
14# CONFIG_HOTPLUG_CPU is not set 15# CONFIG_HOTPLUG_CPU is not set
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 4557cb7ffddf..2e56498a40df 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -135,8 +135,8 @@ CONFIG_PROVE_LOCKING=y
135CONFIG_LOCK_STAT=y 135CONFIG_LOCK_STAT=y
136CONFIG_DEBUG_LOCKDEP=y 136CONFIG_DEBUG_LOCKDEP=y
137CONFIG_DEBUG_ATOMIC_SLEEP=y 137CONFIG_DEBUG_ATOMIC_SLEEP=y
138CONFIG_DEBUG_WRITECOUNT=y
139CONFIG_DEBUG_LIST=y 138CONFIG_DEBUG_LIST=y
139CONFIG_DEBUG_PI_LIST=y
140CONFIG_DEBUG_SG=y 140CONFIG_DEBUG_SG=y
141CONFIG_DEBUG_NOTIFIERS=y 141CONFIG_DEBUG_NOTIFIERS=y
142CONFIG_PROVE_RCU=y 142CONFIG_PROVE_RCU=y
@@ -199,4 +199,10 @@ CONFIG_CRYPTO_SHA512_S390=m
199CONFIG_CRYPTO_DES_S390=m 199CONFIG_CRYPTO_DES_S390=m
200CONFIG_CRYPTO_AES_S390=m 200CONFIG_CRYPTO_AES_S390=m
201CONFIG_CRC7=m 201CONFIG_CRC7=m
202# CONFIG_XZ_DEC_X86 is not set
203# CONFIG_XZ_DEC_POWERPC is not set
204# CONFIG_XZ_DEC_IA64 is not set
205# CONFIG_XZ_DEC_ARM is not set
206# CONFIG_XZ_DEC_ARMTHUMB is not set
207# CONFIG_XZ_DEC_SPARC is not set
202CONFIG_CMM=m 208CONFIG_CMM=m
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h
index c28f32a45af5..3815bfea1b2d 100644
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -33,10 +33,9 @@ static inline int init_new_context(struct task_struct *tsk,
33 33
34static inline void set_user_asce(struct mm_struct *mm) 34static inline void set_user_asce(struct mm_struct *mm)
35{ 35{
36 pgd_t *pgd = mm->pgd; 36 S390_lowcore.user_asce = mm->context.asce_bits | __pa(mm->pgd);
37 37 if (current->thread.mm_segment.ar4)
38 S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd); 38 __ctl_load(S390_lowcore.user_asce, 7, 7);
39 set_fs(current->thread.mm_segment);
40 set_cpu_flag(CIF_ASCE); 39 set_cpu_flag(CIF_ASCE);
41} 40}
42 41
@@ -70,12 +69,11 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
70 /* Clear old ASCE by loading the kernel ASCE. */ 69 /* Clear old ASCE by loading the kernel ASCE. */
71 __ctl_load(S390_lowcore.kernel_asce, 1, 1); 70 __ctl_load(S390_lowcore.kernel_asce, 1, 1);
72 __ctl_load(S390_lowcore.kernel_asce, 7, 7); 71 __ctl_load(S390_lowcore.kernel_asce, 7, 7);
73 /* Delay loading of the new ASCE to control registers CR1 & CR7 */
74 set_cpu_flag(CIF_ASCE);
75 atomic_inc(&next->context.attach_count); 72 atomic_inc(&next->context.attach_count);
76 atomic_dec(&prev->context.attach_count); 73 atomic_dec(&prev->context.attach_count);
77 if (MACHINE_HAS_TLB_LC) 74 if (MACHINE_HAS_TLB_LC)
78 cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask); 75 cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask);
76 S390_lowcore.user_asce = next->context.asce_bits | __pa(next->pgd);
79} 77}
80 78
81#define finish_arch_post_lock_switch finish_arch_post_lock_switch 79#define finish_arch_post_lock_switch finish_arch_post_lock_switch
@@ -84,17 +82,18 @@ static inline void finish_arch_post_lock_switch(void)
84 struct task_struct *tsk = current; 82 struct task_struct *tsk = current;
85 struct mm_struct *mm = tsk->mm; 83 struct mm_struct *mm = tsk->mm;
86 84
87 if (!mm) 85 load_kernel_asce();
88 return; 86 if (mm) {
89 preempt_disable(); 87 preempt_disable();
90 while (atomic_read(&mm->context.attach_count) >> 16) 88 while (atomic_read(&mm->context.attach_count) >> 16)
91 cpu_relax(); 89 cpu_relax();
92 90
93 cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); 91 cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
94 set_user_asce(mm); 92 if (mm->context.flush_mm)
95 if (mm->context.flush_mm) 93 __tlb_flush_mm(mm);
96 __tlb_flush_mm(mm); 94 preempt_enable();
97 preempt_enable(); 95 }
96 set_fs(current->thread.mm_segment);
98} 97}
99 98
100#define enter_lazy_tlb(mm,tsk) do { } while (0) 99#define enter_lazy_tlb(mm,tsk) do { } while (0)
diff --git a/arch/s390/include/asm/switch_to.h b/arch/s390/include/asm/switch_to.h
index 29c81f82705e..df38c70cd59e 100644
--- a/arch/s390/include/asm/switch_to.h
+++ b/arch/s390/include/asm/switch_to.h
@@ -134,8 +134,4 @@ static inline void restore_access_regs(unsigned int *acrs)
134 prev = __switch_to(prev,next); \ 134 prev = __switch_to(prev,next); \
135} while (0) 135} while (0)
136 136
137#define finish_arch_switch(prev) do { \
138 set_fs(current->thread.mm_segment); \
139} while (0)
140
141#endif /* __ASM_SWITCH_TO_H */ 137#endif /* __ASM_SWITCH_TO_H */
diff --git a/arch/s390/include/uapi/asm/ucontext.h b/arch/s390/include/uapi/asm/ucontext.h
index 200e06325c6a..3e077b2a4705 100644
--- a/arch/s390/include/uapi/asm/ucontext.h
+++ b/arch/s390/include/uapi/asm/ucontext.h
@@ -16,7 +16,9 @@ struct ucontext_extended {
16 struct ucontext *uc_link; 16 struct ucontext *uc_link;
17 stack_t uc_stack; 17 stack_t uc_stack;
18 _sigregs uc_mcontext; 18 _sigregs uc_mcontext;
19 unsigned long uc_sigmask[2]; 19 sigset_t uc_sigmask;
20 /* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */
21 unsigned char __unused[128 - sizeof(sigset_t)];
20 unsigned long uc_gprs_high[16]; 22 unsigned long uc_gprs_high[16];
21}; 23};
22 24
@@ -27,7 +29,9 @@ struct ucontext {
27 struct ucontext *uc_link; 29 struct ucontext *uc_link;
28 stack_t uc_stack; 30 stack_t uc_stack;
29 _sigregs uc_mcontext; 31 _sigregs uc_mcontext;
30 sigset_t uc_sigmask; /* mask last for extensibility */ 32 sigset_t uc_sigmask;
33 /* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */
34 unsigned char __unused[128 - sizeof(sigset_t)];
31}; 35};
32 36
33#endif /* !_ASM_S390_UCONTEXT_H */ 37#endif /* !_ASM_S390_UCONTEXT_H */
diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h
index 39ddfdb40ae8..70d4b7c4beaa 100644
--- a/arch/s390/kernel/compat_linux.h
+++ b/arch/s390/kernel/compat_linux.h
@@ -69,7 +69,9 @@ struct ucontext32 {
69 __u32 uc_link; /* pointer */ 69 __u32 uc_link; /* pointer */
70 compat_stack_t uc_stack; 70 compat_stack_t uc_stack;
71 _sigregs32 uc_mcontext; 71 _sigregs32 uc_mcontext;
72 compat_sigset_t uc_sigmask; /* mask last for extensibility */ 72 compat_sigset_t uc_sigmask;
73 /* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */
74 unsigned char __unused[128 - sizeof(compat_sigset_t)];
73}; 75};
74 76
75struct stat64_emu31; 77struct stat64_emu31;
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index ee0e85abe1fd..0f471750327e 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -593,7 +593,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
593 dev_info->start = dcssblk_find_lowest_addr(dev_info); 593 dev_info->start = dcssblk_find_lowest_addr(dev_info);
594 dev_info->end = dcssblk_find_highest_addr(dev_info); 594 dev_info->end = dcssblk_find_highest_addr(dev_info);
595 595
596 dev_set_name(&dev_info->dev, dev_info->segment_name); 596 dev_set_name(&dev_info->dev, "%s", dev_info->segment_name);
597 dev_info->dev.release = dcssblk_release_segment; 597 dev_info->dev.release = dcssblk_release_segment;
598 dev_info->dev.groups = dcssblk_dev_attr_groups; 598 dev_info->dev.groups = dcssblk_dev_attr_groups;
599 INIT_LIST_HEAD(&dev_info->lh); 599 INIT_LIST_HEAD(&dev_info->lh);
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
index 629fcc275e92..78b6ace7edcb 100644
--- a/drivers/s390/char/Makefile
+++ b/drivers/s390/char/Makefile
@@ -19,7 +19,6 @@ obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o
19obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o 19obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o
20obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o 20obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o
21 21
22obj-$(CONFIG_ZVM_WATCHDOG) += vmwatchdog.o
23obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o 22obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o
24obj-$(CONFIG_VMCP) += vmcp.o 23obj-$(CONFIG_VMCP) += vmcp.o
25 24
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index cd9c91909596..b9a9f721716d 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -838,8 +838,6 @@ sclp_vt220_con_init(void)
838{ 838{
839 int rc; 839 int rc;
840 840
841 if (!CONSOLE_IS_SCLP)
842 return 0;
843 rc = __sclp_vt220_init(sclp_console_pages); 841 rc = __sclp_vt220_init(sclp_console_pages);
844 if (rc) 842 if (rc)
845 return rc; 843 return rc;
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index cf31d3321dab..a8848db7b09d 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -761,7 +761,7 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
761 761
762 dev = kzalloc(sizeof(struct device), GFP_KERNEL); 762 dev = kzalloc(sizeof(struct device), GFP_KERNEL);
763 if (dev) { 763 if (dev) {
764 dev_set_name(dev, priv->internal_name); 764 dev_set_name(dev, "%s", priv->internal_name);
765 dev->bus = &iucv_bus; 765 dev->bus = &iucv_bus;
766 dev->parent = iucv_root; 766 dev->parent = iucv_root;
767 dev->driver = &vmlogrdr_driver; 767 dev->driver = &vmlogrdr_driver;
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
deleted file mode 100644
index d5eac985976b..000000000000
--- a/drivers/s390/char/vmwatchdog.c
+++ /dev/null
@@ -1,338 +0,0 @@
1/*
2 * Watchdog implementation based on z/VM Watchdog Timer API
3 *
4 * Copyright IBM Corp. 2004, 2009
5 *
6 * The user space watchdog daemon can use this driver as
7 * /dev/vmwatchdog to have z/VM execute the specified CP
8 * command when the timeout expires. The default command is
9 * "IPL", which which cause an immediate reboot.
10 */
11#define KMSG_COMPONENT "vmwatchdog"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13
14#include <linux/init.h>
15#include <linux/fs.h>
16#include <linux/kernel.h>
17#include <linux/miscdevice.h>
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/slab.h>
21#include <linux/suspend.h>
22#include <linux/watchdog.h>
23
24#include <asm/ebcdic.h>
25#include <asm/io.h>
26#include <asm/uaccess.h>
27
28#define MAX_CMDLEN 240
29#define MIN_INTERVAL 15
30static char vmwdt_cmd[MAX_CMDLEN] = "IPL";
31static bool vmwdt_conceal;
32
33static bool vmwdt_nowayout = WATCHDOG_NOWAYOUT;
34
35MODULE_LICENSE("GPL");
36MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
37MODULE_DESCRIPTION("z/VM Watchdog Timer");
38module_param_string(cmd, vmwdt_cmd, MAX_CMDLEN, 0644);
39MODULE_PARM_DESC(cmd, "CP command that is run when the watchdog triggers");
40module_param_named(conceal, vmwdt_conceal, bool, 0644);
41MODULE_PARM_DESC(conceal, "Enable the CONCEAL CP option while the watchdog "
42 " is active");
43module_param_named(nowayout, vmwdt_nowayout, bool, 0);
44MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"
45 " (default=CONFIG_WATCHDOG_NOWAYOUT)");
46MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
47
48static unsigned int vmwdt_interval = 60;
49static unsigned long vmwdt_is_open;
50static int vmwdt_expect_close;
51
52static DEFINE_MUTEX(vmwdt_mutex);
53
54#define VMWDT_OPEN 0 /* devnode is open or suspend in progress */
55#define VMWDT_RUNNING 1 /* The watchdog is armed */
56
57enum vmwdt_func {
58 /* function codes */
59 wdt_init = 0,
60 wdt_change = 1,
61 wdt_cancel = 2,
62 /* flags */
63 wdt_conceal = 0x80000000,
64};
65
66static int __diag288(enum vmwdt_func func, unsigned int timeout,
67 char *cmd, size_t len)
68{
69 register unsigned long __func asm("2") = func;
70 register unsigned long __timeout asm("3") = timeout;
71 register unsigned long __cmdp asm("4") = virt_to_phys(cmd);
72 register unsigned long __cmdl asm("5") = len;
73 int err;
74
75 err = -EINVAL;
76 asm volatile(
77 " diag %1,%3,0x288\n"
78 "0: la %0,0\n"
79 "1:\n"
80 EX_TABLE(0b,1b)
81 : "+d" (err) : "d"(__func), "d"(__timeout),
82 "d"(__cmdp), "d"(__cmdl) : "1", "cc");
83 return err;
84}
85
86static int vmwdt_keepalive(void)
87{
88 /* we allocate new memory every time to avoid having
89 * to track the state. static allocation is not an
90 * option since that might not be contiguous in real
91 * storage in case of a modular build */
92 static char *ebc_cmd;
93 size_t len;
94 int ret;
95 unsigned int func;
96
97 ebc_cmd = kmalloc(MAX_CMDLEN, GFP_KERNEL);
98 if (!ebc_cmd)
99 return -ENOMEM;
100
101 len = strlcpy(ebc_cmd, vmwdt_cmd, MAX_CMDLEN);
102 ASCEBC(ebc_cmd, MAX_CMDLEN);
103 EBC_TOUPPER(ebc_cmd, MAX_CMDLEN);
104
105 func = vmwdt_conceal ? (wdt_init | wdt_conceal) : wdt_init;
106 set_bit(VMWDT_RUNNING, &vmwdt_is_open);
107 ret = __diag288(func, vmwdt_interval, ebc_cmd, len);
108 WARN_ON(ret != 0);
109 kfree(ebc_cmd);
110 return ret;
111}
112
113static int vmwdt_disable(void)
114{
115 char cmd[] = {'\0'};
116 int ret = __diag288(wdt_cancel, 0, cmd, 0);
117 WARN_ON(ret != 0);
118 clear_bit(VMWDT_RUNNING, &vmwdt_is_open);
119 return ret;
120}
121
122static int __init vmwdt_probe(void)
123{
124 /* there is no real way to see if the watchdog is supported,
125 * so we try initializing it with a NOP command ("BEGIN")
126 * that won't cause any harm even if the following disable
127 * fails for some reason */
128 char ebc_begin[] = {
129 194, 197, 199, 201, 213
130 };
131 if (__diag288(wdt_init, 15, ebc_begin, sizeof(ebc_begin)) != 0)
132 return -EINVAL;
133 return vmwdt_disable();
134}
135
136static int vmwdt_open(struct inode *i, struct file *f)
137{
138 int ret;
139 if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open))
140 return -EBUSY;
141 ret = vmwdt_keepalive();
142 if (ret)
143 clear_bit(VMWDT_OPEN, &vmwdt_is_open);
144 return ret ? ret : nonseekable_open(i, f);
145}
146
147static int vmwdt_close(struct inode *i, struct file *f)
148{
149 if (vmwdt_expect_close == 42)
150 vmwdt_disable();
151 vmwdt_expect_close = 0;
152 clear_bit(VMWDT_OPEN, &vmwdt_is_open);
153 return 0;
154}
155
156static struct watchdog_info vmwdt_info = {
157 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
158 .firmware_version = 0,
159 .identity = "z/VM Watchdog Timer",
160};
161
162static int __vmwdt_ioctl(unsigned int cmd, unsigned long arg)
163{
164 switch (cmd) {
165 case WDIOC_GETSUPPORT:
166 if (copy_to_user((void __user *)arg, &vmwdt_info,
167 sizeof(vmwdt_info)))
168 return -EFAULT;
169 return 0;
170 case WDIOC_GETSTATUS:
171 case WDIOC_GETBOOTSTATUS:
172 return put_user(0, (int __user *)arg);
173 case WDIOC_GETTEMP:
174 return -EINVAL;
175 case WDIOC_SETOPTIONS:
176 {
177 int options, ret;
178 if (get_user(options, (int __user *)arg))
179 return -EFAULT;
180 ret = -EINVAL;
181 if (options & WDIOS_DISABLECARD) {
182 ret = vmwdt_disable();
183 if (ret)
184 return ret;
185 }
186 if (options & WDIOS_ENABLECARD) {
187 ret = vmwdt_keepalive();
188 }
189 return ret;
190 }
191 case WDIOC_GETTIMEOUT:
192 return put_user(vmwdt_interval, (int __user *)arg);
193 case WDIOC_SETTIMEOUT:
194 {
195 int interval;
196 if (get_user(interval, (int __user *)arg))
197 return -EFAULT;
198 if (interval < MIN_INTERVAL)
199 return -EINVAL;
200 vmwdt_interval = interval;
201 }
202 return vmwdt_keepalive();
203 case WDIOC_KEEPALIVE:
204 return vmwdt_keepalive();
205 }
206 return -EINVAL;
207}
208
209static long vmwdt_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
210{
211 int rc;
212
213 mutex_lock(&vmwdt_mutex);
214 rc = __vmwdt_ioctl(cmd, arg);
215 mutex_unlock(&vmwdt_mutex);
216 return (long) rc;
217}
218
219static ssize_t vmwdt_write(struct file *f, const char __user *buf,
220 size_t count, loff_t *ppos)
221{
222 if(count) {
223 if (!vmwdt_nowayout) {
224 size_t i;
225
226 /* note: just in case someone wrote the magic character
227 * five months ago... */
228 vmwdt_expect_close = 0;
229
230 for (i = 0; i != count; i++) {
231 char c;
232 if (get_user(c, buf+i))
233 return -EFAULT;
234 if (c == 'V')
235 vmwdt_expect_close = 42;
236 }
237 }
238 /* someone wrote to us, we should restart timer */
239 vmwdt_keepalive();
240 }
241 return count;
242}
243
244static int vmwdt_resume(void)
245{
246 clear_bit(VMWDT_OPEN, &vmwdt_is_open);
247 return NOTIFY_DONE;
248}
249
250/*
251 * It makes no sense to go into suspend while the watchdog is running.
252 * Depending on the memory size, the watchdog might trigger, while we
253 * are still saving the memory.
254 * We reuse the open flag to ensure that suspend and watchdog open are
255 * exclusive operations
256 */
257static int vmwdt_suspend(void)
258{
259 if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) {
260 pr_err("The system cannot be suspended while the watchdog"
261 " is in use\n");
262 return notifier_from_errno(-EBUSY);
263 }
264 if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) {
265 clear_bit(VMWDT_OPEN, &vmwdt_is_open);
266 pr_err("The system cannot be suspended while the watchdog"
267 " is running\n");
268 return notifier_from_errno(-EBUSY);
269 }
270 return NOTIFY_DONE;
271}
272
273/*
274 * This function is called for suspend and resume.
275 */
276static int vmwdt_power_event(struct notifier_block *this, unsigned long event,
277 void *ptr)
278{
279 switch (event) {
280 case PM_POST_HIBERNATION:
281 case PM_POST_SUSPEND:
282 return vmwdt_resume();
283 case PM_HIBERNATION_PREPARE:
284 case PM_SUSPEND_PREPARE:
285 return vmwdt_suspend();
286 default:
287 return NOTIFY_DONE;
288 }
289}
290
291static struct notifier_block vmwdt_power_notifier = {
292 .notifier_call = vmwdt_power_event,
293};
294
295static const struct file_operations vmwdt_fops = {
296 .open = &vmwdt_open,
297 .release = &vmwdt_close,
298 .unlocked_ioctl = &vmwdt_ioctl,
299 .write = &vmwdt_write,
300 .owner = THIS_MODULE,
301 .llseek = noop_llseek,
302};
303
304static struct miscdevice vmwdt_dev = {
305 .minor = WATCHDOG_MINOR,
306 .name = "watchdog",
307 .fops = &vmwdt_fops,
308};
309
310static int __init vmwdt_init(void)
311{
312 int ret;
313
314 ret = vmwdt_probe();
315 if (ret)
316 return ret;
317 ret = register_pm_notifier(&vmwdt_power_notifier);
318 if (ret)
319 return ret;
320 /*
321 * misc_register() has to be the last action in module_init(), because
322 * file operations will be available right after this.
323 */
324 ret = misc_register(&vmwdt_dev);
325 if (ret) {
326 unregister_pm_notifier(&vmwdt_power_notifier);
327 return ret;
328 }
329 return 0;
330}
331module_init(vmwdt_init);
332
333static void __exit vmwdt_exit(void)
334{
335 unregister_pm_notifier(&vmwdt_power_notifier);
336 misc_deregister(&vmwdt_dev);
337}
338module_exit(vmwdt_exit);
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c
index 445564c790f6..00bfbee0af9e 100644
--- a/drivers/s390/cio/airq.c
+++ b/drivers/s390/cio/airq.c
@@ -196,11 +196,11 @@ EXPORT_SYMBOL(airq_iv_release);
196 */ 196 */
197unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num) 197unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num)
198{ 198{
199 unsigned long bit, i; 199 unsigned long bit, i, flags;
200 200
201 if (!iv->avail || num == 0) 201 if (!iv->avail || num == 0)
202 return -1UL; 202 return -1UL;
203 spin_lock(&iv->lock); 203 spin_lock_irqsave(&iv->lock, flags);
204 bit = find_first_bit_inv(iv->avail, iv->bits); 204 bit = find_first_bit_inv(iv->avail, iv->bits);
205 while (bit + num <= iv->bits) { 205 while (bit + num <= iv->bits) {
206 for (i = 1; i < num; i++) 206 for (i = 1; i < num; i++)
@@ -218,9 +218,8 @@ unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num)
218 } 218 }
219 if (bit + num > iv->bits) 219 if (bit + num > iv->bits)
220 bit = -1UL; 220 bit = -1UL;
221 spin_unlock(&iv->lock); 221 spin_unlock_irqrestore(&iv->lock, flags);
222 return bit; 222 return bit;
223
224} 223}
225EXPORT_SYMBOL(airq_iv_alloc); 224EXPORT_SYMBOL(airq_iv_alloc);
226 225
@@ -232,11 +231,11 @@ EXPORT_SYMBOL(airq_iv_alloc);
232 */ 231 */
233void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num) 232void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num)
234{ 233{
235 unsigned long i; 234 unsigned long i, flags;
236 235
237 if (!iv->avail || num == 0) 236 if (!iv->avail || num == 0)
238 return; 237 return;
239 spin_lock(&iv->lock); 238 spin_lock_irqsave(&iv->lock, flags);
240 for (i = 0; i < num; i++) { 239 for (i = 0; i < num; i++) {
241 /* Clear (possibly left over) interrupt bit */ 240 /* Clear (possibly left over) interrupt bit */
242 clear_bit_inv(bit + i, iv->vector); 241 clear_bit_inv(bit + i, iv->vector);
@@ -248,7 +247,7 @@ void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num)
248 while (iv->end > 0 && !test_bit_inv(iv->end - 1, iv->avail)) 247 while (iv->end > 0 && !test_bit_inv(iv->end - 1, iv->avail))
249 iv->end--; 248 iv->end--;
250 } 249 }
251 spin_unlock(&iv->lock); 250 spin_unlock_irqrestore(&iv->lock, flags);
252} 251}
253EXPORT_SYMBOL(airq_iv_free); 252EXPORT_SYMBOL(airq_iv_free);
254 253
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index dfd7bc681c25..e443b0d0b236 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -184,7 +184,7 @@ static ssize_t ccwgroup_ungroup_store(struct device *dev,
184 const char *buf, size_t count) 184 const char *buf, size_t count)
185{ 185{
186 struct ccwgroup_device *gdev = to_ccwgroupdev(dev); 186 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
187 int rc; 187 int rc = 0;
188 188
189 /* Prevent concurrent online/offline processing and ungrouping. */ 189 /* Prevent concurrent online/offline processing and ungrouping. */
190 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0) 190 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
@@ -196,11 +196,12 @@ static ssize_t ccwgroup_ungroup_store(struct device *dev,
196 196
197 if (device_remove_file_self(dev, attr)) 197 if (device_remove_file_self(dev, attr))
198 ccwgroup_ungroup(gdev); 198 ccwgroup_ungroup(gdev);
199 else
200 rc = -ENODEV;
199out: 201out:
200 if (rc) { 202 if (rc) {
201 if (rc != -EAGAIN) 203 /* Release onoff "lock" when ungrouping failed. */
202 /* Release onoff "lock" when ungrouping failed. */ 204 atomic_set(&gdev->onoff, 0);
203 atomic_set(&gdev->onoff, 0);
204 return rc; 205 return rc;
205 } 206 }
206 return count; 207 return count;
@@ -227,6 +228,7 @@ static void ccwgroup_ungroup_workfn(struct work_struct *work)
227 container_of(work, struct ccwgroup_device, ungroup_work); 228 container_of(work, struct ccwgroup_device, ungroup_work);
228 229
229 ccwgroup_ungroup(gdev); 230 ccwgroup_ungroup(gdev);
231 put_device(&gdev->dev);
230} 232}
231 233
232static void ccwgroup_release(struct device *dev) 234static void ccwgroup_release(struct device *dev)
@@ -412,8 +414,10 @@ static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
412{ 414{
413 struct ccwgroup_device *gdev = to_ccwgroupdev(data); 415 struct ccwgroup_device *gdev = to_ccwgroupdev(data);
414 416
415 if (action == BUS_NOTIFY_UNBIND_DRIVER) 417 if (action == BUS_NOTIFY_UNBIND_DRIVER) {
418 get_device(&gdev->dev);
416 schedule_work(&gdev->ungroup_work); 419 schedule_work(&gdev->ungroup_work);
420 }
417 421
418 return NOTIFY_OK; 422 return NOTIFY_OK;
419} 423}
@@ -582,11 +586,7 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver)
582 __ccwgroup_match_all))) { 586 __ccwgroup_match_all))) {
583 struct ccwgroup_device *gdev = to_ccwgroupdev(dev); 587 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
584 588
585 mutex_lock(&gdev->reg_mutex); 589 ccwgroup_ungroup(gdev);
586 __ccwgroup_remove_symlinks(gdev);
587 device_unregister(dev);
588 __ccwgroup_remove_cdev_refs(gdev);
589 mutex_unlock(&gdev->reg_mutex);
590 put_device(dev); 590 put_device(dev);
591 } 591 }
592 driver_unregister(&cdriver->driver); 592 driver_unregister(&cdriver->driver);
@@ -633,13 +633,7 @@ void ccwgroup_remove_ccwdev(struct ccw_device *cdev)
633 get_device(&gdev->dev); 633 get_device(&gdev->dev);
634 spin_unlock_irq(cdev->ccwlock); 634 spin_unlock_irq(cdev->ccwlock);
635 /* Unregister group device. */ 635 /* Unregister group device. */
636 mutex_lock(&gdev->reg_mutex); 636 ccwgroup_ungroup(gdev);
637 if (device_is_registered(&gdev->dev)) {
638 __ccwgroup_remove_symlinks(gdev);
639 device_unregister(&gdev->dev);
640 __ccwgroup_remove_cdev_refs(gdev);
641 }
642 mutex_unlock(&gdev->reg_mutex);
643 /* Release ccwgroup device reference for local processing. */ 637 /* Release ccwgroup device reference for local processing. */
644 put_device(&gdev->dev); 638 put_device(&gdev->dev);
645} 639}
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 77f9c92df4b9..2905d8b0ec95 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -602,6 +602,7 @@ void __init init_cio_interrupts(void)
602 602
603#ifdef CONFIG_CCW_CONSOLE 603#ifdef CONFIG_CCW_CONSOLE
604static struct subchannel *console_sch; 604static struct subchannel *console_sch;
605static struct lock_class_key console_sch_key;
605 606
606/* 607/*
607 * Use cio_tsch to update the subchannel status and call the interrupt handler 608 * Use cio_tsch to update the subchannel status and call the interrupt handler
@@ -686,6 +687,7 @@ struct subchannel *cio_probe_console(void)
686 if (IS_ERR(sch)) 687 if (IS_ERR(sch))
687 return sch; 688 return sch;
688 689
690 lockdep_set_class(sch->lock, &console_sch_key);
689 isc_register(CONSOLE_ISC); 691 isc_register(CONSOLE_ISC);
690 sch->config.isc = CONSOLE_ISC; 692 sch->config.isc = CONSOLE_ISC;
691 sch->config.intparm = (u32)(addr_t)sch; 693 sch->config.intparm = (u32)(addr_t)sch;
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index d8d9b5b5cc56..dfef5e63cb7b 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -678,18 +678,11 @@ static const struct attribute_group *ccwdev_attr_groups[] = {
678 NULL, 678 NULL,
679}; 679};
680 680
681/* this is a simple abstraction for device_register that sets the 681static int ccw_device_add(struct ccw_device *cdev)
682 * correct bus type and adds the bus specific files */
683static int ccw_device_register(struct ccw_device *cdev)
684{ 682{
685 struct device *dev = &cdev->dev; 683 struct device *dev = &cdev->dev;
686 int ret;
687 684
688 dev->bus = &ccw_bus_type; 685 dev->bus = &ccw_bus_type;
689 ret = dev_set_name(&cdev->dev, "0.%x.%04x", cdev->private->dev_id.ssid,
690 cdev->private->dev_id.devno);
691 if (ret)
692 return ret;
693 return device_add(dev); 686 return device_add(dev);
694} 687}
695 688
@@ -764,22 +757,46 @@ static void ccw_device_todo(struct work_struct *work);
764static int io_subchannel_initialize_dev(struct subchannel *sch, 757static int io_subchannel_initialize_dev(struct subchannel *sch,
765 struct ccw_device *cdev) 758 struct ccw_device *cdev)
766{ 759{
767 cdev->private->cdev = cdev; 760 struct ccw_device_private *priv = cdev->private;
768 cdev->private->int_class = IRQIO_CIO; 761 int ret;
769 atomic_set(&cdev->private->onoff, 0); 762
763 priv->cdev = cdev;
764 priv->int_class = IRQIO_CIO;
765 priv->state = DEV_STATE_NOT_OPER;
766 priv->dev_id.devno = sch->schib.pmcw.dev;
767 priv->dev_id.ssid = sch->schid.ssid;
768 priv->schid = sch->schid;
769
770 INIT_WORK(&priv->todo_work, ccw_device_todo);
771 INIT_LIST_HEAD(&priv->cmb_list);
772 init_waitqueue_head(&priv->wait_q);
773 init_timer(&priv->timer);
774
775 atomic_set(&priv->onoff, 0);
776 cdev->ccwlock = sch->lock;
770 cdev->dev.parent = &sch->dev; 777 cdev->dev.parent = &sch->dev;
771 cdev->dev.release = ccw_device_release; 778 cdev->dev.release = ccw_device_release;
772 INIT_WORK(&cdev->private->todo_work, ccw_device_todo);
773 cdev->dev.groups = ccwdev_attr_groups; 779 cdev->dev.groups = ccwdev_attr_groups;
774 /* Do first half of device_register. */ 780 /* Do first half of device_register. */
775 device_initialize(&cdev->dev); 781 device_initialize(&cdev->dev);
782 ret = dev_set_name(&cdev->dev, "0.%x.%04x", cdev->private->dev_id.ssid,
783 cdev->private->dev_id.devno);
784 if (ret)
785 goto out_put;
776 if (!get_device(&sch->dev)) { 786 if (!get_device(&sch->dev)) {
777 /* Release reference from device_initialize(). */ 787 ret = -ENODEV;
778 put_device(&cdev->dev); 788 goto out_put;
779 return -ENODEV;
780 } 789 }
781 cdev->private->flags.initialized = 1; 790 priv->flags.initialized = 1;
791 spin_lock_irq(sch->lock);
792 sch_set_cdev(sch, cdev);
793 spin_unlock_irq(sch->lock);
782 return 0; 794 return 0;
795
796out_put:
797 /* Release reference from device_initialize(). */
798 put_device(&cdev->dev);
799 return ret;
783} 800}
784 801
785static struct ccw_device * io_subchannel_create_ccwdev(struct subchannel *sch) 802static struct ccw_device * io_subchannel_create_ccwdev(struct subchannel *sch)
@@ -858,7 +875,7 @@ static void io_subchannel_register(struct ccw_device *cdev)
858 dev_set_uevent_suppress(&sch->dev, 0); 875 dev_set_uevent_suppress(&sch->dev, 0);
859 kobject_uevent(&sch->dev.kobj, KOBJ_ADD); 876 kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
860 /* make it known to the system */ 877 /* make it known to the system */
861 ret = ccw_device_register(cdev); 878 ret = ccw_device_add(cdev);
862 if (ret) { 879 if (ret) {
863 CIO_MSG_EVENT(0, "Could not register ccw dev 0.%x.%04x: %d\n", 880 CIO_MSG_EVENT(0, "Could not register ccw dev 0.%x.%04x: %d\n",
864 cdev->private->dev_id.ssid, 881 cdev->private->dev_id.ssid,
@@ -923,26 +940,11 @@ io_subchannel_recog_done(struct ccw_device *cdev)
923 940
924static void io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) 941static void io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
925{ 942{
926 struct ccw_device_private *priv;
927
928 cdev->ccwlock = sch->lock;
929
930 /* Init private data. */
931 priv = cdev->private;
932 priv->dev_id.devno = sch->schib.pmcw.dev;
933 priv->dev_id.ssid = sch->schid.ssid;
934 priv->schid = sch->schid;
935 priv->state = DEV_STATE_NOT_OPER;
936 INIT_LIST_HEAD(&priv->cmb_list);
937 init_waitqueue_head(&priv->wait_q);
938 init_timer(&priv->timer);
939
940 /* Increase counter of devices currently in recognition. */ 943 /* Increase counter of devices currently in recognition. */
941 atomic_inc(&ccw_device_init_count); 944 atomic_inc(&ccw_device_init_count);
942 945
943 /* Start async. device sensing. */ 946 /* Start async. device sensing. */
944 spin_lock_irq(sch->lock); 947 spin_lock_irq(sch->lock);
945 sch_set_cdev(sch, cdev);
946 ccw_device_recognition(cdev); 948 ccw_device_recognition(cdev);
947 spin_unlock_irq(sch->lock); 949 spin_unlock_irq(sch->lock);
948} 950}
@@ -1083,7 +1085,7 @@ static int io_subchannel_probe(struct subchannel *sch)
1083 dev_set_uevent_suppress(&sch->dev, 0); 1085 dev_set_uevent_suppress(&sch->dev, 0);
1084 kobject_uevent(&sch->dev.kobj, KOBJ_ADD); 1086 kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
1085 cdev = sch_get_cdev(sch); 1087 cdev = sch_get_cdev(sch);
1086 rc = ccw_device_register(cdev); 1088 rc = ccw_device_add(cdev);
1087 if (rc) { 1089 if (rc) {
1088 /* Release online reference. */ 1090 /* Release online reference. */
1089 put_device(&cdev->dev); 1091 put_device(&cdev->dev);
@@ -1597,7 +1599,6 @@ int __init ccw_device_enable_console(struct ccw_device *cdev)
1597 if (rc) 1599 if (rc)
1598 return rc; 1600 return rc;
1599 sch->driver = &io_subchannel_driver; 1601 sch->driver = &io_subchannel_driver;
1600 sch_set_cdev(sch, cdev);
1601 io_subchannel_recog(cdev, sch); 1602 io_subchannel_recog(cdev, sch);
1602 /* Now wait for the async. recognition to come to an end. */ 1603 /* Now wait for the async. recognition to come to an end. */
1603 spin_lock_irq(cdev->ccwlock); 1604 spin_lock_irq(cdev->ccwlock);
@@ -1639,6 +1640,7 @@ struct ccw_device * __init ccw_device_create_console(struct ccw_driver *drv)
1639 put_device(&sch->dev); 1640 put_device(&sch->dev);
1640 return ERR_PTR(-ENOMEM); 1641 return ERR_PTR(-ENOMEM);
1641 } 1642 }
1643 set_io_private(sch, io_priv);
1642 cdev = io_subchannel_create_ccwdev(sch); 1644 cdev = io_subchannel_create_ccwdev(sch);
1643 if (IS_ERR(cdev)) { 1645 if (IS_ERR(cdev)) {
1644 put_device(&sch->dev); 1646 put_device(&sch->dev);
@@ -1646,7 +1648,6 @@ struct ccw_device * __init ccw_device_create_console(struct ccw_driver *drv)
1646 return cdev; 1648 return cdev;
1647 } 1649 }
1648 cdev->drv = drv; 1650 cdev->drv = drv;
1649 set_io_private(sch, io_priv);
1650 ccw_device_set_int_class(cdev); 1651 ccw_device_set_int_class(cdev);
1651 return cdev; 1652 return cdev;
1652} 1653}
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index 4221b02085ad..f1f3baa8e6e4 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -7,6 +7,7 @@
7#include <linux/debugfs.h> 7#include <linux/debugfs.h>
8#include <linux/uaccess.h> 8#include <linux/uaccess.h>
9#include <linux/export.h> 9#include <linux/export.h>
10#include <linux/slab.h>
10#include <asm/debug.h> 11#include <asm/debug.h>
11#include "qdio_debug.h" 12#include "qdio_debug.h"
12#include "qdio.h" 13#include "qdio.h"
@@ -16,11 +17,51 @@ debug_info_t *qdio_dbf_error;
16 17
17static struct dentry *debugfs_root; 18static struct dentry *debugfs_root;
18#define QDIO_DEBUGFS_NAME_LEN 10 19#define QDIO_DEBUGFS_NAME_LEN 10
20#define QDIO_DBF_NAME_LEN 20
19 21
20void qdio_allocate_dbf(struct qdio_initialize *init_data, 22struct qdio_dbf_entry {
23 char dbf_name[QDIO_DBF_NAME_LEN];
24 debug_info_t *dbf_info;
25 struct list_head dbf_list;
26};
27
28static LIST_HEAD(qdio_dbf_list);
29static DEFINE_MUTEX(qdio_dbf_list_mutex);
30
31static debug_info_t *qdio_get_dbf_entry(char *name)
32{
33 struct qdio_dbf_entry *entry;
34 debug_info_t *rc = NULL;
35
36 mutex_lock(&qdio_dbf_list_mutex);
37 list_for_each_entry(entry, &qdio_dbf_list, dbf_list) {
38 if (strcmp(entry->dbf_name, name) == 0) {
39 rc = entry->dbf_info;
40 break;
41 }
42 }
43 mutex_unlock(&qdio_dbf_list_mutex);
44 return rc;
45}
46
47static void qdio_clear_dbf_list(void)
48{
49 struct qdio_dbf_entry *entry, *tmp;
50
51 mutex_lock(&qdio_dbf_list_mutex);
52 list_for_each_entry_safe(entry, tmp, &qdio_dbf_list, dbf_list) {
53 list_del(&entry->dbf_list);
54 debug_unregister(entry->dbf_info);
55 kfree(entry);
56 }
57 mutex_unlock(&qdio_dbf_list_mutex);
58}
59
60int qdio_allocate_dbf(struct qdio_initialize *init_data,
21 struct qdio_irq *irq_ptr) 61 struct qdio_irq *irq_ptr)
22{ 62{
23 char text[20]; 63 char text[QDIO_DBF_NAME_LEN];
64 struct qdio_dbf_entry *new_entry;
24 65
25 DBF_EVENT("qfmt:%1d", init_data->q_format); 66 DBF_EVENT("qfmt:%1d", init_data->q_format);
26 DBF_HEX(init_data->adapter_name, 8); 67 DBF_HEX(init_data->adapter_name, 8);
@@ -38,11 +79,34 @@ void qdio_allocate_dbf(struct qdio_initialize *init_data,
38 DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr); 79 DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
39 80
40 /* allocate trace view for the interface */ 81 /* allocate trace view for the interface */
41 snprintf(text, 20, "qdio_%s", dev_name(&init_data->cdev->dev)); 82 snprintf(text, QDIO_DBF_NAME_LEN, "qdio_%s",
42 irq_ptr->debug_area = debug_register(text, 2, 1, 16); 83 dev_name(&init_data->cdev->dev));
43 debug_register_view(irq_ptr->debug_area, &debug_hex_ascii_view); 84 irq_ptr->debug_area = qdio_get_dbf_entry(text);
44 debug_set_level(irq_ptr->debug_area, DBF_WARN); 85 if (irq_ptr->debug_area)
45 DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created"); 86 DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf reused");
87 else {
88 irq_ptr->debug_area = debug_register(text, 2, 1, 16);
89 if (!irq_ptr->debug_area)
90 return -ENOMEM;
91 if (debug_register_view(irq_ptr->debug_area,
92 &debug_hex_ascii_view)) {
93 debug_unregister(irq_ptr->debug_area);
94 return -ENOMEM;
95 }
96 debug_set_level(irq_ptr->debug_area, DBF_WARN);
97 DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created");
98 new_entry = kzalloc(sizeof(struct qdio_dbf_entry), GFP_KERNEL);
99 if (!new_entry) {
100 debug_unregister(irq_ptr->debug_area);
101 return -ENOMEM;
102 }
103 strlcpy(new_entry->dbf_name, text, QDIO_DBF_NAME_LEN);
104 new_entry->dbf_info = irq_ptr->debug_area;
105 mutex_lock(&qdio_dbf_list_mutex);
106 list_add(&new_entry->dbf_list, &qdio_dbf_list);
107 mutex_unlock(&qdio_dbf_list_mutex);
108 }
109 return 0;
46} 110}
47 111
48static int qstat_show(struct seq_file *m, void *v) 112static int qstat_show(struct seq_file *m, void *v)
@@ -300,6 +364,7 @@ int __init qdio_debug_init(void)
300 364
301void qdio_debug_exit(void) 365void qdio_debug_exit(void)
302{ 366{
367 qdio_clear_dbf_list();
303 debugfs_remove(debugfs_root); 368 debugfs_remove(debugfs_root);
304 if (qdio_dbf_setup) 369 if (qdio_dbf_setup)
305 debug_unregister(qdio_dbf_setup); 370 debug_unregister(qdio_dbf_setup);
diff --git a/drivers/s390/cio/qdio_debug.h b/drivers/s390/cio/qdio_debug.h
index dfac9bfefea3..f33ce8577619 100644
--- a/drivers/s390/cio/qdio_debug.h
+++ b/drivers/s390/cio/qdio_debug.h
@@ -75,7 +75,7 @@ static inline void DBF_DEV_HEX(struct qdio_irq *dev, void *addr,
75 } 75 }
76} 76}
77 77
78void qdio_allocate_dbf(struct qdio_initialize *init_data, 78int qdio_allocate_dbf(struct qdio_initialize *init_data,
79 struct qdio_irq *irq_ptr); 79 struct qdio_irq *irq_ptr);
80void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, 80void qdio_setup_debug_entries(struct qdio_irq *irq_ptr,
81 struct ccw_device *cdev); 81 struct ccw_device *cdev);
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 77466c4faabb..848e3b64ea6e 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -409,17 +409,16 @@ static inline void qdio_stop_polling(struct qdio_q *q)
409 set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT); 409 set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
410} 410}
411 411
412static inline void account_sbals(struct qdio_q *q, int count) 412static inline void account_sbals(struct qdio_q *q, unsigned int count)
413{ 413{
414 int pos = 0; 414 int pos;
415 415
416 q->q_stats.nr_sbal_total += count; 416 q->q_stats.nr_sbal_total += count;
417 if (count == QDIO_MAX_BUFFERS_MASK) { 417 if (count == QDIO_MAX_BUFFERS_MASK) {
418 q->q_stats.nr_sbals[7]++; 418 q->q_stats.nr_sbals[7]++;
419 return; 419 return;
420 } 420 }
421 while (count >>= 1) 421 pos = ilog2(count);
422 pos++;
423 q->q_stats.nr_sbals[pos]++; 422 q->q_stats.nr_sbals[pos]++;
424} 423}
425 424
@@ -1234,12 +1233,10 @@ int qdio_free(struct ccw_device *cdev)
1234 return -ENODEV; 1233 return -ENODEV;
1235 1234
1236 DBF_EVENT("qfree:%4x", cdev->private->schid.sch_no); 1235 DBF_EVENT("qfree:%4x", cdev->private->schid.sch_no);
1236 DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf abandoned");
1237 mutex_lock(&irq_ptr->setup_mutex); 1237 mutex_lock(&irq_ptr->setup_mutex);
1238 1238
1239 if (irq_ptr->debug_area != NULL) { 1239 irq_ptr->debug_area = NULL;
1240 debug_unregister(irq_ptr->debug_area);
1241 irq_ptr->debug_area = NULL;
1242 }
1243 cdev->private->qdio_data = NULL; 1240 cdev->private->qdio_data = NULL;
1244 mutex_unlock(&irq_ptr->setup_mutex); 1241 mutex_unlock(&irq_ptr->setup_mutex);
1245 1242
@@ -1276,7 +1273,8 @@ int qdio_allocate(struct qdio_initialize *init_data)
1276 goto out_err; 1273 goto out_err;
1277 1274
1278 mutex_init(&irq_ptr->setup_mutex); 1275 mutex_init(&irq_ptr->setup_mutex);
1279 qdio_allocate_dbf(init_data, irq_ptr); 1276 if (qdio_allocate_dbf(init_data, irq_ptr))
1277 goto out_rel;
1280 1278
1281 /* 1279 /*
1282 * Allocate a page for the chsc calls in qdio_establish. 1280 * Allocate a page for the chsc calls in qdio_establish.
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 8eec1653c9cc..69ef4f8cfac8 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -77,12 +77,12 @@ MODULE_ALIAS("z90crypt");
77 * Module parameter 77 * Module parameter
78 */ 78 */
79int ap_domain_index = -1; /* Adjunct Processor Domain Index */ 79int ap_domain_index = -1; /* Adjunct Processor Domain Index */
80module_param_named(domain, ap_domain_index, int, 0000); 80module_param_named(domain, ap_domain_index, int, S_IRUSR|S_IRGRP);
81MODULE_PARM_DESC(domain, "domain index for ap devices"); 81MODULE_PARM_DESC(domain, "domain index for ap devices");
82EXPORT_SYMBOL(ap_domain_index); 82EXPORT_SYMBOL(ap_domain_index);
83 83
84static int ap_thread_flag = 0; 84static int ap_thread_flag = 0;
85module_param_named(poll_thread, ap_thread_flag, int, 0000); 85module_param_named(poll_thread, ap_thread_flag, int, S_IRUSR|S_IRGRP);
86MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off)."); 86MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off).");
87 87
88static struct device *ap_root_device = NULL; 88static struct device *ap_root_device = NULL;
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 5222ebe15705..0e18c5dcd91f 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -356,7 +356,7 @@ struct zcrypt_ops *zcrypt_msgtype_request(unsigned char *name, int variant)
356 356
357 zops = __ops_lookup(name, variant); 357 zops = __ops_lookup(name, variant);
358 if (!zops) { 358 if (!zops) {
359 request_module(name); 359 request_module("%s", name);
360 zops = __ops_lookup(name, variant); 360 zops = __ops_lookup(name, variant);
361 } 361 }
362 if ((!zops) || (!try_module_get(zops->owner))) 362 if ((!zops) || (!try_module_get(zops->owner)))
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index c845527b503a..76dd54122f76 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1280,14 +1280,17 @@ config WATCHDOG_RTAS
1280 1280
1281# S390 Architecture 1281# S390 Architecture
1282 1282
1283config ZVM_WATCHDOG 1283config DIAG288_WATCHDOG
1284 tristate "z/VM Watchdog Timer" 1284 tristate "System z diag288 Watchdog"
1285 depends on S390 1285 depends on S390
1286 select WATCHDOG_CORE
1286 help 1287 help
1287 IBM s/390 and zSeries machines running under z/VM 5.1 or later 1288 IBM s/390 and zSeries machines running under z/VM 5.1 or later
1288 provide a virtual watchdog timer to their guest that cause a 1289 provide a virtual watchdog timer to their guest that cause a
1289 user define Control Program command to be executed after a 1290 user define Control Program command to be executed after a
1290 timeout. 1291 timeout.
1292 LPAR provides a very similar interface. This driver handles
1293 both.
1291 1294
1292 To compile this driver as a module, choose M here. The module 1295 To compile this driver as a module, choose M here. The module
1293 will be called vmwatchdog. 1296 will be called vmwatchdog.
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 7b8a91ed20e7..468c3204c3b1 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -153,6 +153,7 @@ obj-$(CONFIG_MEN_A21_WDT) += mena21_wdt.o
153obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o 153obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
154 154
155# S390 Architecture 155# S390 Architecture
156obj-$(CONFIG_DIAG288_WATCHDOG) += diag288_wdt.o
156 157
157# SUPERH (sh + sh64) Architecture 158# SUPERH (sh + sh64) Architecture
158obj-$(CONFIG_SH_WDT) += shwdt.o 159obj-$(CONFIG_SH_WDT) += shwdt.o
diff --git a/drivers/watchdog/diag288_wdt.c b/drivers/watchdog/diag288_wdt.c
new file mode 100644
index 000000000000..429494b6c822
--- /dev/null
+++ b/drivers/watchdog/diag288_wdt.c
@@ -0,0 +1,316 @@
1/*
2 * Watchdog driver for z/VM and LPAR using the diag 288 interface.
3 *
4 * Under z/VM, expiration of the watchdog will send a "system restart" command
5 * to CP.
6 *
7 * The command can be altered using the module parameter "cmd". This is
8 * not recommended because it's only supported on z/VM but not whith LPAR.
9 *
10 * On LPAR, the watchdog will always trigger a system restart. the module
11 * paramter cmd is meaningless here.
12 *
13 *
14 * Copyright IBM Corp. 2004, 2013
15 * Author(s): Arnd Bergmann (arndb@de.ibm.com)
16 * Philipp Hachtmann (phacht@de.ibm.com)
17 *
18 */
19
20#define KMSG_COMPONENT "diag288_wdt"
21#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
22
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/slab.h>
28#include <linux/miscdevice.h>
29#include <linux/watchdog.h>
30#include <linux/suspend.h>
31#include <asm/ebcdic.h>
32#include <linux/io.h>
33#include <linux/uaccess.h>
34
35#define MAX_CMDLEN 240
36#define DEFAULT_CMD "SYSTEM RESTART"
37
38#define MIN_INTERVAL 15 /* Minimal time supported by diag88 */
39#define MAX_INTERVAL 3600 /* One hour should be enough - pure estimation */
40
41#define WDT_DEFAULT_TIMEOUT 30
42
43/* Function codes - init, change, cancel */
44#define WDT_FUNC_INIT 0
45#define WDT_FUNC_CHANGE 1
46#define WDT_FUNC_CANCEL 2
47#define WDT_FUNC_CONCEAL 0x80000000
48
49/* Action codes for LPAR watchdog */
50#define LPARWDT_RESTART 0
51
52static char wdt_cmd[MAX_CMDLEN] = DEFAULT_CMD;
53static bool conceal_on;
54static bool nowayout_info = WATCHDOG_NOWAYOUT;
55
56MODULE_LICENSE("GPL");
57MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
58MODULE_AUTHOR("Philipp Hachtmann <phacht@de.ibm.com>");
59
60MODULE_DESCRIPTION("System z diag288 Watchdog Timer");
61
62module_param_string(cmd, wdt_cmd, MAX_CMDLEN, 0644);
63MODULE_PARM_DESC(cmd, "CP command that is run when the watchdog triggers (z/VM only)");
64
65module_param_named(conceal, conceal_on, bool, 0644);
66MODULE_PARM_DESC(conceal, "Enable the CONCEAL CP option while the watchdog is active (z/VM only)");
67
68module_param_named(nowayout, nowayout_info, bool, 0444);
69MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default = CONFIG_WATCHDOG_NOWAYOUT)");
70
71MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
72MODULE_ALIAS("vmwatchdog");
73
74static int __diag288(unsigned int func, unsigned int timeout,
75 unsigned long action, unsigned int len)
76{
77 register unsigned long __func asm("2") = func;
78 register unsigned long __timeout asm("3") = timeout;
79 register unsigned long __action asm("4") = action;
80 register unsigned long __len asm("5") = len;
81 int err;
82
83 err = -EINVAL;
84 asm volatile(
85 " diag %1, %3, 0x288\n"
86 "0: la %0, 0\n"
87 "1:\n"
88 EX_TABLE(0b, 1b)
89 : "+d" (err) : "d"(__func), "d"(__timeout),
90 "d"(__action), "d"(__len) : "1", "cc");
91 return err;
92}
93
94static int __diag288_vm(unsigned int func, unsigned int timeout,
95 char *cmd, size_t len)
96{
97 return __diag288(func, timeout, virt_to_phys(cmd), len);
98}
99
100static int __diag288_lpar(unsigned int func, unsigned int timeout,
101 unsigned long action)
102{
103 return __diag288(func, timeout, action, 0);
104}
105
106static int wdt_start(struct watchdog_device *dev)
107{
108 char *ebc_cmd;
109 size_t len;
110 int ret;
111 unsigned int func;
112
113 ret = -ENODEV;
114
115 if (MACHINE_IS_VM) {
116 ebc_cmd = kmalloc(MAX_CMDLEN, GFP_KERNEL);
117 if (!ebc_cmd)
118 return -ENOMEM;
119 len = strlcpy(ebc_cmd, wdt_cmd, MAX_CMDLEN);
120 ASCEBC(ebc_cmd, MAX_CMDLEN);
121 EBC_TOUPPER(ebc_cmd, MAX_CMDLEN);
122
123 func = conceal_on ? (WDT_FUNC_INIT | WDT_FUNC_CONCEAL)
124 : WDT_FUNC_INIT;
125 ret = __diag288_vm(func, dev->timeout, ebc_cmd, len);
126 WARN_ON(ret != 0);
127 kfree(ebc_cmd);
128 }
129
130 if (MACHINE_IS_LPAR) {
131 ret = __diag288_lpar(WDT_FUNC_INIT,
132 dev->timeout, LPARWDT_RESTART);
133 }
134
135 if (ret) {
136 pr_err("The watchdog cannot be activated\n");
137 return ret;
138 }
139 pr_info("The watchdog was activated\n");
140 return 0;
141}
142
143static int wdt_stop(struct watchdog_device *dev)
144{
145 int ret;
146
147 ret = __diag288(WDT_FUNC_CANCEL, 0, 0, 0);
148 pr_info("The watchdog was deactivated\n");
149 return ret;
150}
151
152static int wdt_ping(struct watchdog_device *dev)
153{
154 char *ebc_cmd;
155 size_t len;
156 int ret;
157 unsigned int func;
158
159 ret = -ENODEV;
160
161 if (MACHINE_IS_VM) {
162 ebc_cmd = kmalloc(MAX_CMDLEN, GFP_KERNEL);
163 if (!ebc_cmd)
164 return -ENOMEM;
165 len = strlcpy(ebc_cmd, wdt_cmd, MAX_CMDLEN);
166 ASCEBC(ebc_cmd, MAX_CMDLEN);
167 EBC_TOUPPER(ebc_cmd, MAX_CMDLEN);
168
169 /*
170 * It seems to be ok to z/VM to use the init function to
171 * retrigger the watchdog. On LPAR WDT_FUNC_CHANGE must
172 * be used when the watchdog is running.
173 */
174 func = conceal_on ? (WDT_FUNC_INIT | WDT_FUNC_CONCEAL)
175 : WDT_FUNC_INIT;
176
177 ret = __diag288_vm(func, dev->timeout, ebc_cmd, len);
178 WARN_ON(ret != 0);
179 kfree(ebc_cmd);
180 }
181
182 if (MACHINE_IS_LPAR)
183 ret = __diag288_lpar(WDT_FUNC_CHANGE, dev->timeout, 0);
184
185 if (ret)
186 pr_err("The watchdog timer cannot be started or reset\n");
187 return ret;
188}
189
190static int wdt_set_timeout(struct watchdog_device * dev, unsigned int new_to)
191{
192 dev->timeout = new_to;
193 return wdt_ping(dev);
194}
195
196static struct watchdog_ops wdt_ops = {
197 .owner = THIS_MODULE,
198 .start = wdt_start,
199 .stop = wdt_stop,
200 .ping = wdt_ping,
201 .set_timeout = wdt_set_timeout,
202};
203
204static struct watchdog_info wdt_info = {
205 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
206 .firmware_version = 0,
207 .identity = "z Watchdog",
208};
209
210static struct watchdog_device wdt_dev = {
211 .parent = NULL,
212 .info = &wdt_info,
213 .ops = &wdt_ops,
214 .bootstatus = 0,
215 .timeout = WDT_DEFAULT_TIMEOUT,
216 .min_timeout = MIN_INTERVAL,
217 .max_timeout = MAX_INTERVAL,
218};
219
220/*
221 * It makes no sense to go into suspend while the watchdog is running.
222 * Depending on the memory size, the watchdog might trigger, while we
223 * are still saving the memory.
224 * We reuse the open flag to ensure that suspend and watchdog open are
225 * exclusive operations
226 */
227static int wdt_suspend(void)
228{
229 if (test_and_set_bit(WDOG_DEV_OPEN, &wdt_dev.status)) {
230 pr_err("Linux cannot be suspended while the watchdog is in use\n");
231 return notifier_from_errno(-EBUSY);
232 }
233 if (test_bit(WDOG_ACTIVE, &wdt_dev.status)) {
234 clear_bit(WDOG_DEV_OPEN, &wdt_dev.status);
235 pr_err("Linux cannot be suspended while the watchdog is in use\n");
236 return notifier_from_errno(-EBUSY);
237 }
238 return NOTIFY_DONE;
239}
240
241static int wdt_resume(void)
242{
243 clear_bit(WDOG_DEV_OPEN, &wdt_dev.status);
244 return NOTIFY_DONE;
245}
246
247static int wdt_power_event(struct notifier_block *this, unsigned long event,
248 void *ptr)
249{
250 switch (event) {
251 case PM_POST_HIBERNATION:
252 case PM_POST_SUSPEND:
253 return wdt_resume();
254 case PM_HIBERNATION_PREPARE:
255 case PM_SUSPEND_PREPARE:
256 return wdt_suspend();
257 default:
258 return NOTIFY_DONE;
259 }
260}
261
262static struct notifier_block wdt_power_notifier = {
263 .notifier_call = wdt_power_event,
264};
265
266static int __init diag288_init(void)
267{
268 int ret;
269 char ebc_begin[] = {
270 194, 197, 199, 201, 213
271 };
272
273 watchdog_set_nowayout(&wdt_dev, nowayout_info);
274
275 if (MACHINE_IS_VM) {
276 pr_info("The watchdog device driver detected a z/VM environment\n");
277 if (__diag288_vm(WDT_FUNC_INIT, 15,
278 ebc_begin, sizeof(ebc_begin)) != 0) {
279 pr_err("The watchdog cannot be initialized\n");
280 return -EINVAL;
281 }
282 } else if (MACHINE_IS_LPAR) {
283 pr_info("The watchdog device driver detected an LPAR environment\n");
284 if (__diag288_lpar(WDT_FUNC_INIT, 30, LPARWDT_RESTART)) {
285 pr_err("The watchdog cannot be initialized\n");
286 return -EINVAL;
287 }
288 } else {
289 pr_err("Linux runs in an environment that does not support the diag288 watchdog\n");
290 return -ENODEV;
291 }
292
293 if (__diag288_lpar(WDT_FUNC_CANCEL, 0, 0)) {
294 pr_err("The watchdog cannot be deactivated\n");
295 return -EINVAL;
296 }
297
298 ret = register_pm_notifier(&wdt_power_notifier);
299 if (ret)
300 return ret;
301
302 ret = watchdog_register_device(&wdt_dev);
303 if (ret)
304 unregister_pm_notifier(&wdt_power_notifier);
305
306 return ret;
307}
308
309static void __exit diag288_exit(void)
310{
311 watchdog_unregister_device(&wdt_dev);
312 unregister_pm_notifier(&wdt_power_notifier);
313}
314
315module_init(diag288_init);
316module_exit(diag288_exit);