Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.9.
  1/*
  2 *  linux/arch/arm/include/asm/pmu.h
  3 *
  4 *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
  5 *
  6 * This program is free software; you can redistribute it and/or modify
  7 * it under the terms of the GNU General Public License version 2 as
  8 * published by the Free Software Foundation.
  9 *
 10 */
 11
 12#ifndef __ARM_PMU_H__
 13#define __ARM_PMU_H__
 14
 15#include <linux/interrupt.h>
 16#include <linux/perf_event.h>
 17
 18/*
 19 * Types of PMUs that can be accessed directly and require mutual
 20 * exclusion between profiling tools.
 21 */
 22enum arm_pmu_type {
 23	ARM_PMU_DEVICE_CPU	= 0,
 24	ARM_NUM_PMU_DEVICES,
 25};
 26
 27/*
 28 * struct arm_pmu_platdata - ARM PMU platform data
 29 *
 30 * @handle_irq: an optional handler which will be called from the
 31 *	interrupt and passed the address of the low level handler,
 32 *	and can be used to implement any platform specific handling
 33 *	before or after calling it.
 34 * @enable_irq: an optional handler which will be called after
 35 *	request_irq and be used to handle some platform specific
 36 *	irq enablement
 37 * @disable_irq: an optional handler which will be called before
 38 *	free_irq and be used to handle some platform specific
 39 *	irq disablement
 40 */
 41struct arm_pmu_platdata {
 42	irqreturn_t (*handle_irq)(int irq, void *dev,
 43				  irq_handler_t pmu_handler);
 44	void (*enable_irq)(int irq);
 45	void (*disable_irq)(int irq);
 46};
 47
 48#ifdef CONFIG_CPU_HAS_PMU
 49
 50/**
 51 * reserve_pmu() - reserve the hardware performance counters
 52 *
 53 * Reserve the hardware performance counters in the system for exclusive use.
 54 * Returns 0 on success or -EBUSY if the lock is already held.
 55 */
 56extern int
 57reserve_pmu(enum arm_pmu_type type);
 58
 59/**
 60 * release_pmu() - Relinquish control of the performance counters
 61 *
 62 * Release the performance counters and allow someone else to use them.
 63 */
 64extern void
 65release_pmu(enum arm_pmu_type type);
 66
 67#else /* CONFIG_CPU_HAS_PMU */
 68
 69#include <linux/err.h>
 70
 71static inline int
 72reserve_pmu(enum arm_pmu_type type)
 73{
 74	return -ENODEV;
 75}
 76
 77static inline void
 78release_pmu(enum arm_pmu_type type)	{ }
 79
 80#endif /* CONFIG_CPU_HAS_PMU */
 81
 82#ifdef CONFIG_HW_PERF_EVENTS
 83
 84/* The events for a given PMU register set. */
 85struct pmu_hw_events {
 86	/*
 87	 * The events that are active on the PMU for the given index.
 88	 */
 89	struct perf_event	**events;
 90
 91	/*
 92	 * A 1 bit for an index indicates that the counter is being used for
 93	 * an event. A 0 means that the counter can be used.
 94	 */
 95	unsigned long           *used_mask;
 96
 97	/*
 98	 * Hardware lock to serialize accesses to PMU registers. Needed for the
 99	 * read/modify/write sequences.
100	 */
101	raw_spinlock_t		pmu_lock;
102};
103
104struct arm_pmu {
105	struct pmu	pmu;
106	enum arm_perf_pmu_ids id;
107	enum arm_pmu_type type;
108	cpumask_t	active_irqs;
109	const char	*name;
110	irqreturn_t	(*handle_irq)(int irq_num, void *dev);
111	void		(*enable)(struct hw_perf_event *evt, int idx);
112	void		(*disable)(struct hw_perf_event *evt, int idx);
113	int		(*get_event_idx)(struct pmu_hw_events *hw_events,
114					 struct hw_perf_event *hwc);
115	int		(*set_event_filter)(struct hw_perf_event *evt,
116					    struct perf_event_attr *attr);
117	u32		(*read_counter)(int idx);
118	void		(*write_counter)(int idx, u32 val);
119	void		(*start)(void);
120	void		(*stop)(void);
121	void		(*reset)(void *);
122	int		(*map_event)(struct perf_event *event);
123	int		num_events;
124	atomic_t	active_events;
125	struct mutex	reserve_mutex;
126	u64		max_period;
127	struct platform_device	*plat_device;
128	struct pmu_hw_events	*(*get_hw_events)(void);
129};
130
131#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
132
133int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type);
134
135u64 armpmu_event_update(struct perf_event *event,
136			struct hw_perf_event *hwc,
137			int idx);
138
139int armpmu_event_set_period(struct perf_event *event,
140			    struct hw_perf_event *hwc,
141			    int idx);
142
143#endif /* CONFIG_HW_PERF_EVENTS */
144
145#endif /* __ARM_PMU_H__ */