diff options
author | Steven Whitehouse <steve@men-an-tol.chygwyn.com> | 2006-02-23 10:49:43 +0100 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-02-23 10:49:43 +0100 |
commit | d35462b4bb847b68321c55e95c926aa485aecce2 (patch) | |
tree | b08e18bf6e672633402871ee763102fdb5e63229 /arch/ia64/kernel | |
parent | [GFS2] Missed deletion of debugging code (diff) | |
parent | Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6 (diff) | |
download | linux-d35462b4bb847b68321c55e95c926aa485aecce2.tar.xz linux-d35462b4bb847b68321c55e95c926aa485aecce2.zip |
Merge branch 'master'
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r-- | arch/ia64/kernel/Makefile | 5 | ||||
-rw-r--r-- | arch/ia64/kernel/acpi-ext.c | 22 | ||||
-rw-r--r-- | arch/ia64/kernel/acpi-processor.c | 67 | ||||
-rw-r--r-- | arch/ia64/kernel/acpi.c | 59 | ||||
-rw-r--r-- | arch/ia64/kernel/cpufreq/Makefile | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/cpufreq/acpi-cpufreq.c | 51 | ||||
-rw-r--r-- | arch/ia64/kernel/efi.c | 16 | ||||
-rw-r--r-- | arch/ia64/kernel/entry.S | 20 | ||||
-rw-r--r-- | arch/ia64/kernel/fsys.S | 29 | ||||
-rw-r--r-- | arch/ia64/kernel/head.S | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/ia64_ksyms.c | 15 | ||||
-rw-r--r-- | arch/ia64/kernel/mca_asm.S | 2 | ||||
-rw-r--r-- | arch/ia64/kernel/mca_drv.c | 3 | ||||
-rw-r--r-- | arch/ia64/kernel/sal.c | 75 | ||||
-rw-r--r-- | arch/ia64/kernel/setup.c | 8 | ||||
-rw-r--r-- | arch/ia64/kernel/smpboot.c | 5 | ||||
-rw-r--r-- | arch/ia64/kernel/time.c | 62 | ||||
-rw-r--r-- | arch/ia64/kernel/topology.c | 18 | ||||
-rw-r--r-- | arch/ia64/kernel/traps.c | 8 | ||||
-rw-r--r-- | arch/ia64/kernel/unaligned.c | 3 |
20 files changed, 317 insertions, 153 deletions
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 307514f7a282..09a0dbc17fb6 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -13,6 +13,11 @@ obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o obj-$(CONFIG_IA64_HP_ZX1) += acpi-ext.o obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acpi-ext.o + +ifneq ($(CONFIG_ACPI_PROCESSOR),) +obj-y += acpi-processor.o +endif + obj-$(CONFIG_IA64_PALINFO) += palinfo.o obj-$(CONFIG_IOSAPIC) += iosapic.o obj-$(CONFIG_MODULES) += module.o diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c index 13a5b3b49bf8..4a5574ff007b 100644 --- a/arch/ia64/kernel/acpi-ext.c +++ b/arch/ia64/kernel/acpi-ext.c @@ -33,33 +33,33 @@ acpi_vendor_resource_match(struct acpi_resource *resource, void *context) struct acpi_vendor_info *info = (struct acpi_vendor_info *)context; struct acpi_resource_vendor *vendor; struct acpi_vendor_descriptor *descriptor; - u32 length; + u32 byte_length; - if (resource->id != ACPI_RSTYPE_VENDOR) + if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) return AE_OK; vendor = (struct acpi_resource_vendor *)&resource->data; - descriptor = (struct acpi_vendor_descriptor *)vendor->reserved; - if (vendor->length <= sizeof(*info->descriptor) || + descriptor = (struct acpi_vendor_descriptor *)vendor->byte_data; + if (vendor->byte_length <= sizeof(*info->descriptor) || descriptor->guid_id != info->descriptor->guid_id || efi_guidcmp(descriptor->guid, info->descriptor->guid)) return AE_OK; - length = vendor->length - sizeof(struct acpi_vendor_descriptor); - info->data = acpi_os_allocate(length); + byte_length = vendor->byte_length - sizeof(struct acpi_vendor_descriptor); + info->data = acpi_os_allocate(byte_length); if (!info->data) return AE_NO_MEMORY; memcpy(info->data, - vendor->reserved + sizeof(struct acpi_vendor_descriptor), - length); - info->length = length; + vendor->byte_data + sizeof(struct acpi_vendor_descriptor), + byte_length); + info->length = byte_length; return AE_CTRL_TERMINATE; } acpi_status acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id, - u8 ** data, u32 * length) + u8 ** data, u32 * byte_length) { struct acpi_vendor_info info; @@ -72,7 +72,7 @@ acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id, return AE_NOT_FOUND; *data = info.data; - *length = info.length; + *byte_length = info.length; return AE_OK; } diff --git a/arch/ia64/kernel/acpi-processor.c b/arch/ia64/kernel/acpi-processor.c new file mode 100644 index 000000000000..e683630c8ce2 --- /dev/null +++ b/arch/ia64/kernel/acpi-processor.c @@ -0,0 +1,67 @@ +/* + * arch/ia64/kernel/cpufreq/processor.c + * + * Copyright (C) 2005 Intel Corporation + * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> + * - Added _PDC for platforms with Intel CPUs + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/acpi.h> + +#include <acpi/processor.h> +#include <asm/acpi.h> + +static void init_intel_pdc(struct acpi_processor *pr) +{ + struct acpi_object_list *obj_list; + union acpi_object *obj; + u32 *buf; + + /* allocate and initialize pdc. It will be used later. */ + obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); + if (!obj_list) { + printk(KERN_ERR "Memory allocation error\n"); + return; + } + + obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); + if (!obj) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj_list); + return; + } + + buf = kmalloc(12, GFP_KERNEL); + if (!buf) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj); + kfree(obj_list); + return; + } + + buf[0] = ACPI_PDC_REVISION_ID; + buf[1] = 1; + buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; + + obj->type = ACPI_TYPE_BUFFER; + obj->buffer.length = 12; + obj->buffer.pointer = (u8 *) buf; + obj_list->count = 1; + obj_list->pointer = obj; + pr->pdc = obj_list; + + return; +} + +/* Initialize _PDC data based on the CPU vendor */ +void arch_acpi_processor_init_pdc(struct acpi_processor *pr) +{ + pr->pdc = NULL; + init_intel_pdc(pr); + return; +} + +EXPORT_SYMBOL(arch_acpi_processor_init_pdc); diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 9ad94ddf6687..ecd44bdc8394 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -567,16 +567,16 @@ void __init acpi_numa_arch_fixup(void) * success: return IRQ number (>=0) * failure: return < 0 */ -int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) +int acpi_register_gsi(u32 gsi, int triggering, int polarity) { if (has_8259 && gsi < 16) return isa_irq_to_vector(gsi); return iosapic_register_intr(gsi, - (active_high_low == + (polarity == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, - (edge_level == + (triggering == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); } @@ -761,6 +761,59 @@ int acpi_map_cpu2node(acpi_handle handle, int cpu, long physid) return (0); } +int additional_cpus __initdata = -1; + +static __init int setup_additional_cpus(char *s) +{ + if (s) + additional_cpus = simple_strtol(s, NULL, 0); + + return 0; +} + +early_param("additional_cpus", setup_additional_cpus); + +/* + * cpu_possible_map should be static, it cannot change as cpu's + * are onlined, or offlined. The reason is per-cpu data-structures + * are allocated by some modules at init time, and dont expect to + * do this dynamically on cpu arrival/departure. + * cpu_present_map on the other hand can change dynamically. + * In case when cpu_hotplug is not compiled, then we resort to current + * behaviour, which is cpu_possible == cpu_present. + * - Ashok Raj + * + * Three ways to find out the number of additional hotplug CPUs: + * - If the BIOS specified disabled CPUs in ACPI/mptables use that. + * - The user can overwrite it with additional_cpus=NUM + * - Otherwise don't reserve additional CPUs. + */ +__init void prefill_possible_map(void) +{ + int i; + int possible, disabled_cpus; + + disabled_cpus = total_cpus - available_cpus; + + if (additional_cpus == -1) { + if (disabled_cpus > 0) + additional_cpus = disabled_cpus; + else + additional_cpus = 0; + } + + possible = available_cpus + additional_cpus; + + if (possible > NR_CPUS) + possible = NR_CPUS; + + printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", + possible, max((possible - available_cpus), 0)); + + for (i = 0; i < possible; i++) + cpu_set(i, cpu_possible_map); +} + int acpi_map_lsapic(acpi_handle handle, int *pcpu) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; diff --git a/arch/ia64/kernel/cpufreq/Makefile b/arch/ia64/kernel/cpufreq/Makefile index f748d34c02f0..4838f2a57c7a 100644 --- a/arch/ia64/kernel/cpufreq/Makefile +++ b/arch/ia64/kernel/cpufreq/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_IA64_ACPI_CPUFREQ) += acpi-cpufreq.o + diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c index da4d5cf80a48..5a1bf815282d 100644 --- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c +++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c @@ -269,48 +269,6 @@ acpi_cpufreq_verify ( } -/* - * processor_init_pdc - let BIOS know about the SMP capabilities - * of this driver - * @perf: processor-specific acpi_io_data struct - * @cpu: CPU being initialized - * - * To avoid issues with legacy OSes, some BIOSes require to be informed of - * the SMP capabilities of OS P-state driver. Here we set the bits in _PDC - * accordingly. Actual call to _PDC is done in driver/acpi/processor.c - */ -static void -processor_init_pdc ( - struct acpi_processor_performance *perf, - unsigned int cpu, - struct acpi_object_list *obj_list - ) -{ - union acpi_object *obj; - u32 *buf; - - dprintk("processor_init_pdc\n"); - - perf->pdc = NULL; - /* Initialize pdc. It will be used later. */ - if (!obj_list) - return; - - if (!(obj_list->count && obj_list->pointer)) - return; - - obj = obj_list->pointer; - if ((obj->buffer.length == 12) && obj->buffer.pointer) { - buf = (u32 *)obj->buffer.pointer; - buf[0] = ACPI_PDC_REVISION_ID; - buf[1] = 1; - buf[2] = ACPI_PDC_EST_CAPABILITY_SMP; - perf->pdc = obj_list; - } - return; -} - - static int acpi_cpufreq_cpu_init ( struct cpufreq_policy *policy) @@ -320,14 +278,7 @@ acpi_cpufreq_cpu_init ( struct cpufreq_acpi_io *data; unsigned int result = 0; - union acpi_object arg0 = {ACPI_TYPE_BUFFER}; - u32 arg0_buf[3]; - struct acpi_object_list arg_list = {1, &arg0}; - dprintk("acpi_cpufreq_cpu_init\n"); - /* setup arg_list for _PDC settings */ - arg0.buffer.length = 12; - arg0.buffer.pointer = (u8 *) arg0_buf; data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); if (!data) @@ -337,9 +288,7 @@ acpi_cpufreq_cpu_init ( acpi_io_data[cpu] = data; - processor_init_pdc(&data->acpi_data, cpu, &arg_list); result = acpi_processor_register_performance(&data->acpi_data, cpu); - data->acpi_data.pdc = NULL; if (result) goto err_free; diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index c485a3b32ba8..9990320b6f9a 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -410,24 +410,16 @@ efi_init (void) efi_config_table_t *config_tables; efi_char16_t *c16; u64 efi_desc_size; - char *cp, *end, vendor[100] = "unknown"; + char *cp, vendor[100] = "unknown"; extern char saved_command_line[]; int i; /* it's too early to be able to use the standard kernel command line support... */ for (cp = saved_command_line; *cp; ) { if (memcmp(cp, "mem=", 4) == 0) { - cp += 4; - mem_limit = memparse(cp, &end); - if (end != cp) - break; - cp = end; + mem_limit = memparse(cp + 4, &cp); } else if (memcmp(cp, "max_addr=", 9) == 0) { - cp += 9; - max_addr = GRANULEROUNDDOWN(memparse(cp, &end)); - if (end != cp) - break; - cp = end; + max_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp)); } else { while (*cp != ' ' && *cp) ++cp; @@ -458,7 +450,7 @@ efi_init (void) /* Show what we know for posterity */ c16 = __va(efi.systab->fw_vendor); if (c16) { - for (i = 0;i < (int) sizeof(vendor) && *c16; ++i) + for (i = 0;i < (int) sizeof(vendor) - 1 && *c16; ++i) vendor[i] = *c16++; vendor[i] = '\0'; } diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 7a6ffd613789..930fdfca6ddb 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -569,7 +569,9 @@ GLOBAL_ENTRY(ia64_trace_syscall) .mem.offset 0,0; st8.spill [r2]=r8 // store return value in slot for r8 .mem.offset 8,0; st8.spill [r3]=r10 // clear error indication in slot for r10 br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value -.ret3: br.cond.sptk .work_pending_syscall_end +.ret3: +(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk + br.cond.sptk .work_pending_syscall_end strace_error: ld8 r3=[r2] // load pt_regs.r8 @@ -1601,5 +1603,21 @@ sys_call_table: data8 sys_inotify_add_watch data8 sys_inotify_rm_watch data8 sys_migrate_pages // 1280 + data8 sys_openat + data8 sys_mkdirat + data8 sys_mknodat + data8 sys_fchownat + data8 sys_futimesat // 1285 + data8 sys_newfstatat + data8 sys_unlinkat + data8 sys_renameat + data8 sys_linkat + data8 sys_symlinkat // 1290 + data8 sys_readlinkat + data8 sys_fchmodat + data8 sys_faccessat + data8 sys_ni_syscall // reserved for pselect + data8 sys_ni_syscall // 1295 reserved for ppoll + data8 sys_unshare .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index ce423910ca97..ac6055c83115 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -878,31 +878,8 @@ fsyscall_table: data8 0 // timer_delete data8 0 // clock_settime data8 fsys_clock_gettime // clock_gettime - data8 0 // clock_getres // 1255 - data8 0 // clock_nanosleep - data8 0 // fstatfs64 - data8 0 // statfs64 - data8 0 - data8 0 // 1260 - data8 0 - data8 0 // mq_open - data8 0 // mq_unlink - data8 0 // mq_timedsend - data8 0 // mq_timedreceive // 1265 - data8 0 // mq_notify - data8 0 // mq_getsetattr - data8 0 // kexec_load - data8 0 - data8 0 // 1270 - data8 0 - data8 0 - data8 0 - data8 0 - data8 0 // 1275 - data8 0 - data8 0 - data8 0 - data8 0 - data8 0 // 1280 + #define __NR_syscall_last 1255 + + .space 8*(NR_syscalls + 1024 - __NR_syscall_last), 0 .org fsyscall_table + 8*NR_syscalls // guard against failures to increase NR_syscalls diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index fbc7ea35dd57..f1778a84ea61 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -352,6 +352,7 @@ start_ap: mov ar.rsc=0 // place RSE in enforced lazy mode ;; loadrs // clear the dirty partition + mov IA64_KR(PER_CPU_DATA)=r0 // clear physical per-CPU base ;; mov ar.bspstore=r2 // establish the new RSE stack ;; diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index e72de580ebbf..bbcfd08378a6 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -10,23 +10,8 @@ #include <linux/string.h> EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(memchr); -EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memcpy); -EXPORT_SYMBOL(memmove); -EXPORT_SYMBOL(memscan); -EXPORT_SYMBOL(strcat); -EXPORT_SYMBOL(strchr); -EXPORT_SYMBOL(strcmp); -EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strlen); -EXPORT_SYMBOL(strncat); -EXPORT_SYMBOL(strncmp); -EXPORT_SYMBOL(strncpy); -EXPORT_SYMBOL(strnlen); -EXPORT_SYMBOL(strrchr); -EXPORT_SYMBOL(strstr); -EXPORT_SYMBOL(strpbrk); #include <asm/checksum.h> EXPORT_SYMBOL(ip_fast_csum); /* hand-coded assembly */ diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S index 403a80a58c13..60a464bfd9e2 100644 --- a/arch/ia64/kernel/mca_asm.S +++ b/arch/ia64/kernel/mca_asm.S @@ -512,7 +512,7 @@ ia64_state_save: st8 [temp1]=r12 // os_status, default is cold boot mov r6=IA64_MCA_SAME_CONTEXT ;; - st8 [temp1]=r6 // context, default is same context + st8 [temp2]=r6 // context, default is same context // Save the pt_regs data that is not in minstate. The previous code // left regs at sos. diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index 3492e3211a44..8fd93afa75a7 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c @@ -437,6 +437,9 @@ recover_from_read_error(slidx_table_t *slidx, * the process not have any locks of kernel. */ + /* Is minstate valid? */ + if (!peidx_bottom(peidx) || !(peidx_bottom(peidx)->valid.minstate)) + return 0; psr1 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_ipsr); /* diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c index acc0f132f86c..056f7a6eedc7 100644 --- a/arch/ia64/kernel/sal.c +++ b/arch/ia64/kernel/sal.c @@ -14,6 +14,7 @@ #include <linux/spinlock.h> #include <linux/string.h> +#include <asm/delay.h> #include <asm/page.h> #include <asm/sal.h> #include <asm/pal.h> @@ -214,6 +215,78 @@ chk_nointroute_opt(void) static void __init sal_desc_ap_wakeup(void *p) { } #endif +/* + * HP rx5670 firmware polls for interrupts during SAL_CACHE_FLUSH by reading + * cr.ivr, but it never writes cr.eoi. This leaves any interrupt marked as + * "in-service" and masks other interrupts of equal or lower priority. + * + * HP internal defect reports: F1859, F2775, F3031. + */ +static int sal_cache_flush_drops_interrupts; + +static void __init +check_sal_cache_flush (void) +{ + unsigned long flags, itv; + int cpu; + u64 vector; + + cpu = get_cpu(); + local_irq_save(flags); + + /* + * Schedule a timer interrupt, wait until it's reported, and see if + * SAL_CACHE_FLUSH drops it. + */ + itv = ia64_get_itv(); + BUG_ON((itv & (1 << 16)) == 0); + + ia64_set_itv(IA64_TIMER_VECTOR); + ia64_set_itm(ia64_get_itc() + 1000); + + while (!ia64_get_irr(IA64_TIMER_VECTOR)) + cpu_relax(); + + ia64_sal_cache_flush(3); + + if (ia64_get_irr(IA64_TIMER_VECTOR)) { + vector = ia64_get_ivr(); + ia64_eoi(); + WARN_ON(vector != IA64_TIMER_VECTOR); + } else { + sal_cache_flush_drops_interrupts = 1; + printk(KERN_ERR "SAL: SAL_CACHE_FLUSH drops interrupts; " + "PAL_CACHE_FLUSH will be used instead\n"); + ia64_eoi(); + } + + ia64_set_itv(itv); + local_irq_restore(flags); + put_cpu(); +} + +s64 +ia64_sal_cache_flush (u64 cache_type) +{ + struct ia64_sal_retval isrv; + + if (sal_cache_flush_drops_interrupts) { + unsigned long flags; + u64 progress; + s64 rc; + + progress = 0; + local_irq_save(flags); + rc = ia64_pal_cache_flush(cache_type, + PAL_CACHE_FLUSH_INVALIDATE, &progress, NULL); + local_irq_restore(flags); + return rc; + } + + SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0); + return isrv.status; +} + void __init ia64_sal_init (struct ia64_sal_systab *systab) { @@ -262,6 +335,8 @@ ia64_sal_init (struct ia64_sal_systab *systab) } p += SAL_DESC_SIZE(*p); } + + check_sal_cache_flush(); } int diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index c0766575a3a2..3258e09278d0 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -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); @@ -428,6 +430,7 @@ setup_arch (char **cmdline_p) if (early_console_setup(*cmdline_p) == 0) mark_bsp_online(); + parse_early_param(); #ifdef CONFIG_ACPI /* Initialize the ACPI boot-time table parser */ acpi_table_init(); @@ -445,6 +448,8 @@ setup_arch (char **cmdline_p) /* process SAL system table: */ ia64_sal_init(efi.sal_systab); + ia64_setup_printk_clock(); + #ifdef CONFIG_SMP cpu_physical_id(0) = hard_smp_processor_id(); @@ -684,6 +689,9 @@ void setup_per_cpu_areas (void) { /* start_kernel() requires this... */ +#ifdef CONFIG_ACPI_HOTPLUG_CPU + prefill_possible_map(); +#endif } /* diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 8f44e7d2df66..b681ef34a86e 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -129,7 +129,7 @@ DEFINE_PER_CPU(int, cpu_state); /* Bitmasks of currently online, and possible CPUs */ cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); -cpumask_t cpu_possible_map; +cpumask_t cpu_possible_map = CPU_MASK_NONE; EXPORT_SYMBOL(cpu_possible_map); cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; @@ -506,9 +506,6 @@ smp_build_cpu_map (void) for (cpu = 0; cpu < NR_CPUS; cpu++) { ia64_cpu_to_sapicid[cpu] = -1; -#ifdef CONFIG_HOTPLUG_CPU - cpu_set(cpu, cpu_possible_map); -#endif } ia64_cpu_to_sapicid[0] = boot_cpu_id; diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 028a2b95936c..307d01e15b2e 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -250,31 +250,53 @@ time_init (void) set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); } -#define SMALLUSECS 100 +/* + * Generic udelay assumes that if preemption is allowed and the thread + * migrates to another CPU, that the ITC values are synchronized across + * all CPUs. + */ +static void +ia64_itc_udelay (unsigned long usecs) +{ + unsigned long start = ia64_get_itc(); + unsigned long end = start + usecs*local_cpu_data->cyc_per_usec; + + while (time_before(ia64_get_itc(), end)) + cpu_relax(); +} + +void (*ia64_udelay)(unsigned long usecs) = &ia64_itc_udelay; void udelay (unsigned long usecs) { - unsigned long start; - unsigned long cycles; - unsigned long smallusecs; + (*ia64_udelay)(usecs); +} +EXPORT_SYMBOL(udelay); - /* - * Execute the non-preemptible delay loop (because the ITC might - * not be synchronized between CPUS) in relatively short time - * chunks, allowing preemption between the chunks. - */ - while (usecs > 0) { - smallusecs = (usecs > SMALLUSECS) ? SMALLUSECS : usecs; - preempt_disable(); - cycles = smallusecs*local_cpu_data->cyc_per_usec; - start = ia64_get_itc(); +static unsigned long long ia64_itc_printk_clock(void) +{ + if (ia64_get_kr(IA64_KR_PER_CPU_DATA)) + return sched_clock(); + return 0; +} + +static unsigned long long ia64_default_printk_clock(void) +{ + return (unsigned long long)(jiffies_64 - INITIAL_JIFFIES) * + (1000000000/HZ); +} - while (ia64_get_itc() - start < cycles) - cpu_relax(); +unsigned long long (*ia64_printk_clock)(void) = &ia64_default_printk_clock; - preempt_enable(); - usecs -= smallusecs; - } +unsigned long long printk_clock(void) +{ + return ia64_printk_clock(); +} + +void __init +ia64_setup_printk_clock(void) +{ + if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) + ia64_printk_clock = ia64_itc_printk_clock; } -EXPORT_SYMBOL(udelay); diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index 706b7734e191..6e5eea19fa67 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -71,31 +71,33 @@ static int __init topology_init(void) int i, err = 0; #ifdef CONFIG_NUMA - sysfs_nodes = kmalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL); + sysfs_nodes = kzalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL); if (!sysfs_nodes) { err = -ENOMEM; goto out; } - memset(sysfs_nodes, 0, sizeof(struct node) * MAX_NUMNODES); - /* MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes? */ - for_each_online_node(i) + /* + * MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes? + */ + for_each_online_node(i) { if ((err = register_node(&sysfs_nodes[i], i, 0))) goto out; + } #endif - sysfs_cpus = kmalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL); + sysfs_cpus = kzalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL); if (!sysfs_cpus) { err = -ENOMEM; goto out; } - memset(sysfs_cpus, 0, sizeof(struct ia64_cpu) * NR_CPUS); - for_each_present_cpu(i) + for_each_present_cpu(i) { if((err = arch_register_cpu(i))) goto out; + } out: return err; } -__initcall(topology_init); +subsys_initcall(topology_init); diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index 55391901b013..dabd6c32641e 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -16,6 +16,7 @@ #include <linux/module.h> /* for EXPORT_SYMBOL */ #include <linux/hardirq.h> #include <linux/kprobes.h> +#include <linux/delay.h> /* for ssleep() */ #include <asm/fpswa.h> #include <asm/ia32.h> @@ -116,6 +117,13 @@ die (const char *str, struct pt_regs *regs, long err) bust_spinlocks(0); die.lock_owner = -1; spin_unlock_irq(&die.lock); + + if (panic_on_oops) { + printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n"); + ssleep(5); + panic("Fatal exception"); + } + do_exit(SIGSEGV); } diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c index 43b45b65ee5a..f9e0ae936d1a 100644 --- a/arch/ia64/kernel/unaligned.c +++ b/arch/ia64/kernel/unaligned.c @@ -1283,8 +1283,9 @@ within_logging_rate_limit (void) if (jiffies - last_time > 5*HZ) count = 0; - if (++count < 5) { + if (count < 5) { last_time = jiffies; + count++; return 1; } return 0; |