ARC: SMP resurrect #0: preps/cleanups/comments to keep noise out

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #1: spinlocks for atomic r-m-w

For Atomic R-M-W in SMP (ISS Model) we rely on spinlocks.
For uniprocessor builds, use llock/scond otherwise disable interrupts
This changeset consolidates all such locking into asm/smp.h, making
asm/{atomic.h,bitops.h,cmpxchg.h} free of locking details.

We resort to using the lowest level arch spin lock API because of cyclic
header dependencies (specially for bitops.h) - even after system.h
disintegration backported to 3.2

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #2: Reworked arch spinlock/rwlock backend

-Old routines were 2.6.19 API based
-lot of comments/cleanups

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #3: cpumask API changes, use USE_GENERIC_SMP_HELPERS

for_each_cpu_mask -> for_each_cpu
cpumask_of_cpu -> cpumask_of
cpumask_t -> struct cpumask
cpu_set(cpu_online_map) -> set_cpu_online
cpu_possible_map/cpu_online_map no longer needed in arch code
Add support for IPI_CALL_FUNC_SINGLE
SMP cpu calling / ipi code simplified by using USE_GENERIC_SMP_HELPERS

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #4: cpu wakeup cleanup/platform APIzed

secondary cpu kickstart rewritten in "C" (from asm)
Moved into a platform API - arc_platform_smp_wakeup_cpu( ) which is
  called by __cpu_up( )
Most of secondary boot data for wakeup eliminated - folded into API
Only secondary idle task needs to be passed to setup its SP correctly

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #5: Secondary debug hack

-secondary made to loop to self in early boot code.
 Actually the "flag 1" to park is over-ridden when single stepping the
 master since Metaware Debugger steps both. This causes secondary to
 wander into incorrect code.
 When time comes, Master reprogrammer's it PC to it's real startup code
 @@first_lines_of_secondary.

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #6: Miscll fixes to get SMP building/starting-to-run

-LR/SR for IDU aux regs were not generated correctly with inline-asm
 switched to __builtin_arc_{lr,sr}
-udelay build breakage:  missing __builtin_constant_p
-get_hw_config_num_irq() needs to be exported by arch IRQ sub-system
-ARC_REG_SCRATCH_DATA0 needed for low level scratch handling - can't be
 used for caching task->mm->pgd (just as in uniprocessor builds)
-synchronize_irq( ): just an unimpleneted stub to get build going
-TIF_POLLING_NRFLAG must NOT be set since we sleep (vs. poll) and rely
 on IPI
-Remove the gcc 3.4 workaround for secondary wakeup timeout
-Linker script missing PERCPU_SECTION since our init { } is not using
 tin pack INIT_xxx macros from asm-generic/vmlinux.lds.h

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #7: Correct _current_task[cpu] (ctxt-sw/seondary-boot)

-For secondary CPU needs to be setup early
-In __switch_to, correctly update _current_task[cpu]

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #8: Macros for Initial tsk on cpu / stack base calc

Refs to _current_task now confined to header file macros
Use SET_CURR_TASK_ON_CPU consistently for master/secondary
  This takes care of setting _current_task[ ] and/or R25
Use GET_TSK_STACK_BASE consistently to get to stack page for tsk,
  hoisted at the end of PAGE pointed to by tsk->thread_info

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #9: secondary clockevent reg, master IPI reg etc

Another round of fixes:
-----------------------
-Master was not calling arc_platform_smp_init_cpu( ), needed to
 initialize the low level IPI machinery on it's end
-Secondary needed to register timer0 clockevent to drive it's tick using
 arc_clockevent_init( ), which was anyhow not SMP ready.
-Secondary was getting IPI_RESCHEDULE, but discarding the msg, because
 bit scan loop needs to do find_next_bit( , ,x+1) which would fail to
 find bit 0. IPI_xxx enum needs to start from 1, not 0

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #11: Both cpus in Idle task - fixes needed

Both CPU come up but stuck in idle loop. The fix needed but didn't
help the cause are:

Correct intialization of idel task preempt count, pertaining to
     upstream commits from Peter Zijlstra
     -d86ee480: sched: optimize cond_resched()
     -c99e6efe: sched: INIT_PREEMPT_COUNT

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #13: General Exceptions/Traps SMP safe now

All Exception/Trap handlers need to be re-entrant in SMP setup.
Currently (non-SMP) all of them use the same global @ex_saved_reg1
to free up a core reg (used to code the handler prologue).
In SMP they need to use the per-cpu SCRATCH0 Aux Reg.

To avoid the #ifdef mess, defined pair of macros:
	EXCPN_PROLOG_FREEUP_REG/EXCPN_PROLOG_RESTORE_REG

Note the TLB Miss Hanlders usage of @ex_saved_reg1 is not SMP safe yet.

(thanks to Noam <noamc@ezchip.com>, for pointing this out)

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #14: SMP safe TLB Miss Exception handling

TLB Exeptions were completely messed up due to the special case need to
save the 4 registers w/o full blown stack switching. Their scratch
memory is now per-cpu, with code to locate the per-cpu area first.

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #15: Explicit platform support for some core features

