Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: kdump: Allow shrinking of kdump region to be overridden powerpc/pmac/smp: Remove no-longer needed preempt workaround powerpc/smp: Increase vdso_data->processorCount, not just decrease it powerpc/smp: Create idle threads on demand and properly reset them powerpc/smp: Don't expose per-cpu "cpu_state" array powerpc/pmac/smp: Fix CPU hotplug crashes on some machines powerpc/smp: Add a smp_ops->bringup_up() done callback powerpc/pmac: Rename cpu_state in therm_pm72 to avoid collision powerpc/pmac/smp: Properly NAP offlined CPU on G5 powerpc/pmac/smp: Remove HMT changes for PowerMac offline code powerpc/pmac/smp: Consolidate 32-bit and 64-bit PowerMac cpu_die in one file powerpc/pmac/smp: Fixup smp_core99_cpu_disable() and use it on 64-bit powerpc/pmac/smp: Rename fixup_irqs() to migrate_irqs() and use it on ppc32 powerpc/pmac/smp: Fix 32-bit PowerMac cpu_die powerpc/smp: Remove unused smp_ops->cpu_enable() powerpc/smp: Remove unused generic_cpu_enable() powerpc/smp: Fix generic_mach_cpu_die() powerpc/smp: soft-replugged CPUs must go back to start_secondary powerpc: Make decrementer interrupt robust against offlined CPUs
This commit is contained in:
@@ -35,9 +35,9 @@ struct smp_ops_t {
|
|||||||
int (*probe)(void);
|
int (*probe)(void);
|
||||||
void (*kick_cpu)(int nr);
|
void (*kick_cpu)(int nr);
|
||||||
void (*setup_cpu)(int nr);
|
void (*setup_cpu)(int nr);
|
||||||
|
void (*bringup_done)(void);
|
||||||
void (*take_timebase)(void);
|
void (*take_timebase)(void);
|
||||||
void (*give_timebase)(void);
|
void (*give_timebase)(void);
|
||||||
int (*cpu_enable)(unsigned int nr);
|
|
||||||
int (*cpu_disable)(void);
|
int (*cpu_disable)(void);
|
||||||
void (*cpu_die)(unsigned int nr);
|
void (*cpu_die)(unsigned int nr);
|
||||||
int (*cpu_bootable)(unsigned int nr);
|
int (*cpu_bootable)(unsigned int nr);
|
||||||
@@ -267,7 +267,6 @@ struct machdep_calls {
|
|||||||
|
|
||||||
extern void e500_idle(void);
|
extern void e500_idle(void);
|
||||||
extern void power4_idle(void);
|
extern void power4_idle(void);
|
||||||
extern void power4_cpu_offline_powersave(void);
|
|
||||||
extern void ppc6xx_idle(void);
|
extern void ppc6xx_idle(void);
|
||||||
extern void book3e_idle(void);
|
extern void book3e_idle(void);
|
||||||
|
|
||||||
|
@@ -36,15 +36,16 @@ extern void cpu_die(void);
|
|||||||
|
|
||||||
extern void smp_send_debugger_break(int cpu);
|
extern void smp_send_debugger_break(int cpu);
|
||||||
extern void smp_message_recv(int);
|
extern void smp_message_recv(int);
|
||||||
|
extern void start_secondary_resume(void);
|
||||||
|
|
||||||
DECLARE_PER_CPU(unsigned int, cpu_pvr);
|
DECLARE_PER_CPU(unsigned int, cpu_pvr);
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
extern void fixup_irqs(const struct cpumask *map);
|
extern void migrate_irqs(void);
|
||||||
int generic_cpu_disable(void);
|
int generic_cpu_disable(void);
|
||||||
int generic_cpu_enable(unsigned int cpu);
|
|
||||||
void generic_cpu_die(unsigned int cpu);
|
void generic_cpu_die(unsigned int cpu);
|
||||||
void generic_mach_cpu_die(void);
|
void generic_mach_cpu_die(void);
|
||||||
|
void generic_set_cpu_dead(unsigned int cpu);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
|
@@ -890,6 +890,15 @@ __secondary_start:
|
|||||||
mtspr SPRN_SRR1,r4
|
mtspr SPRN_SRR1,r4
|
||||||
SYNC
|
SYNC
|
||||||
RFI
|
RFI
|
||||||
|
|
||||||
|
_GLOBAL(start_secondary_resume)
|
||||||
|
/* Reset stack */
|
||||||
|
rlwinm r1,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
|
||||||
|
addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
|
||||||
|
li r3,0
|
||||||
|
std r3,0(r1) /* Zero the stack frame pointer */
|
||||||
|
bl start_secondary
|
||||||
|
b .
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
#ifdef CONFIG_KVM_BOOK3S_HANDLER
|
#ifdef CONFIG_KVM_BOOK3S_HANDLER
|
||||||
|
@@ -536,6 +536,13 @@ _GLOBAL(pmac_secondary_start)
|
|||||||
add r13,r13,r4 /* for this processor. */
|
add r13,r13,r4 /* for this processor. */
|
||||||
mtspr SPRN_SPRG_PACA,r13 /* Save vaddr of paca in an SPRG*/
|
mtspr SPRN_SPRG_PACA,r13 /* Save vaddr of paca in an SPRG*/
|
||||||
|
|
||||||
|
/* Mark interrupts soft and hard disabled (they might be enabled
|
||||||
|
* in the PACA when doing hotplug)
|
||||||
|
*/
|
||||||
|
li r0,0
|
||||||
|
stb r0,PACASOFTIRQEN(r13)
|
||||||
|
stb r0,PACAHARDIRQEN(r13)
|
||||||
|
|
||||||
/* Create a temp kernel stack for use before relocation is on. */
|
/* Create a temp kernel stack for use before relocation is on. */
|
||||||
ld r1,PACAEMERGSP(r13)
|
ld r1,PACAEMERGSP(r13)
|
||||||
subi r1,r1,STACK_FRAME_OVERHEAD
|
subi r1,r1,STACK_FRAME_OVERHEAD
|
||||||
|
@@ -53,24 +53,3 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
|||||||
isync
|
isync
|
||||||
b 1b
|
b 1b
|
||||||
|
|
||||||
_GLOBAL(power4_cpu_offline_powersave)
|
|
||||||
/* Go to NAP now */
|
|
||||||
mfmsr r7
|
|
||||||
rldicl r0,r7,48,1
|
|
||||||
rotldi r0,r0,16
|
|
||||||
mtmsrd r0,1 /* hard-disable interrupts */
|
|
||||||
li r0,1
|
|
||||||
li r6,0
|
|
||||||
stb r0,PACAHARDIRQEN(r13) /* we'll hard-enable shortly */
|
|
||||||
stb r6,PACASOFTIRQEN(r13) /* soft-disable irqs */
|
|
||||||
BEGIN_FTR_SECTION
|
|
||||||
DSSALL
|
|
||||||
sync
|
|
||||||
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
|
||||||
ori r7,r7,MSR_EE
|
|
||||||
oris r7,r7,MSR_POW@h
|
|
||||||
sync
|
|
||||||
isync
|
|
||||||
mtmsrd r7
|
|
||||||
isync
|
|
||||||
blr
|
|
||||||
|
@@ -246,12 +246,13 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
void fixup_irqs(const struct cpumask *map)
|
void migrate_irqs(void)
|
||||||
{
|
{
|
||||||
struct irq_desc *desc;
|
struct irq_desc *desc;
|
||||||
unsigned int irq;
|
unsigned int irq;
|
||||||
static int warned;
|
static int warned;
|
||||||
cpumask_var_t mask;
|
cpumask_var_t mask;
|
||||||
|
const struct cpumask *map = cpu_online_mask;
|
||||||
|
|
||||||
alloc_cpumask_var(&mask, GFP_KERNEL);
|
alloc_cpumask_var(&mask, GFP_KERNEL);
|
||||||
|
|
||||||
|
@@ -57,6 +57,25 @@
|
|||||||
#define DBG(fmt...)
|
#define DBG(fmt...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Store all idle threads, this can be reused instead of creating
|
||||||
|
* a new thread. Also avoids complicated thread destroy functionality
|
||||||
|
* for idle threads.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
/*
|
||||||
|
* Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is
|
||||||
|
* removed after init for !CONFIG_HOTPLUG_CPU.
|
||||||
|
*/
|
||||||
|
static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
|
||||||
|
#define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x))
|
||||||
|
#define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p))
|
||||||
|
#else
|
||||||
|
static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
|
||||||
|
#define get_idle_for_cpu(x) (idle_thread_array[(x)])
|
||||||
|
#define set_idle_for_cpu(x, p) (idle_thread_array[(x)] = (p))
|
||||||
|
#endif
|
||||||
|
|
||||||
struct thread_info *secondary_ti;
|
struct thread_info *secondary_ti;
|
||||||
|
|
||||||
DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map);
|
DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map);
|
||||||
@@ -238,23 +257,6 @@ static void __devinit smp_store_cpu_info(int id)
|
|||||||
per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR);
|
per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init smp_create_idle(unsigned int cpu)
|
|
||||||
{
|
|
||||||
struct task_struct *p;
|
|
||||||
|
|
||||||
/* create a process for the processor */
|
|
||||||
p = fork_idle(cpu);
|
|
||||||
if (IS_ERR(p))
|
|
||||||
panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
|
|
||||||
#ifdef CONFIG_PPC64
|
|
||||||
paca[cpu].__current = p;
|
|
||||||
paca[cpu].kstack = (unsigned long) task_thread_info(p)
|
|
||||||
+ THREAD_SIZE - STACK_FRAME_OVERHEAD;
|
|
||||||
#endif
|
|
||||||
current_set[cpu] = task_thread_info(p);
|
|
||||||
task_thread_info(p)->cpu = cpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __init smp_prepare_cpus(unsigned int max_cpus)
|
void __init smp_prepare_cpus(unsigned int max_cpus)
|
||||||
{
|
{
|
||||||
unsigned int cpu;
|
unsigned int cpu;
|
||||||
@@ -288,10 +290,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
|
|||||||
max_cpus = NR_CPUS;
|
max_cpus = NR_CPUS;
|
||||||
else
|
else
|
||||||
max_cpus = 1;
|
max_cpus = 1;
|
||||||
|
|
||||||
for_each_possible_cpu(cpu)
|
|
||||||
if (cpu != boot_cpuid)
|
|
||||||
smp_create_idle(cpu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __devinit smp_prepare_boot_cpu(void)
|
void __devinit smp_prepare_boot_cpu(void)
|
||||||
@@ -305,7 +303,7 @@ void __devinit smp_prepare_boot_cpu(void)
|
|||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
/* State of each CPU during hotplug phases */
|
/* State of each CPU during hotplug phases */
|
||||||
DEFINE_PER_CPU(int, cpu_state) = { 0 };
|
static DEFINE_PER_CPU(int, cpu_state) = { 0 };
|
||||||
|
|
||||||
int generic_cpu_disable(void)
|
int generic_cpu_disable(void)
|
||||||
{
|
{
|
||||||
@@ -317,30 +315,8 @@ int generic_cpu_disable(void)
|
|||||||
set_cpu_online(cpu, false);
|
set_cpu_online(cpu, false);
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
vdso_data->processorCount--;
|
vdso_data->processorCount--;
|
||||||
fixup_irqs(cpu_online_mask);
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int generic_cpu_enable(unsigned int cpu)
|
|
||||||
{
|
|
||||||
/* Do the normal bootup if we haven't
|
|
||||||
* already bootstrapped. */
|
|
||||||
if (system_state != SYSTEM_RUNNING)
|
|
||||||
return -ENOSYS;
|
|
||||||
|
|
||||||
/* get the target out of it's holding state */
|
|
||||||
per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
|
|
||||||
smp_wmb();
|
|
||||||
|
|
||||||
while (!cpu_online(cpu))
|
|
||||||
cpu_relax();
|
|
||||||
|
|
||||||
#ifdef CONFIG_PPC64
|
|
||||||
fixup_irqs(cpu_online_mask);
|
|
||||||
/* counter the irq disable in fixup_irqs */
|
|
||||||
local_irq_enable();
|
|
||||||
#endif
|
#endif
|
||||||
|
migrate_irqs();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,37 +338,89 @@ void generic_mach_cpu_die(void)
|
|||||||
unsigned int cpu;
|
unsigned int cpu;
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
|
idle_task_exit();
|
||||||
cpu = smp_processor_id();
|
cpu = smp_processor_id();
|
||||||
printk(KERN_DEBUG "CPU%d offline\n", cpu);
|
printk(KERN_DEBUG "CPU%d offline\n", cpu);
|
||||||
__get_cpu_var(cpu_state) = CPU_DEAD;
|
__get_cpu_var(cpu_state) = CPU_DEAD;
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
|
while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
set_cpu_online(cpu, true);
|
}
|
||||||
local_irq_enable();
|
|
||||||
|
void generic_set_cpu_dead(unsigned int cpu)
|
||||||
|
{
|
||||||
|
per_cpu(cpu_state, cpu) = CPU_DEAD;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int __devinit cpu_enable(unsigned int cpu)
|
struct create_idle {
|
||||||
{
|
struct work_struct work;
|
||||||
if (smp_ops && smp_ops->cpu_enable)
|
struct task_struct *idle;
|
||||||
return smp_ops->cpu_enable(cpu);
|
struct completion done;
|
||||||
|
int cpu;
|
||||||
|
};
|
||||||
|
|
||||||
return -ENOSYS;
|
static void __cpuinit do_fork_idle(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct create_idle *c_idle =
|
||||||
|
container_of(work, struct create_idle, work);
|
||||||
|
|
||||||
|
c_idle->idle = fork_idle(c_idle->cpu);
|
||||||
|
complete(&c_idle->done);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __cpuinit create_idle(unsigned int cpu)
|
||||||
|
{
|
||||||
|
struct thread_info *ti;
|
||||||
|
struct create_idle c_idle = {
|
||||||
|
.cpu = cpu,
|
||||||
|
.done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
|
||||||
|
};
|
||||||
|
INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
|
||||||
|
|
||||||
|
c_idle.idle = get_idle_for_cpu(cpu);
|
||||||
|
|
||||||
|
/* We can't use kernel_thread since we must avoid to
|
||||||
|
* reschedule the child. We use a workqueue because
|
||||||
|
* we want to fork from a kernel thread, not whatever
|
||||||
|
* userspace process happens to be trying to online us.
|
||||||
|
*/
|
||||||
|
if (!c_idle.idle) {
|
||||||
|
schedule_work(&c_idle.work);
|
||||||
|
wait_for_completion(&c_idle.done);
|
||||||
|
} else
|
||||||
|
init_idle(c_idle.idle, cpu);
|
||||||
|
if (IS_ERR(c_idle.idle)) {
|
||||||
|
pr_err("Failed fork for CPU %u: %li", cpu, PTR_ERR(c_idle.idle));
|
||||||
|
return PTR_ERR(c_idle.idle);
|
||||||
|
}
|
||||||
|
ti = task_thread_info(c_idle.idle);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC64
|
||||||
|
paca[cpu].__current = c_idle.idle;
|
||||||
|
paca[cpu].kstack = (unsigned long)ti + THREAD_SIZE - STACK_FRAME_OVERHEAD;
|
||||||
|
#endif
|
||||||
|
ti->cpu = cpu;
|
||||||
|
current_set[cpu] = ti;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __cpuinit __cpu_up(unsigned int cpu)
|
int __cpuinit __cpu_up(unsigned int cpu)
|
||||||
{
|
{
|
||||||
int c;
|
int rc, c;
|
||||||
|
|
||||||
secondary_ti = current_set[cpu];
|
secondary_ti = current_set[cpu];
|
||||||
if (!cpu_enable(cpu))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (smp_ops == NULL ||
|
if (smp_ops == NULL ||
|
||||||
(smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
|
(smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Make sure we have an idle thread */
|
||||||
|
rc = create_idle(cpu);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
/* Make sure callin-map entry is 0 (can be leftover a CPU
|
/* Make sure callin-map entry is 0 (can be leftover a CPU
|
||||||
* hotplug
|
* hotplug
|
||||||
*/
|
*/
|
||||||
@@ -502,7 +530,7 @@ static struct device_node *cpu_to_l2cache(int cpu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Activate a secondary processor. */
|
/* Activate a secondary processor. */
|
||||||
int __devinit start_secondary(void *unused)
|
void __devinit start_secondary(void *unused)
|
||||||
{
|
{
|
||||||
unsigned int cpu = smp_processor_id();
|
unsigned int cpu = smp_processor_id();
|
||||||
struct device_node *l2_cache;
|
struct device_node *l2_cache;
|
||||||
@@ -523,6 +551,10 @@ int __devinit start_secondary(void *unused)
|
|||||||
|
|
||||||
secondary_cpu_time_init();
|
secondary_cpu_time_init();
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC64
|
||||||
|
if (system_state == SYSTEM_RUNNING)
|
||||||
|
vdso_data->processorCount++;
|
||||||
|
#endif
|
||||||
ipi_call_lock();
|
ipi_call_lock();
|
||||||
notify_cpu_starting(cpu);
|
notify_cpu_starting(cpu);
|
||||||
set_cpu_online(cpu, true);
|
set_cpu_online(cpu, true);
|
||||||
@@ -558,7 +590,8 @@ int __devinit start_secondary(void *unused)
|
|||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
|
|
||||||
cpu_idle();
|
cpu_idle();
|
||||||
return 0;
|
|
||||||
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
int setup_profiling_timer(unsigned int multiplier)
|
int setup_profiling_timer(unsigned int multiplier)
|
||||||
@@ -585,7 +618,11 @@ void __init smp_cpus_done(unsigned int max_cpus)
|
|||||||
|
|
||||||
free_cpumask_var(old_mask);
|
free_cpumask_var(old_mask);
|
||||||
|
|
||||||
|
if (smp_ops && smp_ops->bringup_done)
|
||||||
|
smp_ops->bringup_done();
|
||||||
|
|
||||||
dump_numa_cpu_topology();
|
dump_numa_cpu_topology();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int arch_sd_sibling_asym_packing(void)
|
int arch_sd_sibling_asym_packing(void)
|
||||||
@@ -660,5 +697,9 @@ void cpu_die(void)
|
|||||||
{
|
{
|
||||||
if (ppc_md.cpu_die)
|
if (ppc_md.cpu_die)
|
||||||
ppc_md.cpu_die();
|
ppc_md.cpu_die();
|
||||||
|
|
||||||
|
/* If we return, we re-enter start_secondary */
|
||||||
|
start_secondary_resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -577,14 +577,21 @@ void timer_interrupt(struct pt_regs * regs)
|
|||||||
struct clock_event_device *evt = &decrementer->event;
|
struct clock_event_device *evt = &decrementer->event;
|
||||||
u64 now;
|
u64 now;
|
||||||
|
|
||||||
|
/* Ensure a positive value is written to the decrementer, or else
|
||||||
|
* some CPUs will continue to take decrementer exceptions.
|
||||||
|
*/
|
||||||
|
set_dec(DECREMENTER_MAX);
|
||||||
|
|
||||||
|
/* Some implementations of hotplug will get timer interrupts while
|
||||||
|
* offline, just ignore these
|
||||||
|
*/
|
||||||
|
if (!cpu_online(smp_processor_id()))
|
||||||
|
return;
|
||||||
|
|
||||||
trace_timer_interrupt_entry(regs);
|
trace_timer_interrupt_entry(regs);
|
||||||
|
|
||||||
__get_cpu_var(irq_stat).timer_irqs++;
|
__get_cpu_var(irq_stat).timer_irqs++;
|
||||||
|
|
||||||
/* Ensure a positive value is written to the decrementer, or else
|
|
||||||
* some CPUs will continuue to take decrementer exceptions */
|
|
||||||
set_dec(DECREMENTER_MAX);
|
|
||||||
|
|
||||||
#if defined(CONFIG_PPC32) && defined(CONFIG_PMAC)
|
#if defined(CONFIG_PPC32) && defined(CONFIG_PMAC)
|
||||||
if (atomic_read(&ppc_n_lost_interrupts) != 0)
|
if (atomic_read(&ppc_n_lost_interrupts) != 0)
|
||||||
do_IRQ(regs);
|
do_IRQ(regs);
|
||||||
|
@@ -33,7 +33,6 @@ extern void pmac_setup_pci_dma(void);
|
|||||||
extern void pmac_check_ht_link(void);
|
extern void pmac_check_ht_link(void);
|
||||||
|
|
||||||
extern void pmac_setup_smp(void);
|
extern void pmac_setup_smp(void);
|
||||||
extern void pmac32_cpu_die(void);
|
|
||||||
extern void low_cpu_die(void) __attribute__((noreturn));
|
extern void low_cpu_die(void) __attribute__((noreturn));
|
||||||
|
|
||||||
extern int pmac_nvram_init(void);
|
extern int pmac_nvram_init(void);
|
||||||
|
@@ -650,51 +650,6 @@ static int pmac_pci_probe_mode(struct pci_bus *bus)
|
|||||||
return PCI_PROBE_NORMAL;
|
return PCI_PROBE_NORMAL;
|
||||||
return PCI_PROBE_DEVTREE;
|
return PCI_PROBE_DEVTREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
|
||||||
/* access per cpu vars from generic smp.c */
|
|
||||||
DECLARE_PER_CPU(int, cpu_state);
|
|
||||||
|
|
||||||
static void pmac64_cpu_die(void)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* turn off as much as possible, we'll be
|
|
||||||
* kicked out as this will only be invoked
|
|
||||||
* on core99 platforms for now ...
|
|
||||||
*/
|
|
||||||
|
|
||||||
printk(KERN_INFO "CPU#%d offline\n", smp_processor_id());
|
|
||||||
__get_cpu_var(cpu_state) = CPU_DEAD;
|
|
||||||
smp_wmb();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* during the path that leads here preemption is disabled,
|
|
||||||
* reenable it now so that when coming up preempt count is
|
|
||||||
* zero correctly
|
|
||||||
*/
|
|
||||||
preempt_enable();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* hard-disable interrupts for the non-NAP case, the NAP code
|
|
||||||
* needs to re-enable interrupts (but soft-disables them)
|
|
||||||
*/
|
|
||||||
hard_irq_disable();
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
/* let's not take timer interrupts too often ... */
|
|
||||||
set_dec(0x7fffffff);
|
|
||||||
|
|
||||||
/* should always be true at this point */
|
|
||||||
if (cpu_has_feature(CPU_FTR_CAN_NAP))
|
|
||||||
power4_cpu_offline_powersave();
|
|
||||||
else {
|
|
||||||
HMT_low();
|
|
||||||
HMT_very_low();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_HOTPLUG_CPU */
|
|
||||||
|
|
||||||
#endif /* CONFIG_PPC64 */
|
#endif /* CONFIG_PPC64 */
|
||||||
|
|
||||||
define_machine(powermac) {
|
define_machine(powermac) {
|
||||||
@@ -726,15 +681,4 @@ define_machine(powermac) {
|
|||||||
.pcibios_after_init = pmac_pcibios_after_init,
|
.pcibios_after_init = pmac_pcibios_after_init,
|
||||||
.phys_mem_access_prot = pci_phys_mem_access_prot,
|
.phys_mem_access_prot = pci_phys_mem_access_prot,
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
|
||||||
#ifdef CONFIG_PPC64
|
|
||||||
.cpu_die = pmac64_cpu_die,
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_PPC32
|
|
||||||
.cpu_die = pmac32_cpu_die,
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
|
|
||||||
.cpu_die = generic_mach_cpu_die,
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
@@ -840,92 +840,149 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr)
|
|||||||
|
|
||||||
/* Setup openpic */
|
/* Setup openpic */
|
||||||
mpic_setup_this_cpu();
|
mpic_setup_this_cpu();
|
||||||
|
}
|
||||||
|
|
||||||
if (cpu_nr == 0) {
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
static int smp_core99_cpu_notify(struct notifier_block *self,
|
||||||
|
unsigned long action, void *hcpu)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
switch(action) {
|
||||||
|
case CPU_UP_PREPARE:
|
||||||
|
case CPU_UP_PREPARE_FROZEN:
|
||||||
|
/* Open i2c bus if it was used for tb sync */
|
||||||
|
if (pmac_tb_clock_chip_host) {
|
||||||
|
rc = pmac_i2c_open(pmac_tb_clock_chip_host, 1);
|
||||||
|
if (rc) {
|
||||||
|
pr_err("Failed to open i2c bus for time sync\n");
|
||||||
|
return notifier_from_errno(rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CPU_ONLINE:
|
||||||
|
case CPU_UP_CANCELED:
|
||||||
|
/* Close i2c bus if it was used for tb sync */
|
||||||
|
if (pmac_tb_clock_chip_host)
|
||||||
|
pmac_i2c_close(pmac_tb_clock_chip_host);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NOTIFY_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct notifier_block __cpuinitdata smp_core99_cpu_nb = {
|
||||||
|
.notifier_call = smp_core99_cpu_notify,
|
||||||
|
};
|
||||||
|
#endif /* CONFIG_HOTPLUG_CPU */
|
||||||
|
|
||||||
|
static void __init smp_core99_bringup_done(void)
|
||||||
|
{
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
extern void g5_phy_disable_cpu1(void);
|
extern void g5_phy_disable_cpu1(void);
|
||||||
|
|
||||||
/* Close i2c bus if it was used for tb sync */
|
/* Close i2c bus if it was used for tb sync */
|
||||||
if (pmac_tb_clock_chip_host) {
|
if (pmac_tb_clock_chip_host)
|
||||||
pmac_i2c_close(pmac_tb_clock_chip_host);
|
pmac_i2c_close(pmac_tb_clock_chip_host);
|
||||||
pmac_tb_clock_chip_host = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we didn't start the second CPU, we must take
|
/* If we didn't start the second CPU, we must take
|
||||||
* it off the bus
|
* it off the bus.
|
||||||
*/
|
*/
|
||||||
if (of_machine_is_compatible("MacRISC4") &&
|
if (of_machine_is_compatible("MacRISC4") &&
|
||||||
num_online_cpus() < 2)
|
num_online_cpus() < 2) {
|
||||||
|
set_cpu_present(1, false);
|
||||||
g5_phy_disable_cpu1();
|
g5_phy_disable_cpu1();
|
||||||
|
}
|
||||||
#endif /* CONFIG_PPC64 */
|
#endif /* CONFIG_PPC64 */
|
||||||
|
|
||||||
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
register_cpu_notifier(&smp_core99_cpu_nb);
|
||||||
|
#endif
|
||||||
if (ppc_md.progress)
|
if (ppc_md.progress)
|
||||||
ppc_md.progress("core99_setup_cpu 0 done", 0x349);
|
ppc_md.progress("smp_core99_bringup_done", 0x349);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
|
||||||
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
|
static int smp_core99_cpu_disable(void)
|
||||||
|
|
||||||
int smp_core99_cpu_disable(void)
|
|
||||||
{
|
{
|
||||||
set_cpu_online(smp_processor_id(), false);
|
int rc = generic_cpu_disable();
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
/* XXX reset cpu affinity here */
|
|
||||||
mpic_cpu_set_priority(0xf);
|
mpic_cpu_set_priority(0xf);
|
||||||
asm volatile("mtdec %0" : : "r" (0x7fffffff));
|
|
||||||
mb();
|
|
||||||
udelay(20);
|
|
||||||
asm volatile("mtdec %0" : : "r" (0x7fffffff));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cpu_dead[NR_CPUS];
|
#ifdef CONFIG_PPC32
|
||||||
|
|
||||||
void pmac32_cpu_die(void)
|
static void pmac_cpu_die(void)
|
||||||
{
|
{
|
||||||
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
cpu_dead[smp_processor_id()] = 1;
|
idle_task_exit();
|
||||||
|
pr_debug("CPU%d offline\n", cpu);
|
||||||
|
generic_set_cpu_dead(cpu);
|
||||||
|
smp_wmb();
|
||||||
mb();
|
mb();
|
||||||
low_cpu_die();
|
low_cpu_die();
|
||||||
}
|
}
|
||||||
|
|
||||||
void smp_core99_cpu_die(unsigned int cpu)
|
#else /* CONFIG_PPC32 */
|
||||||
{
|
|
||||||
int timeout;
|
|
||||||
|
|
||||||
timeout = 1000;
|
static void pmac_cpu_die(void)
|
||||||
while (!cpu_dead[cpu]) {
|
{
|
||||||
if (--timeout == 0) {
|
int cpu = smp_processor_id();
|
||||||
printk("CPU %u refused to die!\n", cpu);
|
|
||||||
break;
|
local_irq_disable();
|
||||||
|
idle_task_exit();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* turn off as much as possible, we'll be
|
||||||
|
* kicked out as this will only be invoked
|
||||||
|
* on core99 platforms for now ...
|
||||||
|
*/
|
||||||
|
|
||||||
|
printk(KERN_INFO "CPU#%d offline\n", cpu);
|
||||||
|
generic_set_cpu_dead(cpu);
|
||||||
|
smp_wmb();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Re-enable interrupts. The NAP code needs to enable them
|
||||||
|
* anyways, do it now so we deal with the case where one already
|
||||||
|
* happened while soft-disabled.
|
||||||
|
* We shouldn't get any external interrupts, only decrementer, and the
|
||||||
|
* decrementer handler is safe for use on offline CPUs
|
||||||
|
*/
|
||||||
|
local_irq_enable();
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
/* let's not take timer interrupts too often ... */
|
||||||
|
set_dec(0x7fffffff);
|
||||||
|
|
||||||
|
/* Enter NAP mode */
|
||||||
|
power4_idle();
|
||||||
}
|
}
|
||||||
msleep(1);
|
|
||||||
}
|
|
||||||
cpu_dead[cpu] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_HOTPLUG_CPU && CONFIG_PP32 */
|
#endif /* else CONFIG_PPC32 */
|
||||||
|
#endif /* CONFIG_HOTPLUG_CPU */
|
||||||
|
|
||||||
/* Core99 Macs (dual G4s and G5s) */
|
/* Core99 Macs (dual G4s and G5s) */
|
||||||
struct smp_ops_t core99_smp_ops = {
|
struct smp_ops_t core99_smp_ops = {
|
||||||
.message_pass = smp_mpic_message_pass,
|
.message_pass = smp_mpic_message_pass,
|
||||||
.probe = smp_core99_probe,
|
.probe = smp_core99_probe,
|
||||||
|
.bringup_done = smp_core99_bringup_done,
|
||||||
.kick_cpu = smp_core99_kick_cpu,
|
.kick_cpu = smp_core99_kick_cpu,
|
||||||
.setup_cpu = smp_core99_setup_cpu,
|
.setup_cpu = smp_core99_setup_cpu,
|
||||||
.give_timebase = smp_core99_give_timebase,
|
.give_timebase = smp_core99_give_timebase,
|
||||||
.take_timebase = smp_core99_take_timebase,
|
.take_timebase = smp_core99_take_timebase,
|
||||||
#if defined(CONFIG_HOTPLUG_CPU)
|
#if defined(CONFIG_HOTPLUG_CPU)
|
||||||
# if defined(CONFIG_PPC32)
|
|
||||||
.cpu_disable = smp_core99_cpu_disable,
|
.cpu_disable = smp_core99_cpu_disable,
|
||||||
.cpu_die = smp_core99_cpu_die,
|
|
||||||
# endif
|
|
||||||
# if defined(CONFIG_PPC64)
|
|
||||||
.cpu_disable = generic_cpu_disable,
|
|
||||||
.cpu_die = generic_cpu_die,
|
.cpu_die = generic_cpu_die,
|
||||||
/* intentionally do *NOT* assign cpu_enable,
|
|
||||||
* the generic code will use kick_cpu then! */
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -957,5 +1014,10 @@ void __init pmac_setup_smp(void)
|
|||||||
smp_ops = &psurge_smp_ops;
|
smp_ops = &psurge_smp_ops;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PPC32 */
|
#endif /* CONFIG_PPC32 */
|
||||||
|
|
||||||
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
ppc_md.cpu_die = pmac_cpu_die;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -34,6 +34,4 @@ static inline void set_default_offline_state(int cpu)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern enum cpu_state_vals get_preferred_offline_state(int cpu);
|
extern enum cpu_state_vals get_preferred_offline_state(int cpu);
|
||||||
extern int start_secondary(void);
|
|
||||||
extern void start_secondary_resume(void);
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -153,7 +153,7 @@ static struct i2c_adapter * u3_0;
|
|||||||
static struct i2c_adapter * u3_1;
|
static struct i2c_adapter * u3_1;
|
||||||
static struct i2c_adapter * k2;
|
static struct i2c_adapter * k2;
|
||||||
static struct i2c_client * fcu;
|
static struct i2c_client * fcu;
|
||||||
static struct cpu_pid_state cpu_state[2];
|
static struct cpu_pid_state processor_state[2];
|
||||||
static struct basckside_pid_params backside_params;
|
static struct basckside_pid_params backside_params;
|
||||||
static struct backside_pid_state backside_state;
|
static struct backside_pid_state backside_state;
|
||||||
static struct drives_pid_state drives_state;
|
static struct drives_pid_state drives_state;
|
||||||
@@ -664,8 +664,8 @@ static int read_eeprom(int cpu, struct mpu_data *out)
|
|||||||
|
|
||||||
static void fetch_cpu_pumps_minmax(void)
|
static void fetch_cpu_pumps_minmax(void)
|
||||||
{
|
{
|
||||||
struct cpu_pid_state *state0 = &cpu_state[0];
|
struct cpu_pid_state *state0 = &processor_state[0];
|
||||||
struct cpu_pid_state *state1 = &cpu_state[1];
|
struct cpu_pid_state *state1 = &processor_state[1];
|
||||||
u16 pump_min = 0, pump_max = 0xffff;
|
u16 pump_min = 0, pump_max = 0xffff;
|
||||||
u16 tmp[4];
|
u16 tmp[4];
|
||||||
|
|
||||||
@@ -717,17 +717,17 @@ static ssize_t show_##name(struct device *dev, struct device_attribute *attr, ch
|
|||||||
return sprintf(buf, "%d", data); \
|
return sprintf(buf, "%d", data); \
|
||||||
}
|
}
|
||||||
|
|
||||||
BUILD_SHOW_FUNC_FIX(cpu0_temperature, cpu_state[0].last_temp)
|
BUILD_SHOW_FUNC_FIX(cpu0_temperature, processor_state[0].last_temp)
|
||||||
BUILD_SHOW_FUNC_FIX(cpu0_voltage, cpu_state[0].voltage)
|
BUILD_SHOW_FUNC_FIX(cpu0_voltage, processor_state[0].voltage)
|
||||||
BUILD_SHOW_FUNC_FIX(cpu0_current, cpu_state[0].current_a)
|
BUILD_SHOW_FUNC_FIX(cpu0_current, processor_state[0].current_a)
|
||||||
BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, cpu_state[0].rpm)
|
BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, processor_state[0].rpm)
|
||||||
BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, cpu_state[0].intake_rpm)
|
BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, processor_state[0].intake_rpm)
|
||||||
|
|
||||||
BUILD_SHOW_FUNC_FIX(cpu1_temperature, cpu_state[1].last_temp)
|
BUILD_SHOW_FUNC_FIX(cpu1_temperature, processor_state[1].last_temp)
|
||||||
BUILD_SHOW_FUNC_FIX(cpu1_voltage, cpu_state[1].voltage)
|
BUILD_SHOW_FUNC_FIX(cpu1_voltage, processor_state[1].voltage)
|
||||||
BUILD_SHOW_FUNC_FIX(cpu1_current, cpu_state[1].current_a)
|
BUILD_SHOW_FUNC_FIX(cpu1_current, processor_state[1].current_a)
|
||||||
BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, cpu_state[1].rpm)
|
BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, processor_state[1].rpm)
|
||||||
BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, cpu_state[1].intake_rpm)
|
BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, processor_state[1].intake_rpm)
|
||||||
|
|
||||||
BUILD_SHOW_FUNC_FIX(backside_temperature, backside_state.last_temp)
|
BUILD_SHOW_FUNC_FIX(backside_temperature, backside_state.last_temp)
|
||||||
BUILD_SHOW_FUNC_INT(backside_fan_pwm, backside_state.pwm)
|
BUILD_SHOW_FUNC_INT(backside_fan_pwm, backside_state.pwm)
|
||||||
@@ -919,8 +919,8 @@ static void do_cpu_pid(struct cpu_pid_state *state, s32 temp, s32 power)
|
|||||||
|
|
||||||
static void do_monitor_cpu_combined(void)
|
static void do_monitor_cpu_combined(void)
|
||||||
{
|
{
|
||||||
struct cpu_pid_state *state0 = &cpu_state[0];
|
struct cpu_pid_state *state0 = &processor_state[0];
|
||||||
struct cpu_pid_state *state1 = &cpu_state[1];
|
struct cpu_pid_state *state1 = &processor_state[1];
|
||||||
s32 temp0, power0, temp1, power1;
|
s32 temp0, power0, temp1, power1;
|
||||||
s32 temp_combi, power_combi;
|
s32 temp_combi, power_combi;
|
||||||
int rc, intake, pump;
|
int rc, intake, pump;
|
||||||
@@ -1150,7 +1150,7 @@ static void do_monitor_cpu_rack(struct cpu_pid_state *state)
|
|||||||
/*
|
/*
|
||||||
* Initialize the state structure for one CPU control loop
|
* Initialize the state structure for one CPU control loop
|
||||||
*/
|
*/
|
||||||
static int init_cpu_state(struct cpu_pid_state *state, int index)
|
static int init_processor_state(struct cpu_pid_state *state, int index)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@@ -1205,7 +1205,7 @@ static int init_cpu_state(struct cpu_pid_state *state, int index)
|
|||||||
/*
|
/*
|
||||||
* Dispose of the state data for one CPU control loop
|
* Dispose of the state data for one CPU control loop
|
||||||
*/
|
*/
|
||||||
static void dispose_cpu_state(struct cpu_pid_state *state)
|
static void dispose_processor_state(struct cpu_pid_state *state)
|
||||||
{
|
{
|
||||||
if (state->monitor == NULL)
|
if (state->monitor == NULL)
|
||||||
return;
|
return;
|
||||||
@@ -1804,9 +1804,9 @@ static int main_control_loop(void *x)
|
|||||||
set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM);
|
set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM);
|
||||||
|
|
||||||
/* Initialize ADCs */
|
/* Initialize ADCs */
|
||||||
initialize_adc(&cpu_state[0]);
|
initialize_adc(&processor_state[0]);
|
||||||
if (cpu_state[1].monitor != NULL)
|
if (processor_state[1].monitor != NULL)
|
||||||
initialize_adc(&cpu_state[1]);
|
initialize_adc(&processor_state[1]);
|
||||||
|
|
||||||
fcu_tickle_ticks = FCU_TICKLE_TICKS;
|
fcu_tickle_ticks = FCU_TICKLE_TICKS;
|
||||||
|
|
||||||
@@ -1833,14 +1833,14 @@ static int main_control_loop(void *x)
|
|||||||
if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
|
if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
|
||||||
do_monitor_cpu_combined();
|
do_monitor_cpu_combined();
|
||||||
else if (cpu_pid_type == CPU_PID_TYPE_RACKMAC) {
|
else if (cpu_pid_type == CPU_PID_TYPE_RACKMAC) {
|
||||||
do_monitor_cpu_rack(&cpu_state[0]);
|
do_monitor_cpu_rack(&processor_state[0]);
|
||||||
if (cpu_state[1].monitor != NULL)
|
if (processor_state[1].monitor != NULL)
|
||||||
do_monitor_cpu_rack(&cpu_state[1]);
|
do_monitor_cpu_rack(&processor_state[1]);
|
||||||
// better deal with UP
|
// better deal with UP
|
||||||
} else {
|
} else {
|
||||||
do_monitor_cpu_split(&cpu_state[0]);
|
do_monitor_cpu_split(&processor_state[0]);
|
||||||
if (cpu_state[1].monitor != NULL)
|
if (processor_state[1].monitor != NULL)
|
||||||
do_monitor_cpu_split(&cpu_state[1]);
|
do_monitor_cpu_split(&processor_state[1]);
|
||||||
// better deal with UP
|
// better deal with UP
|
||||||
}
|
}
|
||||||
/* Then, the rest */
|
/* Then, the rest */
|
||||||
@@ -1885,8 +1885,8 @@ static int main_control_loop(void *x)
|
|||||||
*/
|
*/
|
||||||
static void dispose_control_loops(void)
|
static void dispose_control_loops(void)
|
||||||
{
|
{
|
||||||
dispose_cpu_state(&cpu_state[0]);
|
dispose_processor_state(&processor_state[0]);
|
||||||
dispose_cpu_state(&cpu_state[1]);
|
dispose_processor_state(&processor_state[1]);
|
||||||
dispose_backside_state(&backside_state);
|
dispose_backside_state(&backside_state);
|
||||||
dispose_drives_state(&drives_state);
|
dispose_drives_state(&drives_state);
|
||||||
dispose_slots_state(&slots_state);
|
dispose_slots_state(&slots_state);
|
||||||
@@ -1928,12 +1928,12 @@ static int create_control_loops(void)
|
|||||||
/* Create control loops for everything. If any fail, everything
|
/* Create control loops for everything. If any fail, everything
|
||||||
* fails
|
* fails
|
||||||
*/
|
*/
|
||||||
if (init_cpu_state(&cpu_state[0], 0))
|
if (init_processor_state(&processor_state[0], 0))
|
||||||
goto fail;
|
goto fail;
|
||||||
if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
|
if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
|
||||||
fetch_cpu_pumps_minmax();
|
fetch_cpu_pumps_minmax();
|
||||||
|
|
||||||
if (cpu_count > 1 && init_cpu_state(&cpu_state[1], 1))
|
if (cpu_count > 1 && init_processor_state(&processor_state[1], 1))
|
||||||
goto fail;
|
goto fail;
|
||||||
if (init_backside_state(&backside_state))
|
if (init_backside_state(&backside_state))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@@ -208,6 +208,7 @@ int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
|
|||||||
unsigned long long *crash_size, unsigned long long *crash_base);
|
unsigned long long *crash_size, unsigned long long *crash_base);
|
||||||
int crash_shrink_memory(unsigned long new_size);
|
int crash_shrink_memory(unsigned long new_size);
|
||||||
size_t crash_get_memory_size(void);
|
size_t crash_get_memory_size(void);
|
||||||
|
void crash_free_reserved_phys_range(unsigned long begin, unsigned long end);
|
||||||
|
|
||||||
#else /* !CONFIG_KEXEC */
|
#else /* !CONFIG_KEXEC */
|
||||||
struct pt_regs;
|
struct pt_regs;
|
||||||
|
@@ -1099,7 +1099,8 @@ size_t crash_get_memory_size(void)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_reserved_phys_range(unsigned long begin, unsigned long end)
|
void __weak crash_free_reserved_phys_range(unsigned long begin,
|
||||||
|
unsigned long end)
|
||||||
{
|
{
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
|
|
||||||
@@ -1135,7 +1136,7 @@ int crash_shrink_memory(unsigned long new_size)
|
|||||||
start = roundup(start, PAGE_SIZE);
|
start = roundup(start, PAGE_SIZE);
|
||||||
end = roundup(start + new_size, PAGE_SIZE);
|
end = roundup(start + new_size, PAGE_SIZE);
|
||||||
|
|
||||||
free_reserved_phys_range(end, crashk_res.end);
|
crash_free_reserved_phys_range(end, crashk_res.end);
|
||||||
|
|
||||||
if ((start == end) && (crashk_res.parent != NULL))
|
if ((start == end) && (crashk_res.parent != NULL))
|
||||||
release_resource(&crashk_res);
|
release_resource(&crashk_res);
|
||||||
|
Reference in New Issue
Block a user