[PATCH] mark struct file_operations const 2
[safe/jmp/linux-2.6] / arch / ia64 / kernel / setup.c
index d91c8ff..5fa09d1 100644 (file)
@@ -22,7 +22,6 @@
  * 06/24/99 W.Drummond added boot_cpu_data.
  * 05/28/05 Z. Menyhart        Dynamic stride size for "flush_icache_range()"
  */
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 
 #include <linux/seq_file.h>
 #include <linux/string.h>
 #include <linux/threads.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
+#include <linux/dmi.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 #include <linux/efi.h>
 #include <linux/initrd.h>
-#include <linux/platform.h>
 #include <linux/pm.h>
 #include <linux/cpufreq.h>
+#include <linux/kexec.h>
+#include <linux/crash_dump.h>
 
 #include <asm/ia32.h>
 #include <asm/machvec.h>
@@ -55,7 +56,6 @@
 #include <asm/processor.h>
 #include <asm/sal.h>
 #include <asm/sections.h>
-#include <asm/serial.h>
 #include <asm/setup.h>
 #include <asm/smp.h>
 #include <asm/system.h>
@@ -71,6 +71,8 @@ unsigned long __per_cpu_offset[NR_CPUS];
 EXPORT_SYMBOL(__per_cpu_offset);
 #endif
 
+extern void ia64_setup_printk_clock(void);
+
 DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
 DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
 DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8);
@@ -129,8 +131,8 @@ EXPORT_SYMBOL(ia64_max_iommu_merge_mask);
 /*
  * We use a special marker for the end of memory and it uses the extra (+1) slot
  */
-struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1];
-int num_rsvd_regions;
+struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1] __initdata;
+int num_rsvd_regions __initdata;
 
 
 /*
@@ -139,7 +141,7 @@ int num_rsvd_regions;
  * caller-specified function is called with the memory ranges that remain after filtering.
  * This routine does not assume the incoming segments are sorted.
  */
-int
+int __init
 filter_rsvd_memory (unsigned long start, unsigned long end, void *arg)
 {
        unsigned long range_start, range_end, prev_start;
@@ -175,7 +177,7 @@ filter_rsvd_memory (unsigned long start, unsigned long end, void *arg)
        return 0;
 }
 
