summaryrefslogtreecommitdiff
path: root/drivers/s390/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-20 21:23:31 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-20 21:23:31 +0400
commitf479c01c8e81096e01eb20cec67dbaebae669aee (patch)
tree951890b22992aa6366b55308cdc05b1568cb8622 /drivers/s390/char
parentd8ec26d7f8287f5788a494f56e8814210f0e64be (diff)
parentf85168e4d96b31b09ecf09a679820b031224e69e (diff)
downloadlinux-f479c01c8e81096e01eb20cec67dbaebae669aee.tar.xz
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: "The bulk of the s390 updates for v3.14. New features are the perf support for the CPU-Measurement Sample Facility and the EP11 support for the crypto cards. And the normal cleanups and bug-fixes" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (44 commits) s390/cpum_sf: fix printk format warnings s390: Fix misspellings using 'codespell' tool s390/qdio: bridgeport support - CHSC part s390: delete new instances of __cpuinit usage s390/compat: fix PSW32_USER_BITS definition s390/zcrypt: add support for EP11 coprocessor cards s390/mm: optimize randomize_et_dyn for !PF_RANDOMIZE s390: use IS_ENABLED to check if a CONFIG is set to y or m s390/cio: use device_lock to synchronize calls to the ccwgroup driver s390/cio: use device_lock to synchronize calls to the ccw driver s390/cio: fix unlocked access of online member s390/cpum_sf: Add flag to process full SDBs only s390/cpum_sf: Add raw data sampling to support the diagnostic-sampling function s390/cpum_sf: Filter perf events based event->attr.exclude_* settings s390/cpum_sf: Detect KVM guest samples s390/cpum_sf: Add helper to read TOD from trailer entries s390/cpum_sf: Atomically reset trailer entry fields of sample-data-blocks s390/cpum_sf: Dynamically extend the sampling buffer if overflows occur s390/pci: reenable per default s390/pci/dma: fix accounting of allocated_pages ...
Diffstat (limited to 'drivers/s390/char')
-rw-r--r--drivers/s390/char/sclp.h1
-rw-r--r--drivers/s390/char/sclp_cmd.c2
-rw-r--r--drivers/s390/char/sclp_early.c125
-rw-r--r--drivers/s390/char/tty3270.c7
4 files changed, 65 insertions, 70 deletions
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index 6fbe09686d18..fea76aed9eea 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -183,7 +183,6 @@ extern unsigned long sclp_console_full;
extern u8 sclp_fac84;
extern unsigned long long sclp_rzm;
extern unsigned long long sclp_rnmax;
-extern __initdata int sclp_early_read_info_sccb_valid;
/* useful inlines */
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index eaa21d542c5c..cb3c4e05a385 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -455,8 +455,6 @@ static int __init sclp_detect_standby_memory(void)
if (OLDMEM_BASE) /* No standby memory in kdump mode */
return 0;
- if (!sclp_early_read_info_sccb_valid)
- return 0;
if ((sclp_facilities & 0xe00000000000ULL) != 0xe00000000000ULL)
return 0;
rc = -ENOMEM;
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c
index 1465e9563101..82f2c389b4d1 100644
--- a/drivers/s390/char/sclp_early.c
+++ b/drivers/s390/char/sclp_early.c
@@ -35,11 +35,12 @@ struct read_info_sccb {
u8 _reserved5[4096 - 112]; /* 112-4095 */
} __packed __aligned(PAGE_SIZE);
-static __initdata struct read_info_sccb early_read_info_sccb;
-static __initdata char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE);
+static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata;
+static unsigned int sclp_con_has_vt220 __initdata;
+static unsigned int sclp_con_has_linemode __initdata;
static unsigned long sclp_hsa_size;
+static struct sclp_ipl_info sclp_ipl_info;
-__initdata int sclp_early_read_info_sccb_valid;
u64 sclp_facilities;
u8 sclp_fac84;
unsigned long long sclp_rzm;
@@ -63,15 +64,12 @@ out:
return rc;
}
-static void __init sclp_read_info_early(void)
+static int __init sclp_read_info_early(struct read_info_sccb *sccb)
{
- int rc;
- int i;
- struct read_info_sccb *sccb;
+ int rc, i;
sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED,
SCLP_CMDW_READ_SCP_INFO};
- sccb = &early_read_info_sccb;
for (i = 0; i < ARRAY_SIZE(commands); i++) {
do {
memset(sccb, 0, sizeof(*sccb));
@@ -83,24 +81,19 @@ static void __init sclp_read_info_early(void)
if (rc)
break;
- if (sccb->header.response_code == 0x10) {
- sclp_early_read_info_sccb_valid = 1;
- break;
- }
+ if (sccb->header.response_code == 0x10)
+ return 0;
if (sccb->header.response_code != 0x1f0)
break;
}
+ return -EIO;
}
-static void __init sclp_facilities_detect(void)
+static void __init sclp_facilities_detect(struct read_info_sccb *sccb)
{
- struct read_info_sccb *sccb;
-
- sclp_read_info_early();
- if (!sclp_early_read_info_sccb_valid)
+ if (sclp_read_info_early(sccb))
return;
- sccb = &early_read_info_sccb;
sclp_facilities = sccb->facilities;
sclp_fac84 = sccb->fac84;
if (sccb->fac85 & 0x02)
@@ -108,30 +101,22 @@ static void __init sclp_facilities_detect(void)
sclp_rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
sclp_rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
sclp_rzm <<= 20;
+
+ /* Save IPL information */
+ sclp_ipl_info.is_valid = 1;
+ if (sccb->flags & 0x2)
+ sclp_ipl_info.has_dump = 1;
+ memcpy(&sclp_ipl_info.loadparm, &sccb->loadparm, LOADPARM_LEN);
}
bool __init sclp_has_linemode(void)
{
- struct init_sccb *sccb = (void *) &sccb_early;
-
- if (sccb->header.response_code != 0x20)
- return 0;
- if (!(sccb->sclp_send_mask & (EVTYP_OPCMD_MASK | EVTYP_PMSGCMD_MASK)))
- return 0;
- if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)))
- return 0;
- return 1;
+ return !!sclp_con_has_linemode;
}
bool __init sclp_has_vt220(void)
{
- struct init_sccb *sccb = (void *) &sccb_early;
-
- if (sccb->header.response_code != 0x20)
- return 0;
- if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK)
- return 1;
- return 0;
+ return !!sclp_con_has_vt220;
}
unsigned long long sclp_get_rnmax(void)
@@ -146,19 +131,12 @@ unsigned long long sclp_get_rzm(void)
/*
* This function will be called after sclp_facilities_detect(), which gets
- * called from early.c code. Therefore the sccb should have valid contents.
+ * called from early.c code. The sclp_facilities_detect() function retrieves
+ * and saves the IPL information.
*/
void __init sclp_get_ipl_info(struct sclp_ipl_info *info)
{
- struct read_info_sccb *sccb;
-
- if (!sclp_early_read_info_sccb_valid)
- return;
- sccb = &early_read_info_sccb;
- info->is_valid = 1;
- if (sccb->flags & 0x2)
- info->has_dump = 1;
- memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN);
+ *info = sclp_ipl_info;
}
static int __init sclp_cmd_early(sclp_cmdw_t cmd, void *sccb)
@@ -189,11 +167,10 @@ static void __init sccb_init_eq_size(struct sdias_sccb *sccb)
sccb->evbuf.dbs = 1;
}
-static int __init sclp_set_event_mask(unsigned long receive_mask,
+static int __init sclp_set_event_mask(struct init_sccb *sccb,
+ unsigned long receive_mask,
unsigned long send_mask)
{
- struct init_sccb *sccb = (void *) &sccb_early;
-
memset(sccb, 0, sizeof(*sccb));
sccb->header.length = sizeof(*sccb);
sccb->mask_length = sizeof(sccb_mask_t);
@@ -202,10 +179,8 @@ static int __init sclp_set_event_mask(unsigned long receive_mask,
return sclp_cmd_early(SCLP_CMDW_WRITE_EVENT_MASK, sccb);
}
-static long __init sclp_hsa_size_init(void)
+static long __init sclp_hsa_size_init(struct sdias_sccb *sccb)
{
- struct sdias_sccb *sccb = (void *) &sccb_early;
-
sccb_init_eq_size(sccb);
if (sclp_cmd_early(SCLP_CMDW_WRITE_EVENT_DATA, sccb))
return -EIO;
@@ -214,10 +189,8 @@ static long __init sclp_hsa_size_init(void)
return 0;
}
-static long __init sclp_hsa_copy_wait(void)
+static long __init sclp_hsa_copy_wait(struct sccb_header *sccb)
{
- struct sccb_header *sccb = (void *) &sccb_early;
-
memset(sccb, 0, PAGE_SIZE);
sccb->length = PAGE_SIZE;
if (sclp_cmd_early(SCLP_CMDW_READ_EVENT_DATA, sccb))
@@ -230,34 +203,62 @@ unsigned long sclp_get_hsa_size(void)
return sclp_hsa_size;
}
-static void __init sclp_hsa_size_detect(void)
+static void __init sclp_hsa_size_detect(void *sccb)
{
long size;
/* First try synchronous interface (LPAR) */
- if (sclp_set_event_mask(0, 0x40000010))
+ if (sclp_set_event_mask(sccb, 0, 0x40000010))
return;
- size = sclp_hsa_size_init();
+ size = sclp_hsa_size_init(sccb);
if (size < 0)
return;
if (size != 0)
goto out;
/* Then try asynchronous interface (z/VM) */
- if (sclp_set_event_mask(0x00000010, 0x40000010))
+ if (sclp_set_event_mask(sccb, 0x00000010, 0x40000010))
return;
- size = sclp_hsa_size_init();
+ size = sclp_hsa_size_init(sccb);
if (size < 0)
return;
- size = sclp_hsa_copy_wait();
+ size = sclp_hsa_copy_wait(sccb);
if (size < 0)
return;
out:
sclp_hsa_size = size;
}
+static unsigned int __init sclp_con_check_linemode(struct init_sccb *sccb)
+{
+ if (!(sccb->sclp_send_mask & (EVTYP_OPCMD_MASK | EVTYP_PMSGCMD_MASK)))
+ return 0;
+ if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)))
+ return 0;
+ return 1;
+}
+
+static void __init sclp_console_detect(struct init_sccb *sccb)
+{
+ if (sccb->header.response_code != 0x20)
+ return;
+
+ if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK)
+ sclp_con_has_vt220 = 1;
+
+ if (sclp_con_check_linemode(sccb))
+ sclp_con_has_linemode = 1;
+}
+
void __init sclp_early_detect(void)
{
- sclp_facilities_detect();
- sclp_hsa_size_detect();
- sclp_set_event_mask(0, 0);
+ void *sccb = &sccb_early;
+
+ sclp_facilities_detect(sccb);
+ sclp_hsa_size_detect(sccb);
+
+ /* Turn off SCLP event notifications. Also save remote masks in the
+ * sccb. These are sufficient to detect sclp console capabilities.
+ */
+ sclp_set_event_mask(sccb, 0, 0);
+ sclp_console_detect(sccb);
}
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 34629ea913d4..e91b89dc6d1f 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -125,10 +125,7 @@ static void tty3270_resize_work(struct work_struct *work);
*/
static void tty3270_set_timer(struct tty3270 *tp, int expires)
{
- if (expires == 0)
- del_timer(&tp->timer);
- else
- mod_timer(&tp->timer, jiffies + expires);
+ mod_timer(&tp->timer, jiffies + expires);
}
/*
@@ -744,7 +741,6 @@ tty3270_free_view(struct tty3270 *tp)
{
int pages;
- del_timer_sync(&tp->timer);
kbd_free(tp->kbd);
raw3270_request_free(tp->kreset);
raw3270_request_free(tp->read);
@@ -877,6 +873,7 @@ tty3270_free(struct raw3270_view *view)
{
struct tty3270 *tp = container_of(view, struct tty3270, view);
+ del_timer_sync(&tp->timer);
tty3270_free_screen(tp->screen, tp->view.rows);
tty3270_free_view(tp);
}