Some of the core features require hardware assist to be usable in a SMP
setup. Since these are not aviable in vanilla ARC700, we need additional
constraints which need to be fulfilled by the platform/SoC implementing ARC.
This allows auto-disabling of these features in a kernel build.

1. Caches can't be enabled in SMP if platform lacks a Cache-coh module
	CONFIG_ARC_CACHE : if ARC_HAS_COH_CACHES

2. The high priority interrupts are not SMP re-entrant by default
	CONFIG_ARC_COMPACT_IRQ_LEVELS : if ARC_HAS_REENTRANT_IRQ_LV2

3. The lock free atomic ops need to snoop other CPU's bus too
	CONFIG_ARC_HAS_LLSC : if ARC_HAS_COH_LLSC

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #16: missing barriers

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #17: cpu_relax() needs to be compiler barrier too

A lot of SMP loops are based off of loads from memory.

	while (p->on_cpu) {
		cpu_relax();
	}

However the data involved is not volatile - which makes gcc prune away
the load, resulting in unconditional branch-to-self.

The first instance was csd_lock_wait() which I though of fixing by
making call_single_data->flag as volatile.

However next got a loop in try_to_wake_up(), which busy-waits on
task_struct->cpu.

So the solution (ugly as it may be) is to make cpu_relax() a memory
barrier which solves both the above cases (as intended, not by fluke).
Incidently, Documentation/volatile-considered-harmful.txt seems to
confirm that cpu_relax() indeed has to be a barrier.

As a small optimization, it has been done only for SMP case.

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #18: clocksource related fixes for non-boot CPU

We can only have one system wide clocksource, which is backed by
boot-cpu's hardware free flowing counter (TIMER1). Thus the clocksource
registration for non boot CPU was simply wrong.

However since the clocksource counter can't be accessed from "other"
cpus, which need it for timer interpolation for a local gtod call, we
nevertheless setup the "other" cpu counter - albeit w/o clocksource.
Due to different starting points, these counters are certainly not
synchronized, which we live with - fixing purely in software would
require conveying the lag from boot-cpu to them and then makign the
corresponding adjustments [see arch/x86/kernel/tsc.c].

However, any recent release of ARC700 (which will run SMP) will have
a 64-bit raw cycle counter (accessed with RTSC insn) which _shd_ be
precisely synchronized across CPUs

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #19: clockevent routines rename - nothing semantical

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #20: clockevent to use request_irq() [not setup_irq]

Since called by all CPUs, the statically allocated struct irqaction
registration was wrong (link list looping)

Also slab is already init by now so we can freely use request_irq()

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
ARC: SMP resurrect #21: request_irq() workaround for clockevent Timer

request_irq() for TIMER0 failing on CPU1

Ideally we want to use the request_percpu_irq( ) / enable_percpu_irq()
calls from GENERIC_IRQ framework, however that seems to be faltering
even on the boot cpu at the time of first interrupt.

Until that is resolved (with Thomas G), we need to pretend that
TIMER0 is IRQF_SHARED. This also requires yet another hack of explicitly
unmasking the IRQ on that CPU.

Query sent to Thomas Gleixner

======================>8====================================
In a SMP setup, each ARC700 CPU has a in-core TIMER, hooked up to
private IRQ 3 of respective CPU and would serve as the local
clock_event_device.

request_irq( ) for my first CPU which succeeds, looks roughly as
follows:

	void __cpuinit arc_clockevent_init(void)
	{
	    int rc;
	    unsigned int cpu = smp_processor_id();
	    struct clock_event_device *evt = &per_cpu(arc_clockevent_device,
							cpu);
	....
	    rc = request_irq(TIMER0_INT, timer_irq_handler,
        	    IRQF_TIMER | IRQF_DISABLED | IRQF_PERCPU,
	            "Timer0 (clock-evt-dev)", evt);
	....

The exact same call, when done from 2nd CPU fails, as it wants to see
IRQF_SHARED which is semantically not correct, since IRQ is not really
shared, it is a private instance (albeit same value), per cpu.

I figured that the right APIs for our case is the pair:
(request|enable)_percpu_irq to be called for both CPUs, with a prior one
time call to irq_set_percpu_devid().  Is that correct?

Assuming it is, the trouble now is that, even on the first CPU,
handle_level_irq( ) is bailing out w/o calling handle_irq_event()
because irqd_irq_disabled( ) is true. This in turn happens because,
irq_set_percpu_devid(), our much needed init routine, sets IRQ_NOAUTOEN
causing __setup_irq( ) to skip calling irq_startup() => irq_enable()
which would have cleared IRQD_IRQ_DISABLED.

While enable_percpu_irq( ), could have fixed this, it only seems to be
unmasking IRQ at device level, it is not clearing the above flag.

I tried calling enable_irq( ) right after, but that doesn't seem to help
either.
What API am I missing here, to enable the irqd machinery, or am I seeing
a bug where enable_percpu_irq( ) call-chain should somehow be doing it.

======================>8====================================

This needs to be reverted and replaced with right calls once ThomasG
responds to my query.

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>