Explorar o código

Blackfin: add support for gptimer0 as a tick source

For systems where the core cycles are not a usable tick source (like SMP
or cycles gets updated), enable gptimer0 as an alternative.

Signed-off-by: Graf Yang <graf.yang@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Graf Yang %!s(int64=16) %!d(string=hai) anos
pai
achega
1fa9be72b5

+ 22 - 10
arch/blackfin/Kconfig

@@ -241,12 +241,6 @@ config IRQ_PER_CPU
 	depends on SMP
 	depends on SMP
 	default y
 	default y
 
 
-config TICK_SOURCE_SYSTMR0
-	bool
-	select BFIN_GPTIMERS
-	depends on SMP
-	default y
-
 config BF_REV_MIN
 config BF_REV_MIN
 	int
 	int
 	default 0 if (BF51x || BF52x || (BF54x && !BF54xM))
 	default 0 if (BF51x || BF52x || (BF54x && !BF54xM))
@@ -607,7 +601,6 @@ source kernel/Kconfig.hz
 
 
 config GENERIC_TIME
 config GENERIC_TIME
 	bool "Generic time"
 	bool "Generic time"
-	depends on !SMP
 	default y
 	default y
 
 
 config GENERIC_CLOCKEVENTS
 config GENERIC_CLOCKEVENTS
@@ -615,12 +608,26 @@ config GENERIC_CLOCKEVENTS
 	depends on GENERIC_TIME
 	depends on GENERIC_TIME
 	default y
 	default y
 
 
+choice
+	prompt "Kernel Tick Source"
+	depends on GENERIC_CLOCKEVENTS
+	default TICKSOURCE_CORETMR
+
+config TICKSOURCE_GPTMR0
+	bool "Gptimer0 (SCLK domain)"
+	select BFIN_GPTIMERS
+	depends on !IPIPE
+
+config TICKSOURCE_CORETMR
+	bool "Core timer (CCLK domain)"
+
+endchoice
+
 config CYCLES_CLOCKSOURCE
 config CYCLES_CLOCKSOURCE
-	bool "Use 'CYCLES' as a clocksource (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
+	bool "Use 'CYCLES' as a clocksource"
 	depends on GENERIC_CLOCKEVENTS
 	depends on GENERIC_CLOCKEVENTS
 	depends on !BFIN_SCRATCH_REG_CYCLES
 	depends on !BFIN_SCRATCH_REG_CYCLES
-	default n
+	depends on !SMP
 	help
 	help
 	  If you say Y here, you will enable support for using the 'cycles'
 	  If you say Y here, you will enable support for using the 'cycles'
 	  registers as a clock source.  Doing so means you will be unable to
 	  registers as a clock source.  Doing so means you will be unable to
@@ -628,6 +635,11 @@ config CYCLES_CLOCKSOURCE
 	  still be able to read it (such as for performance monitoring), but
 	  still be able to read it (such as for performance monitoring), but
 	  writing the registers will most likely crash the kernel.
 	  writing the registers will most likely crash the kernel.
 
 
+config GPTMR0_CLOCKSOURCE
+	bool "Use GPTimer0 as a clocksource (higher rating)"
+	depends on GENERIC_CLOCKEVENTS
+	depends on !TICKSOURCE_GPTMR0
+
 source kernel/time/Kconfig
 source kernel/time/Kconfig
 
 
 comment "Misc"
 comment "Misc"

+ 1 - 0
arch/blackfin/include/asm/time.h

@@ -37,4 +37,5 @@ extern unsigned long long __bfin_cycles_off;
 extern unsigned int __bfin_cycles_mod;
 extern unsigned int __bfin_cycles_mod;
 #endif
 #endif
 
 
+extern void __init setup_core_timer(void);
 #endif
 #endif

+ 183 - 39
arch/blackfin/kernel/time-ts.c

@@ -20,8 +20,9 @@
 
 
 #include <asm/blackfin.h>
 #include <asm/blackfin.h>
 #include <asm/time.h>
 #include <asm/time.h>