-static void
+static void __init
 sort_regions (struct rsvd_region *rsvd_region, int max)
 {
        int j;
@@ -216,7 +218,7 @@ __initcall(register_memory);
  * initrd, etc.  There are currently %IA64_MAX_RSVD_REGIONS defined,
  * see include/asm-ia64/meminit.h if you need to define more.
  */
-void
+void __init
 reserve_memory (void)
 {
        int n = 0;
@@ -252,23 +254,66 @@ reserve_memory (void)
        efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
        n++;
 
+#ifdef CONFIG_KEXEC
+       /* crashkernel=size@offset specifies the size to reserve for a crash
+        * kernel. If offset is 0, then it is determined automatically.
+        * By reserving this memory we guarantee that linux never set's it
+        * up as a DMA target.Useful for holding code to do something
+        * appropriate after a kernel panic.
+        */
+       {
+               char *from = strstr(boot_command_line, "crashkernel=");
+               unsigned long base, size;
+               if (from) {
+                       size = memparse(from + 12, &from);
+                       if (*from == '@')
+                               base = memparse(from+1, &from);
+                       else
+                               base = 0;
+                       if (size) {
+                               if (!base) {
+                                       sort_regions(rsvd_region, n);
+                                       base = kdump_find_rsvd_region(size,
+                                                               rsvd_region, n);
+                                       }
+                               if (base != ~0UL) {
+                                       rsvd_region[n].start =
+                                               (unsigned long)__va(base);
+                                       rsvd_region[n].end =
+                                               (unsigned long)__va(base + size);
+                                       n++;
+                                       crashk_res.start = base;
+                                       crashk_res.end = base + size - 1;
+                               }
+                       }
+               }
+               efi_memmap_res.start = ia64_boot_param->efi_memmap;
+                efi_memmap_res.end = efi_memmap_res.start +
+                        ia64_boot_param->efi_memmap_size;
+                boot_param_res.start = __pa(ia64_boot_param);
+                boot_param_res.end = boot_param_res.start +
+                        sizeof(*ia64_boot_param);
+       }
+#endif
        /* end of memory marker */
        rsvd_region[n].start = ~0UL;
        rsvd_region[n].end   = ~0UL;
        n++;
 
        num_rsvd_regions = n;
+       BUG_ON(IA64_MAX_RSVD_REGIONS + 1 < n);
 
        sort_regions(rsvd_region, num_rsvd_regions);
 }
 
+
 /**
  * find_initrd - get initrd parameters from the boot parameter structure
  *
  * Grab the initrd start and end from the boot parameter struct given us by
  * the boot loader.
  */
-void
+void __init
 find_initrd (void)
 {
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -360,7 +405,7 @@ mark_bsp_online (void)
 }
 
 #ifdef CONFIG_SMP
-static void
+static void __init
 check_for_logical_procs (void)
 {
        pal_logical_to_physical_t info;
@@ -387,6 +432,29 @@ check_for_logical_procs (void)
 }
 #endif
 
+static __initdata int nomca;
+static __init int setup_nomca(char *s)
+{
+       nomca = 1;
+       return 0;
+}
+early_param("nomca", setup_nomca);
+
+#ifdef CONFIG_PROC_VMCORE
+/* elfcorehdr= specifies the location of elf core header
+ * stored by the crashed kernel.
+ */
+static int __init parse_elfcorehdr(char *arg)
+{
+       if (!arg)
+               return -EINVAL;
+
+        elfcorehdr_addr = memparse(arg, &arg);
+       return 0;
+}
+early_param("elfcorehdr", parse_elfcorehdr);
+#endif /* CONFIG_PROC_VMCORE */
+
 void __init
 setup_arch (char **cmdline_p)
 {
@@ -395,34 +463,15 @@ setup_arch (char **cmdline_p)
        ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist);
 
        *cmdline_p = __va(ia64_boot_param->command_line);
-       strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
+       strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
 
        efi_init();
        io_port_init();
 
-#ifdef CONFIG_IA64_GENERIC
-       {
-               const char *mvec_name = strstr (*cmdline_p, "machvec=");
-               char str[64];
+       parse_early_param();
 
-               if (mvec_name) {
-                       const char *end;
-                       size_t len;
-
-                       mvec_name += 8;
-                       end = strchr (mvec_name, ' ');
-                       if (end)
-                               len = end - mvec_name;
-                       else
-                               len = strlen (mvec_name);
-                       len = min(len, sizeof (str) - 1);
-                       strncpy (str, mvec_name, len);
-                       str[len] = '\0';
-                       mvec_name = str;
-               } else
-                       mvec_name = acpi_get_sysname();
-               machvec_init(mvec_name);
-       }
+#ifdef CONFIG_IA64_GENERIC
+       machvec_init(NULL);
 #endif
 
        if (early_console_setup(*cmdline_p) == 0)
@@ -443,7 +492,9 @@ setup_arch (char **cmdline_p)
        find_memory();
 
        /* process SAL system table: */
-       ia64_sal_init(efi.sal_systab);
+       ia64_sal_init(__va(efi.sal_systab));
+
+       ia64_setup_printk_clock();
 
 #ifdef CONFIG_SMP
        cpu_physical_id(0) = hard_smp_processor_id();
@@ -465,6 +516,8 @@ setup_arch (char **cmdline_p)
        cpu_init();     /* initialize the bootstrap CPU */
        mmu_context_init();     /* initialize context_id bitmap */
 
+       check_sal_cache_flush();
+
 #ifdef CONFIG_ACPI
        acpi_boot_init();
 #endif
@@ -488,7 +541,7 @@ setup_arch (char **cmdline_p)
 #endif
 
        /* enable IA-64 Machine Check Abort Handling unless disabled */
-       if (!strstr(saved_command_line, "nomca"))
+       if (!nomca)
                ia64_mca_init();
 
        platform_setup(cmdline_p);
@@ -516,40 +569,31 @@ show_cpuinfo (struct seq_file *m, void *v)
                { 1UL << 1, "spontaneous deferral"},
                { 1UL << 2, "16-byte atomic ops" }
        };
