It is currently Fri, 23 Oct 2020 17:58:47 GMT



 
Author Message
 Convert APIC to driver model: now it works with SMP
Hi!

I've undone part of renaming, so that now it actually works with
SMP. Sorry.

                                                        Pavel

%patch
Index: linux/arch/i386/kernel/apic.c
===================================================================
--- linux.orig/arch/i386/kernel/apic.c  2003-03-30 19:57:18.000000000 +0200
+++ linux/arch/i386/kernel/apic.c       2003-03-30 20:20:15.000000000 +0200
@@ -10,6 +10,8 @@
  *                                     for testing these extensively.
  *     Maciej W. Rozycki       :       Various updates and fixes.
  *     Mikael Pettersson       :       Power Management for UP-APIC.
+ *     Pavel Machek and
+ *     Mikael Pettersson       :       Converted to driver model.
  */

 #include <linux/config.h>
@@ -23,6 +25,10 @@
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/pm.h>

 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -304,6 +310,27 @@
        apic_write_around(APIC_LVT1, value);
 }

+static struct {
+       /* 'active' is true if the local APIC was enabled by us and
+          not the BIOS; this signifies that we are also responsible
+          for disabling it before entering apm/acpi suspend */
+       int active;
+       /* r/w apic fields */
+       unsigned int apic_id;
+       unsigned int apic_taskpri;
+       unsigned int apic_ldr;
+       unsigned int apic_dfr;
+       unsigned int apic_spiv;
+       unsigned int apic_lvtt;
+       unsigned int apic_lvtpc;
+       unsigned int apic_lvt0;
+       unsigned int apic_lvt1;
+       unsigned int apic_lvterr;
+       unsigned int apic_tmict;
+       unsigned int apic_tdcr;
+       unsigned int apic_thmr;
+} apic_pm_state;
+
 void __init setup_local_APIC (void)
 {
        unsigned long value, ver, maxlvt;
@@ -445,46 +472,24 @@
                        printk("No ESR for 82489DX.\n");
        }

-       if (nmi_watchdog == NMI_LOCAL_APIC)
-               setup_apic_nmi_watchdog();
+       if (nmi_watchdog == NMI_LOCAL_APIC) {
+               enable_lapic_nmi_watchdog();
+       }
+
+       apic_pm_state.active = 1;
 }

 #ifdef CONFIG_PM
-
-#include <linux/slab.h>
-#include <linux/pm.h>
-
-static struct {
-       /* 'active' is true if the local APIC was enabled by us and
-          not the BIOS; this signifies that we are also responsible
-          for disabling it before entering apm/acpi suspend */
-       int active;
-       /* 'perfctr_pmdev' is here because the current (2.4.1) PM
-          callback system doesn't handle hierarchical dependencies */
-       struct pm_dev *perfctr_pmdev;
-       /* r/w apic fields */
-       unsigned int apic_id;
-       unsigned int apic_taskpri;
-       unsigned int apic_ldr;
-       unsigned int apic_dfr;
-       unsigned int apic_spiv;
-       unsigned int apic_lvtt;
-       unsigned int apic_lvtpc;
-       unsigned int apic_lvt0;
-       unsigned int apic_lvt1;
-       unsigned int apic_lvterr;
-       unsigned int apic_tmict;
-       unsigned int apic_tdcr;
-       unsigned int apic_thmr;
-} apic_pm_state;
-
-static void apic_pm_suspend(void *data)
+static int lapic_suspend(struct device *dev, u32 state, u32 level)
 {
        unsigned int l, h;
        unsigned long flags;

-       if (apic_pm_state.perfctr_pmdev)
-               pm_send(apic_pm_state.perfctr_pmdev, PM_SUSPEND, data);
+       if (level != SUSPEND_POWER_DOWN)
+               return 0;
+       if (!apic_pm_state.active)
+               return 0;
+
        apic_pm_state.apic_id = apic_read(APIC_ID);
        apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI);
        apic_pm_state.apic_ldr = apic_read(APIC_LDR);
