common.c

来自「底层驱动开发」· C语言 代码 · 共 157 行

C
157
字号
/** * @file common.c * * @remark Copyright 2004 Oprofile Authors * @remark Read the file COPYING * * @author Zwane Mwaikambo */#include <linux/init.h>#include <linux/oprofile.h>#include <linux/errno.h>#include <asm/semaphore.h>#include <linux/sysdev.h>#include "op_counter.h"#include "op_arm_model.h"static struct op_arm_model_spec *pmu_model;static int pmu_enabled;static struct semaphore pmu_sem;static int pmu_start(void);static int pmu_setup(void);static void pmu_stop(void);static int pmu_create_files(struct super_block *, struct dentry *);#ifdef CONFIG_PMstatic int pmu_suspend(struct sys_device *dev, pm_message_t state){	if (pmu_enabled)		pmu_stop();	return 0;}static int pmu_resume(struct sys_device *dev){	if (pmu_enabled)		pmu_start();	return 0;}static struct sysdev_class oprofile_sysclass = {	set_kset_name("oprofile"),	.resume		= pmu_resume,	.suspend	= pmu_suspend,};static struct sys_device device_oprofile = {	.id		= 0,	.cls		= &oprofile_sysclass,};static int __init init_driverfs(void){	int ret;	if (!(ret = sysdev_class_register(&oprofile_sysclass)))		ret = sysdev_register(&device_oprofile);	return ret;}static void  exit_driverfs(void){	sysdev_unregister(&device_oprofile);	sysdev_class_unregister(&oprofile_sysclass);}#else#define init_driverfs()	do { } while (0)#define exit_driverfs() do { } while (0)#endif /* CONFIG_PM */struct op_counter_config counter_config[OP_MAX_COUNTER];static int pmu_create_files(struct super_block *sb, struct dentry *root){	unsigned int i;	for (i = 0; i < pmu_model->num_counters; i++) {		struct dentry *dir;		char buf[2];		snprintf(buf, sizeof buf, "%d", i);		dir = oprofilefs_mkdir(sb, root, buf);		oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled);		oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event);		oprofilefs_create_ulong(sb, dir, "count", &counter_config[i].count);		oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask);		oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel);		oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user);	}	return 0;}static int pmu_setup(void){	int ret;	spin_lock(&oprofilefs_lock);	ret = pmu_model->setup_ctrs();	spin_unlock(&oprofilefs_lock);	return ret;}static int pmu_start(void){	int ret = -EBUSY;	down(&pmu_sem);	if (!pmu_enabled) {		ret = pmu_model->start();		pmu_enabled = !ret;	}	up(&pmu_sem);	return ret;}static void pmu_stop(void){	down(&pmu_sem);	if (pmu_enabled)		pmu_model->stop();	pmu_enabled = 0;	up(&pmu_sem);}int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec){	init_MUTEX(&pmu_sem);	if (spec->init() < 0)		return -ENODEV;	pmu_model = spec;	init_driverfs();	ops->create_files = pmu_create_files;	ops->setup = pmu_setup;	ops->shutdown = pmu_stop;	ops->start = pmu_start;	ops->stop = pmu_stop;	ops->cpu_type = pmu_model->name;	printk(KERN_INFO "oprofile: using %s PMU\n", spec->name);	return 0;}void pmu_exit(void){	if (pmu_model) {		exit_driverfs();		pmu_model = NULL;	}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?