-       char family[32], features[128], *cp, sep;
+       char features[128], *cp, *sep;
        struct cpuinfo_ia64 *c = v;
        unsigned long mask;
        unsigned long proc_freq;
-       int i;
+       int i, size;
 
        mask = c->features;
 
-       switch (c->family) {
-             case 0x07:        memcpy(family, "Itanium", 8); break;
-             case 0x1f:        memcpy(family, "Itanium 2", 10); break;
-             default:          sprintf(family, "%u", c->family); break;
-       }
-
        /* build the feature string: */
-       memcpy(features, " standard", 10);
+       memcpy(features, "standard", 9);
        cp = features;
-       sep = 0;
-       for (i = 0; i < (int) ARRAY_SIZE(feature_bits); ++i) {
+       size = sizeof(features);
+       sep = "";
+       for (i = 0; i < ARRAY_SIZE(feature_bits) && size > 1; ++i) {
                if (mask & feature_bits[i].mask) {
-                       if (sep)
-                               *cp++ = sep;
-                       sep = ',';
-                       *cp++ = ' ';
-                       strcpy(cp, feature_bits[i].feature_name);
-                       cp += strlen(feature_bits[i].feature_name);
+                       cp += snprintf(cp, size, "%s%s", sep,
+                                      feature_bits[i].feature_name),
+                       sep = ", ";
                        mask &= ~feature_bits[i].mask;
+                       size = sizeof(features) - (cp - features);
                }
        }
-       if (mask) {
-               /* print unknown features as a hex value: */
-               if (sep)
-                       *cp++ = sep;
-               sprintf(cp, " 0x%lx", mask);
+       if (mask && size > 1) {
+               /* print unknown features as a hex value */
+               snprintf(cp, size, "%s0x%lx", sep, mask);
        }
 
        proc_freq = cpufreq_quick_get(cpunum);
@@ -560,17 +604,19 @@ show_cpuinfo (struct seq_file *m, void *v)
                   "processor  : %d\n"
                   "vendor     : %s\n"
                   "arch       : IA-64\n"
-                  "family     : %s\n"
+                  "family     : %u\n"
                   "model      : %u\n"
+                  "model name : %s\n"
                   "revision   : %u\n"
                   "archrev    : %u\n"
-                  "features   :%s\n"   /* don't change this---it _is_ right! */
+                  "features   : %s\n"
                   "cpu number : %lu\n"
                   "cpu regs   : %u\n"
                   "cpu MHz    : %lu.%06lu\n"
                   "itc MHz    : %lu.%06lu\n"
                   "BogoMIPS   : %lu.%02lu\n",
-                  cpunum, c->vendor, family, c->model, c->revision, c->archrev,
+                  cpunum, c->vendor, c->family, c->model,
+                  c->model_name, c->revision, c->archrev,
                   features, c->ppn, c->number,
                   proc_freq / 1000, proc_freq % 1000,
                   c->itc_freq / 1000000, c->itc_freq % 1000000,
@@ -618,7 +664,32 @@ struct seq_operations cpuinfo_op = {
        .show =         show_cpuinfo
 };
 
-void
+static char brandname[128];
+
+static char * __cpuinit
+get_model_name(__u8 family, __u8 model)
+{
+       char brand[128];
+
+       memcpy(brand, "Unknown", 8);
+       if (ia64_pal_get_brand_info(brand)) {
+               if (family == 0x7)
+                       memcpy(brand, "Merced", 7);
+               else if (family == 0x1f) switch (model) {
+                       case 0: memcpy(brand, "McKinley", 9); break;
+                       case 1: memcpy(brand, "Madison", 8); break;
+                       case 2: memcpy(brand, "Madison up to 9M cache", 23); break;
+               }
+       }
+       if (brandname[0] == '\0')
+               return strcpy(brandname, brand);
+       else if (strcmp(brandname, brand) == 0)
+               return brandname;
+       else
+               return kstrdup(brand, GFP_KERNEL);
+}
+
+static void __cpuinit
 identify_cpu (struct cpuinfo_ia64 *c)
 {
        union {
@@ -647,7 +718,6 @@ identify_cpu (struct cpuinfo_ia64 *c)
        pal_status_t status;
        unsigned long impl_va_msb = 50, phys_addr_size = 44;    /* Itanium defaults */
        int i;
-
        for (i = 0; i < 5; ++i)
                cpuid.bits[i] = ia64_get_cpuid(i);
 
@@ -670,6 +740,7 @@ identify_cpu (struct cpuinfo_ia64 *c)
        c->family = cpuid.field.family;
        c->archrev = cpuid.field.archrev;
        c->features = cpuid.field.features;
+       c->model_name = get_model_name(c->family, c->model);
 
        status = ia64_pal_vm_summary(&vm1, &vm2);
        if (status == PAL_STATUS_SUCCESS) {
@@ -684,6 +755,9 @@ void
 setup_per_cpu_areas (void)
 {
        /* start_kernel() requires this... */
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+       prefill_possible_map();
+#endif
 }
 
 /*
@@ -692,10 +766,11 @@ setup_per_cpu_areas (void)
  * In addition, the minimum of the i-cache stride sizes is calculated for
  * "flush_icache_range()".
  */
-static void
+static void __cpuinit
 get_max_cacheline_size (void)
 {
        unsigned long line_size, max = 1;
+       unsigned int cache_size = 0;
        u64 l, levels, unique_caches;
         pal_cache_config_info_t cci;
         s64 status;
@@ -725,6 +800,8 @@ get_max_cacheline_size (void)
                line_size = 1 << cci.pcci_line_size;
                if (line_size > max)
                        max = line_size;
+               if (cache_size < cci.pcci_cache_size)
+                       cache_size = cci.pcci_cache_size;
                if (!cci.pcci_unified) {
                        status = ia64_pal_cache_config_info(l,
                                                    /* cache_type (instruction)= */ 1,
@@ -741,6 +818,9 @@ get_max_cacheline_size (void)
                        ia64_i_cache_stride_shift = cci.pcci_stride;
        }
   out:
+#ifdef CONFIG_SMP
+       max_cache_size = max(max_cache_size, cache_size);
+#endif
        if (max > ia64_max_cacheline_size)
                ia64_max_cacheline_size = max;
 }
@@ -749,10 +829,10 @@ get_max_cacheline_size (void)
  * cpu_init() initializes state that is per-CPU.  This function acts
  * as a 'CPU state barrier', nothing should get across.
  */
-void
+void __cpuinit
 cpu_init (void)
 {
-       extern void __devinit ia64_mmu_init (void *);
+       extern void __cpuinit ia64_mmu_init (void *);
        unsigned long num_phys_stacked;
        pal_vm_info_2_u_t vmi;
        unsigned int max_ctx;
@@ -795,7 +875,7 @@ cpu_init (void)
 #endif
 
        /* Clear the stack memory reserved for pt_regs: */
-       memset(ia64_task_regs(current), 0, sizeof(struct pt_regs));
+       memset(task_pt_regs(current), 0, sizeof(struct pt_regs));
 
        ia64_set_kr(IA64_KR_FPU_OWNER, 0);
 
@@ -880,9 +960,16 @@ void sched_cacheflush(void)
        ia64_sal_cache_flush(3);
 }
 
-void
+void __init
 check_bugs (void)
 {
        ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles,
                               (unsigned long) __end___mckinley_e9_bundles);
 }
+
+static int __init run_dmi_scan(void)
+{
+       dmi_scan_machine();
+       return 0;
+}
+core_initcall(run_dmi_scan);