@@ -505,13 +510,21 @@
        l &= ~MSR_IA32_APICBASE_ENABLE;
        wrmsr(MSR_IA32_APICBASE, l, h);
        local_irq_restore(flags);
+       return 0;
 }

-static void apic_pm_resume(void *data)
+static int lapic_resume(struct device *dev, u32 level)
 {
        unsigned int l, h;
        unsigned long flags;

+       if (level != RESUME_POWER_ON)
+               return 0;
+       if (!apic_pm_state.active)
+               return 0;
+
+       set_fixmap_nocache(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE);      /* FIXME: this is needed for S3 resume, but why? */
+
        local_irq_save(flags);
        rdmsr(MSR_IA32_APICBASE, l, h);
        l &= ~MSR_IA32_APICBASE_BASE;
@@ -536,74 +549,35 @@
        apic_write(APIC_ESR, 0);
        apic_read(APIC_ESR);
        local_irq_restore(flags);
-       if (apic_pm_state.perfctr_pmdev)
-               pm_send(apic_pm_state.perfctr_pmdev, PM_RESUME, data);
-}
-
-static int apic_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
-{
-       switch (rqst) {
-       case PM_SUSPEND:
-               apic_pm_suspend(data);
-               break;
-       case PM_RESUME:
-               apic_pm_resume(data);
-               break;
-       }
        return 0;
 }

-/* perfctr driver should call this instead of pm_register() */
-struct pm_dev *apic_pm_register(pm_dev_t type,
-                               unsigned long id,
-                               pm_callback callback)
-{
-       struct pm_dev *dev;
-
-       if (!apic_pm_state.active)
-               return pm_register(type, id, callback);
-       if (apic_pm_state.perfctr_pmdev)
-               return NULL;    /* we're busy */
-       dev = kmalloc(sizeof(struct pm_dev), GFP_KERNEL);
-       if (dev) {
-               memset(dev, 0, sizeof(*dev));
-               dev->type = type;
-               dev->id = id;
-               dev->callback = callback;
-               apic_pm_state.perfctr_pmdev = dev;
-       }
-       return dev;
-}
-
-/* perfctr driver should call this instead of pm_unregister() */
-void apic_pm_unregister(struct pm_dev *dev)
-{
-       if (!apic_pm_state.active) {
-               pm_unregister(dev);
-       } else if (dev == apic_pm_state.perfctr_pmdev) {
-               apic_pm_state.perfctr_pmdev = NULL;
-               kfree(dev);
-       }
-}
-
-static void __init apic_pm_init1(void)
-{
-       /* can't pm_register() at this early stage in the boot process
-          (causes an immediate reboot), so just set the flag */
-       apic_pm_state.active = 1;
-}
+static struct device_driver lapic_driver = {
+       .name           = "apic",
+       .bus            = &system_bus_type,
+       .resume         = lapic_resume,
+       .suspend        = lapic_suspend,
+};
+
+/* not static, needed by child devices */
+struct sys_device device_lapic = {
+       .name           = "apic",
+       .id             = 0,
+       .dev            = {
+               .name   = "lapic",
+               .driver = &lapic_driver,
+       },
+};

-static void __init apic_pm_init2(void)
+static int __init init_apic_devicefs(void)
 {
+       driver_register(&lapic_driver);
        if (apic_pm_state.active)
-               pm_register(PM_SYS_DEV, 0, apic_pm_callback);
+               return sys_device_register(&device_lapic);
+       return 0;
 }