+#include <asm/gptimers.h>
 
 
-#ifdef CONFIG_CYCLES_CLOCKSOURCE
+#if defined(CONFIG_CYCLES_CLOCKSOURCE)
 
 
 /* Accelerators for sched_clock()
 /* Accelerators for sched_clock()
  * convert from cycles(64bits) => nanoseconds (64bits)
  * convert from cycles(64bits) => nanoseconds (64bits)
@@ -58,15 +59,15 @@ static inline unsigned long long cycles_2_ns(cycle_t cyc)
 	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
 	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
 }
 }
 
 
-static cycle_t read_cycles(struct clocksource *cs)
+static cycle_t bfin_read_cycles(struct clocksource *cs)
 {
 {
 	return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
 	return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
 }
 }
 
 
-static struct clocksource clocksource_bfin = {
-	.name		= "bfin_cycles",
+static struct clocksource bfin_cs_cycles = {
+	.name		= "bfin_cs_cycles",
 	.rating		= 350,
 	.rating		= 350,
-	.read		= read_cycles,
+	.read		= bfin_read_cycles,
 	.mask		= CLOCKSOURCE_MASK(64),
 	.mask		= CLOCKSOURCE_MASK(64),
 	.shift		= 22,
 	.shift		= 22,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
@@ -74,53 +75,198 @@ static struct clocksource clocksource_bfin = {
 
 
 unsigned long long sched_clock(void)
 unsigned long long sched_clock(void)
 {
 {
-	return cycles_2_ns(read_cycles(&clocksource_bfin));
+	return cycles_2_ns(bfin_read_cycles(&bfin_cs_cycles));
 }
 }
 
 
-static int __init bfin_clocksource_init(void)
+static int __init bfin_cs_cycles_init(void)
 {
 {
 	set_cyc2ns_scale(get_cclk() / 1000);
 	set_cyc2ns_scale(get_cclk() / 1000);
 
 
-	clocksource_bfin.mult = clocksource_hz2mult(get_cclk(), clocksource_bfin.shift);
+	bfin_cs_cycles.mult = \
+		clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift);
 
 
-	if (clocksource_register(&clocksource_bfin))
+	if (clocksource_register(&bfin_cs_cycles))
 		panic("failed to register clocksource");
 		panic("failed to register clocksource");
 
 
 	return 0;
 	return 0;
 }
 }
+#else
+# define bfin_cs_cycles_init()
+#endif
+
+#ifdef CONFIG_GPTMR0_CLOCKSOURCE
+
+void __init setup_gptimer0(void)
+{
+	disable_gptimers(TIMER0bit);
+
+	set_gptimer_config(TIMER0_id, \
+		TIMER_OUT_DIS | TIMER_PERIOD_CNT | TIMER_MODE_PWM);
+	set_gptimer_period(TIMER0_id, -1);
+	set_gptimer_pwidth(TIMER0_id, -2);
+	SSYNC();
+	enable_gptimers(TIMER0bit);
+}
+
+static cycle_t bfin_read_gptimer0(void)
+{
+	return bfin_read_TIMER0_COUNTER();
+}
+
+static struct clocksource bfin_cs_gptimer0 = {
+	.name		= "bfin_cs_gptimer0",
+	.rating		= 400,
+	.read		= bfin_read_gptimer0,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.shift		= 22,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init bfin_cs_gptimer0_init(void)
+{
+	setup_gptimer0();
 
 
+	bfin_cs_gptimer0.mult = \
+		clocksource_hz2mult(get_sclk(), bfin_cs_gptimer0.shift);
+
+	if (clocksource_register(&bfin_cs_gptimer0))
+		panic("failed to register clocksource");
+
+	return 0;
+}
 #else
 #else
-# define bfin_clocksource_init()
+# define bfin_cs_gptimer0_init()
 #endif
 #endif
 
 
+#ifdef CONFIG_CORE_TIMER_IRQ_L1
+__attribute__((l1_text))
+#endif
+irqreturn_t timer_interrupt(int irq, void *dev_id);
+
+static int bfin_timer_set_next_event(unsigned long, \
+		struct clock_event_device *);
+
+static void bfin_timer_set_mode(enum clock_event_mode, \
+		struct clock_event_device *);
+
+static struct clock_event_device clockevent_bfin = {
+#if defined(CONFIG_TICKSOURCE_GPTMR0)
+	.name		= "bfin_gptimer0",
+	.rating		= 300,
+	.irq		= IRQ_TIMER0,
+#else
+	.name		= "bfin_core_timer",
+	.rating		= 350,
+	.irq		= IRQ_CORETMR,
+#endif
+	.shift		= 32,
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_next_event = bfin_timer_set_next_event,
+	.set_mode	= bfin_timer_set_mode,
+};
+
+static struct irqaction bfin_timer_irq = {
+#if defined(CONFIG_TICKSOURCE_GPTMR0)
+	.name		= "Blackfin GPTimer0",
+#else
+	.name		= "Blackfin CoreTimer",
+#endif
+	.flags		= IRQF_DISABLED | IRQF_TIMER | \
+			  IRQF_IRQPOLL | IRQF_PERCPU,
+	.handler	= timer_interrupt,
+	.dev_id		= &clockevent_bfin,
+};
+
+#if defined(CONFIG_TICKSOURCE_GPTMR0)
 static int bfin_timer_set_next_event(unsigned long cycles,
 static int bfin_timer_set_next_event(unsigned long cycles,
                                      struct clock_event_device *evt)
                                      struct clock_event_device *evt)
 {
 {
+	disable_gptimers(TIMER0bit);
+
+	/* it starts counting three SCLK cycles after the TIMENx bit is set */
+	set_gptimer_pwidth(TIMER0_id, cycles - 3);
+	enable_gptimers(TIMER0bit);
+	return 0;
+}
+
+static void bfin_timer_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *evt)
+{
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC: {
+		set_gptimer_config(TIMER0_id, \
+			TIMER_OUT_DIS | TIMER_IRQ_ENA | \
+			TIMER_PERIOD_CNT | TIMER_MODE_PWM);
+		set_gptimer_period(TIMER0_id, get_sclk() / HZ);
+		set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1);
+		enable_gptimers(TIMER0bit);
+		break;
+	}
+	case CLOCK_EVT_MODE_ONESHOT:
+		disable_gptimers(TIMER0bit);
+		set_gptimer_config(TIMER0_id, \
+			TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM);
+		set_gptimer_period(TIMER0_id, 0);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		disable_gptimers(TIMER0bit);
+		break;
+	case CLOCK_EVT_MODE_RESUME:
+		break;
+	}
+}
+
+static void bfin_timer_ack(void)
+{
+	set_gptimer_status(TIMER_GROUP1, TIMER_STATUS_TIMIL0);
+}
+
+static void __init bfin_timer_init(void)
+{
+	disable_gptimers(TIMER0bit);
+}
+
+static unsigned long  __init bfin_clockevent_check(void)
+{
+	setup_irq(IRQ_TIMER0, &bfin_timer_irq);
+	return get_sclk();
+}
+
+#else /* CONFIG_TICKSOURCE_CORETMR */
+
+static int bfin_timer_set_next_event(unsigned long cycles,
+				struct clock_event_device *evt)
+{
+	bfin_write_TCNTL(TMPWR);
+	CSYNC();
 	bfin_write_TCOUNT(cycles);
 	bfin_write_TCOUNT(cycles);
 	CSYNC();
 	CSYNC();
+	bfin_write_TCNTL(TMPWR | TMREN);
 	return 0;
 	return 0;
 }
 }
 
 
 static void bfin_timer_set_mode(enum clock_event_mode mode,
 static void bfin_timer_set_mode(enum clock_event_mode mode,
-                                struct clock_event_device *evt)
+				struct clock_event_device *evt)
 {
 {
 	switch (mode) {
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC: {
 	case CLOCK_EVT_MODE_PERIODIC: {
 		unsigned long tcount = ((get_cclk() / (HZ * TIME_SCALE)) - 1);
 		unsigned long tcount = ((get_cclk() / (HZ * TIME_SCALE)) - 1);
 		bfin_write_TCNTL(TMPWR);
 		bfin_write_TCNTL(TMPWR);
-		bfin_write_TSCALE(TIME_SCALE - 1);
 		CSYNC();
 		CSYNC();
+		bfin_write_TSCALE(TIME_SCALE - 1);
 		bfin_write_TPERIOD(tcount);
 		bfin_write_TPERIOD(tcount);
 		bfin_write_TCOUNT(tcount);
 		bfin_write_TCOUNT(tcount);
-		bfin_write_TCNTL(TMPWR | TMREN | TAUTORLD);
 		CSYNC();
 		CSYNC();
+		bfin_write_TCNTL(TMPWR | TMREN | TAUTORLD);
 		break;
 		break;
 	}
 	}
 	case CLOCK_EVT_MODE_ONESHOT:
 	case CLOCK_EVT_MODE_ONESHOT:
+		bfin_write_TCNTL(TMPWR);
+		CSYNC();
 		bfin_write_TSCALE(TIME_SCALE - 1);
 		bfin_write_TSCALE(TIME_SCALE - 1);
+		bfin_write_TPERIOD(0);
 		bfin_write_TCOUNT(0);
 		bfin_write_TCOUNT(0);
-		bfin_write_TCNTL(TMPWR | TMREN);
-		CSYNC();
 		break;
 		break;
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_SHUTDOWN:
 	case CLOCK_EVT_MODE_SHUTDOWN:
@@ -132,6 +278,10 @@ static void bfin_timer_set_mode(enum clock_event_mode mode,
 	}
 	}
 }
 }
 
 
