From 9e32a510afa62c0d548d78572031e6112d21e0ea Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 31 Oct 2007 00:08:06 +0000 Subject: [PATCH 01/25] [MIPS] Sibyte: Build fixes / dead code removal. Signed-off-by: Ralf Baechle --- arch/mips/sibyte/bcm1480/irq.c | 15 --------------- arch/mips/sibyte/sb1250/irq.c | 14 -------------- 2 files changed, 29 deletions(-) diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index 61790c4bfb60..5f4f9b491586 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c @@ -265,21 +265,6 @@ void __init init_bcm1480_irqs(void) } } - -static irqreturn_t bcm1480_dummy_handler(int irq, void *dev_id) -{ - return IRQ_NONE; -} - -static struct irqaction bcm1480_dummy_action = { - .handler = bcm1480_dummy_handler, - .flags = 0, - .mask = CPU_MASK_NONE, - .name = "bcm1480-private", - .next = NULL, - .dev_id = 0 -}; - /* * init_IRQ is called early in the boot sequence from init/main.c. It * is responsible for setting up the interrupt mapper and installing the diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index 52d18fc91f32..eac9065ffe0c 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c @@ -236,20 +236,6 @@ void __init init_sb1250_irqs(void) } -static irqreturn_t sb1250_dummy_handler(int irq, void *dev_id) -{ - return IRQ_NONE; -} - -static struct irqaction sb1250_dummy_action = { - .handler = sb1250_dummy_handler, - .flags = 0, - .mask = CPU_MASK_NONE, - .name = "sb1250-private", - .next = NULL, - .dev_id = 0 -}; - /* * arch_init_irq is called early in the boot sequence from init/main.c via * init_IRQ. It is responsible for setting up the interrupt mapper and From 2e5dcd2b4ce97ebc43703f2645bf2fe978da1627 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 31 Oct 2007 12:34:42 +0000 Subject: [PATCH 02/25] [MIPS] Sibyte: Fix names of the clockevent devices. Signed-off-by: Ralf Baechle --- arch/mips/sibyte/bcm1480/time.c | 2 +- arch/mips/sibyte/sb1250/time.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c index bbf19bfabccb..39e77d9bd944 100644 --- a/arch/mips/sibyte/bcm1480/time.c +++ b/arch/mips/sibyte/bcm1480/time.c @@ -116,7 +116,7 @@ void __cpuinit sb1480_clockevent_init(void) BUG_ON(cpu > 3); /* Only have 4 general purpose timers */ - sprintf(name, "bcm1480-counter %d", cpu); + sprintf(name, "bcm1480-counter-%d", cpu); cd->name = name; cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index 95ad34e3fbac..7f1316dd8add 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c @@ -134,7 +134,7 @@ void __cpuinit sb1250_clockevent_init(void) /* Only have 4 general purpose timers, and we use last one as hpt */ BUG_ON(cpu > 2); - sprintf(name, "bcm1480-counter %d", cpu); + sprintf(name, "sb1250-counter-%d", cpu); cd->name = name; cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; From d1598b6adb0e7d9615f751f3bced128bcceb7378 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 31 Oct 2007 12:36:42 +0000 Subject: [PATCH 03/25] [MIPS] SB1250: Remove stray assignment of cpumask. Signed-off-by: Ralf Baechle --- arch/mips/sibyte/sb1250/time.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index 7f1316dd8add..181a4139dead 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c @@ -154,7 +154,6 @@ void __cpuinit sb1250_clockevent_init(void) __raw_writeq(IMR_IP4_VAL, IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) + (irq << 3))); - cd->cpumask = cpumask_of_cpu(0); sb1250_unmask_irq(cpu, irq); From 46abf4b39a555294ec0df138923daed1ccb9adb5 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 31 Oct 2007 12:42:56 +0000 Subject: [PATCH 04/25] [MIPS] SB1250: Use the right irqaction for the timer interrupt. Signed-off-by: Ralf Baechle --- arch/mips/sibyte/sb1250/time.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index 181a4139dead..e224fe7715c8 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c @@ -113,12 +113,6 @@ static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction sibyte_irqaction = { - .handler = sibyte_counter_handler, - .flags = IRQF_DISABLED | IRQF_PERCPU, - .name = "timer", -}; - 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); @@ -161,7 +155,7 @@ void __cpuinit sb1250_clockevent_init(void) action->flags = IRQF_DISABLED | IRQF_PERCPU; action->name = name; action->dev_id = cd; - setup_irq(irq, &sibyte_irqaction); + setup_irq(irq, &action); } /* From 81b635ef368d994a86f20c0ea5a82f45045da1e9 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 31 Oct 2007 13:10:00 +0000 Subject: [PATCH 05/25] [MIPS] IP32: Fix address of 2nd serial interface. Found by Giuseppe Sacco . Signed-off-by: Ralf Baechle --- arch/mips/sgi-ip32/ip32-platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c index 7309e48d163d..77febd68fcd4 100644 --- a/arch/mips/sgi-ip32/ip32-platform.c +++ b/arch/mips/sgi-ip32/ip32-platform.c @@ -42,7 +42,7 @@ static struct platform_device uart8250_device = { static int __init uart8250_init(void) { uart8250_data[0].membase = (void __iomem *) &mace->isa.serial1; - uart8250_data[1].membase = (void __iomem *) &mace->isa.serial1; + uart8250_data[1].membase = (void __iomem *) &mace->isa.serial2; return platform_device_register(&uart8250_device); } From 1d0a909cfc41f17175023b939b28322e427746b4 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 30 Oct 2007 14:24:51 +0000 Subject: [PATCH 06/25] [MIPS] time: Remove now unused local_timer_interrupt. Signed-off-by: Ralf Baechle --- arch/mips/kernel/time.c | 16 ---------------- include/asm-mips/time.h | 5 ----- 2 files changed, 21 deletions(-) diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 27228f583dae..622379b201aa 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -80,22 +80,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; diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h index 0a6bc7dc158e..a45f24a9ea66 100644 --- a/include/asm-mips/time.h +++ b/include/asm-mips/time.h @@ -48,11 +48,6 @@ extern int (*mips_timer_state)(void); */ extern struct clocksource clocksource_mips; -/* - * profiling and process accouting is done separately in local_timer_interrupt - */ -extern void local_timer_interrupt(int irq, void *dev_id); - /* * board specific routines required by time_init(). */ From d9eec1a5d6ae54b0f7562ffe07008a33ac39e8fe Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 31 Oct 2007 01:21:03 +0900 Subject: [PATCH 07/25] [MIPS] time: Code cleanups * Do not include unnecessary headers. * Do not mention time.README. * Do not mention mips_timer_ack. * Make clocksource_mips static. It is now dedicated to c0_timer. * Initialize clocksource_mips.read statically. * Remove null_hpt_read. * Remove an argument of plat_timer_setup. It is just a placeholder. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/time.c | 57 ++++++++--------------------------------- arch/mips/qemu/q-irq.c | 1 + include/asm-mips/time.h | 13 ---------- 3 files changed, 12 insertions(+), 59 deletions(-) diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 622379b201aa..3284b9b4ecac 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 #include #include -#include #include #include #include -#include #include -#include #include -#include -#include -#include -#include -#include #include #include -#include #include #include -#include - /* * forward reference */ @@ -62,14 +50,6 @@ int update_persistent_clock(struct timespec now) return rtc_mips_set_mmss(now.tv_sec); } -/* - * 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. */ @@ -104,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; @@ -146,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; @@ -187,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; @@ -211,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(); } @@ -220,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(); @@ -242,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(); } diff --git a/arch/mips/qemu/q-irq.c b/arch/mips/qemu/q-irq.c index 4681757460a1..11f984767880 100644 --- a/arch/mips/qemu/q-irq.c +++ b/arch/mips/qemu/q-irq.c @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h index a45f24a9ea66..ee1663e64da1 100644 --- a/include/asm-mips/time.h +++ b/include/asm-mips/time.h @@ -10,15 +10,10 @@ * 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. - * - * Please refer to Documentation/mips/time.README. */ #ifndef _ASM_TIME_H #define _ASM_TIME_H -#include -#include -#include #include #include #include @@ -38,20 +33,12 @@ extern int rtc_mips_set_mmss(unsigned long); /* * Timer interrupt functions. * mips_timer_state is needed for high precision timer calibration. - * mips_timer_ack may be NULL if the interrupt is self-recoverable. */ extern int (*mips_timer_state)(void); -/* - * High precision timer clocksource. - * If .read is NULL, an R4k-compatible timer setup is attempted. - */ -extern struct clocksource clocksource_mips; - /* * board specific routines required by time_init(). */ -struct irqaction; extern void plat_time_init(void); /* From 211a29a87cbde00d8c34fb6d92fc91a87c2c9b47 Mon Sep 17 00:00:00 2001 From: Thiemo Seufer Date: Wed, 31 Oct 2007 16:26:56 +0000 Subject: [PATCH 08/25] [MIPS] Swarm: Fix build failure Signed-off-by: Thiemo Seufer Signed-off-by: Ralf Baechle --- arch/mips/sibyte/sb1250/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index e224fe7715c8..f455ac12a210 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c @@ -155,7 +155,7 @@ void __cpuinit sb1250_clockevent_init(void) action->flags = IRQF_DISABLED | IRQF_PERCPU; action->name = name; action->dev_id = cd; - setup_irq(irq, &action); + setup_irq(irq, action); } /* From faf2782bf3903391936aba0b575fd39b1da10d00 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 00:10:07 +0000 Subject: [PATCH 09/25] [MIPS] Sibyte: Remove blank line. Signed-off-by: Ralf Baechle --- arch/mips/sibyte/bcm1480/irq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index 5f4f9b491586..e28d626255a3 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c @@ -293,7 +293,6 @@ void __init init_bcm1480_irqs(void) void __init arch_init_irq(void) { - unsigned int i, cpu; u64 tmp; unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 | From f3f9ad0edcc1b7bf154bb34fe3b3f71e5379c9f0 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 00:24:50 +0000 Subject: [PATCH 10/25] [MIPS] Sibyte: Fixes for oneshot timer mode. Signed-off-by: Ralf Baechle --- arch/mips/sibyte/bcm1480/time.c | 51 ++++++++++++------------- arch/mips/sibyte/sb1250/time.c | 66 +++++++++++++++------------------ 2 files changed, 55 insertions(+), 62 deletions(-) diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c index 39e77d9bd944..2bcaf5419ac1 100644 --- a/arch/mips/sibyte/bcm1480/time.c +++ b/arch/mips/sibyte/bcm1480/time.c @@ -17,13 +17,11 @@ */ #include #include -#include #include -#include #include -#include #include +#include #include #include @@ -45,23 +43,23 @@ static void sibyte_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { unsigned int cpu = smp_processor_id(); - void __iomem *timer_cfg, *timer_init; + void __iomem *cfg, *init; - timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); - timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_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, timer_cfg); - __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init); + __raw_writeq(0, cfg); + __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init); __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, - timer_cfg); + cfg); break; case CLOCK_EVT_MODE_ONESHOT: /* Stop the timer until we actually program a shot */ case CLOCK_EVT_MODE_SHUTDOWN: - __raw_writeq(0, timer_cfg); + __raw_writeq(0, cfg); break; case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ @@ -73,30 +71,33 @@ static void sibyte_set_mode(enum clock_event_mode mode, static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd) { unsigned int cpu = smp_processor_id(); - void __iomem *timer_init; - unsigned int cnt; - int res; + void __iomem *cfg, *init; - timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); - cnt = __raw_readq(timer_init); - cnt += delta; - __raw_writeq(cnt, timer_init); - res = ((long)(__raw_readq(timer_init) - cnt ) > 0) ? -ETIME : 0; + cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); - return res; + __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 *timer_cfg; + void __iomem *cfg; + unsigned long tmode; - timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + 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); - /* Reset the timer */ - __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, - timer_cfg); cd->event_handler(cd); return IRQ_HANDLED; @@ -133,7 +134,7 @@ void __cpuinit sb1480_clockevent_init(void) bcm1480_mask_irq(cpu, irq); /* - * Map timer interrupt to IP[4] of this cpu + * Map the timer interrupt to IP[4] of this cpu */ __raw_writeq(IMR_IP4_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index f455ac12a210..24b9c8bad62f 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c @@ -15,33 +15,19 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* - * These are routines to set up and handle interrupts from the - * sb1250 general purpose timer 0. We're using the timer as a - * system clock, so we set it up to run at 100 Hz. On every - * interrupt, we update our idea of what the time of day is, - * then call do_timer() in the architecture-independent kernel - * code to do general bookkeeping (e.g. update jiffies, run - * bottom halves, etc.) - */ #include #include -#include -#include -#include +#include -#include #include -#include #include +#include #include #include #include #include - #define IMR_IP2_VAL K_INT_MAP_I0 #define IMR_IP3_VAL K_INT_MAP_I1 #define IMR_IP4_VAL K_INT_MAP_I2 @@ -49,32 +35,31 @@ #define SB1250_HPT_NUM 3 #define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */ - /* - * The general purpose timer ticks at 1 Mhz independent if + * 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 *timer_cfg, *timer_init; + void __iomem *cfg, *init; - timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); - timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_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) { + switch (mode) { case CLOCK_EVT_MODE_PERIODIC: - __raw_writeq(0, timer_cfg); - __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init); + __raw_writeq(0, cfg); + __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init); __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, - timer_cfg); + cfg); break; case CLOCK_EVT_MODE_ONESHOT: /* Stop the timer until we actually program a shot */ case CLOCK_EVT_MODE_SHUTDOWN: - __raw_writeq(0, timer_cfg); + __raw_writeq(0, cfg); break; case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ @@ -83,18 +68,16 @@ static void sibyte_set_mode(enum clock_event_mode mode, } } -static int -sibyte_next_event(unsigned long delta, struct clock_event_device *evt) +static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd) { unsigned int cpu = smp_processor_id(); - void __iomem *timer_cfg, *timer_init; + void __iomem *cfg, *init; - timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); - timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_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(0, timer_cfg); - __raw_writeq(delta, timer_init); - __raw_writeq(M_SCD_TIMER_ENABLE, timer_cfg); + __raw_writeq(delta - 1, init); + __raw_writeq(M_SCD_TIMER_ENABLE, cfg); return 0; } @@ -103,10 +86,17 @@ 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 */ - ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, - IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); + cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + ____raw_writeq(tmode, cfg); cd->event_handler(cd); @@ -144,7 +134,9 @@ void __cpuinit sb1250_clockevent_init(void) sb1250_mask_irq(cpu, irq); - /* Map the timer interrupt to ip[4] of this cpu */ + /* + * 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))); From 217dd11e9d0442767fa13c9c188be0b92dc93d7e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 01:57:55 +0000 Subject: [PATCH 11/25] [MIPS] Sibyte: Split and move clock code. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 12 +++ arch/mips/kernel/Makefile | 4 + arch/mips/kernel/cevt-bcm1480.c | 149 +++++++++++++++++++++++++++ arch/mips/kernel/cevt-sb1250.c | 148 +++++++++++++++++++++++++++ arch/mips/kernel/csrc-bcm1480.c | 54 ++++++++++ arch/mips/kernel/csrc-sb1250.c | 70 +++++++++++++ arch/mips/sibyte/Kconfig | 14 +++ arch/mips/sibyte/bcm1480/time.c | 160 +---------------------------- arch/mips/sibyte/sb1250/time.c | 176 +------------------------------- 9 files changed, 457 insertions(+), 330 deletions(-) create mode 100644 arch/mips/kernel/cevt-bcm1480.c create mode 100644 arch/mips/kernel/cevt-sb1250.c create mode 100644 arch/mips/kernel/csrc-bcm1480.c create mode 100644 arch/mips/kernel/csrc-sb1250.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 97da953eb5d0..3778c3bbcd28 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -733,15 +733,27 @@ config ARCH_MAY_HAVE_PC_FDC config BOOT_RAW bool +config CEVT_BCM1480 + bool + config CEVT_GT641XX bool config CEVT_R4K bool +config CEVT_SB1250 + bool + config CEVT_TXX9 bool +config CSRC_BCM1480 + bool + +config CSRC_SB1250 + bool + config CFE bool diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 3196509a28d5..b551535b7e48 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 000000000000..21e6d63eb4d1 --- /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 +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#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 000000000000..e2029d0fc39b --- /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 +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#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 000000000000..868745e7184b --- /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 + +#include +#include +#include + +#include +#include +#include +#include + +#include + +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 000000000000..ebb16e668877 --- /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 + +#include +#include +#include + +#include +#include +#include +#include + +#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/sibyte/Kconfig b/arch/mips/sibyte/Kconfig index e8fb880272bd..366b19d33f77 100644 --- a/arch/mips/sibyte/Kconfig +++ b/arch/mips/sibyte/Kconfig @@ -1,5 +1,7 @@ config SIBYTE_SB1250 bool + select CEVT_SB1250 + select CSRC_SB1250 select HW_HAS_PCI select IRQ_CPU select SIBYTE_ENABLE_LDT_IF_PCI @@ -9,6 +11,8 @@ config SIBYTE_SB1250 config SIBYTE_BCM1120 bool + select CEVT_SB1250 + select CSRC_SB1250 select IRQ_CPU select SIBYTE_BCM112X select SIBYTE_HAS_ZBUS_PROFILING @@ -16,6 +20,8 @@ config SIBYTE_BCM1120 config SIBYTE_BCM1125 bool + select CEVT_SB1250 + select CSRC_SB1250 select HW_HAS_PCI select IRQ_CPU select SIBYTE_BCM112X @@ -24,6 +30,8 @@ config SIBYTE_BCM1125 config SIBYTE_BCM1125H bool + select CEVT_SB1250 + select CSRC_SB1250 select HW_HAS_PCI select IRQ_CPU select SIBYTE_BCM112X @@ -33,12 +41,16 @@ config SIBYTE_BCM1125H config SIBYTE_BCM112X bool + select CEVT_SB1250 + select CSRC_SB1250 select IRQ_CPU select SIBYTE_SB1xxx_SOC select SIBYTE_HAS_ZBUS_PROFILING config SIBYTE_BCM1x80 bool + select CEVT_BCM1480 + select CSRC_BCM1480 select HW_HAS_PCI select IRQ_CPU select SIBYTE_HAS_ZBUS_PROFILING @@ -47,6 +59,8 @@ config SIBYTE_BCM1x80 config SIBYTE_BCM1x55 bool + select CEVT_BCM1480 + select CSRC_BCM1480 select HW_HAS_PCI select IRQ_CPU select SIBYTE_SB1xxx_SOC diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c index 2bcaf5419ac1..1680a68952ae 100644 --- a/arch/mips/sibyte/bcm1480/time.c +++ b/arch/mips/sibyte/bcm1480/time.c @@ -15,164 +15,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include -#include +#include -#include -#include -#include - -#include -#include -#include -#include - -#include - - -#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); -} - -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); -} +extern void sb1480_clockevent_init(void); +extern void sb1480_clocksource_init(void); void __init plat_time_init(void) { diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index 24b9c8bad62f..68337bf7a5aa 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c @@ -15,180 +15,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include -#include +#include -#include -#include -#include - -#include -#include -#include -#include - -#define IMR_IP2_VAL K_INT_MAP_I0 -#define IMR_IP3_VAL K_INT_MAP_I1 -#define IMR_IP4_VAL K_INT_MAP_I2 - -#define SB1250_HPT_NUM 3 -#define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */ - -/* - * 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); -} - -/* - * 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); -} +extern void sb1250_clocksource_init(void); +extern void sb1250_clockevent_init(void); void __init plat_time_init(void) { From 07f6169cffdca076ef9a67bd69dd1085dc668618 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 12:16:20 +0000 Subject: [PATCH 12/25] [MIPS] Excite: Fix build error. Signed-off-by: Ralf Baechle --- arch/mips/basler/excite/excite_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/basler/excite/excite_setup.c b/arch/mips/basler/excite/excite_setup.c index 24378b9223f9..6dd8f0d46d09 100644 --- a/arch/mips/basler/excite/excite_setup.c +++ b/arch/mips/basler/excite/excite_setup.c @@ -77,7 +77,7 @@ int titan_irqflags; void __init plat_time_init(void) { const u32 modebit5 = ocd_readl(0x00e4); - unsigned int mult = ((modebit5 >> 11) & 0x1f) + 2, + unsigned int mult = ((modebit5 >> 11) & 0x1f) + 2; unsigned int div = ((modebit5 >> 16) & 0x1f) + 2; if (div == 33) From c8925297e875168a7c08965b4f80b418524fb8ce Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 12:20:51 +0000 Subject: [PATCH 13/25] [MIPS] IP27: Fix build error. Signed-off-by: Ralf Baechle --- arch/mips/sgi-ip27/ip27-timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index dc59c3b708ed..08d45369be45 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -131,7 +131,7 @@ static struct irq_chip rt_irq_type = { static int rt_next_event(unsigned long delta, struct clock_event_device *evt) { unsigned int cpu = smp_processor_id(); - int slice putoslice(cpu); + int slice = cputoslice(cpu); unsigned long cnt; cnt = LOCAL_HUB_L(PI_RT_COUNT); @@ -169,7 +169,7 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id) /* * Ack */ - LOCAL_HUB_S(PI_RT_PEND_A + PI_COUNT_OFFSET * slice, cnt); + LOCAL_HUB_S(PI_RT_PEND_A + PI_COUNT_OFFSET * slice, 0); cd->event_handler(cd); return IRQ_HANDLED; From f5cd9f14e2660e610d8bb99ce723ef098b65ae9c Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 12:22:53 +0000 Subject: [PATCH 14/25] [MIPS] Pb1200: Fix warning. arch/mips/au1000/pb1200/board_setup.c:71: warning: unused variable 'pin_func' Signed-off-by: Ralf Baechle --- arch/mips/au1000/pb1200/board_setup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/mips/au1000/pb1200/board_setup.c b/arch/mips/au1000/pb1200/board_setup.c index 5dbc9868f598..b98bebfa87c6 100644 --- a/arch/mips/au1000/pb1200/board_setup.c +++ b/arch/mips/au1000/pb1200/board_setup.c @@ -68,9 +68,11 @@ void board_reset(void) void __init board_setup(void) { char *argptr = NULL; - u32 pin_func; #if 0 + { + u32 pin_func; + /* Enable PSC1 SYNC for AC97. Normaly done in audio driver, * but it is board specific code, so put it here. */ @@ -81,11 +83,13 @@ void __init board_setup(void) au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */ au_sync(); + } #endif #if defined(CONFIG_I2C_AU1550) { u32 freq0, clksrc; + u32 pin_func; /* Select SMBUS in CPLD */ bcsr->resets &= ~(BCSR_RESETS_PCS0MUX); From db0c19e1a6abd9a9bdbf3ffbabc1e8e4995cb462 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 12:59:18 +0000 Subject: [PATCH 15/25] [MIPS] Pb1200: Fix warning. arch/mips/au1000/pb1200/irqmap.c:101: warning: ignoring return value of 'request_irq', declared with attribute warn_unused_result And while at it a few coding style cleanups. Signed-off-by: Ralf Baechle --- arch/mips/au1000/pb1200/irqmap.c | 100 +++++++++++++++++-------------- 1 file changed, 56 insertions(+), 44 deletions(-) diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c index bdf00e2a35e4..c096be4ed4e7 100644 --- a/arch/mips/au1000/pb1200/irqmap.c +++ b/arch/mips/au1000/pb1200/irqmap.c @@ -94,51 +94,41 @@ inline void pb1200_disable_irq(unsigned int irq_nr) bcsr->intclr = 1<<(irq_nr - PB1200_INT_BEGIN); } -static unsigned int pb1200_startup_irq( unsigned int irq_nr ) +static unsigned int pb1200_setup_cascade(void) { - if (++pb1200_cascade_en == 1) - { - request_irq(AU1000_GPIO_7, &pb1200_cascade_handler, - 0, "Pb1200 Cascade", (void *)&pb1200_cascade_handler ); -#ifdef CONFIG_MIPS_PB1200 - /* We have a problem with CPLD rev3. Enable a workaround */ - if( ((bcsr->whoami & BCSR_WHOAMI_CPLD)>>4) <= 3) - { - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("Pb1200 must be at CPLD rev4. Please have Pb1200\n"); - printk("updated to latest revision. This software will not\n"); - printk("work on anything less than CPLD rev4\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - while(1); - } -#endif - } - pb1200_enable_irq(irq_nr); + int err; + + err = request_irq(AU1000_GPIO_7, &pb1200_cascade_handler, + 0, "Pb1200 Cascade", &pb1200_cascade_handler); + if (err) + return err; + return 0; } -static void pb1200_shutdown_irq( unsigned int irq_nr ) +static unsigned int pb1200_startup_irq(unsigned int irq) { - pb1200_disable_irq(irq_nr); - if (--pb1200_cascade_en == 0) - { - free_irq(AU1000_GPIO_7, &pb1200_cascade_handler ); + if (++pb1200_cascade_en == 1) { + int res; + + res = pb1200_setup_cascade(); + if (res) + return res; } - return; + + pb1200_enable_irq(irq); + + return 0; } -static struct irq_chip external_irq_type = +static void pb1200_shutdown_irq(unsigned int irq) { + pb1200_disable_irq(irq); + if (--pb1200_cascade_en == 0) + free_irq(AU1000_GPIO_7, &pb1200_cascade_handler); +} + +static struct irq_chip external_irq_type = { #ifdef CONFIG_MIPS_PB1200 .name = "Pb1200 Ext", #endif @@ -155,16 +145,38 @@ static struct irq_chip external_irq_type = void _board_init_irq(void) { - int irq_nr; + unsigned int irq; - for (irq_nr = PB1200_INT_BEGIN; irq_nr <= PB1200_INT_END; irq_nr++) - { - set_irq_chip_and_handler(irq_nr, &external_irq_type, +#ifdef CONFIG_MIPS_PB1200 + /* We have a problem with CPLD rev3. Enable a workaround */ + if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 3) { + printk("\nWARNING!!!\n"); + printk("\nWARNING!!!\n"); + printk("\nWARNING!!!\n"); + printk("\nWARNING!!!\n"); + printk("\nWARNING!!!\n"); + printk("\nWARNING!!!\n"); + printk("Pb1200 must be at CPLD rev4. Please have Pb1200\n"); + printk("updated to latest revision. This software will not\n"); + printk("work on anything less than CPLD rev4\n"); + printk("\nWARNING!!!\n"); + printk("\nWARNING!!!\n"); + printk("\nWARNING!!!\n"); + printk("\nWARNING!!!\n"); + printk("\nWARNING!!!\n"); + printk("\nWARNING!!!\n"); + panic("Game over. Your score is 0."); + } +#endif + + for (irq = PB1200_INT_BEGIN; irq <= PB1200_INT_END; irq++) { + set_irq_chip_and_handler(irq, &external_irq_type, handle_level_irq); - pb1200_disable_irq(irq_nr); + pb1200_disable_irq(irq); } - /* GPIO_7 can not be hooked here, so it is hooked upon first - request of any source attached to the cascade */ + /* + * GPIO_7 can not be hooked here, so it is hooked upon first + * request of any source attached to the cascade + */ } - From 9aa4cc11b22ec447b42c5df03fdab5eb748971e2 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Thu, 1 Nov 2007 21:51:23 +0900 Subject: [PATCH 16/25] [MIPS] Cobalt: Fix IRQ comment; the Cobalt kernel uses CP0 counter now. Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- include/asm-mips/mach-cobalt/irq.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/asm-mips/mach-cobalt/irq.h b/include/asm-mips/mach-cobalt/irq.h index 179d0e850b59..57c8c9ac5851 100644 --- a/include/asm-mips/mach-cobalt/irq.h +++ b/include/asm-mips/mach-cobalt/irq.h @@ -35,7 +35,7 @@ * 4 - ethernet * 5 - 16550 UART * 6 - cascade i8259 - * 7 - CP0 counter (unused) + * 7 - CP0 counter */ #define MIPS_CPU_IRQ_BASE 16 @@ -48,7 +48,6 @@ #define SCSI_IRQ (MIPS_CPU_IRQ_BASE + 5) #define I8259_CASCADE_IRQ (MIPS_CPU_IRQ_BASE + 6) - #define GT641XX_IRQ_BASE 24 #include From dd3db6eb0e47b4480eeea30394d19bd826e64964 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 14:38:20 +0000 Subject: [PATCH 17/25] [MIPS] i8253: Cleanup. Signed-off-by: Ralf Baechle --- arch/mips/kernel/i8253.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c index 5d9830df3595..a925abd8d29e 100644 --- a/arch/mips/kernel/i8253.c +++ b/arch/mips/kernel/i8253.c @@ -12,6 +12,7 @@ #include #include #include +#include static DEFINE_SPINLOCK(i8253_lock); @@ -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); + 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(0); + irq0.mask = cpumask_of_cpu(cpu); setup_irq(0, &irq0); } From f6a8cc31aa23318c6c95aabad7f49874fb79e527 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 14:44:57 +0000 Subject: [PATCH 18/25] [MIPS] i8253.h: Remove all i8259 related definitions. Signed-off-by: Ralf Baechle --- include/asm-mips/i8253.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/include/asm-mips/i8253.h b/include/asm-mips/i8253.h index affb32ce4af9..778b2f023905 100644 --- a/include/asm-mips/i8253.h +++ b/include/asm-mips/i8253.h @@ -10,21 +10,6 @@ #define PIT_CH0 0x40 #define PIT_CH2 0x42 -/* i8259A PIC registers */ -#define PIC_MASTER_CMD 0x20 -#define PIC_MASTER_IMR 0x21 -#define PIC_MASTER_ISR PIC_MASTER_CMD -#define PIC_MASTER_POLL PIC_MASTER_ISR -#define PIC_MASTER_OCW3 PIC_MASTER_ISR -#define PIC_SLAVE_CMD 0xa0 -#define PIC_SLAVE_IMR 0xa1 - -/* i8259A PIC related value */ -#define PIC_CASCADE_IR 2 -#define MASTER_ICW4_DEFAULT 0x01 -#define SLAVE_ICW4_DEFAULT 0x01 -#define PIC_ICW4_AEOI 2 - extern void setup_pit_timer(void); #endif /* __ASM_I8253_H */ From c9294022af5022584756d67164e68dba0be9302b Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Thu, 1 Nov 2007 11:36:42 +0100 Subject: [PATCH 19/25] [MIPS] SNI: register a02r clockevent; don't use PIT timer Register A20R clockevent. Remove PIT timer setup because it doesn't work Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle --- arch/mips/sni/time.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c index 60bc62ef0935..6f339af08d22 100644 --- a/arch/mips/sni/time.c +++ b/arch/mips/sni/time.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -80,7 +81,7 @@ static void __init sni_a20r_timer_setup(void) unsigned int cpu = smp_processor_id(); cd->cpumask = cpumask_of_cpu(cpu); - + clockevents_register_device(cd); action->dev_id = cd; setup_irq(SNI_A20R_IRQ_TIMER, &a20r_irqaction); } @@ -169,8 +170,6 @@ void __init plat_time_init(void) mips_hpt_frequency = r4k_tick * HZ; - setup_pit_timer(); - switch (sni_brd_type) { case SNI_BRD_10: case SNI_BRD_10NEW: From 72fc19ff51cc32fe85ddb085cb0622b7b97b2158 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 15:45:37 +0000 Subject: [PATCH 20/25] [MIPS] Fix and cleanup the MIPS part of the (ab)use of CLOCK_TICK_RATE. This is the clock rate of the i8253 PIT. A MIPS system may not have a PIT by the symbol is used all over the kernel including some APIs. So keeping it defined to the number for the PIT is the only sane thing for now. Signed-off-by: Ralf Baechle --- include/asm-mips/mach-au1x00/timex.h | 13 ------------- include/asm-mips/mach-generic/timex.h | 13 ------------- include/asm-mips/mach-jazz/timex.h | 16 ---------------- include/asm-mips/mach-qemu/timex.h | 16 ---------------- include/asm-mips/mach-rm/timex.h | 13 ------------- include/asm-mips/timex.h | 25 +++++-------------------- 6 files changed, 5 insertions(+), 91 deletions(-) delete mode 100644 include/asm-mips/mach-au1x00/timex.h delete mode 100644 include/asm-mips/mach-generic/timex.h delete mode 100644 include/asm-mips/mach-jazz/timex.h delete mode 100644 include/asm-mips/mach-qemu/timex.h delete mode 100644 include/asm-mips/mach-rm/timex.h diff --git a/include/asm-mips/mach-au1x00/timex.h b/include/asm-mips/mach-au1x00/timex.h deleted file mode 100644 index e3ada66cb636..000000000000 --- a/include/asm-mips/mach-au1x00/timex.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2003 by Ralf Baechle - */ -#ifndef __ASM_MACH_AU1X00_TIMEX_H -#define __ASM_MACH_AU1X00_TIMEX_H - -#define CLOCK_TICK_RATE ((HZ * 100000UL) / 2) - -#endif /* __ASM_MACH_AU1X00_TIMEX_H */ diff --git a/include/asm-mips/mach-generic/timex.h b/include/asm-mips/mach-generic/timex.h deleted file mode 100644 index 48b4cfaa0d50..000000000000 --- a/include/asm-mips/mach-generic/timex.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2003, 2005 by Ralf Baechle - */ -#ifndef __ASM_MACH_GENERIC_TIMEX_H -#define __ASM_MACH_GENERIC_TIMEX_H - -#define CLOCK_TICK_RATE 500000 - -#endif /* __ASM_MACH_GENERIC_TIMEX_H */ diff --git a/include/asm-mips/mach-jazz/timex.h b/include/asm-mips/mach-jazz/timex.h deleted file mode 100644 index 93affa33dfa8..000000000000 --- a/include/asm-mips/mach-jazz/timex.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2003 by Ralf Baechle - */ -#ifndef __ASM_MACH_JAZZ_TIMEX_H -#define __ASM_MACH_JAZZ_TIMEX_H - -/* - * Jazz is still using the R4030 100Hz counter - */ -#define CLOCK_TICK_RATE 100 - -#endif /* __ASM_MACH_JAZZ_TIMEX_H */ diff --git a/include/asm-mips/mach-qemu/timex.h b/include/asm-mips/mach-qemu/timex.h deleted file mode 100644 index cd543693fb0a..000000000000 --- a/include/asm-mips/mach-qemu/timex.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2005 Daniel Jacobowitz - */ -#ifndef __ASM_MACH_QEMU_TIMEX_H -#define __ASM_MACH_QEMU_TIMEX_H - -/* - * We use a simulated i8254 PIC... - */ -#define CLOCK_TICK_RATE 1193182 - -#endif /* __ASM_MACH_QEMU_TIMEX_H */ diff --git a/include/asm-mips/mach-rm/timex.h b/include/asm-mips/mach-rm/timex.h deleted file mode 100644 index 11ff6cb0f214..000000000000 --- a/include/asm-mips/mach-rm/timex.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2003, 2005 by Ralf Baechle - */ -#ifndef __ASM_MACH_RM200_TIMEX_H -#define __ASM_MACH_RM200_TIMEX_H - -#define CLOCK_TICK_RATE 1193182 - -#endif /* __ASM_MACH_RM200_TIMEX_H */ diff --git a/include/asm-mips/timex.h b/include/asm-mips/timex.h index 87c68ae76ff8..5816ad1569d6 100644 --- a/include/asm-mips/timex.h +++ b/include/asm-mips/timex.h @@ -13,27 +13,12 @@ #include /* - * This is the frequency of the timer used for Linux's timer interrupt. - * The value should be defined as accurate as possible or under certain - * circumstances Linux timekeeping might become inaccurate or fail. - * - * For many system the exact clockrate of the timer isn't known but due to - * the way this value is used we can get away with a wrong value as long - * as this value is: - * - * - a multiple of HZ - * - a divisor of the actual rate - * - * 500000 is a good such cheat value. - * - * The obscure number 1193182 is the same as used by the original i8254 - * time in legacy PC hardware; the chip unfortunately also found in a - * bunch of MIPS systems. The last remaining user of the i8254 for the - * timer interrupt is the RM200; it's a very standard system so there is - * no reason to make this a separate architecture. + * This is the clock rate of the i8253 PIT. A MIPS system may not have + * a PIT by the symbol is used all over the kernel including some APIs. + * So keeping it defined to the number for the PIT is the only sane thing + * for now. */ - -#include +#define CLOCK_TICK_RATE 1193182 /* * Standard way to access the cycle counter. From ae11e3214b0ecfcb2dd2536aab68e8d3834d5c5b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 16:46:14 +0000 Subject: [PATCH 21/25] [MIPS] Pb1200: Enable -Werror. Signed-off-by: Ralf Baechle --- arch/mips/au1000/pb1200/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/mips/au1000/pb1200/Makefile b/arch/mips/au1000/pb1200/Makefile index 22b673cf55af..970b1b1d5cda 100644 --- a/arch/mips/au1000/pb1200/Makefile +++ b/arch/mips/au1000/pb1200/Makefile @@ -3,3 +3,5 @@ # lib-y := init.o board_setup.o irqmap.o + +EXTRA_CFLAGS += -Werror From e7c9d6b927191602cf79ea0183727c7112e79673 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 16:49:12 +0000 Subject: [PATCH 22/25] [MIPS] mtx-1: Remove unused mtx1_sys_btn. Signed-off-by: Ralf Baechle --- arch/mips/au1000/mtx-1/platform.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/arch/mips/au1000/mtx-1/platform.c b/arch/mips/au1000/mtx-1/platform.c index 01ebff677978..49c0fb409fea 100644 --- a/arch/mips/au1000/mtx-1/platform.c +++ b/arch/mips/au1000/mtx-1/platform.c @@ -34,15 +34,6 @@ static struct resource mtx1_wdt_res[] = { } }; -static struct resource mtx1_sys_btn[] = { - [0] = { - .start = 7, - .end = 7, - .name = "mtx1-sys-btn-gpio", - .flags = IORESOURCE_IRQ, - } -}; - static struct platform_device mtx1_wdt = { .name = "mtx1-wdt", .id = 0, From 9603a23d3b28bc1d52492a927d8256f8c46e8f41 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 16:50:06 +0000 Subject: [PATCH 23/25] [MIPS] mtx-1: Enable -Werror. Signed-off-by: Ralf Baechle --- arch/mips/au1000/mtx-1/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/mips/au1000/mtx-1/Makefile b/arch/mips/au1000/mtx-1/Makefile index afa7007d67f7..85a90941de4f 100644 --- a/arch/mips/au1000/mtx-1/Makefile +++ b/arch/mips/au1000/mtx-1/Makefile @@ -9,3 +9,5 @@ lib-y := init.o board_setup.o irqmap.o obj-y := platform.o + +EXTRA_CFLAGS += -Werror From 651194f82066ba3688630b5a0d79d13d26a7ccbb Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 1 Nov 2007 21:55:39 +0000 Subject: [PATCH 24/25] [MIPS] Bigsur supports highmem. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3778c3bbcd28..2c7d6c240b73 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -546,6 +546,7 @@ config SIBYTE_BIGSUR select SWAP_IO_SPACE select SYS_HAS_CPU_SB1 select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_HIGHMEM select SYS_SUPPORTS_LITTLE_ENDIAN config SNI_RM From 3be51f70e1f5e11a723d28b3dde26bc3aacdbc71 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Fri, 2 Nov 2007 11:17:13 +0100 Subject: [PATCH 25/25] [MIPS] Jazz: disable PIT; cleanup R4030 clockevent Fix ISA irq acknowledge. Make r4030 clockevent code look like other mips clockevent code. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle --- arch/mips/jazz/irq.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c index ae25b480723e..d7f8a782aae4 100644 --- a/arch/mips/jazz/irq.c +++ b/arch/mips/jazz/irq.c @@ -97,9 +97,10 @@ asmlinkage void plat_irq_dispatch(void) if (pending & IE_IRQ4) { r4030_read_reg32(JAZZ_TIMER_REGISTER); do_IRQ(JAZZ_TIMER_IRQ); - } else if (pending & IE_IRQ2) - do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK)); - else if (pending & IE_IRQ1) { + } else if (pending & IE_IRQ2) { + irq = *(volatile u8 *)JAZZ_EISA_IRQ_ACK; + do_IRQ(irq); + } else if (pending & IE_IRQ1) { irq = *(volatile u8 *)JAZZ_IO_IRQ_SOURCE >> 2; if (likely(irq > 0)) do_IRQ(irq + JAZZ_IRQ_START - 1); @@ -117,16 +118,16 @@ static void r4030_set_mode(enum clock_event_mode mode, struct clock_event_device r4030_clockevent = { .name = "r4030", .features = CLOCK_EVT_FEAT_PERIODIC, - .rating = 100, + .rating = 300, .irq = JAZZ_TIMER_IRQ, - .cpumask = CPU_MASK_CPU0, .set_mode = r4030_set_mode, }; static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id) { - r4030_clockevent.event_handler(&r4030_clockevent); + struct clock_event_device *cd = dev_id; + cd->event_handler(cd); return IRQ_HANDLED; } @@ -134,15 +135,22 @@ static struct irqaction r4030_timer_irqaction = { .handler = r4030_timer_interrupt, .flags = IRQF_DISABLED, .mask = CPU_MASK_CPU0, - .name = "timer", + .name = "R4030 timer", }; void __init plat_time_init(void) { - struct irqaction *irq = &r4030_timer_irqaction; + struct clock_event_device *cd = &r4030_clockevent; + struct irqaction *action = &r4030_timer_irqaction; + unsigned int cpu = smp_processor_id(); BUG_ON(HZ != 100); + cd->cpumask = cpumask_of_cpu(cpu); + clockevents_register_device(cd); + action->dev_id = cd; + setup_irq(JAZZ_TIMER_IRQ, action); + /* * Set clock to 100Hz. * @@ -150,8 +158,5 @@ void __init plat_time_init(void) * a programmable 4-bit divider. This makes it fairly inflexible. */ r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9); - setup_irq(JAZZ_TIMER_IRQ, irq); - - clockevents_register_device(&r4030_clockevent); setup_pit_timer(); }