#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 int pmu_create_files(struct super_block *, struct dentry *);
#ifdef CONFIG_PM
+static int pmu_suspend(struct sys_device *dev, u32 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,
int ret;
if (!(ret = sysdev_class_register(&oprofile_sysclass)))
- ret = sys_device_register(&device_oprofile);
+ ret = sysdev_register(&device_oprofile);
return ret;
}
-static void __exit exit_driverfs(void)
+static void exit_driverfs(void)
{
- sys_device_unregister(&device_oprofile);
+ sysdev_unregister(&device_oprofile);
sysdev_class_unregister(&oprofile_sysclass);
}
#else
up(&pmu_sem);
}
-int __init
-pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec)
+int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec)
{
init_MUTEX(&pmu_sem);
extern struct op_arm_model_spec op_xscale_spec;
#endif
-extern int pmu_init(struct oprofile_operations **ops, struct op_arm_model_spec *spec);
+extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
extern void pmu_exit(void);
#endif /* OP_ARM_MODEL_H */
#ifdef CONFIG_ARCH_IOP331
#define XSCALE_PMU_IRQ IRQ_IOP331_CORE_PMU
#endif
+#ifdef CONFIG_ARCH_PXA
+#define XSCALE_PMU_IRQ IRQ_PMU
+#endif
/*
* Different types of events that can be counted by the XScale PMU
/* Overflow bit gets cleared. There's no workaround. */
/* Fixed in B stepping or later */
- pmnc &= ~(PMU_ENABLE | pmu->cnt_ovf[PMN0] | pmu->cnt_ovf[PMN1] |
- pmu->cnt_ovf[CCNT]);
- write_pmnc(pmnc);
+ /* Write the value back to clear the overflow flags. Overflow */
+ /* flags remain in pmnc for use below */
+ write_pmnc(pmnc & ~PMU_ENABLE);
for (i = CCNT; i <= PMN1; i++) {
if (!(pmu->int_mask[i] & pmu->int_enable))