-#else  /* CONFIG_PM */
-
-static inline void apic_pm_init1(void) { }
-static inline void apic_pm_init2(void) { }
-
+device_initcall(init_apic_devicefs);
 #endif /* CONFIG_PM */

 /*
@@ -669,9 +643,6 @@
                nmi_watchdog = NMI_LOCAL_APIC;

        printk("Found and enabled local APIC!\n");
-
-       apic_pm_init1();
-
        return 0;

 no_apic:
@@ -682,7 +653,6 @@
 void __init init_apic_mappings(void)
 {
        unsigned long apic_phys;
-
        /*
         * If no local APIC can be found then set up a fake all
         * zeroes page to simulate the local APIC and another
@@ -1150,13 +1120,10 @@
        }

        verify_local_APIC();
-
        connect_bsp_APIC();

        phys_cpu_present_map = 1 << boot_cpu_physical_apicid;

-       apic_pm_init2();
-
        setup_local_APIC();

        if (nmi_watchdog == NMI_LOCAL_APIC)
Index: linux/arch/i386/kernel/apm.c
===================================================================
--- linux.orig/arch/i386/kernel/apm.c   2003-03-30 19:57:18.000000000 +0200
+++ linux/arch/i386/kernel/apm.c        2003-03-30 20:01:56.000000000 +0200
@@ -221,6 +221,7 @@
 #include <linux/kernel.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/device.h>

 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -1237,6 +1238,10 @@
                }
                printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n");
        }
+
+      
+       device_suspend(3, SUSPEND_POWER_DOWN);
+
        /* serialize with the timer interrupt */
        write_seqlock_irq(&xtime_lock);

@@ -1257,6 +1262,7 @@
        if (err != APM_SUCCESS)
                apm_error("suspend", err);
        err = (err == APM_SUCCESS) ? 0 : -EIO;
+       device_resume(RESUME_POWER_ON);
        pm_send_all(PM_RESUME, (void *)0);
        queue_event(APM_NORMAL_RESUME, NULL);
  out:
@@ -1370,6 +1376,7 @@
                                write_seqlock_irq(&xtime_lock);
                                set_time();
                                write_sequnlock_irq(&xtime_lock);
+                               device_resume(RESUME_POWER_ON);
                                pm_send_all(PM_RESUME, (void *)0);
                                queue_event(event, NULL);
                        }
Index: linux/arch/i386/kernel/i386_ksyms.c
===================================================================
--- linux.orig/arch/i386/kernel/i386_ksyms.c    2003-03-30 19:57:18.000000000 +0200
+++ linux/arch/i386/kernel/i386_ksyms.c 2003-03-30 20:01:56.000000000 +0200
@@ -163,10 +163,6 @@
 EXPORT_SYMBOL(flush_tlb_page);
 #endif

-#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PM)
-EXPORT_SYMBOL_GPL(set_nmi_pm_callback);
-EXPORT_SYMBOL_GPL(unset_nmi_pm_callback);
-#endif
 #ifdef CONFIG_X86_IO_APIC
 EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
 #endif
Index: linux/arch/i386/kernel/nmi.c
===================================================================
--- linux.orig/arch/i386/kernel/nmi.c   2003-03-30 19:57:18.000000000 +0200
+++ linux/arch/i386/kernel/nmi.c        2003-03-30 20:01:56.000000000 +0200
@@ -9,6 +9,8 @@
  *  Mikael Pettersson  : AMD K7 support for local APIC NMI watchdog.
  *  Mikael Pettersson  : Power Management for local APIC NMI watchdog.
  *  Mikael Pettersson  : Pentium 4 support for local APIC NMI watchdog.
+ *  Pavel Machek and
+ *  Mikael Pettersson  : PM converted to driver model. disable/enable API.
  */

 #include <linux/config.h>
@@ -20,6 +22,8 @@
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
+#include <linux/device.h>
+#include <linux/module.h>

 #include <asm/smp.h>
 #include <asm/mtrr.h>
@@ -29,6 +33,7 @@
 static unsigned int nmi_hz = HZ;
 unsigned int nmi_perfctr_msr;  /* the MSR to reset in NMI handler */
 extern void show_registers(struct pt_regs *regs);
+static int nmi_active;

 #define K7_EVNTSEL_ENABLE      (1 << 22)
 #define K7_EVNTSEL_INT         (1 << 20)
