aboutsummaryrefslogtreecommitdiff
path: root/arch/s390/oprofile/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/oprofile/init.c')
-rw-r--r--arch/s390/oprofile/init.c75
1 files changed, 45 insertions, 30 deletions
diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c
index 2297be406c6..9ffe645d598 100644
--- a/arch/s390/oprofile/init.c
+++ b/arch/s390/oprofile/init.c
@@ -1,8 +1,6 @@
-/**
- * arch/s390/oprofile/init.c
- *
+/*
* S390 Version
- * Copyright (C) 2002-2011 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Copyright IBM Corp. 2002, 2011
* Author(s): Thomas Spatzier (tspat@de.ibm.com)
* Author(s): Mahesh Salgaonkar (mahesh@linux.vnet.ibm.com)
* Author(s): Heinz Graalfs (graalfs@linux.vnet.ibm.com)
@@ -12,6 +10,7 @@
*/
#include <linux/oprofile.h>
+#include <linux/perf_event.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/fs.h>
@@ -69,6 +68,21 @@ module_param_call(cpu_type, set_cpu_type, NULL, NULL, 0);
MODULE_PARM_DESC(cpu_type, "Force legacy basic mode sampling"
"(report cpu_type \"timer\"");
+static int __oprofile_hwsampler_start(void)
+{
+ int retval;
+
+ retval = hwsampler_allocate(oprofile_sdbt_blocks, oprofile_sdb_blocks);
+ if (retval)
+ return retval;
+
+ retval = hwsampler_start_all(oprofile_hw_interval);
+ if (retval)
+ hwsampler_deallocate();
+
+ return retval;
+}
+
static int oprofile_hwsampler_start(void)
{
int retval;
@@ -78,13 +92,13 @@ static int oprofile_hwsampler_start(void)
if (!hwsampler_running)
return timer_ops.start();
- retval = hwsampler_allocate(oprofile_sdbt_blocks, oprofile_sdb_blocks);
+ retval = perf_reserve_sampling();
if (retval)
return retval;
- retval = hwsampler_start_all(oprofile_hw_interval);
+ retval = __oprofile_hwsampler_start();
if (retval)
- hwsampler_deallocate();
+ perf_release_sampling();
return retval;
}
@@ -98,6 +112,7 @@ static void oprofile_hwsampler_stop(void)
hwsampler_stop_all();
hwsampler_deallocate();
+ perf_release_sampling();
return;
}
@@ -171,7 +186,7 @@ static ssize_t hw_interval_write(struct file *file, char const __user *buf,
if (*offset)
return -EINVAL;
retval = oprofilefs_ulong_from_user(&val, buf, count);
- if (retval)
+ if (retval <= 0)
return retval;
if (val < oprofile_min_interval)
oprofile_hw_interval = oprofile_min_interval;
@@ -214,7 +229,7 @@ static ssize_t hwsampler_zero_write(struct file *file, char const __user *buf,
return -EINVAL;
retval = oprofilefs_ulong_from_user(&val, buf, count);
- if (retval)
+ if (retval <= 0)
return retval;
if (val != 0)
return -EINVAL;
@@ -245,7 +260,7 @@ static ssize_t hwsampler_kernel_write(struct file *file, char const __user *buf,
return -EINVAL;
retval = oprofilefs_ulong_from_user(&val, buf, count);
- if (retval)
+ if (retval <= 0)
return retval;
if (val != 0 && val != 1)
@@ -280,7 +295,7 @@ static ssize_t hwsampler_user_write(struct file *file, char const __user *buf,
return -EINVAL;
retval = oprofilefs_ulong_from_user(&val, buf, count);
- if (retval)
+ if (retval <= 0)
return retval;
if (val != 0 && val != 1)
@@ -319,7 +334,7 @@ static ssize_t timer_enabled_write(struct file *file, char const __user *buf,
return -EINVAL;
retval = oprofilefs_ulong_from_user(&val, buf, count);
- if (retval)
+ if (retval <= 0)
return retval;
if (val != 0 && val != 1)
@@ -348,16 +363,15 @@ static const struct file_operations timer_enabled_fops = {
};
-static int oprofile_create_hwsampling_files(struct super_block *sb,
- struct dentry *root)
+static int oprofile_create_hwsampling_files(struct dentry *root)
{
struct dentry *dir;
- dir = oprofilefs_mkdir(sb, root, "timer");
+ dir = oprofilefs_mkdir(root, "timer");
if (!dir)
return -EINVAL;
- oprofilefs_create_file(sb, dir, "enabled", &timer_enabled_fops);
+ oprofilefs_create_file(dir, "enabled", &timer_enabled_fops);
if (!hwsampler_available)
return 0;
@@ -378,17 +392,17 @@ static int oprofile_create_hwsampling_files(struct super_block *sb,
* and can only be set to 0.
*/
- dir = oprofilefs_mkdir(sb, root, "0");
+ dir = oprofilefs_mkdir(root, "0");
if (!dir)
return -EINVAL;
- oprofilefs_create_file(sb, dir, "enabled", &hwsampler_fops);
- oprofilefs_create_file(sb, dir, "event", &zero_fops);
- oprofilefs_create_file(sb, dir, "count", &hw_interval_fops);
- oprofilefs_create_file(sb, dir, "unit_mask", &zero_fops);
- oprofilefs_create_file(sb, dir, "kernel", &kernel_fops);
- oprofilefs_create_file(sb, dir, "user", &user_fops);
- oprofilefs_create_ulong(sb, dir, "hw_sdbt_blocks",
+ oprofilefs_create_file(dir, "enabled", &hwsampler_fops);
+ oprofilefs_create_file(dir, "event", &zero_fops);
+ oprofilefs_create_file(dir, "count", &hw_interval_fops);
+ oprofilefs_create_file(dir, "unit_mask", &zero_fops);
+ oprofilefs_create_file(dir, "kernel", &kernel_fops);
+ oprofilefs_create_file(dir, "user", &user_fops);
+ oprofilefs_create_ulong(dir, "hw_sdbt_blocks",
&oprofile_sdbt_blocks);
} else {
@@ -398,19 +412,19 @@ static int oprofile_create_hwsampling_files(struct super_block *sb,
* space tools. The /dev/oprofile/hwsampling fs is
* provided in that case.
*/
- dir = oprofilefs_mkdir(sb, root, "hwsampling");
+ dir = oprofilefs_mkdir(root, "hwsampling");
if (!dir)
return -EINVAL;
- oprofilefs_create_file(sb, dir, "hwsampler",
+ oprofilefs_create_file(dir, "hwsampler",
&hwsampler_fops);
- oprofilefs_create_file(sb, dir, "hw_interval",
+ oprofilefs_create_file(dir, "hw_interval",
&hw_interval_fops);
- oprofilefs_create_ro_ulong(sb, dir, "hw_min_interval",
+ oprofilefs_create_ro_ulong(dir, "hw_min_interval",
&oprofile_min_interval);
- oprofilefs_create_ro_ulong(sb, dir, "hw_max_interval",
+ oprofilefs_create_ro_ulong(dir, "hw_max_interval",
&oprofile_max_interval);
- oprofilefs_create_ulong(sb, dir, "hw_sdbt_blocks",
+ oprofilefs_create_ulong(dir, "hw_sdbt_blocks",
&oprofile_sdbt_blocks);
}
return 0;
@@ -442,6 +456,7 @@ static int oprofile_hwsampler_init(struct oprofile_operations *ops)
switch (id.machine) {
case 0x2097: case 0x2098: ops->cpu_type = "s390/z10"; break;
case 0x2817: case 0x2818: ops->cpu_type = "s390/z196"; break;
+ case 0x2827: case 0x2828: ops->cpu_type = "s390/zEC12"; break;
default: return -ENODEV;
}
}