linux/arch/blackfin/oprofile/common.c
<<
>>
Prefs
   1/*
   2 * File:         arch/blackfin/oprofile/common.c
   3 * Based on:     arch/alpha/oprofile/common.c
   4 * Author:       Anton Blanchard <anton@au.ibm.com>
   5 *
   6 * Created:
   7 * Description:
   8 *
   9 * Modified:
  10 *               Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
  11 *               Copyright 2004-2006 Analog Devices Inc.
  12 *
  13 * Bugs:         Enter bugs at http://blackfin.uclinux.org/
  14 *
  15 * This program is free software; you can redistribute it and/or modify
  16 * it under the terms of the GNU General Public License as published by
  17 * the Free Software Foundation; either version 2 of the License, or
  18 * (at your option) any later version.
  19 *
  20 * This program is distributed in the hope that it will be useful,
  21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23 * GNU General Public License for more details.
  24 *
  25 * You should have received a copy of the GNU General Public License
  26 * along with this program; if not, see the file COPYING, or write
  27 * to the Free Software Foundation, Inc.,
  28 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  29 */
  30
  31#include <linux/oprofile.h>
  32#include <linux/init.h>
  33#include <linux/smp.h>
  34#include <linux/errno.h>
  35#include <linux/mutex.h>
  36#include <linux/ptrace.h>
  37#include <linux/irq.h>
  38#include <linux/io.h>
  39
  40#include <asm/system.h>
  41#include <asm/blackfin.h>
  42
  43#include "op_blackfin.h"
  44
  45#define BFIN_533_ID  0xE5040003
  46#define BFIN_537_ID  0xE5040002
  47
  48static int pfmon_enabled;
  49static struct mutex pfmon_lock;
  50
  51struct op_bfin533_model *model;
  52
  53struct op_counter_config ctr[OP_MAX_COUNTER];
  54
  55static int op_bfin_setup(void)
  56{
  57        int ret;
  58
  59        /* Pre-compute the values to stuff in the hardware registers.  */
  60        spin_lock(&oprofilefs_lock);
  61        ret = model->reg_setup(ctr);
  62        spin_unlock(&oprofilefs_lock);
  63
  64        return ret;
  65}
  66
  67static void op_bfin_shutdown(void)
  68{
  69#if 0
  70        /* what is the difference between shutdown and stop? */
  71#endif
  72}
  73
  74static int op_bfin_start(void)
  75{
  76        int ret = -EBUSY;
  77
  78        printk(KERN_INFO "KSDBG:in %s\n", __func__);
  79        mutex_lock(&pfmon_lock);
  80        if (!pfmon_enabled) {
  81                ret = model->start(ctr);
  82                pfmon_enabled = !ret;
  83        }
  84        mutex_unlock(&pfmon_lock);
  85
  86        return ret;
  87}
  88
  89static void op_bfin_stop(void)
  90{
  91        mutex_lock(&pfmon_lock);
  92        if (pfmon_enabled) {
  93                model->stop();
  94                pfmon_enabled = 0;
  95        }
  96        mutex_unlock(&pfmon_lock);
  97}
  98
  99static int op_bfin_create_files(struct super_block *sb, struct dentry *root)
 100{
 101        int i;
 102
 103        for (i = 0; i < model->num_counters; ++i) {
 104                struct dentry *dir;
 105                char buf[3];
 106                printk(KERN_INFO "Oprofile: creating files... \n");
 107
 108                snprintf(buf, sizeof buf, "%d", i);
 109                dir = oprofilefs_mkdir(sb, root, buf);
 110
 111                oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
 112                oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
 113                oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
 114                /*
 115                 * We dont support per counter user/kernel selection, but
 116                 * we leave the entries because userspace expects them
 117                 */
 118                oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
 119                oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
 120                oprofilefs_create_ulong(sb, dir, "unit_mask",
 121                                        &ctr[i].unit_mask);
 122        }
 123
 124        return 0;
 125}
 126int __init oprofile_arch_init(struct oprofile_operations *ops)
 127{
 128#ifdef CONFIG_HARDWARE_PM
 129        unsigned int dspid;
 130
 131        mutex_init(&pfmon_lock);
 132
 133        dspid = bfin_read_DSPID();
 134
 135        printk(KERN_INFO "Oprofile got the cpu id is 0x%x. \n", dspid);
 136
 137        switch (dspid) {
 138        case BFIN_533_ID:
 139                model = &op_model_bfin533;
 140                model->num_counters = 2;
 141                break;
 142        case BFIN_537_ID:
 143                model = &op_model_bfin533;
 144                model->num_counters = 2;
 145                break;
 146        default:
 147                return -ENODEV;
 148        }
 149
 150        ops->cpu_type = model->name;
 151        ops->create_files = op_bfin_create_files;
 152        ops->setup = op_bfin_setup;
 153        ops->shutdown = op_bfin_shutdown;
 154        ops->start = op_bfin_start;
 155        ops->stop = op_bfin_stop;
 156
 157        printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
 158               ops->cpu_type);
 159
 160        return 0;
 161#else
 162        return -1;
 163#endif
 164}
 165
 166void oprofile_arch_exit(void)
 167{
 168}
 169