@@ -117,7 +122,7 @@
         */
        if ((nmi == NMI_LOCAL_APIC) &&
                        (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
-                       (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15))
+                       (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15))
                nmi_watchdog = nmi;
        if ((nmi == NMI_LOCAL_APIC) &&
                        (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
@@ -134,14 +139,11 @@

 __setup("nmi_watchdog=", setup_nmi_watchdog);

-#ifdef CONFIG_PM
-
-#include <linux/pm.h>
-
-struct pm_dev *nmi_pmdev;

-static void disable_apic_nmi_watchdog(void)
+void disable_lapic_nmi_watchdog(void)
 {
+       if (!nmi_active)
+               return;
        switch (boot_cpu_data.x86_vendor) {
...

read more »



 Thu, 15 Sep 2005 20:50:17 GMT   
 Convert APIC to driver model: now it works with SMP
arch/i386/oprofile/nmi_int.c:102: warning: initialization from incompatible pointer type
arch/i386/oprofile/nmi_int.c: In function `init_nmi_driverfs':
arch/i386/oprofile/nmi_int.c:129: warning: control reaches end of non-void function

arch/i386/oprofile/built-in.o(.data+0x568): undefined reference to `device_lapic'

Config is at:
ftp://ftp.kernel.org/pub/linux/kernel/people/mbligh/config/config.numaq

--On Sunday, March 30, 2003 21:30:27 +0200 Pavel Machek <pa...@ucw.cz> wrote:
...

read more »



 Sat, 17 Sep 2005 08:10:10 GMT   
 Convert APIC to driver model: now it works with SMP

Can you try Mikael's (preferable) patch ?

regards,
john
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



 Sat, 17 Sep 2005 16:50:07 GMT   
 Convert APIC to driver model: now it works with SMP

Here's an updated patch for .66, tested on my two-way with OProfile,
CONFIG_PM=yes

It also fixes the CONFIG_PM=n horkage you saw Martin, and some minor
style cleanups in nmi_int.c

regards,
john

diff -Naur -X dontdiff linux-linus/arch/i386/kernel/apic.c linux/arch/i386/kernel/apic.c
--- linux-linus/arch/i386/kernel/apic.c 2003-03-17 21:44:51.000000000 +0000
+++ linux/arch/i386/kernel/apic.c       2003-04-01 17:20:23.000000000 +0100
@@ -10,6 +10,8 @@
  *                                     for testing these extensively.
  *     Maciej W. Rozycki       :       Various updates and fixes.
  *     Mikael Pettersson       :       Power Management for UP-APIC.
+ *     Pavel Machek and
+ *     Mikael Pettersson       :       PM converted to driver model.
  */

 #include <linux/config.h>
@@ -451,17 +453,14 @@

 #ifdef CONFIG_PM

-#include <linux/slab.h>
-#include <linux/pm.h>
+#include <linux/device.h>
+#include <linux/module.h>

 static struct {
        /* 'active' is true if the local APIC was enabled by us and
           not the BIOS; this signifies that we are also responsible
           for disabling it before entering apm/acpi suspend */
        int active;
-       /* 'perfctr_pmdev' is here because the current (2.4.1) PM
-          callback system doesn't handle hierarchical dependencies */
-       struct pm_dev *perfctr_pmdev;
        /* r/w apic fields */
        unsigned int apic_id;
        unsigned int apic_taskpri;
@@ -478,13 +477,16 @@
        unsigned int apic_thmr;
 } apic_pm_state;

-static void apic_pm_suspend(void *data)
+static int lapic_suspend(struct device *dev, u32 state, u32 level)
 {
        unsigned int l, h;
        unsigned long flags;

-       if (apic_pm_state.perfctr_pmdev)
-               pm_send(apic_pm_state.perfctr_pmdev, PM_SUSPEND, data);
+       if (level != SUSPEND_POWER_DOWN)
+               return 0;
+       if (!apic_pm_state.active)
+               return 0;
+
        apic_pm_state.apic_id = apic_read(APIC_ID);
        apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI);
        apic_pm_state.apic_ldr = apic_read(APIC_LDR);
@@ -505,13 +507,22 @@
        l &= ~MSR_IA32_APICBASE_ENABLE;
        wrmsr(MSR_IA32_APICBASE, l, h);
        local_irq_restore(flags);
+       return 0;
 }

-static void apic_pm_resume(void *data)
+static int lapic_resume(struct device *dev, u32 level)
 {
        unsigned int l, h;
        unsigned long flags;

+       if (level != RESUME_POWER_ON)
+               return 0;
+       if (!apic_pm_state.active)
+               return 0;
+
+       /* XXX: Pavel needs this for S3 resume, but can't explain why */
+       set_fixmap_nocache(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE);
+
        local_irq_save(flags);
        rdmsr(MSR_IA32_APICBASE, l, h);
        l &= ~MSR_IA32_APICBASE_BASE;
@@ -536,73 +547,45 @@
        apic_write(APIC_ESR, 0);
        apic_read(APIC_ESR);
        local_irq_restore(flags);
-       if (apic_pm_state.perfctr_pmdev)
-               pm_send(apic_pm_state.perfctr_pmdev, PM_RESUME, data);
-}
-
-static int apic_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
-{
-       switch (rqst) {
-       case PM_SUSPEND:
-               apic_pm_suspend(data);
-               break;
-       case PM_RESUME:
-               apic_pm_resume(data);
-               break;
-       }
        return 0;
 }

-/* perfctr driver should call this instead of pm_register() */
-struct pm_dev *apic_pm_register(pm_dev_t type,
-                               unsigned long id,
-                               pm_callback callback)
-{
-       struct pm_dev *dev;
-
-       if (!apic_pm_state.active)
-               return pm_register(type, id, callback);
-       if (apic_pm_state.perfctr_pmdev)
-               return NULL;    /* we're busy */
-       dev = kmalloc(sizeof(struct pm_dev), GFP_KERNEL);
-       if (dev) {
-               memset(dev, 0, sizeof(*dev));
-               dev->type = type;
-               dev->id = id;
-               dev->callback = callback;
-               apic_pm_state.perfctr_pmdev = dev;
-       }
-       return dev;
-}
-
-/* perfctr driver should call this instead of pm_unregister() */
-void apic_pm_unregister(struct pm_dev *dev)
-{
-       if (!apic_pm_state.active) {
-               pm_unregister(dev);
-       } else if (dev == apic_pm_state.perfctr_pmdev) {
-               apic_pm_state.perfctr_pmdev = NULL;
-               kfree(dev);
-       }
-}
+static struct device_driver lapic_driver = {
+       .name           = "lapic",
+       .bus            = &system_bus_type,
+       .resume         = lapic_resume,
+       .suspend        = lapic_suspend,
+};
+
+/* not static, needed by child devices */
+struct sys_device device_lapic = {
+       .name           = "lapic",
+       .id             = 0,
+       .dev            = {
+               .name   = "lapic",
+               .driver = &lapic_driver,
+       },
+};
+EXPORT_SYMBOL(device_lapic);

-static void __init apic_pm_init1(void)
+static void __init apic_pm_activate(void)
 {
-       /* can't pm_register() at this early stage in the boot process
-          (causes an immediate reboot), so just set the flag */
        apic_pm_state.active = 1;
 }

-static void __init apic_pm_init2(void)
+static int __init init_lapic_devicefs(void)
 {
-       if (apic_pm_state.active)
-               pm_register(PM_SYS_DEV, 0, apic_pm_callback);
+       if (!cpu_has_apic)
+               return 0;
+       /* XXX: remove suspend/resume procs if !apic_pm_state.active? */
+       driver_register(&lapic_driver);
+       return sys_device_register(&device_lapic);
 }
+device_initcall(init_lapic_devicefs);

 #else  /* CONFIG_PM */

-static inline void apic_pm_init1(void) { }
-static inline void apic_pm_init2(void) { }
+static inline void apic_pm_activate(void) { }

 #endif /* CONFIG_PM */

@@ -670,7 +653,7 @@

        printk("Found and enabled local APIC!\n");

-       apic_pm_init1();
+       apic_pm_activate();

        return 0;

@@ -1155,8 +1138,6 @@

        phys_cpu_present_map = 1 << boot_cpu_physical_apicid;

-       apic_pm_init2();
-
        setup_local_APIC();

        if (nmi_watchdog == NMI_LOCAL_APIC)
diff -Naur -X dontdiff linux-linus/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c
--- linux-linus/arch/i386/kernel/apm.c  2003-03-17 21:43:39.000000000 +0000
+++ linux/arch/i386/kernel/apm.c        2003-04-01 17:20:23.000000000 +0100
@@ -218,6 +218,7 @@
 #include <linux/time.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
+#include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
@@ -1237,6 +1238,9 @@
                }
                printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n");
        }
+
+       device_suspend(3, SUSPEND_POWER_DOWN);
+
        /* serialize with the timer interrupt */
        write_seqlock_irq(&xtime_lock);

@@ -1257,6 +1261,7 @@
        if (err != APM_SUCCESS)
                apm_error("suspend", err);
        err = (err == APM_SUCCESS) ? 0 : -EIO;
+       device_resume(RESUME_POWER_ON);
        pm_send_all(PM_RESUME, (void *)0);
        queue_event(APM_NORMAL_RESUME, NULL);
  out:
@@ -1370,6 +1375,7 @@
                                write_seqlock_irq(&xtime_lock);
                                set_time();
                                write_sequnlock_irq(&xtime_lock);
+                               device_resume(RESUME_POWER_ON);
                                pm_send_all(PM_RESUME, (void *)0);
                                queue_event(event, NULL);
                        }