+static void bfin_timer_ack(void)
+{
+}
+
 static void __init bfin_timer_init(void)
 static void __init bfin_timer_init(void)
 {
 {
 	/* power up the timer, but don't enable it just yet */
 	/* power up the timer, but don't enable it just yet */
@@ -145,38 +295,32 @@ static void __init bfin_timer_init(void)
 	bfin_write_TPERIOD(0);
 	bfin_write_TPERIOD(0);
 	bfin_write_TCOUNT(0);
 	bfin_write_TCOUNT(0);
 
 
-	/* now enable the timer */
 	CSYNC();
 	CSYNC();
 }
 }
 
 
+static unsigned long  __init bfin_clockevent_check(void)
+{
+	setup_irq(IRQ_CORETMR, &bfin_timer_irq);
+	return get_cclk() / TIME_SCALE;
+}
+
+void __init setup_core_timer(void)
+{
+	bfin_timer_init();
+	bfin_timer_set_mode(CLOCK_EVT_MODE_PERIODIC, NULL);
+}
+#endif /* CONFIG_TICKSOURCE_GPTMR0 */
+
 /*
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  * as well as call the "do_timer()" routine every clocktick
  */
  */
-#ifdef CONFIG_CORE_TIMER_IRQ_L1
-__attribute__((l1_text))
-#endif
-irqreturn_t timer_interrupt(int irq, void *dev_id);
-
-static struct clock_event_device clockevent_bfin = {
-	.name		= "bfin_core_timer",
-	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.shift		= 32,
-	.set_next_event = bfin_timer_set_next_event,
-	.set_mode	= bfin_timer_set_mode,
-};
-
-static struct irqaction bfin_timer_irq = {
-	.name		= "Blackfin Core Timer",
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= timer_interrupt,
-	.dev_id		= &clockevent_bfin,
-};
-
 irqreturn_t timer_interrupt(int irq, void *dev_id)
 irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
 {
 	struct clock_event_device *evt = dev_id;
 	struct clock_event_device *evt = dev_id;
+	smp_mb();
 	evt->event_handler(evt);
 	evt->event_handler(evt);
+	bfin_timer_ack();
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
@@ -184,9 +328,8 @@ static int __init bfin_clockevent_init(void)
 {
 {
 	unsigned long timer_clk;
 	unsigned long timer_clk;
 
 
-	timer_clk = get_cclk() / TIME_SCALE;
+	timer_clk = bfin_clockevent_check();
 
 
-	setup_irq(IRQ_CORETMR, &bfin_timer_irq);
 	bfin_timer_init();
 	bfin_timer_init();
 
 
 	clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift);
 	clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift);
@@ -218,6 +361,7 @@ void __init time_init(void)
 	xtime.tv_nsec = 0;
 	xtime.tv_nsec = 0;
 	set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
 	set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
 
 
-	bfin_clocksource_init();
+	bfin_cs_cycles_init();
+	bfin_cs_gptimer0_init();
 	bfin_clockevent_init();
 	bfin_clockevent_init();
 }
 }

