Merge branch 'master' into upstream
[pandora-kernel.git] / arch / i386 / kernel / cpu / cyrix.c
index fc32c80..de27bd0 100644 (file)
@@ -6,13 +6,14 @@
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/timer.h>
+#include <asm/pci-direct.h>
 
 #include "cpu.h"
 
 /*
  * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
  */
-static void __init do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
+static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
 {
        unsigned char ccr2, ccr3;
        unsigned long flags;
@@ -52,25 +53,25 @@ static void __init do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
  * Actually since bugs.h doesn't even reference this perhaps someone should
  * fix the documentation ???
  */
-static unsigned char Cx86_dir0_msb __initdata = 0;
+static unsigned char Cx86_dir0_msb __cpuinitdata = 0;
 
-static char Cx86_model[][9] __initdata = {
+static char Cx86_model[][9] __cpuinitdata = {
        "Cx486", "Cx486", "5x86 ", "6x86", "MediaGX ", "6x86MX ",
        "M II ", "Unknown"
 };
-static char Cx486_name[][5] __initdata = {
+static char Cx486_name[][5] __cpuinitdata = {
        "SLC", "DLC", "SLC2", "DLC2", "SRx", "DRx",
        "SRx2", "DRx2"
 };
-static char Cx486S_name[][4] __initdata = {
+static char Cx486S_name[][4] __cpuinitdata = {
        "S", "S2", "Se", "S2e"
 };
-static char Cx486D_name[][4] __initdata = {
+static char Cx486D_name[][4] __cpuinitdata = {
        "DX", "DX2", "?", "?", "?", "DX4"
 };
-static char Cx86_cb[] __initdata = "?.5x Core/Bus Clock";
-static char cyrix_model_mult1[] __initdata = "12??43";
-static char cyrix_model_mult2[] __initdata = "12233445";
+static char Cx86_cb[] __cpuinitdata = "?.5x Core/Bus Clock";
+static char cyrix_model_mult1[] __cpuinitdata = "12??43";
+static char cyrix_model_mult2[] __cpuinitdata = "12233445";
 
 /*
  * Reset the slow-loop (SLOP) bit on the 686(L) which is set by some old
@@ -82,7 +83,7 @@ static char cyrix_model_mult2[] __initdata = "12233445";
 
 extern void calibrate_delay(void) __init;
 
-static void __init check_cx686_slop(struct cpuinfo_x86 *c)
+static void __cpuinit check_cx686_slop(struct cpuinfo_x86 *c)
 {
        unsigned long flags;
        
@@ -107,7 +108,7 @@ static void __init check_cx686_slop(struct cpuinfo_x86 *c)
 }
 
 
-static void __init set_cx86_reorder(void)
+static void __cpuinit set_cx86_reorder(void)
 {
        u8 ccr3;
 
@@ -122,7 +123,7 @@ static void __init set_cx86_reorder(void)
        setCx86(CX86_CCR3, ccr3);
 }
 
-static void __init set_cx86_memwb(void)
+static void __cpuinit set_cx86_memwb(void)
 {
        u32 cr0;
 
@@ -137,7 +138,7 @@ static void __init set_cx86_memwb(void)
        setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14 );
 }
 
-static void __init set_cx86_inc(void)
+static void __cpuinit set_cx86_inc(void)
 {
        unsigned char ccr3;
 
@@ -158,22 +159,22 @@ static void __init set_cx86_inc(void)
  *     Configure later MediaGX and/or Geode processor.
  */
 
-static void __init geode_configure(void)
+static void __cpuinit geode_configure(void)
 {
        unsigned long flags;
-       u8 ccr3, ccr4;
+       u8 ccr3;
        local_irq_save(flags);
 
        /* Suspend on halt power saving and enable #SUSP pin */
        setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x88);
 
        ccr3 = getCx86(CX86_CCR3);
-       setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);       /* Enable */
-       
-       ccr4 = getCx86(CX86_CCR4);
-       ccr4 |= 0x38;           /* FPU fast, DTE cache, Mem bypass */
+       setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);       /* enable MAPEN */
        
-       setCx86(CX86_CCR3, ccr3);
+
+       /* FPU fast, DTE cache, Mem bypass */
+       setCx86(CX86_CCR4, getCx86(CX86_CCR4) | 0x38);
+       setCx86(CX86_CCR3, ccr3);                       /* disable MAPEN */
        
        set_cx86_memwb();
        set_cx86_reorder();     
@@ -183,15 +184,7 @@ static void __init geode_configure(void)
 }
 
 
-#ifdef CONFIG_PCI
-static struct pci_device_id __initdata cyrix_55x0[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510) },
-       { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520) },
-       { },
-};
-#endif
-
-static void __init init_cyrix(struct cpuinfo_x86 *c)
+static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
 {
        unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0;
        char *buf = c->x86_model_id;
@@ -258,6 +251,8 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
 
        case 4: /* MediaGX/GXm or Geode GXM/GXLV/GX1 */
 #ifdef CONFIG_PCI
+       {
+               u32 vendor, device;
                /* It isn't really a PCI quirk directly, but the cure is the
                   same. The MediaGX has deep magic SMM stuff that handles the
                   SB emulation. It thows away the fifo on disable_dma() which
@@ -273,22 +268,34 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
                printk(KERN_INFO "Working around Cyrix MediaGX virtual DMA bugs.\n");
                isa_dma_bridge_buggy = 2;
 
+               /* We do this before the PCI layer is running. However we
+                  are safe here as we know the bridge must be a Cyrix
+                  companion and must be present */
+               vendor = read_pci_config_16(0, 0, 0x12, PCI_VENDOR_ID);
+               device = read_pci_config_16(0, 0, 0x12, PCI_DEVICE_ID);
 
                /*
                 *  The 5510/5520 companion chips have a funky PIT.
                 */  
-               if (pci_dev_present(cyrix_55x0))
+               if (vendor == PCI_VENDOR_ID_CYRIX &&
+        (device == PCI_DEVICE_ID_CYRIX_5510 || device == PCI_DEVICE_ID_CYRIX_5520))
                        pit_latch_buggy = 1;
+       }
 #endif
                c->x86_cache_size=16;   /* Yep 16K integrated cache thats it */
 
                /* GXm supports extended cpuid levels 'ala' AMD */
                if (c->cpuid_level == 2) {
                        /* Enable cxMMX extensions (GX1 Datasheet 54) */
-                       setCx86(CX86_CCR7, getCx86(CX86_CCR7)|1);
+                       setCx86(CX86_CCR7, getCx86(CX86_CCR7) | 1);
                        
-                       /* GXlv/GXm/GX1 */
-                       if((dir1 >= 0x50 && dir1 <= 0x54) || dir1 >= 0x63)
+                       /*
+                        * GXm : 0x30 ... 0x5f GXm  datasheet 51
+                        * GXlv: 0x6x          GXlv datasheet 54
+                        *  ?  : 0x7x
+                        * GX1 : 0x8x          GX1  datasheet 56
+                        */
+                       if((0x30 <= dir1 && dir1 <= 0x6f) || (0x80 <=dir1 && dir1 <= 0x8f))
                                geode_configure();
                        get_model_name(c);  /* get CPU marketing name */
                        return;
@@ -346,7 +353,7 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
 /*
  * Handle National Semiconductor branded processors
  */
-static void __init init_nsc(struct cpuinfo_x86 *c)
+static void __cpuinit init_nsc(struct cpuinfo_x86 *c)
 {
        /* There may be GX1 processors in the wild that are branded
         * NSC and not Cyrix.
@@ -354,7 +361,7 @@ static void __init init_nsc(struct cpuinfo_x86 *c)
         * This function only handles the GX processor, and kicks every
         * thing else to the Cyrix init function above - that should
         * cover any processors that might have been branded differently
-        * after NSC aquired Cyrix.
+        * after NSC acquired Cyrix.
         *
         * If this breaks your GX1 horribly, please e-mail
         * info-linux@ldcmail.amd.com to tell us.
@@ -394,7 +401,7 @@ static inline int test_cyrix_52div(void)
        return (unsigned char) (test >> 8) == 0x02;
 }
 
-static void cyrix_identify(struct cpuinfo_x86 * c)
+static void __cpuinit cyrix_identify(struct cpuinfo_x86 * c)
 {
        /* Detect Cyrix with disabled CPUID */
        if ( c->x86 == 4 && test_cyrix_52div() ) {
@@ -415,22 +422,20 @@ static void cyrix_identify(struct cpuinfo_x86 * c)
                
                if (dir0 == 5 || dir0 == 3)
                {
-                       unsigned char ccr3, ccr4;
+                       unsigned char ccr3;
                        unsigned long flags;
                        printk(KERN_INFO "Enabling CPUID on Cyrix processor.\n");
                        local_irq_save(flags);
                        ccr3 = getCx86(CX86_CCR3);
-                       setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN  */
-                       ccr4 = getCx86(CX86_CCR4);
-                       setCx86(CX86_CCR4, ccr4 | 0x80);          /* enable cpuid  */
-                       setCx86(CX86_CCR3, ccr3);                 /* disable MAPEN */
+                       setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);       /* enable MAPEN  */
+                       setCx86(CX86_CCR4, getCx86(CX86_CCR4) | 0x80);  /* enable cpuid  */
+                       setCx86(CX86_CCR3, ccr3);                       /* disable MAPEN */
                        local_irq_restore(flags);
                }
        }
-       generic_identify(c);
 }
 
-static struct cpu_dev cyrix_cpu_dev __initdata = {
+static struct cpu_dev cyrix_cpu_dev __cpuinitdata = {
        .c_vendor       = "Cyrix",
        .c_ident        = { "CyrixInstead" },
        .c_init         = init_cyrix,
@@ -453,11 +458,10 @@ static int __init cyrix_exit_cpu(void)
 
 late_initcall(cyrix_exit_cpu);
 
-static struct cpu_dev nsc_cpu_dev __initdata = {
+static struct cpu_dev nsc_cpu_dev __cpuinitdata = {
        .c_vendor       = "NSC",
        .c_ident        = { "Geode by NSC" },
        .c_init         = init_nsc,
-       .c_identify     = generic_identify,
 };
 
 int __init nsc_init_cpu(void)