Commit cd754736 authored by Olof Johansson's avatar Olof Johansson
Browse files

Merge tag 'arm-perf-3.7' of...

Merge tag 'arm-perf-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux into next/cleanup

From Will Deacon:

Bunch of perf updates for the ARM backend that pave the way for
big.LITTLE support in the future. The separation of CPU and PMU code
is also the start of being able to move some of this stuff under
drivers/.

* tag 'arm-perf-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux:
  ARM: perf: move irq registration into pmu implementation
  ARM: perf: move CPU-specific PMU handling code into separate file
  ARM: perf: prepare for moving CPU PMU code into separate file
  ARM: perf: probe devicetree in preference to current CPU
  ARM: perf: remove mysterious compiler barrier
  ARM: pmu: remove arm_pmu_type enumeration
  ARM: pmu: remove unused reservation mechanism
  ARM: perf: add devicetree bindings for 11MPcore, A5, A7 and A15 PMUs
  ARM: PMU: Add runtime PM Support
parents 242521e9 051f1b13
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -7,8 +7,12 @@ representation in the device tree should be done as under:-
Required properties:

- compatible : should be one of
	"arm,cortex-a15-pmu"
	"arm,cortex-a9-pmu"
	"arm,cortex-a8-pmu"
	"arm,cortex-a7-pmu"
	"arm,cortex-a5-pmu"
	"arm,arm11mpcore-pmu"
	"arm,arm1176-pmu"
	"arm,arm1136-pmu"
- interrupts : 1 combined interrupt or 1 per core.
+0 −1
Original line number Diff line number Diff line
@@ -595,7 +595,6 @@ M: Will Deacon <will.deacon@arm.com>
S:	Maintained
F:	arch/arm/kernel/perf_event*
F:	arch/arm/oprofile/common.c
F:	arch/arm/kernel/pmu.c
F:	arch/arm/include/asm/pmu.h
F:	arch/arm/kernel/hw_breakpoint.c
F:	arch/arm/include/asm/hw_breakpoint.h
+1 −7
Original line number Diff line number Diff line
@@ -1169,12 +1169,6 @@ config XSCALE_PMU
	depends on CPU_XSCALE
	default y

config CPU_HAS_PMU
	depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU) && \
		   (!ARCH_OMAP3 || OMAP3_EMU)
	default y
	bool

config MULTI_IRQ_HANDLER
	bool
	help
@@ -1747,7 +1741,7 @@ config HIGHPTE

config HW_PERF_EVENTS
	bool "Enable hardware performance counter support for perf events"
	depends on PERF_EVENTS && CPU_HAS_PMU
	depends on PERF_EVENTS
	default y
	help
	  Enable hardware performance counter support for perf events. If
+8 −1
Original line number Diff line number Diff line
@@ -12,6 +12,13 @@
#ifndef __ARM_PERF_EVENT_H__
#define __ARM_PERF_EVENT_H__

/* Nothing to see here... */
/*
 * The ARMv7 CPU PMU supports up to 32 event counters.
 */
#define ARMPMU_MAX_HWEVENTS		32

#define HW_OP_UNSUPPORTED		0xFFFF
#define C(_x)				PERF_COUNT_HW_CACHE_##_x
#define CACHE_OP_UNSUPPORTED		0xFFFF

#endif /* __ARM_PERF_EVENT_H__ */
+24 −53
Original line number Diff line number Diff line
@@ -15,15 +15,6 @@
#include <linux/interrupt.h>
#include <linux/perf_event.h>

/*
 * Types of PMUs that can be accessed directly and require mutual
 * exclusion between profiling tools.
 */
enum arm_pmu_type {
	ARM_PMU_DEVICE_CPU	= 0,
	ARM_NUM_PMU_DEVICES,
};

/*
 * struct arm_pmu_platdata - ARM PMU platform data
 *
@@ -31,54 +22,24 @@ enum arm_pmu_type {
 *	interrupt and passed the address of the low level handler,
 *	and can be used to implement any platform specific handling
 *	before or after calling it.
 * @enable_irq: an optional handler which will be called after
 *	request_irq and be used to handle some platform specific
 *	irq enablement
 * @disable_irq: an optional handler which will be called before
 *	free_irq and be used to handle some platform specific
 *	irq disablement
 * @runtime_resume: an optional handler which will be called by the
 *	runtime PM framework following a call to pm_runtime_get().
 *	Note that if pm_runtime_get() is called more than once in
 *	succession this handler will only be called once.
 * @runtime_suspend: an optional handler which will be called by the
 *	runtime PM framework following a call to pm_runtime_put().
 *	Note that if pm_runtime_get() is called more than once in
 *	succession this handler will only be called following the
 *	final call to pm_runtime_put() that actually disables the
 *	hardware.
 */
struct arm_pmu_platdata {
	irqreturn_t (*handle_irq)(int irq, void *dev,
				  irq_handler_t pmu_handler);
	void (*enable_irq)(int irq);
	void (*disable_irq)(int irq);
	int (*runtime_resume)(struct device *dev);
	int (*runtime_suspend)(struct device *dev);
};

#ifdef CONFIG_CPU_HAS_PMU

/**
 * reserve_pmu() - reserve the hardware performance counters
 *
 * Reserve the hardware performance counters in the system for exclusive use.
 * Returns 0 on success or -EBUSY if the lock is already held.
 */
extern int
reserve_pmu(enum arm_pmu_type type);

/**
 * release_pmu() - Relinquish control of the performance counters
 *
 * Release the performance counters and allow someone else to use them.
 */
extern void
release_pmu(enum arm_pmu_type type);

#else /* CONFIG_CPU_HAS_PMU */

#include <linux/err.h>

static inline int
reserve_pmu(enum arm_pmu_type type)
{
	return -ENODEV;
}

static inline void
release_pmu(enum arm_pmu_type type)	{ }

#endif /* CONFIG_CPU_HAS_PMU */

#ifdef CONFIG_HW_PERF_EVENTS

/* The events for a given PMU register set. */
@@ -103,7 +64,6 @@ struct pmu_hw_events {

struct arm_pmu {
	struct pmu	pmu;
	enum arm_pmu_type type;
	cpumask_t	active_irqs;
	char		*name;
	irqreturn_t	(*handle_irq)(int irq_num, void *dev);
@@ -118,6 +78,8 @@ struct arm_pmu {
	void		(*start)(void);
	void		(*stop)(void);
	void		(*reset)(void *);
	int		(*request_irq)(irq_handler_t handler);
	void		(*free_irq)(void);
	int		(*map_event)(struct perf_event *event);
	int		num_events;
	atomic_t	active_events;
@@ -129,7 +91,9 @@ struct arm_pmu {

#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))

int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type);
extern const struct dev_pm_ops armpmu_dev_pm_ops;

int armpmu_register(struct arm_pmu *armpmu, char *name, int type);

u64 armpmu_event_update(struct perf_event *event,
			struct hw_perf_event *hwc,
@@ -139,6 +103,13 @@ int armpmu_event_set_period(struct perf_event *event,
			    struct hw_perf_event *hwc,
			    int idx);

int armpmu_map_event(struct perf_event *event,
		     const unsigned (*event_map)[PERF_COUNT_HW_MAX],
		     const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX]
						[PERF_COUNT_HW_CACHE_OP_MAX]
						[PERF_COUNT_HW_CACHE_RESULT_MAX],
		     u32 raw_event_mask);

#endif /* CONFIG_HW_PERF_EVENTS */

#endif /* __ARM_PMU_H__ */
Loading