+ 5 - 5
arch/blackfin/kernel/time.c

@@ -31,7 +31,7 @@ static struct irqaction bfin_timer_irq = {
 #endif
 #endif
 };
 };
 
 
-#if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE)
+#if defined(CONFIG_TICKSOURCE_GPTMR0) || defined(CONFIG_IPIPE)
 void __init setup_system_timer0(void)
 void __init setup_system_timer0(void)
 {
 {
 	/* Power down the core timer, just to play safe. */
 	/* Power down the core timer, just to play safe. */
@@ -74,7 +74,7 @@ void __init setup_core_timer(void)
 static void __init
 static void __init
 time_sched_init(irqreturn_t(*timer_routine) (int, void *))
 time_sched_init(irqreturn_t(*timer_routine) (int, void *))
 {
 {
-#if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE)
+#if defined(CONFIG_TICKSOURCE_GPTMR0) || defined(CONFIG_IPIPE)
 	setup_system_timer0();
 	setup_system_timer0();
 	bfin_timer_irq.handler = timer_routine;
 	bfin_timer_irq.handler = timer_routine;
 	setup_irq(IRQ_TIMER0, &bfin_timer_irq);
 	setup_irq(IRQ_TIMER0, &bfin_timer_irq);
@@ -94,7 +94,7 @@ static unsigned long gettimeoffset(void)
 	unsigned long offset;
 	unsigned long offset;
 	unsigned long clocks_per_jiffy;
 	unsigned long clocks_per_jiffy;
 
 
-#if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE)
+#if defined(CONFIG_TICKSOURCE_GPTMR0) || defined(CONFIG_IPIPE)
 	clocks_per_jiffy = bfin_read_TIMER0_PERIOD();
 	clocks_per_jiffy = bfin_read_TIMER0_PERIOD();
 	offset = bfin_read_TIMER0_COUNTER() / \
 	offset = bfin_read_TIMER0_COUNTER() / \
 		(((clocks_per_jiffy + 1) * HZ) / USEC_PER_SEC);
 		(((clocks_per_jiffy + 1) * HZ) / USEC_PER_SEC);
@@ -133,7 +133,7 @@ irqreturn_t timer_interrupt(int irq, void *dummy)
 	static long last_rtc_update;
 	static long last_rtc_update;
 
 
 	write_seqlock(&xtime_lock);
 	write_seqlock(&xtime_lock);
-#if defined(CONFIG_TICK_SOURCE_SYSTMR0) && !defined(CONFIG_IPIPE)
+#if defined(CONFIG_TICKSOURCE_GPTMR0) && !defined(CONFIG_IPIPE)
 	/*
 	/*
 	 * TIMIL0 is latched in __ipipe_grab_irq() when the I-Pipe is
 	 * TIMIL0 is latched in __ipipe_grab_irq() when the I-Pipe is
 	 * enabled.
 	 * enabled.
@@ -159,7 +159,7 @@ irqreturn_t timer_interrupt(int irq, void *dummy)
 				/* Do it again in 60s. */
 				/* Do it again in 60s. */
 				last_rtc_update = xtime.tv_sec - 600;
 				last_rtc_update = xtime.tv_sec - 600;
 		}
 		}
-#if defined(CONFIG_TICK_SOURCE_SYSTMR0) && !defined(CONFIG_IPIPE)
+#if defined(CONFIG_TICKSOURCE_GPTMR0) && !defined(CONFIG_IPIPE)
 		set_gptimer_status(0, TIMER_STATUS_TIMIL0);
 		set_gptimer_status(0, TIMER_STATUS_TIMIL0);
 	}
 	}
 #endif
 #endif

