diff options
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/mips/kernel/cevt-bcm1480.c | 149 | ||||
-rw-r--r-- | arch/mips/kernel/cevt-sb1250.c | 148 | ||||
-rw-r--r-- | arch/mips/kernel/csrc-bcm1480.c | 54 | ||||
-rw-r--r-- | arch/mips/kernel/csrc-sb1250.c | 70 | ||||
-rw-r--r-- | arch/mips/kernel/i8253.c | 25 | ||||
-rw-r--r-- | arch/mips/kernel/time.c | 73 |
7 files changed, 449 insertions, 74 deletions
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 3196509a28d..b551535b7e4 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -8,9 +8,13 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \ time.o topology.o traps.o unaligned.o +obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o +obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o +obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o +obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ irix5sys.o sysirix.o diff --git a/arch/mips/kernel/cevt-bcm1480.c b/arch/mips/kernel/cevt-bcm1480.c new file mode 100644 index 00000000000..21e6d63eb4d --- /dev/null +++ b/arch/mips/kernel/cevt-bcm1480.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2000,2001,2004 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/clockchips.h> +#include <linux/interrupt.h> +#include <linux/percpu.h> + +#include <asm/addrspace.h> +#include <asm/io.h> +#include <asm/time.h> + +#include <asm/sibyte/bcm1480_regs.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/bcm1480_int.h> +#include <asm/sibyte/bcm1480_scd.h> + +#include <asm/sibyte/sb1250.h> + +#define IMR_IP2_VAL K_BCM1480_INT_MAP_I0 +#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1 +#define IMR_IP4_VAL K_BCM1480_INT_MAP_I2 + +/* + * The general purpose timer ticks at 1MHz independent if + * the rest of the system + */ +static void sibyte_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned int cpu = smp_processor_id(); + void __iomem *cfg, *init; + + cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + __raw_writeq(0, cfg); + __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init); + __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, + cfg); + break; + + case CLOCK_EVT_MODE_ONESHOT: + /* Stop the timer until we actually program a shot */ + case CLOCK_EVT_MODE_SHUTDOWN: + __raw_writeq(0, cfg); + break; + + case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ + case CLOCK_EVT_MODE_RESUME: + ; + } +} + +static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd) +{ + unsigned int cpu = smp_processor_id(); + void __iomem *cfg, *init; + + cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); + + __raw_writeq(delta - 1, init); + __raw_writeq(M_SCD_TIMER_ENABLE, cfg); + + return 0; +} + +static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) +{ + unsigned int cpu = smp_processor_id(); + struct clock_event_device *cd = dev_id; + void __iomem *cfg; + unsigned long tmode; + + if (cd->mode == CLOCK_EVT_MODE_PERIODIC) + tmode = M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS; + else + tmode = 0; + + /* ACK interrupt */ + cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + ____raw_writeq(tmode, cfg); + + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent); +static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction); +static DEFINE_PER_CPU(char [18], sibyte_hpt_name); + +void __cpuinit sb1480_clockevent_init(void) +{ + unsigned int cpu = smp_processor_id(); + unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu; + struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu); + struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu); + unsigned char *name = per_cpu(sibyte_hpt_name, cpu); + + BUG_ON(cpu > 3); /* Only have 4 general purpose timers */ + + sprintf(name, "bcm1480-counter-%d", cpu); + cd->name = name; + cd->features = CLOCK_EVT_FEAT_PERIODIC | + CLOCK_EVT_FEAT_ONESHOT; + clockevent_set_clock(cd, V_SCD_TIMER_FREQ); + cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd); + cd->min_delta_ns = clockevent_delta2ns(1, cd); + cd->rating = 200; + cd->irq = irq; + cd->cpumask = cpumask_of_cpu(cpu); + cd->set_next_event = sibyte_next_event; + cd->set_mode = sibyte_set_mode; + clockevents_register_device(cd); + + bcm1480_mask_irq(cpu, irq); + + /* + * Map the timer interrupt to IP[4] of this cpu + */ + __raw_writeq(IMR_IP4_VAL, + IOADDR(A_BCM1480_IMR_REGISTER(cpu, + R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3))); + + bcm1480_unmask_irq(cpu, irq); + + action->handler = sibyte_counter_handler; + action->flags = IRQF_DISABLED | IRQF_PERCPU; + action->name = name; + action->dev_id = cd; + setup_irq(irq, action); +} diff --git a/arch/mips/kernel/cevt-sb1250.c b/arch/mips/kernel/cevt-sb1250.c new file mode 100644 index 00000000000..e2029d0fc39 --- /dev/null +++ b/arch/mips/kernel/cevt-sb1250.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/clockchips.h> +#include <linux/interrupt.h> +#include <linux/percpu.h> + +#include <asm/addrspace.h> +#include <asm/io.h> +#include <asm/time.h> + +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_int.h> +#include <asm/sibyte/sb1250_scd.h> + +#define IMR_IP2_VAL K_INT_MAP_I0 +#define IMR_IP3_VAL K_INT_MAP_I1 +#define IMR_IP4_VAL K_INT_MAP_I2 + +/* + * The general purpose timer ticks at 1MHz independent if + * the rest of the system + */ +static void sibyte_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned int cpu = smp_processor_id(); + void __iomem *cfg, *init; + + cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + __raw_writeq(0, cfg); + __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init); + __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, + cfg); + break; + + case CLOCK_EVT_MODE_ONESHOT: + /* Stop the timer until we actually program a shot */ + case CLOCK_EVT_MODE_SHUTDOWN: + __raw_writeq(0, cfg); + break; + + case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ + case CLOCK_EVT_MODE_RESUME: + ; + } +} + +static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd) +{ + unsigned int cpu = smp_processor_id(); + void __iomem *cfg, *init; + + cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); + + __raw_writeq(delta - 1, init); + __raw_writeq(M_SCD_TIMER_ENABLE, cfg); + + return 0; +} + +static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) +{ + unsigned int cpu = smp_processor_id(); + struct clock_event_device *cd = dev_id; + void __iomem *cfg; + unsigned long tmode; + + if (cd->mode == CLOCK_EVT_MODE_PERIODIC) + tmode = M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS; + else + tmode = 0; + + /* ACK interrupt */ + cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + ____raw_writeq(tmode, cfg); + + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent); +static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction); +static DEFINE_PER_CPU(char [18], sibyte_hpt_name); + +void __cpuinit sb1250_clockevent_init(void) +{ + unsigned int cpu = smp_processor_id(); + unsigned int irq = K_INT_TIMER_0 + cpu; + struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu); + struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu); + unsigned char *name = per_cpu(sibyte_hpt_name, cpu); + + /* Only have 4 general purpose timers, and we use last one as hpt */ + BUG_ON(cpu > 2); + + sprintf(name, "sb1250-counter-%d", cpu); + cd->name = name; + cd->features = CLOCK_EVT_FEAT_PERIODIC | + CLOCK_EVT_FEAT_ONESHOT; + clockevent_set_clock(cd, V_SCD_TIMER_FREQ); + cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd); + cd->min_delta_ns = clockevent_delta2ns(1, cd); + cd->rating = 200; + cd->irq = irq; + cd->cpumask = cpumask_of_cpu(cpu); + cd->set_next_event = sibyte_next_event; + cd->set_mode = sibyte_set_mode; + clockevents_register_device(cd); + + sb1250_mask_irq(cpu, irq); + + /* + * Map the timer interrupt to IP[4] of this cpu + */ + __raw_writeq(IMR_IP4_VAL, + IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) + + (irq << 3))); + + sb1250_unmask_irq(cpu, irq); + + action->handler = sibyte_counter_handler; + action->flags = IRQF_DISABLED | IRQF_PERCPU; + action->name = name; + action->dev_id = cd; + setup_irq(irq, action); +} diff --git a/arch/mips/kernel/csrc-bcm1480.c b/arch/mips/kernel/csrc-bcm1480.c new file mode 100644 index 00000000000..868745e7184 --- /dev/null +++ b/arch/mips/kernel/csrc-bcm1480.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2000,2001,2004 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/clocksource.h> + +#include <asm/addrspace.h> +#include <asm/io.h> +#include <asm/time.h> + +#include <asm/sibyte/bcm1480_regs.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/bcm1480_int.h> +#include <asm/sibyte/bcm1480_scd.h> + +#include <asm/sibyte/sb1250.h> + +static cycle_t bcm1480_hpt_read(void) +{ + return (cycle_t) __raw_readq(IOADDR(A_SCD_ZBBUS_CYCLE_COUNT)); +} + +struct clocksource bcm1480_clocksource = { + .name = "zbbus-cycles", + .rating = 200, + .read = bcm1480_hpt_read, + .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +void __init sb1480_clocksource_init(void) +{ + struct clocksource *cs = &bcm1480_clocksource; + unsigned int plldiv; + unsigned long zbbus; + + plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG))); + zbbus = ((plldiv >> 1) * 50000000) + ((plldiv & 1) * 25000000); + clocksource_set_clock(cs, zbbus); + clocksource_register(cs); +} diff --git a/arch/mips/kernel/csrc-sb1250.c b/arch/mips/kernel/csrc-sb1250.c new file mode 100644 index 00000000000..ebb16e66887 --- /dev/null +++ b/arch/mips/kernel/csrc-sb1250.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/clocksource.h> + +#include <asm/addrspace.h> +#include <asm/io.h> +#include <asm/time.h> + +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_int.h> +#include <asm/sibyte/sb1250_scd.h> + +#define SB1250_HPT_NUM 3 +#define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */ + +/* + * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over + * again. + */ +static cycle_t sb1250_hpt_read(void) +{ + unsigned int count; + + count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT)))); + + return SB1250_HPT_VALUE - count; +} + +struct clocksource bcm1250_clocksource = { + .name = "MIPS", + .rating = 200, + .read = sb1250_hpt_read, + .mask = CLOCKSOURCE_MASK(23), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +void __init sb1250_clocksource_init(void) +{ + struct clocksource *cs = &bcm1250_clocksource; + + /* Setup hpt using timer #3 but do not enable irq for it */ + __raw_writeq(0, + IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, + R_SCD_TIMER_CFG))); + __raw_writeq(SB1250_HPT_VALUE, + IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, + R_SCD_TIMER_INIT))); + __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, + IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, + R_SCD_TIMER_CFG))); + + clocksource_set_clock(cs, V_SCD_TIMER_FREQ); + clocksource_register(cs); +} diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c index 5d9830df359..c2d497ceffd 100644 --- a/arch/mips/kernel/i8253.c +++ b/arch/mips/kernel/i8253.c @@ -12,8 +12,9 @@ #include <asm/delay.h> #include <asm/i8253.h> #include <asm/io.h> +#include <asm/time.h> -static DEFINE_SPINLOCK(i8253_lock); +DEFINE_SPINLOCK(i8253_lock); /* * Initialize the PIT timer. @@ -87,11 +88,10 @@ struct clock_event_device pit_clockevent = { .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .set_mode = init_pit_timer, .set_next_event = pit_next_event, - .shift = 32, .irq = 0, }; -irqreturn_t timer_interrupt(int irq, void *dev_id) +static irqreturn_t timer_interrupt(int irq, void *dev_id) { pit_clockevent.event_handler(&pit_clockevent); @@ -111,19 +111,20 @@ static struct irqaction irq0 = { */ void __init setup_pit_timer(void) { + struct clock_event_device *cd = &pit_clockevent; + unsigned int cpu = smp_processor_id(); + /* * Start pit with the boot cpu mask and make it global after the * IO_APIC has been initialized. */ - pit_clockevent.cpumask = cpumask_of_cpu(0); - pit_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, 32); - pit_clockevent.max_delta_ns = - clockevent_delta2ns(0x7FFF, &pit_clockevent); - pit_clockevent.min_delta_ns = - clockevent_delta2ns(0xF, &pit_clockevent); - clockevents_register_device(&pit_clockevent); - - irq0.mask = cpumask_of_cpu(0); + cd->cpumask = cpumask_of_cpu(cpu); + clockevent_set_clock(cd, CLOCK_TICK_RATE); + cd->max_delta_ns = clockevent_delta2ns(0x7FFF, cd); + cd->min_delta_ns = clockevent_delta2ns(0xF, cd); + clockevents_register_device(cd); + + irq0.mask = cpumask_of_cpu(cpu); setup_irq(0, &irq0); } diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 27228f583da..3284b9b4eca 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -3,8 +3,7 @@ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net * Copyright (c) 2003, 2004 Maciej W. Rozycki * - * Common time service routines for MIPS machines. See - * Documentation/mips/time.README. + * Common time service routines for MIPS machines. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -18,28 +17,17 @@ #include <linux/init.h> #include <linux/sched.h> #include <linux/param.h> -#include <linux/profile.h> #include <linux/time.h> #include <linux/timex.h> #include <linux/smp.h> -#include <linux/kernel_stat.h> #include <linux/spinlock.h> -#include <linux/interrupt.h> #include <linux/module.h> -#include <linux/kallsyms.h> -#include <asm/bootinfo.h> -#include <asm/cache.h> -#include <asm/compiler.h> -#include <asm/cpu.h> #include <asm/cpu-features.h> #include <asm/div64.h> -#include <asm/sections.h> #include <asm/smtc_ipi.h> #include <asm/time.h> -#include <irq.h> - /* * forward reference */ @@ -63,14 +51,6 @@ int update_persistent_clock(struct timespec now) } /* - * Null high precision timer functions for systems lacking one. - */ -static cycle_t null_hpt_read(void) -{ - return 0; -} - -/* * High precision timer functions for a R4k-compatible timer. */ static cycle_t c0_hpt_read(void) @@ -80,22 +60,6 @@ static cycle_t c0_hpt_read(void) int (*mips_timer_state)(void); -/* - * local_timer_interrupt() does profiling and process accounting - * on a per-CPU basis. - * - * In UP mode, it is invoked from the (global) timer_interrupt. - * - * In SMP mode, it might invoked by per-CPU timer interrupt, or - * a broadcasted inter-processor interrupt which itself is triggered - * by the global timer interrupt. - */ -void local_timer_interrupt(int irq, void *dev_id) -{ - profile_tick(CPU_PROFILING); - update_process_times(user_mode(get_irq_regs())); -} - int null_perf_irq(void) { return 0; @@ -120,6 +84,13 @@ EXPORT_SYMBOL(perf_irq); unsigned int mips_hpt_frequency; +static struct clocksource clocksource_mips = { + .name = "MIPS", + .read = c0_hpt_read, + .mask = CLOCKSOURCE_MASK(32), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + static unsigned int __init calibrate_hpt(void) { cycle_t frequency, hpt_start, hpt_end, hpt_count, hz; @@ -162,12 +133,6 @@ static unsigned int __init calibrate_hpt(void) return frequency >> log_2_loops; } -struct clocksource clocksource_mips = { - .name = "MIPS", - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock) { u64 temp; @@ -203,9 +168,6 @@ void __cpuinit clockevent_set_clock(struct clock_event_device *cd, static void __init init_mips_clocksource(void) { - if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read) - return; - /* Calclate a somewhat reasonable rating value */ clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; @@ -227,7 +189,7 @@ void __init __weak plat_time_init(void) * setup_irq calls and each clock_event_device should use its own * struct irqrequest. */ -void __init plat_timer_setup(struct irqaction *irq) +void __init plat_timer_setup(void) { BUG(); } @@ -236,21 +198,8 @@ void __init time_init(void) { plat_time_init(); - /* Choose appropriate high precision timer routines. */ - if (!cpu_has_counter && !clocksource_mips.read) - /* No high precision timer -- sorry. */ - clocksource_mips.read = null_hpt_read; - else if (!mips_hpt_frequency && !mips_timer_state) { - /* A high precision timer of unknown frequency. */ - if (!clocksource_mips.read) - /* No external high precision timer -- use R4k. */ - clocksource_mips.read = c0_hpt_read; - } else { + if (cpu_has_counter && (mips_hpt_frequency || mips_timer_state)) { /* We know counter frequency. Or we can get it. */ - if (!clocksource_mips.read) { - /* No external high precision timer -- use R4k. */ - clocksource_mips.read = c0_hpt_read; - } if (!mips_hpt_frequency) mips_hpt_frequency = calibrate_hpt(); @@ -258,8 +207,8 @@ void __init time_init(void) printk("Using %u.%03u MHz high precision timer.\n", ((mips_hpt_frequency + 500) / 1000) / 1000, ((mips_hpt_frequency + 500) / 1000) % 1000); + init_mips_clocksource(); } - init_mips_clocksource(); mips_clockevent_init(); } |