• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/arm/kernel/
1/*
2 *  linux/arch/arm/kernel/smp.c
3 *
4 *  Copyright (C) 2002 ARM Limited, All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/module.h>
11#include <linux/delay.h>
12#include <linux/init.h>
13#include <linux/spinlock.h>
14#include <linux/sched.h>
15#include <linux/interrupt.h>
16#include <linux/cache.h>
17#include <linux/profile.h>
18#include <linux/errno.h>
19#include <linux/mm.h>
20#include <linux/err.h>
21#include <linux/cpu.h>
22#include <linux/smp.h>
23#include <linux/seq_file.h>
24#include <linux/irq.h>
25#include <linux/percpu.h>
26#include <linux/clockchips.h>
27
28#include <asm/atomic.h>
29#include <asm/cacheflush.h>
30#include <asm/cpu.h>
31#include <asm/cputype.h>
32#include <asm/mmu_context.h>
33#include <asm/pgtable.h>
34#include <asm/pgalloc.h>
35#include <asm/processor.h>
36#include <asm/tlbflush.h>
37#include <asm/ptrace.h>
38#include <asm/localtimer.h>
39#include <asm/smp_plat.h>
40
41/*Foxconn add start by Hank 05/31/2013*/
42#include <typedefs.h>
43#include <osl.h>
44#include <wps_led.h>
45#include <siutils.h>
46/*Foxconn add end by Hank 05/31/2013*/
47
48#ifdef WIFI_LED_BLINKING
49#include <linux/netdevice.h>
50#endif
51
52#ifdef CONFIG_BCM47XX
53extern void soc_watchdog(void);
54#endif
55
56/*Foxconn add start by Hank 05/31/2013*/
57/*declare parameter*/
58#define LED_BLINK_RATE_NORMAL   50
59#define LED_BLINK_RATE_QUICK    10
60static si_t *gpio_sih;
61int wps_led_state_smp = 0;
62int is_wl_secu_mode_smp = 0;
63static int wps_led_is_on_smp = 0;
64static int wps_led_state_smp_old = 0;
65
66/* foxconn added start, ken chen, 12/13/2013, Support LED_CONTROL_SETTINGS */
67int led_control_settings_smp = 3;    /* 1=enable_blink, 2=disable_blink, 3=turn_off */
68/* foxconn added end, ken chen, 12/13/2013, Support LED_CONTROL_SETTINGS */
69
70/*
71 * as from 2.5, kernels no longer have an init_tasks structure
72 * so we need some other way of telling a new secondary core
73 * where to place its SVC stack
74 */
75struct secondary_data secondary_data;
76
77/*
78 * structures for inter-processor calls
79 * - A collection of single bit ipi messages.
80 */
81struct ipi_data {
82	spinlock_t lock;
83	unsigned long ipi_count;
84	unsigned long bits;
85};
86
87static DEFINE_PER_CPU(struct ipi_data, ipi_data) = {
88	.lock	= SPIN_LOCK_UNLOCKED,
89};
90
91enum ipi_msg_type {
92	IPI_TIMER,
93	IPI_RESCHEDULE,
94	IPI_CALL_FUNC,
95	IPI_CALL_FUNC_SINGLE,
96	IPI_CPU_STOP,
97};
98
99int __cpuinit __cpu_up(unsigned int cpu)
100{
101	struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
102	struct task_struct *idle = ci->idle;
103	pgd_t *pgd;
104	pmd_t *pmd;
105	int ret;
106
107	/*
108	 * Spawn a new process manually, if not already done.
109	 * Grab a pointer to its task struct so we can mess with it
110	 */
111	if (!idle) {
112		idle = fork_idle(cpu);
113		if (IS_ERR(idle)) {
114			printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
115			return PTR_ERR(idle);
116		}
117		ci->idle = idle;
118	} else {
119		/*
120		 * Since this idle thread is being re-used, call
121		 * init_idle() to reinitialize the thread structure.
122		 */
123		init_idle(idle, cpu);
124	}
125
126	/*
127	 * Allocate initial page tables to allow the new CPU to
128	 * enable the MMU safely.  This essentially means a set
129	 * of our "standard" page tables, with the addition of
130	 * a 1:1 mapping for the physical address of the kernel.
131	 */
132	pgd = pgd_alloc(&init_mm);
133	pmd = pmd_offset(pgd + pgd_index(PHYS_OFFSET), PHYS_OFFSET);
134	*pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) |
135		     PMD_TYPE_SECT | PMD_SECT_AP_WRITE);
136	flush_pmd_entry(pmd);
137	outer_clean_range(__pa(pmd), __pa(pmd + 1));
138
139	/*
140	 * We need to tell the secondary core where to find
141	 * its stack and the page tables.
142	 */
143	secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
144	secondary_data.pgdir = virt_to_phys(pgd);
145	__cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
146	outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1));
147
148	/*
149	 * Now bring the CPU into our world.
150	 */
151	ret = boot_secondary(cpu, idle);
152	if (ret == 0) {
153		/*
154		 * timeout is in fixed jiffies - for slow processor
155	 	 * the HZ is low, making the waiting longer as necesary.
156		 */
157		unsigned long timeout = 128 ;
158
159		/*
160		 * CPU was successfully started, wait for it
161		 * to come online or time out.
162		 */
163		timeout += jiffies ;
164		while (time_before(jiffies, timeout)) {
165			if (cpu_online(cpu))
166				break;
167
168			udelay(10);
169			barrier();
170		}
171
172		if (!cpu_online(cpu))
173			ret = -EIO;
174	}
175
176	secondary_data.stack = NULL;
177	secondary_data.pgdir = 0;
178
179	*pmd = __pmd(0);
180	clean_pmd_entry(pmd);
181	pgd_free(&init_mm, pgd);
182
183	if (ret) {
184		printk(KERN_CRIT "CPU%u: processor failed to boot\n", cpu);
185
186	}
187
188	return ret;
189}
190
191
192/* Foxconn modified start antony 07/22/2013, for R7000 WIFI Blinking */
193#if (defined WIFI_LED_BLINKING)
194#define GPIO_WIFI_2G_LED        13
195#define GPIO_WIFI_5G_LED        12
196//static __u64 wifi_2g_tx_cnt_smp=0;
197//static __u64 wifi_2g_rx_cnt_smp=0;
198//static __u64 wifi_5g_tx_cnt_smp=0;
199//static __u64 wifi_5g_rx_cnt_smp=0;
200int wifi_2g_led_state_smp=-1;
201int wifi_5g_led_state_smp=-1;
202
203EXPORT_SYMBOL(wifi_2g_led_state_smp);
204EXPORT_SYMBOL(wifi_5g_led_state_smp);
205
206#endif
207/* Foxconn modified end antony 07/22/2013*/
208
209
210#if (defined INCLUDE_USB_LED)
211/* Foxconn modified start, Wins, 04/11/2011 */
212/* Foxconn modified start pling 12/26/2011, for WNDR4000AC */
213#if (defined WNDR4000AC)
214#define GPIO_USB1_LED       (GPIO_LED_USB)
215#elif (defined R6700)
216#define GPIO_USB1_LED       18   /* USB1 LED. */
217#elif (defined R7000)
218#define GPIO_USB1_LED       17   /* USB1 LED. */
219#define GPIO_USB2_LED       18   /* USB2 LED. */
220#else
221#define GPIO_USB1_LED       8   /* USB1 LED. */
222#define GPIO_USB2_LED       8   /* USB2 LED. */
223#endif /* WNDR4000AC */
224/* Foxconn modified end pling 12/26/2011, for WNDR4000AC */
225#define LED_BLINK_RATE  10
226int usb1_pkt_cnt_smp;
227int usb2_pkt_cnt_smp = 0;
228int usb1_led_state_smp = 0;
229int usb2_led_state_smp = 0;
230static int usb1_led_state_old_smp = 0;
231static int usb2_led_state_old_smp = 0;
232EXPORT_SYMBOL(usb1_pkt_cnt_smp);
233EXPORT_SYMBOL(usb2_pkt_cnt_smp);
234EXPORT_SYMBOL(usb1_led_state_smp);
235EXPORT_SYMBOL(usb2_led_state_smp);
236/* Foxconn modified end, Wins, 04/11/2011 */
237
238
239#ifdef CONFIG_HOTPLUG_CPU
240/*
241 * __cpu_disable runs on the processor to be shutdown.
242 */
243int __cpu_disable(void)
244{
245	unsigned int cpu = smp_processor_id();
246	struct task_struct *p;
247	int ret;
248
249	ret = platform_cpu_disable(cpu);
250	if (ret)
251		return ret;
252
253	/*
254	 * Take this CPU offline.  Once we clear this, we can't return,
255	 * and we must not schedule until we're ready to give up the cpu.
256	 */
257	set_cpu_online(cpu, false);
258
259	/*
260	 * OK - migrate IRQs away from this CPU
261	 */
262	migrate_irqs();
263
264	/*
265	 * Stop the local timer for this CPU.
266	 */
267	local_timer_stop();
268
269	/*
270	 * Flush user cache and TLB mappings, and then remove this CPU
271	 * from the vm mask set of all processes.
272	 */
273	flush_cache_all();
274	local_flush_tlb_all();
275
276	read_lock(&tasklist_lock);
277	for_each_process(p) {
278		if (p->mm)
279			cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
280	}
281	read_unlock(&tasklist_lock);
282
283	return 0;
284}
285
286/*
287 * called on the thread which is asking for a CPU to be shutdown -
288 * waits until shutdown has completed, or it is timed out.
289 */
290void __cpu_die(unsigned int cpu)
291{
292	if (!platform_cpu_kill(cpu))
293		printk("CPU%u: unable to kill\n", cpu);
294}
295
296/*
297 * Called from the idle thread for the CPU which has been shutdown.
298 *
299 * Note that we disable IRQs here, but do not re-enable them
300 * before returning to the caller. This is also the behaviour
301 * of the other hotplug-cpu capable cores, so presumably coming
302 * out of idle fixes this.
303 */
304void __ref cpu_die(void)
305{
306	unsigned int cpu = smp_processor_id();
307
308	local_irq_disable();
309	idle_task_exit();
310
311	/*
312	 * actual CPU shutdown procedure is at least platform (if not
313	 * CPU) specific
314	 */
315	platform_cpu_die(cpu);
316
317	/*
318	 * Do not return to the idle loop - jump back to the secondary
319	 * cpu initialisation.  There's some initialisation which needs
320	 * to be repeated to undo the effects of taking the CPU offline.
321	 */
322	__asm__("mov	sp, %0\n"
323	"	b	secondary_start_kernel"
324		:
325		: "r" (task_stack_page(current) + THREAD_SIZE - 8));
326}
327#endif /* CONFIG_HOTPLUG_CPU */
328
329/*
330 * This is the secondary CPU boot entry.  We're using this CPUs
331 * idle thread stack, but a set of temporary page tables.
332 */
333asmlinkage void __cpuinit secondary_start_kernel(void)
334{
335	struct mm_struct *mm = &init_mm;
336	unsigned int cpu = smp_processor_id();
337
338	printk("CPU%u: Booted secondary processor\n", cpu);
339
340	/*
341	 * All kernel threads share the same mm context; grab a
342	 * reference and switch to it.
343	 */
344	atomic_inc(&mm->mm_users);
345	atomic_inc(&mm->mm_count);
346	current->active_mm = mm;
347	cpumask_set_cpu(cpu, mm_cpumask(mm));
348	cpu_switch_mm(mm->pgd, mm);
349	enter_lazy_tlb(mm, current);
350	local_flush_tlb_all();
351
352	cpu_init();
353	preempt_disable();
354
355	/*
356	 * Give the platform a chance to do its own initialisation.
357	 */
358	platform_secondary_init(cpu);
359
360	/*
361	 * Enable local interrupts.
362	 */
363	notify_cpu_starting(cpu);
364	local_irq_enable();
365	local_fiq_enable();
366
367	/*
368	 * Setup the percpu timer for this CPU.
369	 */
370	percpu_timer_setup();
371
372	calibrate_delay();
373
374	smp_store_cpu_info(cpu);
375
376	/*
377	 * OK, now it's safe to let the boot CPU continue
378	 */
379	set_cpu_online(cpu, true);
380
381	/*
382	 * OK, it's off to the idle thread for us
383	 */
384	cpu_idle();
385}
386
387/*
388 * Called by both boot and secondaries to move global data into
389 * per-processor storage.
390 */
391void __cpuinit smp_store_cpu_info(unsigned int cpuid)
392{
393	struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
394
395	cpu_info->loops_per_jiffy = loops_per_jiffy;
396}
397
398void __init smp_cpus_done(unsigned int max_cpus)
399{
400	int cpu;
401	unsigned long bogosum = 0;
402
403	for_each_online_cpu(cpu)
404		bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy;
405
406	printk(KERN_INFO "SMP: Total of %d processors activated "
407	       "(%lu.%02lu BogoMIPS).\n",
408	       num_online_cpus(),
409	       bogosum / (500000/HZ),
410	       (bogosum / (5000/HZ)) % 100);
411}
412
413void __init smp_prepare_boot_cpu(void)
414{
415	unsigned int cpu = smp_processor_id();
416
417	per_cpu(cpu_data, cpu).idle = current;
418}
419
420static void send_ipi_message(const struct cpumask *mask, enum ipi_msg_type msg)
421{
422	unsigned long flags;
423	unsigned int cpu;
424
425	local_irq_save(flags);
426
427	for_each_cpu(cpu, mask) {
428		struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
429
430		spin_lock(&ipi->lock);
431		ipi->bits |= 1 << msg;
432		spin_unlock(&ipi->lock);
433	}
434
435	/*
436	 * Call the platform specific cross-CPU call function.
437	 */
438	smp_cross_call(mask);
439
440	local_irq_restore(flags);
441}
442
443void arch_send_call_function_ipi_mask(const struct cpumask *mask)
444{
445	send_ipi_message(mask, IPI_CALL_FUNC);
446}
447
448void arch_send_call_function_single_ipi(int cpu)
449{
450	send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
451}
452
453void show_ipi_list(struct seq_file *p)
454{
455	unsigned int cpu;
456
457	seq_puts(p, "IPI:");
458
459	for_each_present_cpu(cpu)
460		seq_printf(p, " %10lu", per_cpu(ipi_data, cpu).ipi_count);
461
462	seq_putc(p, '\n');
463}
464
465void show_local_irqs(struct seq_file *p)
466{
467	unsigned int cpu;
468
469	seq_printf(p, "LOC: ");
470
471	for_each_present_cpu(cpu)
472		seq_printf(p, "%10u ", irq_stat[cpu].local_timer_irqs);
473
474	seq_putc(p, '\n');
475}
476
477/*
478 * Timer (local or broadcast) support
479 */
480static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent);
481
482/*Foxconn add start by Hank 05/31/2013*/
483/*add function for blinking or light up WPS LED or USB LED for SMP*/
484static int wps_led_init(void)
485{
486    if (!(gpio_sih = si_kattach(SI_OSH)))
487    {
488        printk("%s failed!\n", __FUNCTION__);
489        return -ENODEV;
490    }
491
492    return 0;
493}
494
495static int gpio_control_normal(int pin, int value)
496{
497    si_gpioreserve(gpio_sih, 1 << pin, GPIO_APP_PRIORITY);
498    si_gpioouten(gpio_sih, 1 << pin, 1 << pin, GPIO_APP_PRIORITY);
499    si_gpioout(gpio_sih, 1 << pin, value << pin, GPIO_APP_PRIORITY);
500
501    return 0;
502}
503
504#define GPIO_PIN(x)                     ((x) & 0x00FF)
505
506static int gpio_led_on_off(int gpio, int value)
507{
508    int pin = GPIO_PIN(gpio);
509
510    if (gpio == WPS_LED_GPIO)
511#if defined(R7000)
512        wps_led_is_on_smp = value;
513#else
514        wps_led_is_on_smp = !value;
515#endif
516
517#if (defined GPIO_EXT_CTRL)
518    int ctrl_mode = GPIO_CTRL_MODE(gpio);
519
520    switch (ctrl_mode)
521    {
522        case GPIO_CTRL_MODE_CLK_DATA:
523            /* implement in ext_led */
524            gpio_control_clk_data(pin, value);
525            break;
526
527        case GPIO_CTRL_MODE_NONE:
528        default:
529            gpio_control_normal(pin, value);
530            break;
531    }
532#else
533    gpio_control_normal(pin, value);
534#endif
535
536    return 0;
537}
538
539static int usb1_normal_blink_smp(void)
540{
541
542    static int interrupt_count1 = -1;
543    static int usb1_pkt_cnt_old_smp = 0;
544    /* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
545    int led_on, led_off;
546    led_on = (led_control_settings_smp == 3) ? 1 : 0;
547	led_off = (led_control_settings_smp == 2) ? 0 : 1;
548    /* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
549
550    interrupt_count1++;
551    if (interrupt_count1 == (LED_BLINK_RATE * 2))
552    {
553        interrupt_count1 = 0;
554    }
555    if (interrupt_count1 == 0){
556        /*Foxconn, [MJ], turn off USB_Led. */
557        //gpio_led_on_off(GPIO_USB1_LED, 0);
558        gpio_led_on_off(GPIO_USB1_LED, led_on);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
559    }
560    else if (interrupt_count1 == LED_BLINK_RATE)
561    {
562        if (usb1_pkt_cnt_smp != usb1_pkt_cnt_old_smp)
563        {
564            usb1_pkt_cnt_old_smp = usb1_pkt_cnt_smp;
565//old0=usb1_pkt_cnt_old;
566            /*Foxconn, [MJ], turn on USB_Led. */
567            //gpio_led_on_off(GPIO_USB1_LED, 1);
568            gpio_led_on_off(GPIO_USB1_LED, led_off);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
569            //printk("<1> turn on USB_LED.\n");
570        }
571    }
572
573    return 0;
574}
575/*Foxconn modify end by Hank 06/21/2012*/
576
577/* Added by Foxconn Antony to blink WIFI LED when there is traffic*/
578#ifdef WIFI_LED_BLINKING
579void wifi_normal_blink_smp()
580{
581    struct net_device *net_dev;
582    static int interrupt_wifi_count = -1;
583static __u64 wifi_2g_tx_cnt_old_smp=0;
584static __u64 wifi_2g_rx_cnt_old_smp=0;
585static __u64 wifi_5g_tx_cnt_old_smp=0;
586static __u64 wifi_5g_rx_cnt_old_smp=0;
587	struct rtnl_link_stats64 temp;
588	const struct rtnl_link_stats64 *stats;
589	static int repeat_2g=4,repeat_5g=4;
590    /* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
591	int led_on;
592	int led_off;
593	led_on = (led_control_settings_smp == 3) ? 1 : 0;
594	led_off = (led_control_settings_smp == 2) ? 0 : 1;
595	/* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
596
597    interrupt_wifi_count++;
598
599    if (interrupt_wifi_count == (LED_BLINK_RATE * 2))
600        interrupt_wifi_count = 0;
601
602    if(wifi_2g_led_state_smp==1)
603    {
604   	    if (interrupt_wifi_count == 0)
605   	    {
606        /*Foxconn, [MJ], turn off USB_Led. */
607            //gpio_led_on_off(GPIO_WIFI_2G_LED, 0);
608			gpio_led_on_off(GPIO_WIFI_2G_LED, led_on);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
609        }
610        else if(interrupt_wifi_count == LED_BLINK_RATE)
611        {
612#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
613	          net_dev = dev_get_by_name("eth1");
614#else
615          	net_dev = dev_get_by_name(&init_net, "eth1");
616#endif
617
618            if(net_dev)
619            {
620    	        stats = dev_get_stats(net_dev, &temp);
621
622                if((wifi_2g_tx_cnt_old_smp!=stats->tx_packets) || (wifi_2g_rx_cnt_old_smp!=stats->rx_packets))
623                {
624            				//gpio_led_on_off(GPIO_WIFI_2G_LED, 1);
625							gpio_led_on_off(GPIO_WIFI_2G_LED, led_off);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
626            				wifi_2g_tx_cnt_old_smp=stats->tx_packets;
627            				wifi_2g_rx_cnt_old_smp=stats->rx_packets;
628                    repeat_2g=0;
629                }
630                else if( repeat_2g <4)
631                {
632                    repeat_2g++;
633            				//gpio_led_on_off(GPIO_WIFI_2G_LED, 1);
634							gpio_led_on_off(GPIO_WIFI_2G_LED, led_off);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
635
636            	}
637            	dev_put(net_dev);
638            }
639            else
640            {
641            }
642        }
643    }
644    else if(wifi_2g_led_state_smp==0)
645        gpio_led_on_off(GPIO_WIFI_2G_LED, 1);
646
647
648    if(wifi_5g_led_state_smp==1)
649    {
650   	    if (interrupt_wifi_count == 0)
651   	    {
652        /*Foxconn, [MJ], turn off USB_Led. */
653            //gpio_led_on_off(GPIO_WIFI_5G_LED, 0);
654			gpio_led_on_off(GPIO_WIFI_5G_LED, led_on);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
655        }
656        else if(interrupt_wifi_count == LED_BLINK_RATE)
657        {
658#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
659	          net_dev = dev_get_by_name("eth2");
660#else
661          	net_dev = dev_get_by_name(&init_net, "eth2");
662#endif
663
664            if(net_dev)
665            {
666    	        stats = dev_get_stats(net_dev, &temp);
667                if((wifi_5g_tx_cnt_old_smp!=stats->tx_packets) || (wifi_5g_rx_cnt_old_smp!=stats->rx_packets))
668                {
669            				//gpio_led_on_off(GPIO_WIFI_5G_LED, 1);
670							gpio_led_on_off(GPIO_WIFI_5G_LED, led_off);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
671            				wifi_5g_tx_cnt_old_smp=stats->tx_packets;
672            				wifi_5g_rx_cnt_old_smp=stats->rx_packets;
673            				repeat_5g=0;
674                }
675                else if( repeat_5g <4)
676                {
677                    repeat_5g++;
678            		//gpio_led_on_off(GPIO_WIFI_5G_LED, 1);
679					gpio_led_on_off(GPIO_WIFI_5G_LED, led_off);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
680            	}
681            	dev_put(net_dev);
682
683            }
684            else
685            {
686            }
687        }
688    }else if(wifi_5g_led_state_smp==0)
689        gpio_led_on_off(GPIO_WIFI_5G_LED, 1);
690}
691#endif
692/* Added by Foxconn Antony end */
693
694
695#if (!defined WNDR4000AC) && !defined(R6250) && !defined(R6200v2) && !defined(R6700)
696/*Foxconn modify start by Hank 06/21/2012*/
697/*change LED behavior, avoid blink when have traffic, plug second USB must blink,  plug first USB not blink*/
698static int usb2_normal_blink_smp(void)
699{
700    static int interrupt_count2 = -1;
701    static int first_both_usb = 0;
702
703	/* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
704	int led_on, led_off;
705	led_on = (led_control_settings_smp == 3) ? 1 : 0;
706	led_off = (led_control_settings_smp == 2) ? 0 : 1;
707	/* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
708
709	if(usb1_led_state_smp==1){
710		if(usb1_led_state_old_smp==0 || usb2_led_state_old_smp==0)
711			first_both_usb=1;
712
713		if(first_both_usb){
714			interrupt_count2++;
715
716			if (interrupt_count2%50 == 0)
717				//gpio_led_on_off(GPIO_USB2_LED, 0);
718				gpio_led_on_off(GPIO_USB2_LED, led_on);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
719			else if (interrupt_count2%50 == 25)
720				//gpio_led_on_off(GPIO_USB2_LED, 1);
721				gpio_led_on_off(GPIO_USB2_LED, led_off);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
722
723			if(interrupt_count2>=500){
724				interrupt_count2=0;
725				first_both_usb=0;
726			}
727		}else
728			//gpio_led_on_off(GPIO_USB2_LED, 0);
729			gpio_led_on_off(GPIO_USB2_LED, led_on);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
730
731	}
732
733  if(!first_both_usb)
734  {
735    static int interrupt_count2 = -1;
736    static int usb2_pkt_cnt_old_smp = 0;
737
738    interrupt_count2++;
739    if (interrupt_count2 == LED_BLINK_RATE * 2)
740        interrupt_count2 = 0;
741
742    if (interrupt_count2 == 0){
743        /*Foxconn, [MJ], turn off USB_Led. */
744        //gpio_led_on_off(GPIO_USB2_LED, 0);
745		gpio_led_on_off(GPIO_USB2_LED, led_on);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
746    }
747    else if (interrupt_count2 == LED_BLINK_RATE)
748    {
749        if (usb2_pkt_cnt_smp != usb2_pkt_cnt_old_smp)
750        {
751            usb2_pkt_cnt_old_smp = usb2_pkt_cnt_smp;
752//old1=usb2_pkt_cnt_old;
753            /*Foxconn, [MJ], turn on USB_Led. */
754            //gpio_led_on_off(GPIO_USB2_LED, 1);
755			gpio_led_on_off(GPIO_USB2_LED, led_off);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
756            //printk("<1> turn on USB_LED.\n");
757        }
758    }
759
760  }
761
762    return 0;
763}
764
765#endif
766#endif
767
768
769static int normal_blink(void)
770{
771    static int interrupt_count = -1;
772    /* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
773    int led_on;
774    led_on = (led_control_settings_smp == 3) ? 0 : 1;
775    /* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
776
777    interrupt_count++;
778    if (interrupt_count == LED_BLINK_RATE_NORMAL * 2)
779        interrupt_count = 0;
780
781    if (interrupt_count == 0)
782        gpio_led_on_off(WPS_LED_GPIO, 0);
783    else if (interrupt_count == LED_BLINK_RATE_NORMAL)
784        //gpio_led_on_off(WPS_LED_GPIO, 1);
785		gpio_led_on_off(WPS_LED_GPIO, led_on);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
786}
787
788static void quick_blink(void)
789{
790    static int blink_interval = 500; /* 5 seconds */
791    static int interrupt_count = -1;
792    /* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
793    int led_on;
794    led_on = (led_control_settings_smp == 3) ? 0 : 1;
795    /* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
796
797    blink_interval--;
798    interrupt_count++;
799    if (interrupt_count == LED_BLINK_RATE_QUICK * 2)
800        interrupt_count = 0;
801
802    if (interrupt_count == 0)
803        gpio_led_on_off(WPS_LED_GPIO, 0);
804    else if (interrupt_count == LED_BLINK_RATE_QUICK)
805        //gpio_led_on_off(WPS_LED_GPIO, 1);
806		gpio_led_on_off(WPS_LED_GPIO, led_on);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
807
808    if ( blink_interval <= 0 )
809    {
810        blink_interval = 500;
811        wps_led_state_smp = 0;
812    }
813}
814
815static void quick_blink2(void)
816{
817    static int interrupt_count = -1;
818    /* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
819    int led_on;
820    led_on = (led_control_settings_smp == 3) ? 0 : 1;
821    /* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
822
823    interrupt_count++;
824    if (interrupt_count == LED_BLINK_RATE_QUICK * 2)
825        interrupt_count = 0;
826
827    if (interrupt_count == 0)
828        gpio_led_on_off(WPS_LED_GPIO, 0);
829    else if (interrupt_count == LED_BLINK_RATE_QUICK)
830        //gpio_led_on_off(WPS_LED_GPIO, 1);
831        gpio_led_on_off(WPS_LED_GPIO, led_on);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
832}
833
834static int wps_ap_lockdown_blink(void)
835{
836    static int interrupt_count = -1;
837    /* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
838    int led_on;
839    led_on = (led_control_settings_smp == 3) ? 0 : 1;
840    /* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
841
842    interrupt_count++;
843    if (interrupt_count == LED_BLINK_RATE_QUICK * 10)
844        interrupt_count = 0;
845
846    if (interrupt_count == 0)
847        gpio_led_on_off(WPS_LED_GPIO, 0);
848    else if (interrupt_count == LED_BLINK_RATE_QUICK)
849        //gpio_led_on_off(WPS_LED_GPIO, 1);
850		gpio_led_on_off(WPS_LED_GPIO, led_on);  /* foxconn add ken chen, 12/13/2013, to support LED control Settings */
851}
852
853/*Foxconn add end by Hank 05/31/2013*/
854
855static void ipi_timer(void)
856{
857	struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
858#ifdef CONFIG_BCM47XX
859	int cpu = smp_processor_id();
860#endif
861	irq_enter();
862	evt->event_handler(evt);
863#ifdef CONFIG_BCM47XX
864	if (cpu == 0)
865		soc_watchdog();
866#endif
867	/*Foxconn add start by Hank 05/31/2013*/
868	/*add feature for blinking or light up WPS LED or USB LED for SMP*/
869	if (cpu == 0){
870		if ( wps_led_state_smp == 0 ){
871#if defined(R7000)
872            /* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
873            int led_on;
874            led_on = (led_control_settings_smp == 3) ? 0 : 1;
875            /* foxconn add start ken chen, 12/13/2013, to support LED control Settings */
876
877			if (wps_led_state_smp_old != 0)
878				gpio_led_on_off(WPS_LED_GPIO, 0);
879
880			if ((!is_wl_secu_mode_smp) && wps_led_is_on_smp)
881				gpio_led_on_off(WPS_LED_GPIO, 0);
882
883            //if (is_wl_secu_mode_smp && (!wps_led_is_on_smp))
884            //    gpio_led_on_off(WPS_LED_GPIO, 1);
885
886            /* foxconn add start, ken chen, 12/13/2013, to support LED control Settings */
887            if (led_on) {
888                if (is_wl_secu_mode_smp && (!wps_led_is_on_smp)) {
889                    gpio_led_on_off(WPS_LED_GPIO, led_on);
890                }
891            }
892			else {
893                if (is_wl_secu_mode_smp && (wps_led_is_on_smp)) {
894                    gpio_led_on_off(WPS_LED_GPIO, led_on);
895                }
896            }
897            /* foxconn add end, ken chen, 12/13/2013, to support LED control Settings */
898#else
899			if (wps_led_state_smp_old != 0)
900				gpio_led_on_off(WPS_LED_GPIO, 1);
901
902			if ((!is_wl_secu_mode_smp) && wps_led_is_on_smp)
903				gpio_led_on_off(WPS_LED_GPIO, 1);
904
905			if (is_wl_secu_mode_smp && (!wps_led_is_on_smp))
906				gpio_led_on_off(WPS_LED_GPIO, 0);
907#endif
908		}else if (wps_led_state_smp == 1){
909			normal_blink();
910		}else if (wps_led_state_smp == 2){
911			quick_blink();
912		}else if (wps_led_state_smp == 3){
913			quick_blink2();
914		}else if (wps_led_state_smp == 4){
915			wps_ap_lockdown_blink();
916		}
917
918		wps_led_state_smp_old = wps_led_state_smp;
919#if (defined INCLUDE_USB_LED)
920    	/* plug second USB must blink,  plug first USB not blink*/
921        if (usb1_led_state_smp)
922	    /*Foxconn modify end by Hank 06/21/2012*/
923        {
924            usb1_normal_blink_smp();
925        }
926        else
927        {
928            if (usb1_led_state_old_smp)
929            {
930            /* Foxconn modified start pling 12/26/2011, for WNDR4000AC */
931#if (defined WNDR4000AC)
932                gpio_led_on_off(GPIO_USB1_LED, 0);
933#elif defined(R6250) || defined(R6200v2)
934                gpio_led_on_off(GPIO_USB1_LED, 1); //off
935#else
936                gpio_led_on_off(GPIO_USB1_LED, 1);
937#endif
938            /* Foxconn modified end pling 12/26/2011 */
939            }
940        }
941	    /*Foxconn modify start by Hank 06/21/2012*/
942	    /*change LED behavior, avoid blink when have traffic,
943	    plug second USB must blink,  plug first USB not blink*/
944#ifdef WIFI_LED_BLINKING
945        wifi_normal_blink_smp();
946#endif
947
948#if (!defined WNDR4000AC) && !defined(R6250) && !defined(R6200v2) && !defined(R6700)
949        if (usb2_led_state_smp)
950        {
951            usb2_normal_blink_smp();
952        }
953        else
954        {
955            if (usb2_led_state_old_smp)
956            {
957                /* Foxconn, [MJ], turn on USB2_Led. */
958                gpio_led_on_off(GPIO_USB2_LED, 1);
959            }
960        }
961        usb2_led_state_old_smp = usb2_led_state_smp;
962#endif /* WNDR4000AC */
963        /* Foxconn modified end, Wins, 04/11/2011 */
964	    usb1_led_state_old_smp = usb1_led_state_smp;
965	    /*Foxconn modify end by Hank 06/21/2012*/
966#endif
967	}
968	/*Foxconn add end by Hank 05/31/2013*/
969
970	irq_exit();
971}
972
973#ifdef CONFIG_LOCAL_TIMERS
974asmlinkage void __exception do_local_timer(struct pt_regs *regs)
975{
976	struct pt_regs *old_regs = set_irq_regs(regs);
977	int cpu = smp_processor_id();
978
979	if (local_timer_ack()) {
980		irq_stat[cpu].local_timer_irqs++;
981		ipi_timer();
982	}
983
984	set_irq_regs(old_regs);
985}
986#endif
987
988#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
989static void smp_timer_broadcast(const struct cpumask *mask)
990{
991	send_ipi_message(mask, IPI_TIMER);
992}
993#else
994#define smp_timer_broadcast	NULL
995#endif
996
997#ifndef CONFIG_LOCAL_TIMERS
998static void broadcast_timer_set_mode(enum clock_event_mode mode,
999	struct clock_event_device *evt)
1000{
1001}
1002
1003static void local_timer_setup(struct clock_event_device *evt)
1004{
1005	evt->name	= "dummy_timer";
1006	evt->features	= CLOCK_EVT_FEAT_ONESHOT |
1007			  CLOCK_EVT_FEAT_PERIODIC |
1008			  CLOCK_EVT_FEAT_DUMMY;
1009	evt->rating	= 400;
1010	evt->mult	= 1;
1011	evt->set_mode	= broadcast_timer_set_mode;
1012
1013	clockevents_register_device(evt);
1014}
1015#endif
1016
1017void __cpuinit percpu_timer_setup(void)
1018{
1019	unsigned int cpu = smp_processor_id();
1020	struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
1021
1022	evt->cpumask = cpumask_of(cpu);
1023	evt->broadcast = smp_timer_broadcast;
1024
1025	local_timer_setup(evt);
1026}
1027
1028static DEFINE_SPINLOCK(stop_lock);
1029
1030/*
1031 * ipi_cpu_stop - handle IPI from smp_send_stop()
1032 */
1033static void ipi_cpu_stop(unsigned int cpu)
1034{
1035	if (system_state == SYSTEM_BOOTING ||
1036	    system_state == SYSTEM_RUNNING) {
1037		spin_lock(&stop_lock);
1038		printk(KERN_CRIT "CPU%u: stopping\n", cpu);
1039		dump_stack();
1040		spin_unlock(&stop_lock);
1041	}
1042
1043	set_cpu_online(cpu, false);
1044
1045	local_fiq_disable();
1046	local_irq_disable();
1047
1048	while (1)
1049		cpu_relax();
1050}
1051
1052/*
1053 * Main handler for inter-processor interrupts
1054 *
1055 * For ARM, the ipimask now only identifies a single
1056 * category of IPI (Bit 1 IPIs have been replaced by a
1057 * different mechanism):
1058 *
1059 *  Bit 0 - Inter-processor function call
1060 */
1061asmlinkage void __exception do_IPI(struct pt_regs *regs)
1062{
1063	unsigned int cpu = smp_processor_id();
1064	struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
1065	struct pt_regs *old_regs = set_irq_regs(regs);
1066	/*Foxconn add start by Hank 05/31/2013*/
1067	wps_led_init();
1068	/*Foxconn add end by Hank 05/31/2013*/
1069
1070	ipi->ipi_count++;
1071
1072	for (;;) {
1073		unsigned long msgs;
1074
1075		spin_lock(&ipi->lock);
1076		msgs = ipi->bits;
1077		ipi->bits = 0;
1078		spin_unlock(&ipi->lock);
1079
1080		if (!msgs)
1081			break;
1082
1083		do {
1084			unsigned nextmsg;
1085
1086			nextmsg = msgs & -msgs;
1087			msgs &= ~nextmsg;
1088			nextmsg = ffz(~nextmsg);
1089
1090			switch (nextmsg) {
1091			case IPI_TIMER:
1092				ipi_timer();
1093				break;
1094
1095			case IPI_RESCHEDULE:
1096				/*
1097				 * nothing more to do - eveything is
1098				 * done on the interrupt return path
1099				 */
1100				break;
1101
1102			case IPI_CALL_FUNC:
1103				generic_smp_call_function_interrupt();
1104				break;
1105
1106			case IPI_CALL_FUNC_SINGLE:
1107				generic_smp_call_function_single_interrupt();
1108				break;
1109
1110			case IPI_CPU_STOP:
1111				ipi_cpu_stop(cpu);
1112				break;
1113
1114			default:
1115				printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
1116				       cpu, nextmsg);
1117				break;
1118			}
1119		} while (msgs);
1120	}
1121
1122	set_irq_regs(old_regs);
1123}
1124
1125void smp_send_reschedule(int cpu)
1126{
1127	send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE);
1128}
1129
1130void smp_send_stop(void)
1131{
1132	cpumask_t mask = cpu_online_map;
1133	cpu_clear(smp_processor_id(), mask);
1134	send_ipi_message(&mask, IPI_CPU_STOP);
1135}
1136
1137/*
1138 * not supported here
1139 */
1140int setup_profiling_timer(unsigned int multiplier)
1141{
1142	return -EINVAL;
1143}
1144
1145static void
1146on_each_cpu_mask(void (*func)(void *), void *info, int wait,
1147		const struct cpumask *mask)
1148{
1149	preempt_disable();
1150
1151	smp_call_function_many(mask, func, info, wait);
1152	if (cpumask_test_cpu(smp_processor_id(), mask))
1153		func(info);
1154
1155	preempt_enable();
1156}
1157
1158/**********************************************************************/
1159
1160/*
1161 * TLB operations
1162 */
1163struct tlb_args {
1164	struct vm_area_struct *ta_vma;
1165	unsigned long ta_start;
1166	unsigned long ta_end;
1167};
1168
1169static inline void ipi_flush_tlb_all(void *ignored)
1170{
1171	local_flush_tlb_all();
1172}
1173
1174static inline void ipi_flush_tlb_mm(void *arg)
1175{
1176	struct mm_struct *mm = (struct mm_struct *)arg;
1177
1178	local_flush_tlb_mm(mm);
1179}
1180
1181static inline void ipi_flush_tlb_page(void *arg)
1182{
1183	struct tlb_args *ta = (struct tlb_args *)arg;
1184
1185	local_flush_tlb_page(ta->ta_vma, ta->ta_start);
1186}
1187
1188static inline void ipi_flush_tlb_kernel_page(void *arg)
1189{
1190	struct tlb_args *ta = (struct tlb_args *)arg;
1191
1192	local_flush_tlb_kernel_page(ta->ta_start);
1193}
1194
1195static inline void ipi_flush_tlb_range(void *arg)
1196{
1197	struct tlb_args *ta = (struct tlb_args *)arg;
1198
1199	local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
1200}
1201
1202static inline void ipi_flush_tlb_kernel_range(void *arg)
1203{
1204	struct tlb_args *ta = (struct tlb_args *)arg;
1205
1206	local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
1207}
1208
1209void flush_tlb_all(void)
1210{
1211	if (tlb_ops_need_broadcast())
1212		on_each_cpu(ipi_flush_tlb_all, NULL, 1);
1213	else
1214		local_flush_tlb_all();
1215}
1216
1217void flush_tlb_mm(struct mm_struct *mm)
1218{
1219	if (tlb_ops_need_broadcast())
1220		on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
1221	else
1222		local_flush_tlb_mm(mm);
1223}
1224
1225void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
1226{
1227	if (tlb_ops_need_broadcast()) {
1228		struct tlb_args ta;
1229		ta.ta_vma = vma;
1230		ta.ta_start = uaddr;
1231		on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
1232	} else
1233		local_flush_tlb_page(vma, uaddr);
1234}
1235
1236void flush_tlb_kernel_page(unsigned long kaddr)
1237{
1238	if (tlb_ops_need_broadcast()) {
1239		struct tlb_args ta;
1240		ta.ta_start = kaddr;
1241		on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
1242	} else
1243		local_flush_tlb_kernel_page(kaddr);
1244}
1245
1246void flush_tlb_range(struct vm_area_struct *vma,
1247                     unsigned long start, unsigned long end)
1248{
1249	if (tlb_ops_need_broadcast()) {
1250		struct tlb_args ta;
1251		ta.ta_vma = vma;
1252		ta.ta_start = start;
1253		ta.ta_end = end;
1254		on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
1255	} else
1256		local_flush_tlb_range(vma, start, end);
1257}
1258
1259void flush_tlb_kernel_range(unsigned long start, unsigned long end)
1260{
1261	if (tlb_ops_need_broadcast()) {
1262		struct tlb_args ta;
1263		ta.ta_start = start;
1264		ta.ta_end = end;
1265		on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
1266	} else
1267		local_flush_tlb_kernel_range(start, end);
1268}
1269