Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 346829
b: refs/heads/master
c: bc15236
h: refs/heads/master
i:
  346827: c569c33
v: v3
  • Loading branch information
York Sun authored and Kumar Gala committed Nov 25, 2012
1 parent a1e5f33 commit ad7b7a6
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a393d8977acd834520357f951bb28ef46ee7db0a
refs/heads/master: bc15236fbed1e017b465e38a9d2092393778a2f7
49 changes: 36 additions & 13 deletions trunk/arch/powerpc/platforms/85xx/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,19 @@ static void __cpuinit smp_85xx_mach_cpu_die(void)
}
#endif

static inline void flush_spin_table(void *spin_table)
{
flush_dcache_range((ulong)spin_table,
(ulong)spin_table + sizeof(struct epapr_spin_table));
}

static inline u32 read_spin_table_addr_l(void *spin_table)
{
flush_dcache_range((ulong)spin_table,
(ulong)spin_table + sizeof(struct epapr_spin_table));
return in_be32(&((struct epapr_spin_table *)spin_table)->addr_l);
}

static int __cpuinit smp_85xx_kick_cpu(int nr)
{
unsigned long flags;
Expand Down Expand Up @@ -161,8 +174,8 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)

/* Map the spin table */
if (ioremappable)
spin_table = ioremap(*cpu_rel_addr,
sizeof(struct epapr_spin_table));
spin_table = ioremap_prot(*cpu_rel_addr,
sizeof(struct epapr_spin_table), _PAGE_COHERENT);
else
spin_table = phys_to_virt(*cpu_rel_addr);

Expand All @@ -173,17 +186,31 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
generic_set_cpu_up(nr);

if (system_state == SYSTEM_RUNNING) {
/*
* To keep it compatible with old boot program which uses
* cache-inhibit spin table, we need to flush the cache
* before accessing spin table to invalidate any staled data.
* We also need to flush the cache after writing to spin
* table to push data out.
*/
flush_spin_table(spin_table);
out_be32(&spin_table->addr_l, 0);
flush_spin_table(spin_table);

/*
* We don't set the BPTR register here since it already points
* to the boot page properly.
*/
mpic_reset_core(hw_cpu);

/* wait until core is ready... */
if (!spin_event_timeout(in_be32(&spin_table->addr_l) == 1,
10000, 100)) {
/*
* wait until core is ready...
* We need to invalidate the stale data, in case the boot
* loader uses a cache-inhibited spin table.
*/
if (!spin_event_timeout(
read_spin_table_addr_l(spin_table) == 1,
10000, 100)) {
pr_err("%s: timeout waiting for core %d to reset\n",
__func__, hw_cpu);
ret = -ENOENT;
Expand All @@ -194,12 +221,10 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
__secondary_hold_acknowledge = -1;
}
#endif
flush_spin_table(spin_table);
out_be32(&spin_table->pir, hw_cpu);
out_be32(&spin_table->addr_l, __pa(__early_start));

if (!ioremappable)
flush_dcache_range((ulong)spin_table,
(ulong)spin_table + sizeof(struct epapr_spin_table));
flush_spin_table(spin_table);

/* Wait a bit for the CPU to ack. */
if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu,
Expand All @@ -213,13 +238,11 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
#else
smp_generic_kick_cpu(nr);

flush_spin_table(spin_table);
out_be32(&spin_table->pir, hw_cpu);
out_be64((u64 *)(&spin_table->addr_h),
__pa((u64)*((unsigned long long *)generic_secondary_smp_init)));

if (!ioremappable)
flush_dcache_range((ulong)spin_table,
(ulong)spin_table + sizeof(struct epapr_spin_table));
flush_spin_table(spin_table);
#endif

local_irq_restore(flags);
Expand Down

0 comments on commit ad7b7a6

Please sign in to comment.