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 |
