aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-21 12:47:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-21 12:47:01 -0400
commit7a8e9c80889732891df50d44328f330316834eb1 (patch)
tree69796bb89360fbd90fb72724b00b4f803569619b
parentf1b35b83054cf2b581befd48d32517fadf0d9b16 (diff)
parentfa73eb4738fc75317a481aa95cd472d0d6d057c3 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 patches from Martin Schwidefsky: "A couple of bug fixes, a debug change for qdio, an update for the default config, and one small extension. The watchdog module based on diagnose 0x288 is converted to the watchdog API and it now works under LPAR as well" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/ccwgroup: use ccwgroup_ungroup wrapper s390/ccwgroup: fix an uninitialized return code s390/ccwgroup: obtain extra reference for asynchronous processing qdio: Keep device-specific dbf entries s390/compat: correct ucontext layout for high gprs s390/cio: set device name as early as possible s390: update default configuration s390: avoid format strings leaking into names s390/airq: silence lockdep warning s390/watchdog: add support for LPAR operation (diag288) s390/watchdog: use watchdog API s390/sclp_vt220: Enable ASCII console per default s390/qdio: replace shift loop by ilog2 s390/cio: silence lockdep warning s390/uaccess: always load the kernel ASCE after task switch s390/ap_bus: Make modules parameters visible in sysfs
-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);