diff -Naur -X dontdiff linux-linus/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- linux-linus/arch/i386/kernel/i386_ksyms.c   2003-03-17 21:44:50.000000000 +0000
+++ linux/arch/i386/kernel/i386_ksyms.c 2003-04-01 17:20:23.000000000 +0100
@@ -163,10 +163,6 @@
 EXPORT_SYMBOL(flush_tlb_page);
 #endif

-#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PM)
-EXPORT_SYMBOL_GPL(set_nmi_pm_callback);
-EXPORT_SYMBOL_GPL(unset_nmi_pm_callback);
-#endif
 #ifdef CONFIG_X86_IO_APIC
 EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
 #endif
diff -Naur -X dontdiff linux-linus/arch/i386/kernel/nmi.c linux/arch/i386/kernel/nmi.c
--- linux-linus/arch/i386/kernel/nmi.c  2003-03-17 21:44:07.000000000 +0000
+++ linux/arch/i386/kernel/nmi.c        2003-04-01 17:20:23.000000000 +0100
@@ -9,6 +9,8 @@
  *  Mikael Pettersson  : AMD K7 support for local APIC NMI watchdog.
  *  Mikael Pettersson  : Power Management for local APIC NMI watchdog.
  *  Mikael Pettersson  : Pentium 4 support for local APIC NMI watchdog.
