提交 1fa9be72 编写于 作者: G Graf Yang 提交者: Mike Frysinger

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: NGraf Yang <graf.yang@analog.com>
Signed-off-by: NMike Frysinger <vapier@gentoo.org>
上级 555487bb
...@@ -241,12 +241,6 @@ config IRQ_PER_CPU ...@@ -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 ...@@ -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 ...@@ -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)" bool "Use 'CYCLES' as a clocksource"
depends on EXPERIMENTAL
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 ...@@ -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"
......
...@@ -37,4 +37,5 @@ extern unsigned long long __bfin_cycles_off; ...@@ -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
...@@ -20,8 +20,9 @@ ...@@ -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) ...@@ -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 = { static struct clocksource bfin_cs_cycles = {
.name = "bfin_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 = { ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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();
} }
...@@ -31,7 +31,7 @@ static struct irqaction bfin_timer_irq = { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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
......
...@@ -156,6 +156,7 @@ config IRQ_PORTH_INTB ...@@ -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"
......
...@@ -170,6 +170,7 @@ config IRQ_PORTH_INTB ...@@ -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"
......
...@@ -59,6 +59,7 @@ config DMA7_UARTTX ...@@ -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"
......
...@@ -66,6 +66,7 @@ config IRQ_MAC_TX ...@@ -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"
......
...@@ -57,6 +57,7 @@ config IRQ_UART0_TX ...@@ -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"
......
...@@ -257,6 +257,7 @@ config IRQ_OTPSEC ...@@ -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"
......
...@@ -125,6 +125,7 @@ config IRQ_DMA2_11 ...@@ -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"
......
...@@ -133,7 +133,7 @@ void __init platform_request_ipi(irq_handler_t handler) ...@@ -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");
} }
......
...@@ -1052,7 +1052,7 @@ int __init init_arch_irq(void) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 #ifndef CONFIG_GENERIC_CLOCKEVENTS
core_tick:
#else
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 @@ asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs) ...@@ -1288,9 +1280,6 @@ asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs)
__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 @@ asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs) ...@@ -1308,7 +1297,7 @@ asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs)
} }
} }
return 0; return 0;
} }
#endif /* CONFIG_IPIPE */ #endif /* CONFIG_IPIPE */
...@@ -43,6 +43,7 @@ ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册