diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-28 12:02:27 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-28 12:02:27 -0700 |
commit | 1fdb24e969110fafea36d3b393bea438f702c87f (patch) | |
tree | 47a1dfef8a259e7922285315f8a02d31b4efe2f1 /arch/arm/kernel/perf_event_v6.c | |
parent | f362f98e7c445643d27c610bb7a86b79727b592e (diff) | |
parent | 531a6a941745e1e045dd2a6bd09e1dc01247a5f3 (diff) | |
download | op-kernel-dev-1fdb24e969110fafea36d3b393bea438f702c87f.zip op-kernel-dev-1fdb24e969110fafea36d3b393bea438f702c87f.tar.gz |
Merge branch 'devel-stable' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm
* 'devel-stable' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm: (178 commits)
ARM: 7139/1: fix compilation with CONFIG_ARM_ATAG_DTB_COMPAT and large TEXT_OFFSET
ARM: gic, local timers: use the request_percpu_irq() interface
ARM: gic: consolidate PPI handling
ARM: switch from NO_MACH_MEMORY_H to NEED_MACH_MEMORY_H
ARM: mach-s5p64x0: remove mach/memory.h
ARM: mach-s3c64xx: remove mach/memory.h
ARM: plat-mxc: remove mach/memory.h
ARM: mach-prima2: remove mach/memory.h
ARM: mach-zynq: remove mach/memory.h
ARM: mach-bcmring: remove mach/memory.h
ARM: mach-davinci: remove mach/memory.h
ARM: mach-pxa: remove mach/memory.h
ARM: mach-ixp4xx: remove mach/memory.h
ARM: mach-h720x: remove mach/memory.h
ARM: mach-vt8500: remove mach/memory.h
ARM: mach-s5pc100: remove mach/memory.h
ARM: mach-tegra: remove mach/memory.h
ARM: plat-tcc: remove mach/memory.h
ARM: mach-mmp: remove mach/memory.h
ARM: mach-cns3xxx: remove mach/memory.h
...
Fix up mostly pretty trivial conflicts in:
- arch/arm/Kconfig
- arch/arm/include/asm/localtimer.h
- arch/arm/kernel/Makefile
- arch/arm/mach-shmobile/board-ap4evb.c
- arch/arm/mach-u300/core.c
- arch/arm/mm/dma-mapping.c
- arch/arm/mm/proc-v7.S
- arch/arm/plat-omap/Kconfig
largely due to some CONFIG option renaming (ie CONFIG_PM_SLEEP ->
CONFIG_ARM_CPU_SUSPEND for the arm-specific suspend code etc) and
addition of NEED_MACH_MEMORY_H next to HAVE_IDE.
Diffstat (limited to 'arch/arm/kernel/perf_event_v6.c')
-rw-r--r-- | arch/arm/kernel/perf_event_v6.c | 87 |
1 files changed, 59 insertions, 28 deletions
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c index dd7f3b9..e63d811 100644 --- a/arch/arm/kernel/perf_event_v6.c +++ b/arch/arm/kernel/perf_event_v6.c @@ -54,7 +54,7 @@ enum armv6_perf_types { }; enum armv6_counters { - ARMV6_CYCLE_COUNTER = 1, + ARMV6_CYCLE_COUNTER = 0, ARMV6_COUNTER0, ARMV6_COUNTER1, }; @@ -433,6 +433,7 @@ armv6pmu_enable_event(struct hw_perf_event *hwc, int idx) { unsigned long val, mask, evt, flags; + struct pmu_hw_events *events = cpu_pmu->get_hw_events(); if (ARMV6_CYCLE_COUNTER == idx) { mask = 0; @@ -454,12 +455,29 @@ armv6pmu_enable_event(struct hw_perf_event *hwc, * Mask out the current event and set the counter to count the event * that we're interested in. */ - raw_spin_lock_irqsave(&pmu_lock, flags); + raw_spin_lock_irqsave(&events->pmu_lock, flags); val = armv6_pmcr_read(); val &= ~mask; val |= evt; armv6_pmcr_write(val); - raw_spin_unlock_irqrestore(&pmu_lock, flags); + raw_spin_unlock_irqrestore(&events->pmu_lock, flags); +} + +static int counter_is_active(unsigned long pmcr, int idx) +{ + unsigned long mask = 0; + if (idx == ARMV6_CYCLE_COUNTER) + mask = ARMV6_PMCR_CCOUNT_IEN; + else if (idx == ARMV6_COUNTER0) + mask = ARMV6_PMCR_COUNT0_IEN; + else if (idx == ARMV6_COUNTER1) + mask = ARMV6_PMCR_COUNT1_IEN; + + if (mask) + return pmcr & mask; + + WARN_ONCE(1, "invalid counter number (%d)\n", idx); + return 0; } static irqreturn_t @@ -468,7 +486,7 @@ armv6pmu_handle_irq(int irq_num, { unsigned long pmcr = armv6_pmcr_read(); struct perf_sample_data data; - struct cpu_hw_events *cpuc; + struct pmu_hw_events *cpuc; struct pt_regs *regs; int idx; @@ -487,11 +505,11 @@ armv6pmu_handle_irq(int irq_num, perf_sample_data_init(&data, 0); cpuc = &__get_cpu_var(cpu_hw_events); - for (idx = 0; idx <= armpmu->num_events; ++idx) { + for (idx = 0; idx < cpu_pmu->num_events; ++idx) { struct perf_event *event = cpuc->events[idx]; struct hw_perf_event *hwc; - if (!test_bit(idx, cpuc->active_mask)) + if (!counter_is_active(pmcr, idx)) continue; /* @@ -508,7 +526,7 @@ armv6pmu_handle_irq(int irq_num, continue; if (perf_event_overflow(event, &data, regs)) - armpmu->disable(hwc, idx); + cpu_pmu->disable(hwc, idx); } /* @@ -527,28 +545,30 @@ static void armv6pmu_start(void) { unsigned long flags, val; + struct pmu_hw_events *events = cpu_pmu->get_hw_events(); - raw_spin_lock_irqsave(&pmu_lock, flags); + raw_spin_lock_irqsave(&events->pmu_lock, flags); val = armv6_pmcr_read(); val |= ARMV6_PMCR_ENABLE; armv6_pmcr_write(val); - raw_spin_unlock_irqrestore(&pmu_lock, flags); + raw_spin_unlock_irqrestore(&events->pmu_lock, flags); } static void armv6pmu_stop(void) { unsigned long flags, val; + struct pmu_hw_events *events = cpu_pmu->get_hw_events(); - raw_spin_lock_irqsave(&pmu_lock, flags); + raw_spin_lock_irqsave(&events->pmu_lock, flags); val = armv6_pmcr_read(); val &= ~ARMV6_PMCR_ENABLE; armv6_pmcr_write(val); - raw_spin_unlock_irqrestore(&pmu_lock, flags); + raw_spin_unlock_irqrestore(&events->pmu_lock, flags); } static int -armv6pmu_get_event_idx(struct cpu_hw_events *cpuc, +armv6pmu_get_event_idx(struct pmu_hw_events *cpuc, struct hw_perf_event *event) { /* Always place a cycle counter into the cycle counter. */ @@ -578,6 +598,7 @@ armv6pmu_disable_event(struct hw_perf_event *hwc, int idx) { unsigned long val, mask, evt, flags; + struct pmu_hw_events *events = cpu_pmu->get_hw_events(); if (ARMV6_CYCLE_COUNTER == idx) { mask = ARMV6_PMCR_CCOUNT_IEN; @@ -598,12 +619,12 @@ armv6pmu_disable_event(struct hw_perf_event *hwc, * of ETM bus signal assertion cycles. The external reporting should * be disabled and so this should never increment. */ - raw_spin_lock_irqsave(&pmu_lock, flags); + raw_spin_lock_irqsave(&events->pmu_lock, flags); val = armv6_pmcr_read(); val &= ~mask; val |= evt; armv6_pmcr_write(val); - raw_spin_unlock_irqrestore(&pmu_lock, flags); + raw_spin_unlock_irqrestore(&events->pmu_lock, flags); } static void @@ -611,6 +632,7 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc, int idx) { unsigned long val, mask, flags, evt = 0; + struct pmu_hw_events *events = cpu_pmu->get_hw_events(); if (ARMV6_CYCLE_COUNTER == idx) { mask = ARMV6_PMCR_CCOUNT_IEN; @@ -627,15 +649,21 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc, * Unlike UP ARMv6, we don't have a way of stopping the counters. We * simply disable the interrupt reporting. */ - raw_spin_lock_irqsave(&pmu_lock, flags); + raw_spin_lock_irqsave(&events->pmu_lock, flags); val = armv6_pmcr_read(); val &= ~mask; val |= evt; armv6_pmcr_write(val); - raw_spin_unlock_irqrestore(&pmu_lock, flags); + raw_spin_unlock_irqrestore(&events->pmu_lock, flags); +} + +static int armv6_map_event(struct perf_event *event) +{ + return map_cpu_event(event, &armv6_perf_map, + &armv6_perf_cache_map, 0xFF); } -static const struct arm_pmu armv6pmu = { +static struct arm_pmu armv6pmu = { .id = ARM_PERF_PMU_ID_V6, .name = "v6", .handle_irq = armv6pmu_handle_irq, @@ -646,14 +674,12 @@ static const struct arm_pmu armv6pmu = { .get_event_idx = armv6pmu_get_event_idx, .start = armv6pmu_start, .stop = armv6pmu_stop, - .cache_map = &armv6_perf_cache_map, - .event_map = &armv6_perf_map, - .raw_event_mask = 0xFF, + .map_event = armv6_map_event, .num_events = 3, .max_period = (1LLU << 32) - 1, }; -static const struct arm_pmu *__init armv6pmu_init(void) +static struct arm_pmu *__init armv6pmu_init(void) { return &armv6pmu; } @@ -665,7 +691,14 @@ static const struct arm_pmu *__init armv6pmu_init(void) * disable the interrupt reporting and update the event. When unthrottling we * reset the period and enable the interrupt reporting. */ -static const struct arm_pmu armv6mpcore_pmu = { + +static int armv6mpcore_map_event(struct perf_event *event) +{ + return map_cpu_event(event, &armv6mpcore_perf_map, + &armv6mpcore_perf_cache_map, 0xFF); +} + +static struct arm_pmu armv6mpcore_pmu = { .id = ARM_PERF_PMU_ID_V6MP, .name = "v6mpcore", .handle_irq = armv6pmu_handle_irq, @@ -676,24 +709,22 @@ static const struct arm_pmu armv6mpcore_pmu = { .get_event_idx = armv6pmu_get_event_idx, .start = armv6pmu_start, .stop = armv6pmu_stop, - .cache_map = &armv6mpcore_perf_cache_map, - .event_map = &armv6mpcore_perf_map, - .raw_event_mask = 0xFF, + .map_event = armv6mpcore_map_event, .num_events = 3, .max_period = (1LLU << 32) - 1, }; -static const struct arm_pmu *__init armv6mpcore_pmu_init(void) +static struct arm_pmu *__init armv6mpcore_pmu_init(void) { return &armv6mpcore_pmu; } #else -static const struct arm_pmu *__init armv6pmu_init(void) +static struct arm_pmu *__init armv6pmu_init(void) { return NULL; } -static const struct arm_pmu *__init armv6mpcore_pmu_init(void) +static struct arm_pmu *__init armv6mpcore_pmu_init(void) { return NULL; } |