return -ENODEV;
        }
 
+       /* default values, can be overwritten by model */
+       ops->create_files = nmi_create_files;
+       ops->setup = nmi_setup;
+       ops->shutdown = nmi_shutdown;
+       ops->start = nmi_start;
+       ops->stop = nmi_stop;
+       ops->cpu_type = cpu_type;
+
        if (model->init)
                ret = model->init(ops);
        if (ret)
 
        init_sysfs();
        using_nmi = 1;
-       ops->create_files = nmi_create_files;
-       ops->setup = nmi_setup;
-       ops->shutdown = nmi_shutdown;
-       ops->start = nmi_start;
-       ops->stop = nmi_stop;
-       ops->cpu_type = cpu_type;
        printk(KERN_INFO "oprofile: using NMI interrupt.\n");
        return 0;
 }
 
                on_each_cpu(apic_clear_ibs_nmi_per_cpu, NULL, 1);
 }
 
+static int (*create_arch_files)(struct super_block * sb, struct dentry * root);
+
 static int setup_ibs_files(struct super_block * sb, struct dentry * root)
 {
        char buf[12];
        struct dentry *dir;
+       int ret = 0;
+
+       /* architecture specific files */
+       if (create_arch_files)
+               ret = create_arch_files(sb, root);
+
+       if (ret)
+               return ret;
 
        if (!ibs_allowed)
-               return 0;
+               return ret;
+
+       /* model specific files */
 
        /* setup some reasonable defaults */
        ibs_config.max_cnt_fetch = 250000;
 
 static int op_amd_init(struct oprofile_operations *ops)
 {
+       setup_ibs();
+       create_arch_files = ops->create_files;
+       ops->create_files = setup_ibs_files;
        return 0;
 }
 
 static void op_amd_exit(void)
 {
+       clear_ibs_nmi();
 }
 
 struct op_x86_model_spec const op_amd_spec = {