+ 1 - 0
arch/blackfin/mach-bf518/Kconfig

@@ -156,6 +156,7 @@ config IRQ_PORTH_INTB
 	default 11
 	default 11
 config IRQ_TIMER0
 config IRQ_TIMER0
 	int "IRQ_TIMER0"
 	int "IRQ_TIMER0"
+	default 7 if TICKSOURCE_GPTMR0
 	default 8
 	default 8
 config IRQ_TIMER1
 config IRQ_TIMER1
 	int "IRQ_TIMER1"
 	int "IRQ_TIMER1"

+ 1 - 0
arch/blackfin/mach-bf527/Kconfig

@@ -170,6 +170,7 @@ config IRQ_PORTH_INTB
 	default 11
 	default 11
 config IRQ_TIMER0
 config IRQ_TIMER0
 	int "IRQ_TIMER0"
 	int "IRQ_TIMER0"
+	default 7 if TICKSOURCE_GPTMR0
 	default 8
 	default 8
 config IRQ_TIMER1
 config IRQ_TIMER1
 	int "IRQ_TIMER1"
 	int "IRQ_TIMER1"

+ 1 - 0
arch/blackfin/mach-bf533/Kconfig

@@ -59,6 +59,7 @@ config DMA7_UARTTX
 	default 10
 	default 10
 config TIMER0
 config TIMER0
 	int "TIMER0"
 	int "TIMER0"