+ *  Pavel Machek and
+ *  Mikael Pettersson  : PM converted to driver model. Disable/enable API.
  */

 #include <linux/config.h>
@@ -20,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
+#include <linux/module.h>

 #include <asm/smp.h>
 #include <asm/mtrr.h>
@@ -134,14 +137,18 @@

 __setup("nmi_watchdog=", setup_nmi_watchdog);

-#ifdef CONFIG_PM
-
-#include <linux/pm.h>
-
-struct pm_dev *nmi_pmdev;
+/* nmi_active:
+ * +1: the lapic NMI watchdog is active, but can be disabled
+ *  0: the lapic NMI watchdog has not been set up, and cannot
+ *     be enabled
+ * -1: the lapic NMI watchdog is disabled, but can be enabled
+ */
+static int nmi_active;

-static void disable_apic_nmi_watchdog(void)
+void disable_lapic_nmi_watchdog(void)
 {
+       if (nmi_active <= 0)
+               return;
        switch (boot_cpu_data.x86_vendor) {
        case X86_VENDOR_AMD:
                wrmsr(MSR_K7_EVNTSEL0, 0, 0);
@@ -158,46 +165,65 @@
                }
                break;
        }
+       nmi_active = -1;
+       /* tell do_nmi() and others that we're not active any more */
+       nmi_watchdog = 0;
 }

