summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/oprofile/common.c6
-rw-r--r--arch/i386/Makefile2
-rw-r--r--arch/i386/oprofile/init.c9
-rw-r--r--arch/i386/oprofile/nmi_int.c24
-rw-r--r--arch/parisc/oprofile/init.c5
-rw-r--r--arch/ppc64/oprofile/init.c5
-rw-r--r--arch/sparc64/oprofile/init.c5
-rw-r--r--drivers/oprofile/oprof.c1
-rw-r--r--include/linux/oprofile.h5
9 files changed, 59 insertions, 3 deletions
diff --git a/arch/alpha/oprofile/common.c b/arch/alpha/oprofile/common.c
index 3faf5f796083..4f40b8292e99 100644
--- a/arch/alpha/oprofile/common.c
+++ b/arch/alpha/oprofile/common.c
@@ -186,3 +186,9 @@ oprofile_arch_init(struct oprofile_operations **ops)
return 0;
}
+
+
+void __exit
+oprofile_arch_exit(void)
+{
+}
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 7eea7c1def29..4a748322d50c 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -84,7 +84,7 @@ core-y += arch/i386/kernel/ \
arch/i386/$(mcore-y)/
drivers-$(CONFIG_MATH_EMULATION) += arch/i386/math-emu/
drivers-$(CONFIG_PCI) += arch/i386/pci/
-# FIXME: is drivers- right ?
+# must be linked after kernel/
drivers-$(CONFIG_OPROFILE) += arch/i386/oprofile/
CFLAGS += $(mflags-y)
diff --git a/arch/i386/oprofile/init.c b/arch/i386/oprofile/init.c
index c1d72e747506..911c600eb345 100644
--- a/arch/i386/oprofile/init.c
+++ b/arch/i386/oprofile/init.c
@@ -17,6 +17,7 @@
*/
extern int nmi_init(struct oprofile_operations ** ops);
+extern void nmi_exit(void);
extern void timer_init(struct oprofile_operations ** ops);
int __init oprofile_arch_init(struct oprofile_operations ** ops)
@@ -27,3 +28,11 @@ int __init oprofile_arch_init(struct oprofile_operations ** ops)
timer_init(ops);
return 0;
}
+
+
+void __exit oprofile_arch_exit(void)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+ nmi_exit();
+#endif
+}
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
index c158cc895916..54168cc66918 100644
--- a/arch/i386/oprofile/nmi_int.c
+++ b/arch/i386/oprofile/nmi_int.c
@@ -67,15 +67,22 @@ static struct device device_nmi = {
};
-static int __init init_nmi_driverfs(void)
+static int __init init_driverfs(void)
{
driver_register(&nmi_driver);
return device_register(&device_nmi);
}
-late_initcall(init_nmi_driverfs);
+static void __exit exit_driverfs(void)
+{
+ device_unregister(&device_nmi);
+ driver_unregister(&nmi_driver);
+}
+#else
+#define init_driverfs() do { } while (0)
+#define exit_driverfs() do { } while (0)
#endif /* CONFIG_PM */
@@ -297,6 +304,10 @@ static int __init ppro_init(void)
#endif /* !CONFIG_X86_64 */
+
+/* in order to get driverfs right */
+static int using_nmi;
+
int __init nmi_init(struct oprofile_operations ** ops)
{
__u8 vendor = current_cpu_data.x86_vendor;
@@ -339,7 +350,16 @@ int __init nmi_init(struct oprofile_operations ** ops)
return 0;
}
+ init_driverfs();
+ using_nmi = 1;
*ops = &nmi_ops;
printk(KERN_INFO "oprofile: using NMI interrupt.\n");
return 1;
}
+
+
+void __exit nmi_exit(void)
+{
+ if (using_nmi)
+ exit_driverfs();
+}
diff --git a/arch/parisc/oprofile/init.c b/arch/parisc/oprofile/init.c
index c7268ba1a8d2..78adf8e9e5aa 100644
--- a/arch/parisc/oprofile/init.c
+++ b/arch/parisc/oprofile/init.c
@@ -18,3 +18,8 @@ int __init oprofile_arch_init(struct oprofile_operations ** ops)
timer_init(ops);
return 0;
}
+
+
+void __exit oprofile_arch_exit()
+{
+}
diff --git a/arch/ppc64/oprofile/init.c b/arch/ppc64/oprofile/init.c
index c7268ba1a8d2..cb73527a8900 100644
--- a/arch/ppc64/oprofile/init.c
+++ b/arch/ppc64/oprofile/init.c
@@ -18,3 +18,8 @@ int __init oprofile_arch_init(struct oprofile_operations ** ops)
timer_init(ops);
return 0;
}
+
+
+void __exit oprofile_arch_exit(void)
+{
+}
diff --git a/arch/sparc64/oprofile/init.c b/arch/sparc64/oprofile/init.c
index c7268ba1a8d2..cb73527a8900 100644
--- a/arch/sparc64/oprofile/init.c
+++ b/arch/sparc64/oprofile/init.c
@@ -18,3 +18,8 @@ int __init oprofile_arch_init(struct oprofile_operations ** ops)
timer_init(ops);
return 0;
}
+
+
+void __exit oprofile_arch_exit(void)
+{
+}
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
index 04f9131c8dd5..1515d4a39e85 100644
--- a/drivers/oprofile/oprof.c
+++ b/drivers/oprofile/oprof.c
@@ -148,6 +148,7 @@ out:
static void __exit oprofile_exit(void)
{
oprofilefs_unregister();
+ oprofile_arch_exit();
}
diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h
index 5d906c21103f..6dba9058bca0 100644
--- a/include/linux/oprofile.h
+++ b/include/linux/oprofile.h
@@ -46,6 +46,11 @@ struct oprofile_operations {
int oprofile_arch_init(struct oprofile_operations ** ops);
/**
+ * One-time exit/cleanup for the arch.
+ */
+void oprofile_arch_exit(void);
+
+/**
* Add a sample. This may be called from any context. Pass
* smp_processor_id() as cpu.
*/