diff options
author | Mark Rutland <mark.rutland@arm.com> | 2011-04-28 05:17:04 -0400 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2011-08-31 05:50:07 -0400 |
commit | 0f78d2d5ccf72ec834da6901886a40fd8e3b7615 (patch) | |
tree | da1262d040b2c10d95c6fc313b44e18801bcb4a3 | |
parent | 1b69beb7684c79673995607939d8acab51056b63 (diff) |
ARM: perf: lock PMU registers per-CPU
Currently, a single lock serialises access to CPU PMU registers. This
global locking is unnecessary as PMU registers are local to the CPU
they monitor.
This patch replaces the global lock with a per-CPU lock. As the lock is
in struct cpu_hw_events, PMUs providing a single cpu_hw_events instance
can be locked globally.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Jamie Iles <jamie@jamieiles.com>
Reviewed-by: Ashwin Chaugule <ashwinc@codeaurora.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r-- | arch/arm/kernel/perf_event.c | 17 | ||||
-rw-r--r-- | arch/arm/kernel/perf_event_v6.c | 25 | ||||
-rw-r--r-- | arch/arm/kernel/perf_event_v7.c | 20 | ||||
-rw-r--r-- | arch/arm/kernel/perf_event_xscale.c | 40 |
4 files changed, 62 insertions, 40 deletions
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 5ce6c3332915..9331d5731445 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -27,12 +27,6 @@ | |||
27 | #include <asm/stacktrace.h> | 27 | #include <asm/stacktrace.h> |
28 | 28 | ||
29 | /* | 29 | /* |
30 | * Hardware lock to serialize accesses to PMU registers. Needed for the | ||
31 | * read/modify/write sequences. | ||
32 | */ | ||
33 | static DEFINE_RAW_SPINLOCK(pmu_lock); | ||
34 | |||
35 | /* | ||
36 | * ARMv6 supports a maximum of 3 events, starting from index 0. If we add | 30 | * ARMv6 supports a maximum of 3 events, starting from index 0. If we add |
37 | * another platform that supports more, we need to increase this to be the | 31 | * another platform that supports more, we need to increase this to be the |
38 | * largest of all platforms. | 32 | * largest of all platforms. |
@@ -55,6 +49,12 @@ struct cpu_hw_events { | |||
55 | * an event. A 0 means that the counter can be used. | 49 | * an event. A 0 means that the counter can be used. |
56 | */ | 50 | */ |
57 | unsigned long used_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)]; | 51 | unsigned long used_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)]; |
52 | |||
53 | /* | ||
54 | * Hardware lock to serialize accesses to PMU registers. Needed for the | ||
55 | * read/modify/write sequences. | ||
56 | */ | ||
57 | raw_spinlock_t pmu_lock; | ||
58 | }; | 58 | }; |
59 | static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); | 59 | static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); |
60 | 60 | ||
@@ -685,6 +685,11 @@ static struct cpu_hw_events *armpmu_get_cpu_events(void) | |||
685 | 685 | ||
686 | static void __init cpu_pmu_init(struct arm_pmu *armpmu) | 686 | static void __init cpu_pmu_init(struct arm_pmu *armpmu) |
687 | { | 687 | { |
688 | int cpu; | ||
689 | for_each_possible_cpu(cpu) { | ||
690 | struct cpu_hw_events *events = &per_cpu(cpu_hw_events, cpu); | ||
691 | raw_spin_lock_init(&events->pmu_lock); | ||
692 | } | ||
688 | armpmu->get_hw_events = armpmu_get_cpu_events; | 693 | armpmu->get_hw_events = armpmu_get_cpu_events; |
689 | } | 694 | } |
690 | 695 | ||
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c index 839012862264..68cf70425f2f 100644 --- a/arch/arm/kernel/perf_event_v6.c +++ b/arch/arm/kernel/perf_event_v6.c | |||
@@ -433,6 +433,7 @@ armv6pmu_enable_event(struct hw_perf_event *hwc, | |||
433 | int idx) | 433 | int idx) |
434 | { | 434 | { |
435 | unsigned long val, mask, evt, flags; | 435 | unsigned long val, mask, evt, flags; |
436 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
436 | 437 | ||
437 | if (ARMV6_CYCLE_COUNTER == idx) { | 438 | if (ARMV6_CYCLE_COUNTER == idx) { |
438 | mask = 0; | 439 | mask = 0; |
@@ -454,12 +455,12 @@ armv6pmu_enable_event(struct hw_perf_event *hwc, | |||
454 | * Mask out the current event and set the counter to count the event | 455 | * Mask out the current event and set the counter to count the event |
455 | * that we're interested in. | 456 | * that we're interested in. |
456 | */ | 457 | */ |
457 | raw_spin_lock_irqsave(&pmu_lock, flags); | 458 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
458 | val = armv6_pmcr_read(); | 459 | val = armv6_pmcr_read(); |
459 | val &= ~mask; | 460 | val &= ~mask; |
460 | val |= evt; | 461 | val |= evt; |
461 | armv6_pmcr_write(val); | 462 | armv6_pmcr_write(val); |
462 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 463 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
463 | } | 464 | } |
464 | 465 | ||
465 | static int counter_is_active(unsigned long pmcr, int idx) | 466 | static int counter_is_active(unsigned long pmcr, int idx) |
@@ -544,24 +545,26 @@ static void | |||
544 | armv6pmu_start(void) | 545 | armv6pmu_start(void) |
545 | { | 546 | { |
546 | unsigned long flags, val; | 547 | unsigned long flags, val; |
548 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
547 | 549 | ||
548 | raw_spin_lock_irqsave(&pmu_lock, flags); | 550 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
549 | val = armv6_pmcr_read(); | 551 | val = armv6_pmcr_read(); |
550 | val |= ARMV6_PMCR_ENABLE; | 552 | val |= ARMV6_PMCR_ENABLE; |
551 | armv6_pmcr_write(val); | 553 | armv6_pmcr_write(val); |
552 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 554 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
553 | } | 555 | } |
554 | 556 | ||
555 | static void | 557 | static void |
556 | armv6pmu_stop(void) | 558 | armv6pmu_stop(void) |
557 | { | 559 | { |
558 | unsigned long flags, val; | 560 | unsigned long flags, val; |
561 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
559 | 562 | ||
560 | raw_spin_lock_irqsave(&pmu_lock, flags); | 563 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
561 | val = armv6_pmcr_read(); | 564 | val = armv6_pmcr_read(); |
562 | val &= ~ARMV6_PMCR_ENABLE; | 565 | val &= ~ARMV6_PMCR_ENABLE; |
563 | armv6_pmcr_write(val); | 566 | armv6_pmcr_write(val); |
564 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 567 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
565 | } | 568 | } |
566 | 569 | ||
567 | static int | 570 | static int |
@@ -595,6 +598,7 @@ armv6pmu_disable_event(struct hw_perf_event *hwc, | |||
595 | int idx) | 598 | int idx) |
596 | { | 599 | { |
597 | unsigned long val, mask, evt, flags; | 600 | unsigned long val, mask, evt, flags; |
601 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
598 | 602 | ||
599 | if (ARMV6_CYCLE_COUNTER == idx) { | 603 | if (ARMV6_CYCLE_COUNTER == idx) { |
600 | mask = ARMV6_PMCR_CCOUNT_IEN; | 604 | mask = ARMV6_PMCR_CCOUNT_IEN; |
@@ -615,12 +619,12 @@ armv6pmu_disable_event(struct hw_perf_event *hwc, | |||
615 | * of ETM bus signal assertion cycles. The external reporting should | 619 | * of ETM bus signal assertion cycles. The external reporting should |
616 | * be disabled and so this should never increment. | 620 | * be disabled and so this should never increment. |
617 | */ | 621 | */ |
618 | raw_spin_lock_irqsave(&pmu_lock, flags); | 622 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
619 | val = armv6_pmcr_read(); | 623 | val = armv6_pmcr_read(); |
620 | val &= ~mask; | 624 | val &= ~mask; |
621 | val |= evt; | 625 | val |= evt; |
622 | armv6_pmcr_write(val); | 626 | armv6_pmcr_write(val); |
623 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 627 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
624 | } | 628 | } |
625 | 629 | ||
626 | static void | 630 | static void |
@@ -628,6 +632,7 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc, | |||
628 | int idx) | 632 | int idx) |
629 | { | 633 | { |
630 | unsigned long val, mask, flags, evt = 0; | 634 | unsigned long val, mask, flags, evt = 0; |
635 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
631 | 636 | ||
632 | if (ARMV6_CYCLE_COUNTER == idx) { | 637 | if (ARMV6_CYCLE_COUNTER == idx) { |
633 | mask = ARMV6_PMCR_CCOUNT_IEN; | 638 | mask = ARMV6_PMCR_CCOUNT_IEN; |
@@ -644,12 +649,12 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc, | |||
644 | * Unlike UP ARMv6, we don't have a way of stopping the counters. We | 649 | * Unlike UP ARMv6, we don't have a way of stopping the counters. We |
645 | * simply disable the interrupt reporting. | 650 | * simply disable the interrupt reporting. |
646 | */ | 651 | */ |
647 | raw_spin_lock_irqsave(&pmu_lock, flags); | 652 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
648 | val = armv6_pmcr_read(); | 653 | val = armv6_pmcr_read(); |
649 | val &= ~mask; | 654 | val &= ~mask; |
650 | val |= evt; | 655 | val |= evt; |
651 | armv6_pmcr_write(val); | 656 | armv6_pmcr_write(val); |
652 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 657 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
653 | } | 658 | } |
654 | 659 | ||
655 | static struct arm_pmu armv6pmu = { | 660 | static struct arm_pmu armv6pmu = { |
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index f4170fc228b6..68ac522fd940 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c | |||
@@ -936,12 +936,13 @@ static void armv7_pmnc_dump_regs(void) | |||
936 | static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx) | 936 | static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx) |
937 | { | 937 | { |
938 | unsigned long flags; | 938 | unsigned long flags; |
939 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
939 | 940 | ||
940 | /* | 941 | /* |
941 | * Enable counter and interrupt, and set the counter to count | 942 | * Enable counter and interrupt, and set the counter to count |
942 | * the event that we're interested in. | 943 | * the event that we're interested in. |
943 | */ | 944 | */ |
944 | raw_spin_lock_irqsave(&pmu_lock, flags); | 945 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
945 | 946 | ||
946 | /* | 947 | /* |
947 | * Disable counter | 948 | * Disable counter |
@@ -966,17 +967,18 @@ static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx) | |||
966 | */ | 967 | */ |
967 | armv7_pmnc_enable_counter(idx); | 968 | armv7_pmnc_enable_counter(idx); |
968 | 969 | ||
969 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 970 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
970 | } | 971 | } |
971 | 972 | ||
972 | static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx) | 973 | static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx) |
973 | { | 974 | { |
974 | unsigned long flags; | 975 | unsigned long flags; |
976 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
975 | 977 | ||
976 | /* | 978 | /* |
977 | * Disable counter and interrupt | 979 | * Disable counter and interrupt |
978 | */ | 980 | */ |
979 | raw_spin_lock_irqsave(&pmu_lock, flags); | 981 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
980 | 982 | ||
981 | /* | 983 | /* |
982 | * Disable counter | 984 | * Disable counter |
@@ -988,7 +990,7 @@ static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx) | |||
988 | */ | 990 | */ |
989 | armv7_pmnc_disable_intens(idx); | 991 | armv7_pmnc_disable_intens(idx); |
990 | 992 | ||
991 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 993 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
992 | } | 994 | } |
993 | 995 | ||
994 | static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) | 996 | static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) |
@@ -1054,21 +1056,23 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) | |||
1054 | static void armv7pmu_start(void) | 1056 | static void armv7pmu_start(void) |
1055 | { | 1057 | { |
1056 | unsigned long flags; | 1058 | unsigned long flags; |
1059 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
1057 | 1060 | ||
1058 | raw_spin_lock_irqsave(&pmu_lock, flags); | 1061 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
1059 | /* Enable all counters */ | 1062 | /* Enable all counters */ |
1060 | armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E); | 1063 | armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E); |
1061 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 1064 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
1062 | } | 1065 | } |
1063 | 1066 | ||
1064 | static void armv7pmu_stop(void) | 1067 | static void armv7pmu_stop(void) |
1065 | { | 1068 | { |
1066 | unsigned long flags; | 1069 | unsigned long flags; |
1070 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
1067 | 1071 | ||
1068 | raw_spin_lock_irqsave(&pmu_lock, flags); | 1072 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
1069 | /* Disable all counters */ | 1073 | /* Disable all counters */ |
1070 | armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E); | 1074 | armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E); |
1071 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 1075 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
1072 | } | 1076 | } |
1073 | 1077 | ||
1074 | static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc, | 1078 | static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc, |
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c index ca89a06c8e92..18e4823a0a62 100644 --- a/arch/arm/kernel/perf_event_xscale.c +++ b/arch/arm/kernel/perf_event_xscale.c | |||
@@ -281,6 +281,7 @@ static void | |||
281 | xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx) | 281 | xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx) |
282 | { | 282 | { |
283 | unsigned long val, mask, evt, flags; | 283 | unsigned long val, mask, evt, flags; |
284 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
284 | 285 | ||
285 | switch (idx) { | 286 | switch (idx) { |
286 | case XSCALE_CYCLE_COUNTER: | 287 | case XSCALE_CYCLE_COUNTER: |
@@ -302,18 +303,19 @@ xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx) | |||
302 | return; | 303 | return; |
303 | } | 304 | } |
304 | 305 | ||
305 | raw_spin_lock_irqsave(&pmu_lock, flags); | 306 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
306 | val = xscale1pmu_read_pmnc(); | 307 | val = xscale1pmu_read_pmnc(); |
307 | val &= ~mask; | 308 | val &= ~mask; |
308 | val |= evt; | 309 | val |= evt; |
309 | xscale1pmu_write_pmnc(val); | 310 | xscale1pmu_write_pmnc(val); |
310 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 311 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
311 | } | 312 | } |
312 | 313 | ||
313 | static void | 314 | static void |
314 | xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx) | 315 | xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx) |
315 | { | 316 | { |
316 | unsigned long val, mask, evt, flags; | 317 | unsigned long val, mask, evt, flags; |
318 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
317 | 319 | ||
318 | switch (idx) { | 320 | switch (idx) { |
319 | case XSCALE_CYCLE_COUNTER: | 321 | case XSCALE_CYCLE_COUNTER: |
@@ -333,12 +335,12 @@ xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx) | |||
333 | return; | 335 | return; |
334 | } | 336 | } |
335 | 337 | ||
336 | raw_spin_lock_irqsave(&pmu_lock, flags); | 338 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
337 | val = xscale1pmu_read_pmnc(); | 339 | val = xscale1pmu_read_pmnc(); |
338 | val &= ~mask; | 340 | val &= ~mask; |
339 | val |= evt; | 341 | val |= evt; |
340 | xscale1pmu_write_pmnc(val); | 342 | xscale1pmu_write_pmnc(val); |
341 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 343 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
342 | } | 344 | } |
343 | 345 | ||
344 | static int | 346 | static int |
@@ -365,24 +367,26 @@ static void | |||
365 | xscale1pmu_start(void) | 367 | xscale1pmu_start(void) |
366 | { | 368 | { |
367 | unsigned long flags, val; | 369 | unsigned long flags, val; |
370 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
368 | 371 | ||
369 | raw_spin_lock_irqsave(&pmu_lock, flags); | 372 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
370 | val = xscale1pmu_read_pmnc(); | 373 | val = xscale1pmu_read_pmnc(); |
371 | val |= XSCALE_PMU_ENABLE; | 374 | val |= XSCALE_PMU_ENABLE; |
372 | xscale1pmu_write_pmnc(val); | 375 | xscale1pmu_write_pmnc(val); |
373 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 376 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
374 | } | 377 | } |
375 | 378 | ||
376 | static void | 379 | static void |
377 | xscale1pmu_stop(void) | 380 | xscale1pmu_stop(void) |
378 | { | 381 | { |
379 | unsigned long flags, val; | 382 | unsigned long flags, val; |
383 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
380 | 384 | ||
381 | raw_spin_lock_irqsave(&pmu_lock, flags); | 385 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
382 | val = xscale1pmu_read_pmnc(); | 386 | val = xscale1pmu_read_pmnc(); |
383 | val &= ~XSCALE_PMU_ENABLE; | 387 | val &= ~XSCALE_PMU_ENABLE; |
384 | xscale1pmu_write_pmnc(val); | 388 | xscale1pmu_write_pmnc(val); |
385 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 389 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
386 | } | 390 | } |
387 | 391 | ||
388 | static inline u32 | 392 | static inline u32 |
@@ -610,6 +614,7 @@ static void | |||
610 | xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx) | 614 | xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx) |
611 | { | 615 | { |
612 | unsigned long flags, ien, evtsel; | 616 | unsigned long flags, ien, evtsel; |
617 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
613 | 618 | ||
614 | ien = xscale2pmu_read_int_enable(); | 619 | ien = xscale2pmu_read_int_enable(); |
615 | evtsel = xscale2pmu_read_event_select(); | 620 | evtsel = xscale2pmu_read_event_select(); |
@@ -643,16 +648,17 @@ xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx) | |||
643 | return; | 648 | return; |
644 | } | 649 | } |
645 | 650 | ||
646 | raw_spin_lock_irqsave(&pmu_lock, flags); | 651 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
647 | xscale2pmu_write_event_select(evtsel); | 652 | xscale2pmu_write_event_select(evtsel); |
648 | xscale2pmu_write_int_enable(ien); | 653 | xscale2pmu_write_int_enable(ien); |
649 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 654 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
650 | } | 655 | } |
651 | 656 | ||
652 | static void | 657 | static void |
653 | xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx) | 658 | xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx) |
654 | { | 659 | { |
655 | unsigned long flags, ien, evtsel; | 660 | unsigned long flags, ien, evtsel; |
661 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
656 | 662 | ||
657 | ien = xscale2pmu_read_int_enable(); | 663 | ien = xscale2pmu_read_int_enable(); |
658 | evtsel = xscale2pmu_read_event_select(); | 664 | evtsel = xscale2pmu_read_event_select(); |
@@ -686,10 +692,10 @@ xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx) | |||
686 | return; | 692 | return; |
687 | } | 693 | } |
688 | 694 | ||
689 | raw_spin_lock_irqsave(&pmu_lock, flags); | 695 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
690 | xscale2pmu_write_event_select(evtsel); | 696 | xscale2pmu_write_event_select(evtsel); |
691 | xscale2pmu_write_int_enable(ien); | 697 | xscale2pmu_write_int_enable(ien); |
692 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 698 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
693 | } | 699 | } |
694 | 700 | ||
695 | static int | 701 | static int |
@@ -712,24 +718,26 @@ static void | |||
712 | xscale2pmu_start(void) | 718 | xscale2pmu_start(void) |
713 | { | 719 | { |
714 | unsigned long flags, val; | 720 | unsigned long flags, val; |
721 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
715 | 722 | ||
716 | raw_spin_lock_irqsave(&pmu_lock, flags); | 723 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
717 | val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64; | 724 | val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64; |
718 | val |= XSCALE_PMU_ENABLE; | 725 | val |= XSCALE_PMU_ENABLE; |
719 | xscale2pmu_write_pmnc(val); | 726 | xscale2pmu_write_pmnc(val); |
720 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 727 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
721 | } | 728 | } |
722 | 729 | ||
723 | static void | 730 | static void |
724 | xscale2pmu_stop(void) | 731 | xscale2pmu_stop(void) |
725 | { | 732 | { |
726 | unsigned long flags, val; | 733 | unsigned long flags, val; |
734 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
727 | 735 | ||
728 | raw_spin_lock_irqsave(&pmu_lock, flags); | 736 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
729 | val = xscale2pmu_read_pmnc(); | 737 | val = xscale2pmu_read_pmnc(); |
730 | val &= ~XSCALE_PMU_ENABLE; | 738 | val &= ~XSCALE_PMU_ENABLE; |
731 | xscale2pmu_write_pmnc(val); | 739 | xscale2pmu_write_pmnc(val); |
732 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 740 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
733 | } | 741 | } |
734 | 742 | ||
735 | static inline u32 | 743 | static inline u32 |