summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-03 17:26:41 (GMT)
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-03 17:26:41 (GMT)
commit8f5759aeb88a47448cd92ab55a016d013b154a98 (patch)
treea9c0536e10300a95292b99332171837675af1e16 /drivers
parente5c4ecdc55b6d824365ba7964bcd3185223f9688 (diff)
parent63aef00b55d37e9fad837a8b38a2c261f0d32041 (diff)
downloadlinux-8f5759aeb88a47448cd92ab55a016d013b154a98.tar.xz
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux into next
Pull first set of s390 updates from Martin Schwidefsky: "The biggest change in this patchset is conversion from the bootmem bitmaps to the memblock code. This conversion requires two common code patches to introduce the 'physmem' memblock list. We experimented with ticket spinlocks but in the end decided against them as they perform poorly on virtualized systems. But the spinlock cleanup and some small improvements are included. The uaccess code got another optimization, the get_user/put_user calls are now inline again for kernel compiles targeted at z10 or newer machines. This makes the text segment shorter and the code gets a little bit faster. And as always some bug fixes" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (31 commits) s390/lowcore: replace lowcore irb array with a per-cpu variable s390/lowcore: reserve 96 bytes for IRB in lowcore s390/facilities: remove extract-cpu-time facility check s390: require mvcos facility for z10 and newer machines s390/boot: fix boot of compressed kernel built with gcc 4.9 s390/cio: remove weird assignment during argument evaluation s390/time: cast tv_nsec to u64 prior to shift in update_vsyscall s390/oprofile: make return of 0 explicit s390/spinlock: refactor arch_spin_lock_wait[_flags] s390/rwlock: add missing local_irq_restore calls s390/spinlock,rwlock: always to a load-and-test first s390/cio: fix multiple structure definitions s390/spinlock: fix system hang with spin_retry <= 0 s390/appldata: add slab.h for kzalloc/kfree s390/uaccess: provide inline variants of get_user/put_user s390/pci: add some new arch specific pci attributes s390/pci: use pdev->dev.groups for attribute creation s390/pci: use macro for attribute creation s390/pci: improve state check when processing hotplug events s390: split TIF bits into CIF, PIF and TIF bits ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/char/Makefile2
-rw-r--r--drivers/s390/char/zcore.c44
-rw-r--r--drivers/s390/cio/ccwreq.c4
-rw-r--r--drivers/s390/cio/chp.c2
-rw-r--r--drivers/s390/cio/chp.h2
-rw-r--r--drivers/s390/cio/chsc.h11
-rw-r--r--drivers/s390/cio/chsc_sch.c2
-rw-r--r--drivers/s390/cio/cio.c9
-rw-r--r--drivers/s390/cio/cio.h2
-rw-r--r--drivers/s390/cio/device_fsm.c4
-rw-r--r--drivers/s390/cio/device_ops.c13
-rw-r--r--drivers/s390/cio/eadm_sch.c2
-rw-r--r--drivers/s390/net/qeth_core_main.c12
13 files changed, 44 insertions, 65 deletions
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
index b69ab17..629fcc2 100644
--- a/drivers/s390/char/Makefile
+++ b/drivers/s390/char/Makefile
@@ -33,4 +33,4 @@ obj-$(CONFIG_MONWRITER) += monwriter.o
obj-$(CONFIG_S390_VMUR) += vmur.o
zcore_mod-objs := sclp_sdias.o zcore.o
-obj-$(CONFIG_ZFCPDUMP) += zcore_mod.o
+obj-$(CONFIG_CRASH_DUMP) += zcore_mod.o
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index 3d8e4d6..1884653 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -17,6 +17,8 @@
#include <linux/miscdevice.h>
#include <linux/debugfs.h>
#include <linux/module.h>
+#include <linux/memblock.h>
+
#include <asm/asm-offsets.h>
#include <asm/ipl.h>
#include <asm/sclp.h>
@@ -411,33 +413,24 @@ static ssize_t zcore_memmap_read(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
{
return simple_read_from_buffer(buf, count, ppos, filp->private_data,
- MEMORY_CHUNKS * CHUNK_INFO_SIZE);
+ memblock.memory.cnt * CHUNK_INFO_SIZE);
}
static int zcore_memmap_open(struct inode *inode, struct file *filp)
{
- int i;
+ struct memblock_region *reg;
char *buf;
- struct mem_chunk *chunk_array;
+ int i = 0;
- chunk_array = kzalloc(MEMORY_CHUNKS * sizeof(struct mem_chunk),
- GFP_KERNEL);
- if (!chunk_array)
- return -ENOMEM;
- detect_memory_layout(chunk_array, 0);
- buf = kzalloc(MEMORY_CHUNKS * CHUNK_INFO_SIZE, GFP_KERNEL);
+ buf = kzalloc(memblock.memory.cnt * CHUNK_INFO_SIZE, GFP_KERNEL);
if (!buf) {
- kfree(chunk_array);
return -ENOMEM;
}
- for (i = 0; i < MEMORY_CHUNKS; i++) {
- sprintf(buf + (i * CHUNK_INFO_SIZE), "%016llx %016llx ",
- (unsigned long long) chunk_array[i].addr,
- (unsigned long long) chunk_array[i].size);
- if (chunk_array[i].size == 0)
- break;
+ for_each_memblock(memory, reg) {
+ sprintf(buf + (i++ * CHUNK_INFO_SIZE), "%016llx %016llx ",
+ (unsigned long long) reg->base,
+ (unsigned long long) reg->size);
}
- kfree(chunk_array);
filp->private_data = buf;
return nonseekable_open(inode, filp);
}
@@ -593,21 +586,12 @@ static int __init check_sdias(void)
static int __init get_mem_info(unsigned long *mem, unsigned long *end)
{
- int i;
- struct mem_chunk *chunk_array;
+ struct memblock_region *reg;
- chunk_array = kzalloc(MEMORY_CHUNKS * sizeof(struct mem_chunk),
- GFP_KERNEL);
- if (!chunk_array)
- return -ENOMEM;
- detect_memory_layout(chunk_array, 0);
- for (i = 0; i < MEMORY_CHUNKS; i++) {
- if (chunk_array[i].size == 0)
- break;
- *mem += chunk_array[i].size;
- *end = max(*end, chunk_array[i].addr + chunk_array[i].size);
+ for_each_memblock(memory, reg) {
+ *mem += reg->size;
+ *end = max_t(unsigned long, *end, reg->base + reg->size);
}
- kfree(chunk_array);
return 0;
}
diff --git a/drivers/s390/cio/ccwreq.c b/drivers/s390/cio/ccwreq.c
index 5156264..07676c2 100644
--- a/drivers/s390/cio/ccwreq.c
+++ b/drivers/s390/cio/ccwreq.c
@@ -46,7 +46,7 @@ static u16 ccwreq_next_path(struct ccw_device *cdev)
goto out;
}
req->retries = req->maxretries;
- req->mask = lpm_adjust(req->mask >>= 1, req->lpm);
+ req->mask = lpm_adjust(req->mask >> 1, req->lpm);
out:
return req->mask;
}
@@ -252,7 +252,7 @@ static void ccwreq_log_status(struct ccw_device *cdev, enum io_status status)
*/
void ccw_request_handler(struct ccw_device *cdev)
{
- struct irb *irb = (struct irb *)&S390_lowcore.irb;
+ struct irb *irb = &__get_cpu_var(cio_irb);
struct ccw_request *req = &cdev->private->req;
enum io_status status;
int rc = -EOPNOTSUPP;
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 6c440d4..d497aa0 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -509,7 +509,7 @@ out:
* On success return a newly allocated copy of the channel-path description
* data associated with the given channel-path ID. Return %NULL on error.
*/
-void *chp_get_chp_desc(struct chp_id chpid)
+struct channel_path_desc *chp_get_chp_desc(struct chp_id chpid)
{
struct channel_path *chp;
struct channel_path_desc *desc;
diff --git a/drivers/s390/cio/chp.h b/drivers/s390/cio/chp.h
index 9284b78..4efd5b8 100644
--- a/drivers/s390/cio/chp.h
+++ b/drivers/s390/cio/chp.h
@@ -60,7 +60,7 @@ static inline struct channel_path *chpid_to_chp(struct chp_id chpid)
int chp_get_status(struct chp_id chpid);
u8 chp_get_sch_opm(struct subchannel *sch);
int chp_is_registered(struct chp_id chpid);
-void *chp_get_chp_desc(struct chp_id chpid);
+struct channel_path_desc *chp_get_chp_desc(struct chp_id chpid);
void chp_remove_cmg_attr(struct channel_path *chp);
int chp_add_cmg_attr(struct channel_path *chp);
int chp_update_desc(struct channel_path *chp);
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h
index 7e53a9c..76c9b50 100644
--- a/drivers/s390/cio/chsc.h
+++ b/drivers/s390/cio/chsc.h
@@ -21,17 +21,6 @@ struct cmg_entry {
u32 values[NR_MEASUREMENT_ENTRIES];
} __attribute__ ((packed));
-struct channel_path_desc {
- u8 flags;
- u8 lsn;
- u8 desc;
- u8 chpid;
- u8 swla;
- u8 zeroes;
- u8 chla;
- u8 chpp;
-} __attribute__ ((packed));
-
struct channel_path_desc_fmt1 {
u8 flags;
u8 lsn;
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index 1d3661a..3d22d2a 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -58,7 +58,7 @@ static void chsc_subchannel_irq(struct subchannel *sch)
{
struct chsc_private *private = dev_get_drvdata(&sch->dev);
struct chsc_request *request = private->request;
- struct irb *irb = (struct irb *)&S390_lowcore.irb;
+ struct irb *irb = &__get_cpu_var(cio_irb);
CHSC_LOG(4, "irb");
CHSC_LOG_HEX(4, irb, sizeof(*irb));
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 9e058c4..77f9c92d 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -46,6 +46,9 @@ debug_info_t *cio_debug_msg_id;
debug_info_t *cio_debug_trace_id;
debug_info_t *cio_debug_crw_id;
+DEFINE_PER_CPU_ALIGNED(struct irb, cio_irb);
+EXPORT_PER_CPU_SYMBOL(cio_irb);
+
/*
* Function: cio_debug_init
* Initializes three debug logs for common I/O:
@@ -560,7 +563,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy)
__this_cpu_write(s390_idle.nohz_delay, 1);
tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
- irb = (struct irb *) &S390_lowcore.irb;
+ irb = &__get_cpu_var(cio_irb);
sch = (struct subchannel *)(unsigned long) tpi_info->intparm;
if (!sch) {
/* Clear pending interrupt condition. */
@@ -609,7 +612,7 @@ void cio_tsch(struct subchannel *sch)
struct irb *irb;
int irq_context;
- irb = (struct irb *)&S390_lowcore.irb;
+ irb = &__get_cpu_var(cio_irb);
/* Store interrupt response block to lowcore. */
if (tsch(sch->schid, irb) != 0)
/* Not status pending or not operational. */
@@ -746,7 +749,7 @@ __clear_io_subchannel_easy(struct subchannel_id schid)
struct tpi_info ti;
if (tpi(&ti)) {
- tsch(ti.schid, (struct irb *)&S390_lowcore.irb);
+ tsch(ti.schid, &__get_cpu_var(cio_irb));
if (schid_equal(&ti.schid, &schid))
return 0;
}
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index d42f674..a01376a 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -102,6 +102,8 @@ struct subchannel {
struct schib_config config;
} __attribute__ ((aligned(8)));
+DECLARE_PER_CPU(struct irb, cio_irb);
+
#define to_subchannel(n) container_of(n, struct subchannel, dev)
extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id);
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index c7638c5..0bc902b 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -739,7 +739,7 @@ ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event)
struct irb *irb;
int is_cmd;
- irb = (struct irb *)&S390_lowcore.irb;
+ irb = &__get_cpu_var(cio_irb);
is_cmd = !scsw_is_tm(&irb->scsw);
/* Check for unsolicited interrupt. */
if (!scsw_is_solicited(&irb->scsw)) {
@@ -805,7 +805,7 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
{
struct irb *irb;
- irb = (struct irb *)&S390_lowcore.irb;
+ irb = &__get_cpu_var(cio_irb);
/* Check for unsolicited interrupt. */
if (scsw_stctl(&irb->scsw) ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 4845d64..f3c4179 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -563,14 +563,23 @@ out_unlock:
return rc;
}
-void *ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no)
+/**
+ * chp_get_chp_desc - return newly allocated channel-path descriptor
+ * @cdev: device to obtain the descriptor for
+ * @chp_idx: index of the channel path
+ *
+ * On success return a newly allocated copy of the channel-path description
+ * data associated with the given channel path. Return %NULL on error.
+ */
+struct channel_path_desc *ccw_device_get_chp_desc(struct ccw_device *cdev,
+ int chp_idx)
{
struct subchannel *sch;
struct chp_id chpid;
sch = to_subchannel(cdev->dev.parent);
chp_id_init(&chpid);
- chpid.id = sch->schib.pmcw.chpid[chp_no];
+ chpid.id = sch->schib.pmcw.chpid[chp_idx];
return chp_get_chp_desc(chpid);
}
diff --git a/drivers/s390/cio/eadm_sch.c b/drivers/s390/cio/eadm_sch.c
index 3a2ee4a..c4f7bf3 100644
--- a/drivers/s390/cio/eadm_sch.c
+++ b/drivers/s390/cio/eadm_sch.c
@@ -134,7 +134,7 @@ static void eadm_subchannel_irq(struct subchannel *sch)
{
struct eadm_private *private = get_eadm_private(sch);
struct eadm_scsw *scsw = &sch->schib.scsw.eadm;
- struct irb *irb = (struct irb *)&S390_lowcore.irb;
+ struct irb *irb = &__get_cpu_var(cio_irb);
int error = 0;
EADM_LOG(6, "irq");
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 22470a3..e89f38c 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -22,6 +22,7 @@
#include <net/iucv/af_iucv.h>
#include <asm/ebcdic.h>
+#include <asm/chpid.h>
#include <asm/io.h>
#include <asm/sysinfo.h>
#include <asm/compat.h>
@@ -1344,16 +1345,7 @@ static void qeth_set_multiple_write_queues(struct qeth_card *card)
static void qeth_update_from_chp_desc(struct qeth_card *card)
{
struct ccw_device *ccwdev;
- struct channelPath_dsc {
- u8 flags;
- u8 lsn;
- u8 desc;
- u8 chpid;
- u8 swla;
- u8 zeroes;
- u8 chla;
- u8 chpp;
- } *chp_dsc;
+ struct channel_path_desc *chp_dsc;
QETH_DBF_TEXT(SETUP, 2, "chp_desc");