+	default 7 if TICKSOURCE_GPTMR0
 	default 8
 	default 8
 config TIMER1
 config TIMER1
 	int "TIMER1"
 	int "TIMER1"

+ 1 - 0
arch/blackfin/mach-bf537/Kconfig

@@ -66,6 +66,7 @@ config IRQ_MAC_TX
 	default 11
 	default 11
 config IRQ_TIMER0
 config IRQ_TIMER0
 	int "IRQ_TIMER0"
 	int "IRQ_TIMER0"
+	default 7 if TICKSOURCE_GPTMR0
 	default 8
 	default 8
 config IRQ_TIMER1
 config IRQ_TIMER1
 	int "IRQ_TIMER1"
 	int "IRQ_TIMER1"

+ 1 - 0
arch/blackfin/mach-bf538/Kconfig

@@ -57,6 +57,7 @@ config IRQ_UART0_TX
 	default 10
 	default 10
 config IRQ_TIMER0
 config IRQ_TIMER0
 	int "IRQ_TIMER0"
 	int "IRQ_TIMER0"
+	default 7 if TICKSOURCE_GPTMR0
 	default 8
 	default 8
 config IRQ_TIMER1
 config IRQ_TIMER1
 	int "IRQ_TIMER1"
 	int "IRQ_TIMER1"

+ 1 - 0
arch/blackfin/mach-bf548/Kconfig

@@ -257,6 +257,7 @@ config IRQ_OTPSEC
 	default 11
 	default 11
 config IRQ_TIMER0
 config IRQ_TIMER0
 	int "IRQ_TIMER0"
 	int "IRQ_TIMER0"
+	default 7 if TICKSOURCE_GPTMR0
 	default 8
 	default 8
 config IRQ_TIMER1
 config IRQ_TIMER1
 	int "IRQ_TIMER1"
 	int "IRQ_TIMER1"

+ 1 - 0
arch/blackfin/mach-bf561/Kconfig

@@ -125,6 +125,7 @@ config IRQ_DMA2_11
 	default 9
 	default 9
 config IRQ_TIMER0
 config IRQ_TIMER0
 	int "TIMER 0  Interrupt"
 	int "TIMER 0  Interrupt"
+	default 7 if TICKSOURCE_GPTMR0
 	default 8
 	default 8
 config IRQ_TIMER1
 config IRQ_TIMER1
 	int "TIMER 1  Interrupt"
 	int "TIMER 1  Interrupt"

+ 1 - 1
arch/blackfin/mach-bf561/smp.c

@@ -133,7 +133,7 @@ void __init platform_request_ipi(irq_handler_t handler)
 	int ret;
 	int ret;
 
 
 	ret = request_irq(IRQ_SUPPLE_0, handler, IRQF_DISABLED,
 	ret = request_irq(IRQ_SUPPLE_0, handler, IRQF_DISABLED,
-			  "SMP interrupt", handler);
+			  "Supplemental Interrupt0", handler);
 	if (ret)
 	if (ret)
 		panic("Cannot request supplemental interrupt 0 for IPI service");
 		panic("Cannot request supplemental interrupt 0 for IPI service");
 }
 }

+ 6 - 17
arch/blackfin/mach-common/ints-priority.c

@@ -1052,7 +1052,7 @@ int __init init_arch_irq(void)
 			set_irq_chained_handler(irq, bfin_demux_error_irq);
 			set_irq_chained_handler(irq, bfin_demux_error_irq);
 			break;
 			break;
 #endif
 #endif
