From 417528a2e35f46bc42721de5c4efd33a0eba019d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Nov 2006 11:18:30 +0900 Subject: sh: Configurable timer IRQ. All of the various CPU subtypes currently hardcode TIMER_IRQ, switch this to a config option in the few places we need this. This allows further removal of hardcoded IRQ headers.. Signed-off-by: Paul Mundt --- arch/sh/kernel/timers/timer-tmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh/kernel/timers/timer-tmu.c') diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index 24927015dc3..06a70db7386 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c @@ -149,7 +149,7 @@ static int tmu_timer_init(void) { unsigned long interval; - setup_irq(TIMER_IRQ, &tmu_irq); + setup_irq(CONFIG_SH_TIMER_IRQ, &tmu_irq); tmu0_clk.parent = clk_get("module_clk"); -- cgit v1.2.3-70-g09d2 From e74b56800e78a10bc09b56a87831876a1d9d09ae Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 1 Dec 2006 13:12:05 +0900 Subject: sh: Turn off IRQs around get_timer_offset() calls. Since all of the sys_timer sources currently do this on their own within the ->get_offset() path, it's more sensible to just have the caller take care of it when grabbing xtime_lock. Incidentally, this is more in line with what others (ie, ARM) are doing already. Signed-off-by: Paul Mundt --- arch/sh/kernel/time.c | 13 +++++++++---- arch/sh/kernel/timers/timer-cmt.c | 9 +-------- arch/sh/kernel/timers/timer-mtu2.c | 10 +--------- arch/sh/kernel/timers/timer-tmu.c | 9 +-------- 4 files changed, 12 insertions(+), 29 deletions(-) (limited to 'arch/sh/kernel/timers/timer-tmu.c') diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index 57e708d7b52..c55d6f217a4 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -50,15 +50,20 @@ unsigned long long __attribute__ ((weak)) sched_clock(void) #ifndef CONFIG_GENERIC_TIME void do_gettimeofday(struct timeval *tv) { + unsigned long flags; unsigned long seq; unsigned long usec, sec; do { - seq = read_seqbegin(&xtime_lock); + /* + * Turn off IRQs when grabbing xtime_lock, so that + * the sys_timer get_offset code doesn't have to handle it. + */ + seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = get_timer_offset(); sec = xtime.tv_sec; - usec += xtime.tv_nsec / 1000; - } while (read_seqretry(&xtime_lock, seq)); + usec += xtime.tv_nsec / NSEC_PER_USEC; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); while (usec >= 1000000) { usec -= 1000000; @@ -85,7 +90,7 @@ int do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ - nsec -= 1000 * get_timer_offset(); + nsec -= get_timer_offset() * NSEC_PER_USEC; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c index 24b03996da5..95581dccbbf 100644 --- a/arch/sh/kernel/timers/timer-cmt.c +++ b/arch/sh/kernel/timers/timer-cmt.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -46,13 +45,9 @@ #error "Unknown CPU SUBTYPE" #endif -static DEFINE_SPINLOCK(cmt0_lock); - static unsigned long cmt_timer_get_offset(void) { int count; - unsigned long flags; - static unsigned short count_p = 0xffff; /* for the first call after boot */ static unsigned long jiffies_p = 0; @@ -61,7 +56,6 @@ static unsigned long cmt_timer_get_offset(void) */ unsigned long jiffies_t; - spin_lock_irqsave(&cmt0_lock, flags); /* timer count may underflow right here */ count = ctrl_inw(CMT_CMCOR_0); count -= ctrl_inw(CMT_CMCNT_0); @@ -88,7 +82,6 @@ static unsigned long cmt_timer_get_offset(void) jiffies_p = jiffies_t; count_p = count; - spin_unlock_irqrestore(&cmt0_lock, flags); count = ((LATCH-1) - count) * TICK_SIZE; count = (count + LATCH/2) / LATCH; @@ -122,7 +115,7 @@ static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id) static struct irqaction cmt_irq = { .name = "timer", .handler = cmt_timer_interrupt, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED | IRQF_TIMER, .mask = CPU_MASK_NONE, }; diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c index 92c98b5b11e..201f0a62132 100644 --- a/arch/sh/kernel/timers/timer-mtu2.c +++ b/arch/sh/kernel/timers/timer-mtu2.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -28,9 +27,6 @@ * However, we can implement channel cascade if we go the overflow route and * get away with using 2 MTU2 channels as a 32-bit timer. */ - -static DEFINE_SPINLOCK(mtu2_lock); - #define MTU2_TSTR 0xfffe4280 #define MTU2_TCR_1 0xfffe4380 #define MTU2_TMDR_1 0xfffe4381 @@ -55,8 +51,6 @@ static DEFINE_SPINLOCK(mtu2_lock); static unsigned long mtu2_timer_get_offset(void) { int count; - unsigned long flags; - static int count_p = 0x7fff; /* for the first call after boot */ static unsigned long jiffies_p = 0; @@ -65,7 +59,6 @@ static unsigned long mtu2_timer_get_offset(void) */ unsigned long jiffies_t; - spin_lock_irqsave(&mtu2_lock, flags); /* timer count may underflow right here */ count = ctrl_inw(MTU2_TCNT_1); /* read the latched count */ @@ -90,7 +83,6 @@ static unsigned long mtu2_timer_get_offset(void) jiffies_p = jiffies_t; count_p = count; - spin_unlock_irqrestore(&mtu2_lock, flags); count = ((LATCH-1) - count) * TICK_SIZE; count = (count + LATCH/2) / LATCH; @@ -118,7 +110,7 @@ static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id) static struct irqaction mtu2_irq = { .name = "timer", .handler = mtu2_timer_interrupt, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED | IRQF_TIMER, .mask = CPU_MASK_NONE, }; diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index 06a70db7386..b9ed8a38755 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -31,13 +30,9 @@ #define TMU0_TCR_CALIB 0x0000 -static DEFINE_SPINLOCK(tmu0_lock); - static unsigned long tmu_timer_get_offset(void) { int count; - unsigned long flags; - static int count_p = 0x7fffffff; /* for the first call after boot */ static unsigned long jiffies_p = 0; @@ -46,7 +41,6 @@ static unsigned long tmu_timer_get_offset(void) */ unsigned long jiffies_t; - spin_lock_irqsave(&tmu0_lock, flags); /* timer count may underflow right here */ count = ctrl_inl(TMU0_TCNT); /* read the latched count */ @@ -72,7 +66,6 @@ static unsigned long tmu_timer_get_offset(void) jiffies_p = jiffies_t; count_p = count; - spin_unlock_irqrestore(&tmu0_lock, flags); count = ((LATCH-1) - count) * TICK_SIZE; count = (count + LATCH/2) / LATCH; @@ -106,7 +99,7 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dummy) static struct irqaction tmu_irq = { .name = "timer", .handler = tmu_timer_interrupt, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED | IRQF_TIMER, .mask = CPU_MASK_NONE, }; -- cgit v1.2.3-70-g09d2 From 1d118562c2067a42d0e8f70671a4ce27d7c6ffee Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 1 Dec 2006 13:15:14 +0900 Subject: sh: Clock framework tidying. This syncs up the SH clock framework with the linux/clk.h API, for which there were only some minor changes required, namely the clk_get() dev_id and subsequent callsites. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock.c | 27 +++++++++++++++++++++++++-- arch/sh/kernel/cpu/sh3/clock-sh7709.c | 2 +- arch/sh/kernel/cpu/sh4/clock-sh4-202.c | 4 ++-- arch/sh/kernel/cpu/sh4/clock-sh7780.c | 2 +- arch/sh/kernel/timers/timer-cmt.c | 4 ++-- arch/sh/kernel/timers/timer-mtu2.c | 2 +- arch/sh/kernel/timers/timer-tmu.c | 2 +- drivers/serial/sh-sci.c | 6 +++--- include/asm-sh/clock.h | 12 ++---------- 9 files changed, 38 insertions(+), 23 deletions(-) (limited to 'arch/sh/kernel/timers/timer-tmu.c') diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 51ec64cdf34..abb586b1256 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -5,9 +5,11 @@ * * This clock framework is derived from the OMAP version by: * - * Copyright (C) 2004 Nokia Corporation + * Copyright (C) 2004 - 2005 Nokia Corporation * Written by Tuukka Tikkanen * + * Modified for omap shared clock framework by Tony Lindgren + * * 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. @@ -20,6 +22,7 @@ #include #include #include +#include #include #include @@ -195,17 +198,37 @@ void clk_recalc_rate(struct clk *clk) propagate_rate(clk); } -struct clk *clk_get(const char *id) +/* + * Returns a clock. Note that we first try to use device id on the bus + * and clock name. If this fails, we try to use clock name only. + */ +struct clk *clk_get(struct device *dev, const char *id) { struct clk *p, *clk = ERR_PTR(-ENOENT); + int idno; + + if (dev == NULL || dev->bus != &platform_bus_type) + idno = -1; + else + idno = to_platform_device(dev)->id; mutex_lock(&clock_list_sem); + list_for_each_entry(p, &clock_list, node) { + if (p->id == idno && + strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + clk = p; + goto found; + } + } + list_for_each_entry(p, &clock_list, node) { if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { clk = p; break; } } + +found: mutex_unlock(&clock_list_sem); return clk; diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7709.c b/arch/sh/kernel/cpu/sh3/clock-sh7709.c index 10461a745e5..b791a29fdb6 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh7709.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh7709.c @@ -24,7 +24,7 @@ static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 }; static void set_bus_parent(struct clk *clk) { - struct clk *bus_clk = clk_get("bus_clk"); + struct clk *bus_clk = clk_get(NULL, "bus_clk"); clk->parent = bus_clk; clk_put(bus_clk); } diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index bfdf5fe8d94..fa2019aabd7 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -97,7 +97,7 @@ static void shoc_clk_recalc(struct clk *clk) static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate) { - struct clk *bclk = clk_get("bus_clk"); + struct clk *bclk = clk_get(NULL, "bus_clk"); unsigned long bclk_rate = clk_get_rate(bclk); clk_put(bclk); @@ -151,7 +151,7 @@ static struct clk *sh4202_onchip_clocks[] = { static int __init sh4202_clk_init(void) { - struct clk *clk = clk_get("master_clk"); + struct clk *clk = clk_get(NULL, "master_clk"); int i; for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) { diff --git a/arch/sh/kernel/cpu/sh4/clock-sh7780.c b/arch/sh/kernel/cpu/sh4/clock-sh7780.c index 93ad367342c..9e6a216750c 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh7780.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh7780.c @@ -98,7 +98,7 @@ static struct clk *sh7780_onchip_clocks[] = { static int __init sh7780_clk_init(void) { - struct clk *clk = clk_get("master_clk"); + struct clk *clk = clk_get(NULL, "master_clk"); int i; for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) { diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c index 95581dccbbf..a574b93a4e7 100644 --- a/arch/sh/kernel/timers/timer-cmt.c +++ b/arch/sh/kernel/timers/timer-cmt.c @@ -124,7 +124,7 @@ static void cmt_clk_init(struct clk *clk) u8 divisor = CMT_CMCSR_INIT & 0x3; ctrl_inw(CMT_CMCSR_0); ctrl_outw(CMT_CMCSR_INIT, CMT_CMCSR_0); - clk->parent = clk_get("module_clk"); + clk->parent = clk_get(NULL, "module_clk"); clk->rate = clk->parent->rate / (8 << (divisor << 1)); } @@ -164,7 +164,7 @@ static int cmt_timer_init(void) setup_irq(CONFIG_SH_TIMER_IRQ, &cmt_irq); - cmt0_clk.parent = clk_get("module_clk"); + cmt0_clk.parent = clk_get(NULL, "module_clk"); cmt_timer_stop(); diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c index 201f0a62132..fffcd1c0987 100644 --- a/arch/sh/kernel/timers/timer-mtu2.c +++ b/arch/sh/kernel/timers/timer-mtu2.c @@ -161,7 +161,7 @@ static int mtu2_timer_init(void) setup_irq(CONFIG_SH_TIMER_IRQ, &mtu2_irq); - mtu2_clk1.parent = clk_get("module_clk"); + mtu2_clk1.parent = clk_get(NULL, "module_clk"); ctrl_outb(ctrl_inb(STBCR3) & (~0x20), STBCR3); diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index b9ed8a38755..e060e71d078 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c @@ -144,7 +144,7 @@ static int tmu_timer_init(void) setup_irq(CONFIG_SH_TIMER_IRQ, &tmu_irq); - tmu0_clk.parent = clk_get("module_clk"); + tmu0_clk.parent = clk_get(NULL, "module_clk"); /* Start TMU0 */ tmu_timer_stop(); diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index cfcc3caf49d..3b5f19ec212 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -775,7 +775,7 @@ static int sci_notifier(struct notifier_block *self, * * Clean this up later.. */ - clk = clk_get("module_clk"); + clk = clk_get(NULL, "module_clk"); port->uartclk = clk_get_rate(clk) * 16; clk_put(clk); } @@ -960,7 +960,7 @@ static void sci_set_termios(struct uart_port *port, struct termios *termios, default: { #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) - struct clk *clk = clk_get("module_clk"); + struct clk *clk = clk_get(NULL, "module_clk"); t = SCBRR_VALUE(baud, clk_get_rate(clk)); clk_put(clk); #else @@ -1128,7 +1128,7 @@ static void __init sci_init_ports(void) * XXX: We should use a proper SCI/SCIF clock */ { - struct clk *clk = clk_get("module_clk"); + struct clk *clk = clk_get(NULL, "module_clk"); sci_ports[i].port.uartclk = clk_get_rate(clk) * 16; clk_put(clk); } diff --git a/include/asm-sh/clock.h b/include/asm-sh/clock.h index fdfb75b30f0..1df92807f8c 100644 --- a/include/asm-sh/clock.h +++ b/include/asm-sh/clock.h @@ -4,6 +4,7 @@ #include #include #include +#include struct clk; @@ -18,7 +19,7 @@ struct clk_ops { struct clk { struct list_head node; const char *name; - + int id; struct module *owner; struct clk *parent; @@ -40,22 +41,13 @@ void arch_init_clk_ops(struct clk_ops **, int type); int clk_init(void); int __clk_enable(struct clk *); -int clk_enable(struct clk *); - void __clk_disable(struct clk *); -void clk_disable(struct clk *); -int clk_set_rate(struct clk *, unsigned long rate); -unsigned long clk_get_rate(struct clk *); void clk_recalc_rate(struct clk *); -struct clk *clk_get(const char *id); -void clk_put(struct clk *); - int clk_register(struct clk *); void clk_unregister(struct clk *); int show_clocks(struct seq_file *m); #endif /* __ASM_SH_CLOCK_H */ - -- cgit v1.2.3-70-g09d2