-static int nmi_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
+void enable_lapic_nmi_watchdog(void)
 {
-       switch (rqst) {
-       case PM_SUSPEND:
-               disable_apic_nmi_watchdog();
-               break;
-       case PM_RESUME:
+       if (nmi_active < 0) {
+               nmi_watchdog = NMI_LOCAL_APIC;
                setup_apic_nmi_watchdog();
-               break;
        }
-       return 0;
 }

-struct pm_dev * set_nmi_pm_callback(pm_callback callback)
-{
-       apic_pm_unregister(nmi_pmdev);
-       return apic_pm_register(PM_SYS_DEV, 0, callback);
-}
+#ifdef CONFIG_PM
+
+#include <linux/device.h>

-void unset_nmi_pm_callback(struct pm_dev * dev)
+static int lapic_nmi_suspend(struct device *dev, u32 state, u32 level)
 {
-       apic_pm_unregister(dev);
-       nmi_pmdev = apic_pm_register(PM_SYS_DEV, 0, nmi_pm_callback);
+       if (level != SUSPEND_POWER_DOWN)
+               return 0;
+       disable_lapic_nmi_watchdog();
+       return 0;
 }
-
-static void nmi_pm_init(void)
+
+static int lapic_nmi_resume(struct device *dev, u32 level)
 {
-       if (!nmi_pmdev)
-               nmi_pmdev = apic_pm_register(PM_SYS_DEV, 0, nmi_pm_callback);
+       if (level != RESUME_POWER_ON)
+               return 0;
+       enable_lapic_nmi_watchdog();
+       return 0;
 }

-#define __pminit       /*empty*/
-
-#else  /* CONFIG_PM */
+static struct device_driver lapic_nmi_driver = {
+       .name           = "lapic_nmi",
+       .bus            = &system_bus_type,
+       .resume         = lapic_nmi_resume,
+       .suspend        = lapic_nmi_suspend,
+};
+
+static struct sys_device device_lapic_nmi = {
+ ...

read more »



 Sat, 17 Sep 2005 19:00:09 GMT   
 Convert APIC to driver model: now it works with SMP
Hi!

Well, that patch broke as soon as you enabled oprofile (last time I
checked).
                                                                Pavel
--
When do you have a heart between your knees?
[Johanka's followup: and *two* hearts?]
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



 Sat, 17 Sep 2005 21:40:18 GMT   
 Convert APIC to driver model: now it works with SMP
 > Hi!
 >
 > > > arch/i386/oprofile/nmi_int.c:102: warning: initialization from incompatible pointer type
 > > > arch/i386/oprofile/nmi_int.c: In function `init_nmi_driverfs':
 > > > arch/i386/oprofile/nmi_int.c:129: warning: control reaches end of non-void function
 > >
 > > Can you try Mikael's (preferable) patch ?
 >
 > Well, that patch broke as soon as you enabled oprofile (last time I
 > checked).

John wrote that the latest works for him, with oprofile enabled.
Maybe he fixed some detail, I haven't compared it with mine yet.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



 Sun, 18 Sep 2005 14:10:15 GMT   
 Convert APIC to driver model: now it works with SMP

The only fix I made was to let CONFIG_PM=n compile.

regards,
john
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



 Sun, 18 Sep 2005 19:30:13 GMT   
 
   [ 7 post ] 

Similar Threads

1. Convert APIC to driver model

2. Switch APIC to driver model (and make S3 sleep with APIC on)

3. [2.5.74] x86_64 apic/nmi driver model conversion cleanups

4. Switch APIC to driver model

5. Driver model for APIC

6. Switch APIC (+nmi, +oprofile) to driver model

7. Switch APIC (+nmi, +oprofile) to driver model

8. APIC Model in Linux

9. APIC Cluster Model


 
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software