aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kernel/smp.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 1f4711b60aab..fe5f8dc1e6fa 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -534,18 +534,23 @@ int __cpuinit __cpu_up(unsigned int cpu)
534 struct _lowcore *cpu_lowcore; 534 struct _lowcore *cpu_lowcore;
535 struct stack_frame *sf; 535 struct stack_frame *sf;
536 sigp_ccode ccode; 536 sigp_ccode ccode;
537 u32 lowcore;
537 538
538 if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED) 539 if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
539 return -EIO; 540 return -EIO;
540 if (smp_alloc_lowcore(cpu)) 541 if (smp_alloc_lowcore(cpu))
541 return -ENOMEM; 542 return -ENOMEM;
542 543 do {
543 ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]), 544 ccode = signal_processor(cpu, sigp_initial_cpu_reset);
544 cpu, sigp_set_prefix); 545 if (ccode == sigp_busy)
545 if (ccode) { 546 udelay(10);
546 smp_free_lowcore(cpu); 547 if (ccode == sigp_not_operational)
547 return -EIO; 548 goto err_out;
548 } 549 } while (ccode == sigp_busy);
550
551 lowcore = (u32)(unsigned long)lowcore_ptr[cpu];
552 while (signal_processor_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
553 udelay(10);
549 554
550 idle = current_set[cpu]; 555 idle = current_set[cpu];
551 cpu_lowcore = lowcore_ptr[cpu]; 556 cpu_lowcore = lowcore_ptr[cpu];
@@ -574,6 +579,10 @@ int __cpuinit __cpu_up(unsigned int cpu)
574 while (!cpu_online(cpu)) 579 while (!cpu_online(cpu))
575 cpu_relax(); 580 cpu_relax();
576 return 0; 581 return 0;
582
583err_out:
584 smp_free_lowcore(cpu);
585 return -EIO;
577} 586}
578 587
579static int __init setup_possible_cpus(char *s) 588static int __init setup_possible_cpus(char *s)