18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * arch/sh/oprofile/init.c
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (C) 2003 - 2010  Paul Mundt
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Based on arch/mips/oprofile/common.c:
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci *	Copyright (C) 2004, 2005 Ralf Baechle
98c2ecf20Sopenharmony_ci *	Copyright (C) 2005 MIPS Technologies, Inc.
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
128c2ecf20Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
138c2ecf20Sopenharmony_ci * for more details.
148c2ecf20Sopenharmony_ci */
158c2ecf20Sopenharmony_ci#include <linux/kernel.h>
168c2ecf20Sopenharmony_ci#include <linux/oprofile.h>
178c2ecf20Sopenharmony_ci#include <linux/init.h>
188c2ecf20Sopenharmony_ci#include <linux/errno.h>
198c2ecf20Sopenharmony_ci#include <linux/smp.h>
208c2ecf20Sopenharmony_ci#include <linux/perf_event.h>
218c2ecf20Sopenharmony_ci#include <linux/slab.h>
228c2ecf20Sopenharmony_ci#include <asm/processor.h>
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ciextern void sh_backtrace(struct pt_regs * const regs, unsigned int depth);
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci#ifdef CONFIG_HW_PERF_EVENTS
278c2ecf20Sopenharmony_ci/*
288c2ecf20Sopenharmony_ci * This will need to be reworked when multiple PMUs are supported.
298c2ecf20Sopenharmony_ci */
308c2ecf20Sopenharmony_cistatic char *sh_pmu_op_name;
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_cichar *op_name_from_perf_id(void)
338c2ecf20Sopenharmony_ci{
348c2ecf20Sopenharmony_ci	return sh_pmu_op_name;
358c2ecf20Sopenharmony_ci}
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ciint __init oprofile_arch_init(struct oprofile_operations *ops)
388c2ecf20Sopenharmony_ci{
398c2ecf20Sopenharmony_ci	ops->backtrace = sh_backtrace;
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	if (perf_num_counters() == 0)
428c2ecf20Sopenharmony_ci		return -ENODEV;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	sh_pmu_op_name = kasprintf(GFP_KERNEL, "%s/%s",
458c2ecf20Sopenharmony_ci				   UTS_MACHINE, perf_pmu_name());
468c2ecf20Sopenharmony_ci	if (unlikely(!sh_pmu_op_name))
478c2ecf20Sopenharmony_ci		return -ENOMEM;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	return oprofile_perf_init(ops);
508c2ecf20Sopenharmony_ci}
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_civoid oprofile_arch_exit(void)
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci	oprofile_perf_exit();
558c2ecf20Sopenharmony_ci	kfree(sh_pmu_op_name);
568c2ecf20Sopenharmony_ci}
578c2ecf20Sopenharmony_ci#else
588c2ecf20Sopenharmony_ciint __init oprofile_arch_init(struct oprofile_operations *ops)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	ops->backtrace = sh_backtrace;
618c2ecf20Sopenharmony_ci	return -ENODEV;
628c2ecf20Sopenharmony_ci}
638c2ecf20Sopenharmony_civoid oprofile_arch_exit(void) {}
648c2ecf20Sopenharmony_ci#endif /* CONFIG_HW_PERF_EVENTS */
65