-#if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE)
+#if defined(CONFIG_TICKSOURCE_GPTMR0)
 		case IRQ_TIMER0:
 		case IRQ_TIMER0:
 			set_irq_handler(irq, handle_percpu_irq);
 			set_irq_handler(irq, handle_percpu_irq);
 			break;
 			break;
@@ -1232,13 +1232,9 @@ asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs)
 
 
 	if (likely(vec == EVT_IVTMR_P)) {
 	if (likely(vec == EVT_IVTMR_P)) {
 		irq = IRQ_CORETMR;
 		irq = IRQ_CORETMR;
-		goto core_tick;
-	}
-
-	SSYNC();
 
 
+	} else {
 #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
 #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
-	{
 		unsigned long sic_status[3];
 		unsigned long sic_status[3];
 
 
 		sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
 		sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
@@ -1254,9 +1250,7 @@ asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs)
 			if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag)
 			if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag)
 				break;
 				break;
 		}
 		}
-	}
 #else
 #else
-	{
 		unsigned long sic_status;
 		unsigned long sic_status;
 
 
 		sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
 		sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
@@ -1268,15 +1262,13 @@ asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs)
 			} else if (sic_status & ivg->isrflag)
 			} else if (sic_status & ivg->isrflag)
 				break;
 				break;
 		}
 		}
-	}
 #endif
 #endif
 
 
-	irq = ivg->irqno;
+		irq = ivg->irqno;
+	}
 
 
 	if (irq == IRQ_SYSTMR) {
 	if (irq == IRQ_SYSTMR) {
-#ifdef CONFIG_GENERIC_CLOCKEVENTS
-core_tick:
-#else
+#ifndef CONFIG_GENERIC_CLOCKEVENTS
 		bfin_write_TIMER_STATUS(1); /* Latch TIMIL0 */
 		bfin_write_TIMER_STATUS(1); /* Latch TIMIL0 */
 #endif
 #endif
 		/* This is basically what we need from the register frame. */
 		/* This is basically what we need from the register frame. */
@@ -1288,9 +1280,6 @@ core_tick:
 			__raw_get_cpu_var(__ipipe_tick_regs).ipend |= 0x10;
 			__raw_get_cpu_var(__ipipe_tick_regs).ipend |= 0x10;
 	}
 	}
 
 
-#ifndef CONFIG_GENERIC_CLOCKEVENTS
-core_tick:
-#endif
 	if (this_domain == ipipe_root_domain) {
 	if (this_domain == ipipe_root_domain) {
 		s = __test_and_set_bit(IPIPE_SYNCDEFER_FLAG, &p->status);
 		s = __test_and_set_bit(IPIPE_SYNCDEFER_FLAG, &p->status);
 		barrier();
 		barrier();
@@ -1308,7 +1297,7 @@ core_tick:
 		}
 		}
 	}
 	}
 
 
-       return 0;
+	return 0;
 }
 }
 
 
 #endif /* CONFIG_IPIPE */
 #endif /* CONFIG_IPIPE */

+ 3 - 2
arch/blackfin/mach-common/smp.c

@@ -43,6 +43,7 @@
 #include <asm/processor.h>
 #include <asm/processor.h>
 #include <asm/ptrace.h>
 #include <asm/ptrace.h>
 #include <asm/cpu.h>
 #include <asm/cpu.h>
+#include <asm/time.h>
 #include <linux/err.h>
 #include <linux/err.h>
 
 
 /*
 /*
@@ -356,7 +357,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
 
 
 static void __cpuinit setup_secondary(unsigned int cpu)
 static void __cpuinit setup_secondary(unsigned int cpu)
 {
 {
-#if !(defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE))
+#if !defined(CONFIG_TICKSOURCE_GPTMR0)
 	struct irq_desc *timer_desc;
 	struct irq_desc *timer_desc;
 #endif
 #endif
 	unsigned long ilat;
 	unsigned long ilat;
@@ -377,7 +378,7 @@ static void __cpuinit setup_secondary(unsigned int cpu)
 	    IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
 	    IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
 	    IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
 	    IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
 
 
-#if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE)
+#if defined(CONFIG_TICKSOURCE_GPTMR0)
 	/* Power down the core timer, just to play safe. */
 	/* Power down the core timer, just to play safe. */
 	bfin_write_TCNTL(0);
 	bfin_write_TCNTL(0);