aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/oprofile/common.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-20 16:45:53 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-20 16:45:53 -0400
commitede13d81b4dda409a6d271b34b8e2ec9383e255d (patch)
tree2e32142d5a8e076c64f1871f5ad162fffff5f357 /arch/powerpc/oprofile/common.c
parent2008220879af095d00ca27eb168a55c8595fbc0b (diff)
parent486acd4850dde6d2f8c7f431432f3914c4bfb5f5 (diff)
Merge branch 'for-2.6.23' of master.kernel.org:/pub/scm/linux/kernel/git/arnd/cell-2.6
* 'for-2.6.23' of master.kernel.org:/pub/scm/linux/kernel/git/arnd/cell-2.6: (37 commits) [CELL] spufs: rework list management and associated locking [CELL] oprofile: add support to OProfile for profiling CELL BE SPUs [CELL] oprofile: enable SPU switch notification to detect currently active SPU tasks [CELL] spu_base: locking cleanup [CELL] cell: indexing of SPUs based on firmware vicinity properties [CELL] spufs: integration of SPE affinity with the scheduller [CELL] cell: add placement computation for scheduling of affinity contexts [CELL] spufs: extension of spu_create to support affinity definition [CELL] cell: add hardcoded spu vicinity information for QS20 [CELL] cell: add vicinity information on spus [CELL] cell: add per BE structure with info about its SPUs [CELL] spufs: use find_first_bit() instead of sched_find_first_bit() [CELL] spufs: remove unused file argument from spufs_run_spu() [CELL] spufs: change decrementer restore timing [CELL] spufs: dont halt decrementer at restore step 47 [CELL] spufs: limit saving MFC_CNTL bits [CELL] spufs: fix read and write for decr_status file [CELL] spufs: fix decr_status meanings [CELL] spufs: remove needless context save/restore code [CELL] spufs: fix array size of channel index ...
Diffstat (limited to 'arch/powerpc/oprofile/common.c')
-rw-r--r--arch/powerpc/oprofile/common.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c
index 1a7ef7e246d2..a28cce1d6c24 100644
--- a/arch/powerpc/oprofile/common.c
+++ b/arch/powerpc/oprofile/common.c
@@ -29,6 +29,8 @@ static struct op_powerpc_model *model;
29static struct op_counter_config ctr[OP_MAX_COUNTER]; 29static struct op_counter_config ctr[OP_MAX_COUNTER];
30static struct op_system_config sys; 30static struct op_system_config sys;
31 31
32static int op_per_cpu_rc;
33
32static void op_handle_interrupt(struct pt_regs *regs) 34static void op_handle_interrupt(struct pt_regs *regs)
33{ 35{
34 model->handle_interrupt(regs, ctr); 36 model->handle_interrupt(regs, ctr);
@@ -36,25 +38,41 @@ static void op_handle_interrupt(struct pt_regs *regs)
36 38
37static void op_powerpc_cpu_setup(void *dummy) 39static void op_powerpc_cpu_setup(void *dummy)
38{ 40{
39 model->cpu_setup(ctr); 41 int ret;
42
43 ret = model->cpu_setup(ctr);
44
45 if (ret != 0)
46 op_per_cpu_rc = ret;
40} 47}
41 48
42static int op_powerpc_setup(void) 49static int op_powerpc_setup(void)
43{ 50{
44 int err; 51 int err;
45 52
53 op_per_cpu_rc = 0;
54
46 /* Grab the hardware */ 55 /* Grab the hardware */
47 err = reserve_pmc_hardware(op_handle_interrupt); 56 err = reserve_pmc_hardware(op_handle_interrupt);
48 if (err) 57 if (err)
49 return err; 58 return err;
50 59
51 /* Pre-compute the values to stuff in the hardware registers. */ 60 /* Pre-compute the values to stuff in the hardware registers. */
52 model->reg_setup(ctr, &sys, model->num_counters); 61 op_per_cpu_rc = model->reg_setup(ctr, &sys, model->num_counters);
53 62
54 /* Configure the registers on all cpus. */ 63 if (op_per_cpu_rc)
64 goto out;
65
66 /* Configure the registers on all cpus. If an error occurs on one
67 * of the cpus, op_per_cpu_rc will be set to the error */
55 on_each_cpu(op_powerpc_cpu_setup, NULL, 0, 1); 68 on_each_cpu(op_powerpc_cpu_setup, NULL, 0, 1);
56 69
57 return 0; 70out: if (op_per_cpu_rc) {
71 /* error on setup release the performance counter hardware */
72 release_pmc_hardware();
73 }
74
75 return op_per_cpu_rc;
58} 76}
59 77
60static void op_powerpc_shutdown(void) 78static void op_powerpc_shutdown(void)
@@ -64,16 +82,29 @@ static void op_powerpc_shutdown(void)
64 82
65static void op_powerpc_cpu_start(void *dummy) 83static void op_powerpc_cpu_start(void *dummy)
66{ 84{
67 model->start(ctr); 85 /* If any of the cpus have return an error, set the
86 * global flag to the error so it can be returned
87 * to the generic OProfile caller.
88 */
89 int ret;
90
91 ret = model->start(ctr);
92 if (ret != 0)
93 op_per_cpu_rc = ret;
68} 94}
69 95
70static int op_powerpc_start(void) 96static int op_powerpc_start(void)
71{ 97{
98 op_per_cpu_rc = 0;
99
72 if (model->global_start) 100 if (model->global_start)
73 model->global_start(ctr); 101 return model->global_start(ctr);
74 if (model->start) 102 if (model->start) {
75 on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1); 103 on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1);
76 return 0; 104 return op_per_cpu_rc;
105 }
106 return -EIO; /* No start function is defined for this
107 power architecture */
77} 108}
78 109
79static inline void op_powerpc_cpu_stop(void *dummy) 110static inline void op_powerpc_cpu_stop(void *dummy)
@@ -147,11 +178,13 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
147 178
148 switch (cur_cpu_spec->oprofile_type) { 179 switch (cur_cpu_spec->oprofile_type) {
149#ifdef CONFIG_PPC64 180#ifdef CONFIG_PPC64
150#ifdef CONFIG_PPC_CELL_NATIVE 181#ifdef CONFIG_OPROFILE_CELL
151 case PPC_OPROFILE_CELL: 182 case PPC_OPROFILE_CELL:
152 if (firmware_has_feature(FW_FEATURE_LPAR)) 183 if (firmware_has_feature(FW_FEATURE_LPAR))
153 return -ENODEV; 184 return -ENODEV;
154 model = &op_model_cell; 185 model = &op_model_cell;
186 ops->sync_start = model->sync_start;
187 ops->sync_stop = model->sync_stop;
155 break; 188 break;
156#endif 189#endif
157 case PPC_OPROFILE_RS64: 190 case PPC_OPROFILE_RS64: