1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * arch/sh/oprofile/init.c 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Copyright (C) 2003 - 2010 Paul Mundt 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Based on arch/mips/oprofile/common.c: 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * Copyright (C) 2004, 2005 Ralf Baechle 9*4882a593Smuzhiyun * Copyright (C) 2005 MIPS Technologies, Inc. 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun * This file is subject to the terms and conditions of the GNU General Public 12*4882a593Smuzhiyun * License. See the file "COPYING" in the main directory of this archive 13*4882a593Smuzhiyun * for more details. 14*4882a593Smuzhiyun */ 15*4882a593Smuzhiyun #include <linux/kernel.h> 16*4882a593Smuzhiyun #include <linux/oprofile.h> 17*4882a593Smuzhiyun #include <linux/init.h> 18*4882a593Smuzhiyun #include <linux/errno.h> 19*4882a593Smuzhiyun #include <linux/smp.h> 20*4882a593Smuzhiyun #include <linux/perf_event.h> 21*4882a593Smuzhiyun #include <linux/slab.h> 22*4882a593Smuzhiyun #include <asm/processor.h> 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun extern void sh_backtrace(struct pt_regs * const regs, unsigned int depth); 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun #ifdef CONFIG_HW_PERF_EVENTS 27*4882a593Smuzhiyun /* 28*4882a593Smuzhiyun * This will need to be reworked when multiple PMUs are supported. 29*4882a593Smuzhiyun */ 30*4882a593Smuzhiyun static char *sh_pmu_op_name; 31*4882a593Smuzhiyun op_name_from_perf_id(void)32*4882a593Smuzhiyunchar *op_name_from_perf_id(void) 33*4882a593Smuzhiyun { 34*4882a593Smuzhiyun return sh_pmu_op_name; 35*4882a593Smuzhiyun } 36*4882a593Smuzhiyun oprofile_arch_init(struct oprofile_operations * ops)37*4882a593Smuzhiyunint __init oprofile_arch_init(struct oprofile_operations *ops) 38*4882a593Smuzhiyun { 39*4882a593Smuzhiyun ops->backtrace = sh_backtrace; 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun if (perf_num_counters() == 0) 42*4882a593Smuzhiyun return -ENODEV; 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun sh_pmu_op_name = kasprintf(GFP_KERNEL, "%s/%s", 45*4882a593Smuzhiyun UTS_MACHINE, perf_pmu_name()); 46*4882a593Smuzhiyun if (unlikely(!sh_pmu_op_name)) 47*4882a593Smuzhiyun return -ENOMEM; 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun return oprofile_perf_init(ops); 50*4882a593Smuzhiyun } 51*4882a593Smuzhiyun oprofile_arch_exit(void)52*4882a593Smuzhiyunvoid oprofile_arch_exit(void) 53*4882a593Smuzhiyun { 54*4882a593Smuzhiyun oprofile_perf_exit(); 55*4882a593Smuzhiyun kfree(sh_pmu_op_name); 56*4882a593Smuzhiyun } 57*4882a593Smuzhiyun #else oprofile_arch_init(struct oprofile_operations * ops)58*4882a593Smuzhiyunint __init oprofile_arch_init(struct oprofile_operations *ops) 59*4882a593Smuzhiyun { 60*4882a593Smuzhiyun ops->backtrace = sh_backtrace; 61*4882a593Smuzhiyun return -ENODEV; 62*4882a593Smuzhiyun } oprofile_arch_exit(void)63*4882a593Smuzhiyunvoid oprofile_arch_exit(void) {} 64*4882a593Smuzhiyun #endif /* CONFIG_HW_PERF_EVENTS */ 65