mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-30 07:34:12 +08:00
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: [S390] define KTIME_SCALAR for 32-bit s390 [S390] add generic atomic64 support for 31 bit [S390] improve suspend/resume error messages [S390] set SCHED_OMIT_FRAME_POINTER for s390 [S390] add __ucmpdi2() helper function [S390] perf_counter build fix [S390] shutdown actions: save/return rc from init function [S390] dasd: correct debugfeature sense dump [S390] udelay: disable lockdep to avoid false positives [S390] monreader: fix dev_set_drvdata conversion [S390] sclp: fix compile error for !SCLP_CONSOLE
This commit is contained in:
commit
eee33abe59
@ -95,6 +95,11 @@ config S390
|
|||||||
select HAVE_ARCH_TRACEHOOK
|
select HAVE_ARCH_TRACEHOOK
|
||||||
select INIT_ALL_POSSIBLE
|
select INIT_ALL_POSSIBLE
|
||||||
select HAVE_PERF_COUNTERS
|
select HAVE_PERF_COUNTERS
|
||||||
|
select GENERIC_ATOMIC64 if !64BIT
|
||||||
|
|
||||||
|
config SCHED_OMIT_FRAME_POINTER
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
source "init/Kconfig"
|
source "init/Kconfig"
|
||||||
|
|
||||||
@ -116,6 +121,9 @@ config 32BIT
|
|||||||
bool
|
bool
|
||||||
default y if !64BIT
|
default y if !64BIT
|
||||||
|
|
||||||
|
config KTIME_SCALAR
|
||||||
|
def_bool 32BIT
|
||||||
|
|
||||||
config SMP
|
config SMP
|
||||||
bool "Symmetric multi-processing support"
|
bool "Symmetric multi-processing support"
|
||||||
---help---
|
---help---
|
||||||
|
@ -268,7 +268,12 @@ static __inline__ int atomic64_add_unless(atomic64_t *v,
|
|||||||
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
|
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
|
||||||
|
|
||||||
#undef __CSG_LOOP
|
#undef __CSG_LOOP
|
||||||
#endif
|
|
||||||
|
#else /* __s390x__ */
|
||||||
|
|
||||||
|
#include <asm-generic/atomic64.h>
|
||||||
|
|
||||||
|
#endif /* __s390x__ */
|
||||||
|
|
||||||
#define smp_mb__before_atomic_dec() smp_mb()
|
#define smp_mb__before_atomic_dec() smp_mb()
|
||||||
#define smp_mb__after_atomic_dec() smp_mb()
|
#define smp_mb__after_atomic_dec() smp_mb()
|
||||||
|
@ -6,3 +6,5 @@
|
|||||||
|
|
||||||
static inline void set_perf_counter_pending(void) {}
|
static inline void set_perf_counter_pending(void) {}
|
||||||
static inline void clear_perf_counter_pending(void) {}
|
static inline void clear_perf_counter_pending(void) {}
|
||||||
|
|
||||||
|
#define PERF_COUNTER_INDEX_OFFSET 0
|
||||||
|
@ -70,6 +70,7 @@ struct shutdown_action {
|
|||||||
char *name;
|
char *name;
|
||||||
void (*fn) (struct shutdown_trigger *trigger);
|
void (*fn) (struct shutdown_trigger *trigger);
|
||||||
int (*init) (void);
|
int (*init) (void);
|
||||||
|
int init_rc;
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *ipl_type_str(enum ipl_type type)
|
static char *ipl_type_str(enum ipl_type type)
|
||||||
@ -1486,11 +1487,13 @@ static int set_trigger(const char *buf, struct shutdown_trigger *trigger,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
|
for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
|
||||||
if (!shutdown_actions_list[i])
|
|
||||||
continue;
|
|
||||||
if (sysfs_streq(buf, shutdown_actions_list[i]->name)) {
|
if (sysfs_streq(buf, shutdown_actions_list[i]->name)) {
|
||||||
trigger->action = shutdown_actions_list[i];
|
if (shutdown_actions_list[i]->init_rc) {
|
||||||
return len;
|
return shutdown_actions_list[i]->init_rc;
|
||||||
|
} else {
|
||||||
|
trigger->action = shutdown_actions_list[i];
|
||||||
|
return len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -1640,8 +1643,8 @@ static void __init shutdown_actions_init(void)
|
|||||||
for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
|
for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
|
||||||
if (!shutdown_actions_list[i]->init)
|
if (!shutdown_actions_list[i]->init)
|
||||||
continue;
|
continue;
|
||||||
if (shutdown_actions_list[i]->init())
|
shutdown_actions_list[i]->init_rc =
|
||||||
shutdown_actions_list[i] = NULL;
|
shutdown_actions_list[i]->init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
|
lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
|
||||||
obj-$(CONFIG_32BIT) += div64.o qrnnd.o
|
obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o
|
||||||
lib-$(CONFIG_64BIT) += uaccess_mvcos.o
|
lib-$(CONFIG_64BIT) += uaccess_mvcos.o
|
||||||
lib-$(CONFIG_SMP) += spinlock.o
|
lib-$(CONFIG_SMP) += spinlock.o
|
||||||
|
@ -36,9 +36,11 @@ static void __udelay_disabled(unsigned long usecs)
|
|||||||
cr0 = (cr0_saved & 0xffff00e0) | 0x00000800;
|
cr0 = (cr0_saved & 0xffff00e0) | 0x00000800;
|
||||||
__ctl_load(cr0 , 0, 0);
|
__ctl_load(cr0 , 0, 0);
|
||||||
mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
|
mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
|
||||||
|
lockdep_off();
|
||||||
trace_hardirqs_on();
|
trace_hardirqs_on();
|
||||||
__load_psw_mask(mask);
|
__load_psw_mask(mask);
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
|
lockdep_on();
|
||||||
__ctl_load(cr0_saved, 0, 0);
|
__ctl_load(cr0_saved, 0, 0);
|
||||||
local_tick_enable(clock_saved);
|
local_tick_enable(clock_saved);
|
||||||
set_clock_comparator(S390_lowcore.clock_comparator);
|
set_clock_comparator(S390_lowcore.clock_comparator);
|
||||||
|
26
arch/s390/lib/ucmpdi2.c
Normal file
26
arch/s390/lib/ucmpdi2.c
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
union ull_union {
|
||||||
|
unsigned long long ull;
|
||||||
|
struct {
|
||||||
|
unsigned int high;
|
||||||
|
unsigned int low;
|
||||||
|
} ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
int __ucmpdi2(unsigned long long a, unsigned long long b)
|
||||||
|
{
|
||||||
|
union ull_union au = {.ull = a};
|
||||||
|
union ull_union bu = {.ull = b};
|
||||||
|
|
||||||
|
if (au.ui.high < bu.ui.high)
|
||||||
|
return 0;
|
||||||
|
else if (au.ui.high > bu.ui.high)
|
||||||
|
return 2;
|
||||||
|
if (au.ui.low < bu.ui.low)
|
||||||
|
return 0;
|
||||||
|
else if (au.ui.low > bu.ui.low)
|
||||||
|
return 2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__ucmpdi2);
|
@ -1696,8 +1696,7 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
|
|||||||
DBF_DEV_EVENT(DBF_ERR, device, "%s",
|
DBF_DEV_EVENT(DBF_ERR, device, "%s",
|
||||||
"unsolicited interrupt received "
|
"unsolicited interrupt received "
|
||||||
"(sense available)");
|
"(sense available)");
|
||||||
device->discipline->dump_sense_dbf(device, NULL, irb,
|
device->discipline->dump_sense_dbf(device, irb, "unsolicited");
|
||||||
"unsolicited");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dasd_schedule_device_bh(device);
|
dasd_schedule_device_bh(device);
|
||||||
@ -2941,42 +2940,20 @@ dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req,
|
dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct irb *irb,
|
||||||
struct irb *irb, char *reason)
|
char *reason)
|
||||||
{
|
{
|
||||||
u64 *sense;
|
u64 *sense;
|
||||||
int sl;
|
|
||||||
struct tsb *tsb;
|
|
||||||
|
|
||||||
sense = NULL;
|
sense = (u64 *) dasd_get_sense(irb);
|
||||||
tsb = NULL;
|
|
||||||
if (req && scsw_is_tm(&req->irb.scsw)) {
|
|
||||||
if (irb->scsw.tm.tcw)
|
|
||||||
tsb = tcw_get_tsb(
|
|
||||||
(struct tcw *)(unsigned long)irb->scsw.tm.tcw);
|
|
||||||
if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
|
|
||||||
switch (tsb->flags & 0x07) {
|
|
||||||
case 1: /* tsa_iostat */
|
|
||||||
sense = (u64 *)tsb->tsa.iostat.sense;
|
|
||||||
break;
|
|
||||||
case 2: /* ts_ddpc */
|
|
||||||
sense = (u64 *)tsb->tsa.ddpc.sense;
|
|
||||||
break;
|
|
||||||
case 3: /* tsa_intrg */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (irb->esw.esw0.erw.cons)
|
|
||||||
sense = (u64 *)irb->ecw;
|
|
||||||
}
|
|
||||||
if (sense) {
|
if (sense) {
|
||||||
for (sl = 0; sl < 4; sl++) {
|
DBF_DEV_EVENT(DBF_EMERG, device,
|
||||||
DBF_DEV_EVENT(DBF_EMERG, device,
|
"%s: %s %02x%02x%02x %016llx %016llx %016llx "
|
||||||
"%s: %016llx %016llx %016llx %016llx",
|
"%016llx", reason,
|
||||||
reason, sense[0], sense[1], sense[2],
|
scsw_is_tm(&irb->scsw) ? "t" : "c",
|
||||||
sense[3]);
|
scsw_cc(&irb->scsw), scsw_cstat(&irb->scsw),
|
||||||
}
|
scsw_dstat(&irb->scsw), sense[0], sense[1],
|
||||||
|
sense[2], sense[3]);
|
||||||
} else {
|
} else {
|
||||||
DBF_DEV_EVENT(DBF_EMERG, device, "%s",
|
DBF_DEV_EVENT(DBF_EMERG, device, "%s",
|
||||||
"SORRY - NO VALID SENSE AVAILABLE\n");
|
"SORRY - NO VALID SENSE AVAILABLE\n");
|
||||||
|
@ -172,7 +172,7 @@ dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb)
|
|||||||
device = cqr->startdev;
|
device = cqr->startdev;
|
||||||
/* dump sense data to s390 debugfeature*/
|
/* dump sense data to s390 debugfeature*/
|
||||||
if (device->discipline && device->discipline->dump_sense_dbf)
|
if (device->discipline && device->discipline->dump_sense_dbf)
|
||||||
device->discipline->dump_sense_dbf(device, cqr, irb, "log");
|
device->discipline->dump_sense_dbf(device, irb, "log");
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dasd_log_sense_dbf);
|
EXPORT_SYMBOL(dasd_log_sense_dbf);
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ static void dasd_fba_handle_unsolicited_interrupt(struct dasd_device *device,
|
|||||||
/* check for unsolicited interrupts */
|
/* check for unsolicited interrupts */
|
||||||
DBF_DEV_EVENT(DBF_WARNING, device, "%s",
|
DBF_DEV_EVENT(DBF_WARNING, device, "%s",
|
||||||
"unsolicited interrupt received");
|
"unsolicited interrupt received");
|
||||||
device->discipline->dump_sense_dbf(device, NULL, irb, "unsolicited");
|
device->discipline->dump_sense_dbf(device, irb, "unsolicited");
|
||||||
dasd_schedule_device_bh(device);
|
dasd_schedule_device_bh(device);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@ -444,17 +444,20 @@ dasd_fba_fill_info(struct dasd_device * device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dasd_fba_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req,
|
dasd_fba_dump_sense_dbf(struct dasd_device *device, struct irb *irb,
|
||||||
struct irb *irb, char *reason)
|
char *reason)
|
||||||
{
|
{
|
||||||
int sl;
|
u64 *sense;
|
||||||
if (irb->esw.esw0.erw.cons) {
|
|
||||||
for (sl = 0; sl < 4; sl++) {
|
sense = (u64 *) dasd_get_sense(irb);
|
||||||
DBF_DEV_EVENT(DBF_EMERG, device,
|
if (sense) {
|
||||||
"%s: %08x %08x %08x %08x",
|
DBF_DEV_EVENT(DBF_EMERG, device,
|
||||||
reason, irb->ecw[8 * 0], irb->ecw[8 * 1],
|
"%s: %s %02x%02x%02x %016llx %016llx %016llx "
|
||||||
irb->ecw[8 * 2], irb->ecw[8 * 3]);
|
"%016llx", reason,
|
||||||
}
|
scsw_is_tm(&irb->scsw) ? "t" : "c",
|
||||||
|
scsw_cc(&irb->scsw), scsw_cstat(&irb->scsw),
|
||||||
|
scsw_dstat(&irb->scsw), sense[0], sense[1],
|
||||||
|
sense[2], sense[3]);
|
||||||
} else {
|
} else {
|
||||||
DBF_DEV_EVENT(DBF_EMERG, device, "%s",
|
DBF_DEV_EVENT(DBF_EMERG, device, "%s",
|
||||||
"SORRY - NO VALID SENSE AVAILABLE\n");
|
"SORRY - NO VALID SENSE AVAILABLE\n");
|
||||||
|
@ -284,8 +284,7 @@ struct dasd_discipline {
|
|||||||
dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *);
|
dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *);
|
||||||
void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *,
|
void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *,
|
||||||
struct irb *);
|
struct irb *);
|
||||||
void (*dump_sense_dbf) (struct dasd_device *, struct dasd_ccw_req *,
|
void (*dump_sense_dbf) (struct dasd_device *, struct irb *, char *);
|
||||||
struct irb *, char *);
|
|
||||||
|
|
||||||
void (*handle_unsolicited_interrupt) (struct dasd_device *,
|
void (*handle_unsolicited_interrupt) (struct dasd_device *,
|
||||||
struct irb *);
|
struct irb *);
|
||||||
|
@ -964,7 +964,8 @@ static int dcssblk_freeze(struct device *dev)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (rc)
|
if (rc)
|
||||||
pr_err("Suspend failed because device %s is writeable.\n",
|
pr_err("Suspending the system failed because DCSS device %s "
|
||||||
|
"is writable\n",
|
||||||
dev_info->segment_name);
|
dev_info->segment_name);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -987,8 +988,8 @@ static int dcssblk_restore(struct device *dev)
|
|||||||
goto out_panic;
|
goto out_panic;
|
||||||
}
|
}
|
||||||
if (start != entry->start || end != entry->end) {
|
if (start != entry->start || end != entry->end) {
|
||||||
pr_err("Mismatch of start / end address after "
|
pr_err("The address range of DCSS %s changed "
|
||||||
"resuming device %s\n",
|
"while the system was suspended\n",
|
||||||
entry->segment_name);
|
entry->segment_name);
|
||||||
goto out_panic;
|
goto out_panic;
|
||||||
}
|
}
|
||||||
|
@ -443,7 +443,7 @@ fail:
|
|||||||
*/
|
*/
|
||||||
static void xpram_resume_error(const char *message)
|
static void xpram_resume_error(const char *message)
|
||||||
{
|
{
|
||||||
pr_err("Resume error: %s\n", message);
|
pr_err("Resuming the system failed: %s\n", message);
|
||||||
panic("xpram resume error\n");
|
panic("xpram resume error\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +320,7 @@ static int mon_open(struct inode *inode, struct file *filp)
|
|||||||
goto out_path;
|
goto out_path;
|
||||||
}
|
}
|
||||||
filp->private_data = monpriv;
|
filp->private_data = monpriv;
|
||||||
dev_set_drvdata(&monreader_device, monpriv);
|
dev_set_drvdata(monreader_device, monpriv);
|
||||||
unlock_kernel();
|
unlock_kernel();
|
||||||
return nonseekable_open(inode, filp);
|
return nonseekable_open(inode, filp);
|
||||||
|
|
||||||
@ -463,7 +463,7 @@ static struct miscdevice mon_dev = {
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static int monreader_freeze(struct device *dev)
|
static int monreader_freeze(struct device *dev)
|
||||||
{
|
{
|
||||||
struct mon_private *monpriv = dev_get_drvdata(&dev);
|
struct mon_private *monpriv = dev_get_drvdata(dev);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!monpriv)
|
if (!monpriv)
|
||||||
|
@ -92,5 +92,10 @@ void sclp_set_columns(struct sclp_buffer *, unsigned short);
|
|||||||
void sclp_set_htab(struct sclp_buffer *, unsigned short);
|
void sclp_set_htab(struct sclp_buffer *, unsigned short);
|
||||||
int sclp_chars_in_buffer(struct sclp_buffer *);
|
int sclp_chars_in_buffer(struct sclp_buffer *);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCLP_CONSOLE
|
||||||
void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event);
|
void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event);
|
||||||
|
#else
|
||||||
|
static inline void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __SCLP_RW_H__ */
|
#endif /* __SCLP_RW_H__ */
|
||||||
|
@ -250,14 +250,14 @@ static int vmwdt_resume(void)
|
|||||||
static int vmwdt_suspend(void)
|
static int vmwdt_suspend(void)
|
||||||
{
|
{
|
||||||
if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) {
|
if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) {
|
||||||
pr_err("The watchdog is in use. "
|
pr_err("The system cannot be suspended while the watchdog"
|
||||||
"This prevents hibernation or suspend.\n");
|
" is in use\n");
|
||||||
return NOTIFY_BAD;
|
return NOTIFY_BAD;
|
||||||
}
|
}
|
||||||
if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) {
|
if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) {
|
||||||
clear_bit(VMWDT_OPEN, &vmwdt_is_open);
|
clear_bit(VMWDT_OPEN, &vmwdt_is_open);
|
||||||
pr_err("The watchdog is running. "
|
pr_err("The system cannot be suspended while the watchdog"
|
||||||
"This prevents hibernation or suspend.\n");
|
" is running\n");
|
||||||
return NOTIFY_BAD;
|
return NOTIFY_BAD;
|
||||||
}
|
}
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
Loading…
Reference in New Issue
Block a user