diff options
Diffstat (limited to 'arch/arm/oprofile/common.c')
| -rw-r--r-- | arch/arm/oprofile/common.c | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 6f8bc1f0e6a1..6f833358cd06 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c | |||
| @@ -10,17 +10,18 @@ | |||
| 10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
| 11 | #include <linux/oprofile.h> | 11 | #include <linux/oprofile.h> |
| 12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
| 13 | #include <linux/slab.h> | ||
| 13 | #include <linux/sysdev.h> | 14 | #include <linux/sysdev.h> |
| 14 | #include <asm/semaphore.h> | 15 | #include <linux/mutex.h> |
| 15 | 16 | ||
| 16 | #include "op_counter.h" | 17 | #include "op_counter.h" |
| 17 | #include "op_arm_model.h" | 18 | #include "op_arm_model.h" |
| 18 | 19 | ||
| 19 | static struct op_arm_model_spec *op_arm_model; | 20 | static struct op_arm_model_spec *op_arm_model; |
| 20 | static int op_arm_enabled; | 21 | static int op_arm_enabled; |
| 21 | static struct semaphore op_arm_sem; | 22 | static DEFINE_MUTEX(op_arm_mutex); |
| 22 | 23 | ||
| 23 | struct op_counter_config counter_config[OP_MAX_COUNTER]; | 24 | struct op_counter_config *counter_config; |
| 24 | 25 | ||
| 25 | static int op_arm_create_files(struct super_block *sb, struct dentry *root) | 26 | static int op_arm_create_files(struct super_block *sb, struct dentry *root) |
| 26 | { | 27 | { |
| @@ -28,7 +29,7 @@ static int op_arm_create_files(struct super_block *sb, struct dentry *root) | |||
| 28 | 29 | ||
| 29 | for (i = 0; i < op_arm_model->num_counters; i++) { | 30 | for (i = 0; i < op_arm_model->num_counters; i++) { |
| 30 | struct dentry *dir; | 31 | struct dentry *dir; |
| 31 | char buf[2]; | 32 | char buf[4]; |
| 32 | 33 | ||
| 33 | snprintf(buf, sizeof buf, "%d", i); | 34 | snprintf(buf, sizeof buf, "%d", i); |
| 34 | dir = oprofilefs_mkdir(sb, root, buf); | 35 | dir = oprofilefs_mkdir(sb, root, buf); |
| @@ -57,40 +58,40 @@ static int op_arm_start(void) | |||
| 57 | { | 58 | { |
| 58 | int ret = -EBUSY; | 59 | int ret = -EBUSY; |
| 59 | 60 | ||
| 60 | down(&op_arm_sem); | 61 | mutex_lock(&op_arm_mutex); |
| 61 | if (!op_arm_enabled) { | 62 | if (!op_arm_enabled) { |
| 62 | ret = op_arm_model->start(); | 63 | ret = op_arm_model->start(); |
| 63 | op_arm_enabled = !ret; | 64 | op_arm_enabled = !ret; |
| 64 | } | 65 | } |
| 65 | up(&op_arm_sem); | 66 | mutex_unlock(&op_arm_mutex); |
| 66 | return ret; | 67 | return ret; |
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | static void op_arm_stop(void) | 70 | static void op_arm_stop(void) |
| 70 | { | 71 | { |
| 71 | down(&op_arm_sem); | 72 | mutex_lock(&op_arm_mutex); |
| 72 | if (op_arm_enabled) | 73 | if (op_arm_enabled) |
| 73 | op_arm_model->stop(); | 74 | op_arm_model->stop(); |
| 74 | op_arm_enabled = 0; | 75 | op_arm_enabled = 0; |
| 75 | up(&op_arm_sem); | 76 | mutex_unlock(&op_arm_mutex); |
| 76 | } | 77 | } |
| 77 | 78 | ||
| 78 | #ifdef CONFIG_PM | 79 | #ifdef CONFIG_PM |
| 79 | static int op_arm_suspend(struct sys_device *dev, pm_message_t state) | 80 | static int op_arm_suspend(struct sys_device *dev, pm_message_t state) |
| 80 | { | 81 | { |
| 81 | down(&op_arm_sem); | 82 | mutex_lock(&op_arm_mutex); |
| 82 | if (op_arm_enabled) | 83 | if (op_arm_enabled) |
| 83 | op_arm_model->stop(); | 84 | op_arm_model->stop(); |
| 84 | up(&op_arm_sem); | 85 | mutex_unlock(&op_arm_mutex); |
| 85 | return 0; | 86 | return 0; |
| 86 | } | 87 | } |
| 87 | 88 | ||
| 88 | static int op_arm_resume(struct sys_device *dev) | 89 | static int op_arm_resume(struct sys_device *dev) |
| 89 | { | 90 | { |
| 90 | down(&op_arm_sem); | 91 | mutex_lock(&op_arm_mutex); |
| 91 | if (op_arm_enabled && op_arm_model->start()) | 92 | if (op_arm_enabled && op_arm_model->start()) |
| 92 | op_arm_enabled = 0; | 93 | op_arm_enabled = 0; |
| 93 | up(&op_arm_sem); | 94 | mutex_unlock(&op_arm_mutex); |
| 94 | return 0; | 95 | return 0; |
| 95 | } | 96 | } |
| 96 | 97 | ||
| @@ -135,12 +136,15 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
| 135 | #endif | 136 | #endif |
| 136 | 137 | ||
| 137 | if (spec) { | 138 | if (spec) { |
| 138 | init_MUTEX(&op_arm_sem); | ||
| 139 | |||
| 140 | ret = spec->init(); | 139 | ret = spec->init(); |
| 141 | if (ret < 0) | 140 | if (ret < 0) |
| 142 | return ret; | 141 | return ret; |
| 143 | 142 | ||
| 143 | counter_config = kcalloc(spec->num_counters, sizeof(struct op_counter_config), | ||
| 144 | GFP_KERNEL); | ||
| 145 | if (!counter_config) | ||
| 146 | return -ENOMEM; | ||
| 147 | |||
| 144 | op_arm_model = spec; | 148 | op_arm_model = spec; |
| 145 | init_driverfs(); | 149 | init_driverfs(); |
| 146 | ops->create_files = op_arm_create_files; | 150 | ops->create_files = op_arm_create_files; |
| @@ -162,5 +166,5 @@ void oprofile_arch_exit(void) | |||
| 162 | exit_driverfs(); | 166 | exit_driverfs(); |
| 163 | op_arm_model = NULL; | 167 | op_arm_model = NULL; |
| 164 | } | 168 | } |
| 169 | kfree(counter_config); | ||
| 165 | } | 170 | } |
| 166 | |||
