diff options
Diffstat (limited to 'arch/powerpc/kernel/setup-common.c')
| -rw-r--r-- | arch/powerpc/kernel/setup-common.c | 128 | 
1 files changed, 76 insertions, 52 deletions
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 9d4882a4664..e5b022c55cc 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -12,7 +12,7 @@  #undef DEBUG -#include <linux/module.h> +#include <linux/export.h>  #include <linux/string.h>  #include <linux/sched.h>  #include <linux/init.h> @@ -51,7 +51,6 @@  #include <asm/btext.h>  #include <asm/nvram.h>  #include <asm/setup.h> -#include <asm/system.h>  #include <asm/rtas.h>  #include <asm/iommu.h>  #include <asm/serial.h> @@ -61,8 +60,7 @@  #include <asm/xmon.h>  #include <asm/cputhreads.h>  #include <mm/mmu_decl.h> - -#include "setup.h" +#include <asm/fadump.h>  #ifdef DEBUG  #include <asm/udbg.h> @@ -78,6 +76,9 @@ EXPORT_SYMBOL(ppc_md);  struct machdep_calls *machine_id;  EXPORT_SYMBOL(machine_id); +int boot_cpuid = -1; +EXPORT_SYMBOL_GPL(boot_cpuid); +  unsigned long klimit = (unsigned long) _end;  char cmd_line[COMMAND_LINE_SIZE]; @@ -109,6 +110,14 @@ EXPORT_SYMBOL(ppc_do_canonicalize_irqs);  /* also used by kexec */  void machine_shutdown(void)  { +#ifdef CONFIG_FA_DUMP +	/* +	 * if fadump is active, cleanup the fadump registration before we +	 * shutdown. +	 */ +	fadump_cleanup(); +#endif +  	if (ppc_md.machine_shutdown)  		ppc_md.machine_shutdown();  } @@ -203,6 +212,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)  {  	unsigned long cpu_id = (unsigned long)v - 1;  	unsigned int pvr; +	unsigned long proc_freq;  	unsigned short maj;  	unsigned short min; @@ -254,12 +264,19 @@ static int show_cpuinfo(struct seq_file *m, void *v)  #endif /* CONFIG_TAU */  	/* -	 * Assume here that all clock rates are the same in a -	 * smp system.  -- Cort +	 * Platforms that have variable clock rates, should implement +	 * the method ppc_md.get_proc_freq() that reports the clock +	 * rate of a given cpu. The rest can use ppc_proc_freq to +	 * report the clock rate that is same across all cpus.  	 */ -	if (ppc_proc_freq) +	if (ppc_md.get_proc_freq) +		proc_freq = ppc_md.get_proc_freq(cpu_id); +	else +		proc_freq = ppc_proc_freq; + +	if (proc_freq)  		seq_printf(m, "clock\t\t: %lu.%06luMHz\n", -			   ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); +			   proc_freq / 1000000, proc_freq % 1000000);  	if (ppc_md.show_percpuinfo != NULL)  		ppc_md.show_percpuinfo(m, cpu_id); @@ -373,15 +390,20 @@ void __init check_for_initrd(void)  #ifdef CONFIG_SMP -int threads_per_core, threads_shift; +int threads_per_core, threads_per_subcore, threads_shift;  cpumask_t threads_core_mask; +EXPORT_SYMBOL_GPL(threads_per_core); +EXPORT_SYMBOL_GPL(threads_per_subcore); +EXPORT_SYMBOL_GPL(threads_shift); +EXPORT_SYMBOL_GPL(threads_core_mask);  static void __init cpu_init_thread_core_maps(int tpc)  {  	int i;  	threads_per_core = tpc; -	threads_core_mask = CPU_MASK_NONE; +	threads_per_subcore = tpc; +	cpumask_clear(&threads_core_mask);  	/* This implementation only supports power of 2 number of threads  	 * for simplicity and performance @@ -390,7 +412,7 @@ static void __init cpu_init_thread_core_maps(int tpc)  	BUG_ON(tpc != (1 << threads_shift));  	for (i = 0; i < tpc; i++) -		cpu_set(i, threads_core_mask); +		cpumask_set_cpu(i, &threads_core_mask);  	printk(KERN_INFO "CPU maps initialized for %d thread%s per core\n",  	       tpc, tpc > 1 ? "s" : ""); @@ -404,7 +426,7 @@ static void __init cpu_init_thread_core_maps(int tpc)   *                  cpu_present_mask   *   * Having the possible map set up early allows us to restrict allocations - * of things like irqstacks to num_possible_cpus() rather than NR_CPUS. + * of things like irqstacks to nr_cpu_ids rather than NR_CPUS.   *   * We do not initialize the online map here; cpus set their own bits in   * cpu_online_mask as they come up. @@ -424,8 +446,9 @@ void __init smp_setup_cpu_maps(void)  	DBG("smp_setup_cpu_maps()\n"); -	while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { -		const int *intserv; +	while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < nr_cpu_ids) { +		const __be32 *intserv; +		__be32 cpu_be;  		int j, len;  		DBG("  * %s...\n", dn->full_name); @@ -439,15 +462,25 @@ void __init smp_setup_cpu_maps(void)  		} else {  			DBG("    no ibm,ppc-interrupt-server#s -> 1 thread\n");  			intserv = of_get_property(dn, "reg", NULL); -			if (!intserv) -				intserv = &cpu;	/* assume logical == phys */ +			if (!intserv) { +				cpu_be = cpu_to_be32(cpu); +				intserv = &cpu_be;	/* assume logical == phys */ +			}  		} -		for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { +		for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) { +			bool avail; +  			DBG("    thread %d -> cpu %d (hard id %d)\n", -			    j, cpu, intserv[j]); -			set_cpu_present(cpu, true); -			set_hard_smp_processor_id(cpu, intserv[j]); +			    j, cpu, be32_to_cpu(intserv[j])); + +			avail = of_device_is_available(dn); +			if (!avail) +				avail = !of_property_match_string(dn, +						"enable-method", "spin-table"); + +			set_cpu_present(cpu, avail); +			set_hard_smp_processor_id(cpu, be32_to_cpu(intserv[j]));  			set_cpu_possible(cpu, true);  			cpu++;  		} @@ -467,7 +500,7 @@ void __init smp_setup_cpu_maps(void)  	if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) &&  	    (dn = of_find_node_by_path("/rtas"))) {  		int num_addr_cell, num_size_cell, maxcpus; -		const unsigned int *ireg; +		const __be32 *ireg;  		num_addr_cell = of_n_addr_cells(dn);  		num_size_cell = of_n_size_cells(dn); @@ -477,18 +510,18 @@ void __init smp_setup_cpu_maps(void)  		if (!ireg)  			goto out; -		maxcpus = ireg[num_addr_cell + num_size_cell]; +		maxcpus = be32_to_cpup(ireg + num_addr_cell + num_size_cell);  		/* Double maxcpus for processors which have SMT capability */  		if (cpu_has_feature(CPU_FTR_SMT))  			maxcpus *= nthreads; -		if (maxcpus > NR_CPUS) { +		if (maxcpus > nr_cpu_ids) {  			printk(KERN_WARNING  			       "Partition configured for %d cpus, "  			       "operating system maximum is %d.\n", -			       maxcpus, NR_CPUS); -			maxcpus = NR_CPUS; +			       maxcpus, nr_cpu_ids); +			maxcpus = nr_cpu_ids;  		} else  			printk(KERN_INFO "Partition configured for %d cpus.\n",  			       maxcpus); @@ -509,6 +542,9 @@ void __init smp_setup_cpu_maps(void)  	 */  	cpu_init_thread_core_maps(nthreads); +	/* Now that possible cpus are set, set nr_cpu_ids for later use */ +	setup_nr_cpu_ids(); +  	free_unused_pacas();  }  #endif /* CONFIG_SMP */ @@ -599,16 +635,14 @@ int check_legacy_ioport(unsigned long base_port)  		 * name instead */  		if (!np)  			np = of_find_node_by_name(NULL, "8042"); +		if (np) { +			of_i8042_kbd_irq = 1; +			of_i8042_aux_irq = 12; +		}  		break;  	case FDC_BASE: /* FDC1 */  		np = of_find_node_by_type(NULL, "fdc");  		break; -#ifdef CONFIG_PPC_PREP -	case _PIDXR: -	case _PNPWRP: -	case PNPBIOS_BASE: -		/* implement me */ -#endif  	default:  		/* ipmi is supposed to fail here */  		break; @@ -629,6 +663,11 @@ EXPORT_SYMBOL(check_legacy_ioport);  static int ppc_panic_event(struct notifier_block *this,                               unsigned long event, void *ptr)  { +	/* +	 * If firmware-assisted dump has been registered then trigger +	 * firmware-assisted dump and let firmware handle everything else. +	 */ +	crash_fadump(NULL, ptr);  	ppc_md.panic(ptr);  /* May not return */  	return NOTIFY_DONE;  } @@ -697,29 +736,14 @@ static int powerpc_debugfs_init(void)  arch_initcall(powerpc_debugfs_init);  #endif -static int ppc_dflt_bus_notify(struct notifier_block *nb, -				unsigned long action, void *data) +void ppc_printk_progress(char *s, unsigned short hex)  { -	struct device *dev = data; - -	/* We are only intereted in device addition */ -	if (action != BUS_NOTIFY_ADD_DEVICE) -		return 0; - -	set_dma_ops(dev, &dma_direct_ops); - -	return NOTIFY_DONE; +	pr_info("%s\n", s);  } -static struct notifier_block ppc_dflt_plat_bus_notifier = { -	.notifier_call = ppc_dflt_bus_notify, -	.priority = INT_MAX, -}; - -static int __init setup_bus_notifier(void) +void arch_setup_pdev_archdata(struct platform_device *pdev)  { -	bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier); -	return 0; +	pdev->archdata.dma_mask = DMA_BIT_MASK(32); +	pdev->dev.dma_mask = &pdev->archdata.dma_mask; + 	set_dma_ops(&pdev->dev, &dma_direct_ops);  } - -arch_initcall(setup_bus_notifier);  | 
