Commit e0b0f9e4ead2468f84c26332ec42b118e76af572
Committed by
Linus Torvalds
1 parent
4b6aba51fb
Exists in
master
and in
7 other branches
h8300: update timer handler - new files
New timer handler files. Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 6 changed files with 397 additions and 0 deletions Side-by-side Diff
arch/h8300/kernel/timer/Makefile
arch/h8300/kernel/timer/itu.c
1 | +/* | |
2 | + * linux/arch/h8300/kernel/timer/itu.c | |
3 | + * | |
4 | + * Yoshinori Sato <ysato@users.sourcefoge.jp> | |
5 | + * | |
6 | + * ITU Timer Handler | |
7 | + * | |
8 | + */ | |
9 | + | |
10 | +#include <linux/errno.h> | |
11 | +#include <linux/sched.h> | |
12 | +#include <linux/kernel.h> | |
13 | +#include <linux/param.h> | |
14 | +#include <linux/string.h> | |
15 | +#include <linux/mm.h> | |
16 | +#include <linux/interrupt.h> | |
17 | +#include <linux/init.h> | |
18 | +#include <linux/timex.h> | |
19 | + | |
20 | +#include <asm/segment.h> | |
21 | +#include <asm/io.h> | |
22 | +#include <asm/irq.h> | |
23 | +#include <asm/regs306x.h> | |
24 | + | |
25 | +#if CONFIG_H8300_ITU_CH == 0 | |
26 | +#define ITUBASE 0xffff64 | |
27 | +#define ITUIRQ 24 | |
28 | +#elif CONFIG_H8300_ITU_CH == 1 | |
29 | +#define ITUBASE 0xffff6e | |
30 | +#define ITUIRQ 28 | |
31 | +#elif CONFIG_H8300_ITU_CH == 2 | |
32 | +#define ITUBASE 0xffff78 | |
33 | +#define ITUIRQ 32 | |
34 | +#elif CONFIG_H8300_ITU_CH == 3 | |
35 | +#define ITUBASE 0xffff82 | |
36 | +#define ITUIRQ 36 | |
37 | +#elif CONFIG_H8300_ITU_CH == 4 | |
38 | +#define ITUBASE 0xffff92 | |
39 | +#define ITUIRQ 40 | |
40 | +#else | |
41 | +#error Unknown timer channel. | |
42 | +#endif | |
43 | + | |
44 | +#define TCR 0 | |
45 | +#define TIOR 1 | |
46 | +#define TIER 2 | |
47 | +#define TSR 3 | |
48 | +#define TCNT 4 | |
49 | +#define GRA 6 | |
50 | +#define GRB 8 | |
51 | + | |
52 | +static irqreturn_t timer_interrupt(int irq, void *dev_id) | |
53 | +{ | |
54 | + h8300_timer_tick(); | |
55 | + ctrl_bclr(IMFA, ITUBASE + TSR); | |
56 | + return IRQ_HANDLED; | |
57 | +} | |
58 | + | |
59 | +static struct irqaction itu_irq = { | |
60 | + .name = "itu", | |
61 | + .handler = timer_interrupt, | |
62 | + .flags = IRQF_DISABLED | IRQF_TIMER, | |
63 | + .mask = CPU_MASK_NONE, | |
64 | +}; | |
65 | + | |
66 | +static const int __initdata divide_rate[] = {1, 2, 4, 8}; | |
67 | + | |
68 | +void __init h8300_timer_setup(void) | |
69 | +{ | |
70 | + unsigned int div; | |
71 | + unsigned int cnt; | |
72 | + | |
73 | + calc_param(cnt, div, divide_rate, 0x10000); | |
74 | + | |
75 | + setup_irq(ITUIRQ, &itu_irq); | |
76 | + | |
77 | + /* initalize timer */ | |
78 | + ctrl_outb(0, TSTR); | |
79 | + ctrl_outb(CCLR0 | div, ITUBASE + TCR); | |
80 | + ctrl_outb(0x01, ITUBASE + TIER); | |
81 | + ctrl_outw(cnt, ITUBASE + GRA); | |
82 | + ctrl_bset(CONFIG_H8300_ITU_CH, TSTR); | |
83 | +} |
arch/h8300/kernel/timer/timer16.c
1 | +/* | |
2 | + * linux/arch/h8300/kernel/timer/timer16.c | |
3 | + * | |
4 | + * Yoshinori Sato <ysato@users.sourcefoge.jp> | |
5 | + * | |
6 | + * 16bit Timer Handler | |
7 | + * | |
8 | + */ | |
9 | + | |
10 | +#include <linux/errno.h> | |
11 | +#include <linux/sched.h> | |
12 | +#include <linux/kernel.h> | |
13 | +#include <linux/param.h> | |
14 | +#include <linux/string.h> | |
15 | +#include <linux/mm.h> | |
16 | +#include <linux/interrupt.h> | |
17 | +#include <linux/init.h> | |
18 | +#include <linux/timex.h> | |
19 | + | |
20 | +#include <asm/segment.h> | |
21 | +#include <asm/io.h> | |
22 | +#include <asm/irq.h> | |
23 | +#include <asm/regs306x.h> | |
24 | + | |
25 | +/* 16bit timer */ | |
26 | +#if CONFIG_H8300_TIMER16_CH == 0 | |
27 | +#define _16BASE 0xffff78 | |
28 | +#define _16IRQ 24 | |
29 | +#elif CONFIG_H8300_TIMER16_CH == 1 | |
30 | +#define _16BASE 0xffff80 | |
31 | +#define _16IRQ 28 | |
32 | +#elif CONFIG_H8300_TIMER16_CH == 2 | |
33 | +#define _16BASE 0xffff88 | |
34 | +#define _16IRQ 32 | |
35 | +#else | |
36 | +#error Unknown timer channel. | |
37 | +#endif | |
38 | + | |
39 | +#define TCR 0 | |
40 | +#define TIOR 1 | |
41 | +#define TCNT 2 | |
42 | +#define GRA 4 | |
43 | +#define GRB 6 | |
44 | + | |
45 | +#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*10000 /* Timer input freq. */ | |
46 | + | |
47 | +static irqreturn_t timer_interrupt(int irq, void *dev_id) | |
48 | +{ | |
49 | + h8300_timer_tick(); | |
50 | + ctrl_bclr(CONFIG_H8300_TIMER16_CH, TISRA); | |
51 | + return IRQ_HANDLED; | |
52 | +} | |
53 | + | |
54 | +static struct irqaction timer16_irq = { | |
55 | + .name = "timer-16", | |
56 | + .handler = timer_interrupt, | |
57 | + .flags = IRQF_DISABLED | IRQF_TIMER, | |
58 | + .mask = CPU_MASK_NONE, | |
59 | +}; | |
60 | + | |
61 | +static const int __initdata divide_rate[] = {1, 2, 4, 8}; | |
62 | + | |
63 | +void __init h8300_timer_setup(void) | |
64 | +{ | |
65 | + unsigned int div; | |
66 | + unsigned int cnt; | |
67 | + | |
68 | + calc_param(cnt, div, divide_rate, 0x10000); | |
69 | + | |
70 | + setup_irq(_16IRQ, &timer16_irq); | |
71 | + | |
72 | + /* initalize timer */ | |
73 | + ctrl_outb(0, TSTR); | |
74 | + ctrl_outb(CCLR0 | div, _16BASE + TCR); | |
75 | + ctrl_outw(cnt, _16BASE + GRA); | |
76 | + ctrl_bset(4 + CONFIG_H8300_TIMER16_CH, TISRA); | |
77 | + ctrl_bset(CONFIG_H8300_TIMER16_CH, TSTR); | |
78 | +} |
arch/h8300/kernel/timer/timer8.c
1 | +/* | |
2 | + * linux/arch/h8300/kernel/cpu/timer/timer8.c | |
3 | + * | |
4 | + * Yoshinori Sato <ysato@users.sourcefoge.jp> | |
5 | + * | |
6 | + * 8bit Timer Handler | |
7 | + * | |
8 | + */ | |
9 | + | |
10 | +#include <linux/errno.h> | |
11 | +#include <linux/sched.h> | |
12 | +#include <linux/kernel.h> | |
13 | +#include <linux/param.h> | |
14 | +#include <linux/string.h> | |
15 | +#include <linux/mm.h> | |
16 | +#include <linux/interrupt.h> | |
17 | +#include <linux/init.h> | |
18 | +#include <linux/profile.h> | |
19 | + | |
20 | +#include <asm/io.h> | |
21 | +#include <asm/irq.h> | |
22 | +#include <asm/timer.h> | |
23 | +#if defined(CONFIG_CPU_H8300H) | |
24 | +#include <asm/regs306x.h> | |
25 | +#endif | |
26 | +#if defined(CONFIG_CPU_H8S) | |
27 | +#include <asm/regs267x.h> | |
28 | +#endif | |
29 | + | |
30 | +/* 8bit timer x2 */ | |
31 | +#define CMFA 6 | |
32 | + | |
33 | +#if defined(CONFIG_H8300_TIMER8_CH0) | |
34 | +#define _8BASE _8TCR0 | |
35 | +#ifdef CONFIG_CPU_H8300H | |
36 | +#define _8IRQ 36 | |
37 | +#endif | |
38 | +#ifdef CONFIG_CPU_H8S | |
39 | +#define _8IRQ 72 | |
40 | +#endif | |
41 | +#elif defined(CONFIG_H8300_TIMER8_CH2) | |
42 | +#ifdef CONFIG_CPU_H8300H | |
43 | +#define _8BASE _8TCR2 | |
44 | +#define _8IRQ 40 | |
45 | +#endif | |
46 | +#endif | |
47 | + | |
48 | +#ifndef _8BASE | |
49 | +#error Unknown timer channel. | |
50 | +#endif | |
51 | + | |
52 | +#define _8TCR 0 | |
53 | +#define _8TCSR 2 | |
54 | +#define TCORA 4 | |
55 | +#define TCORB 6 | |
56 | +#define _8TCNT 8 | |
57 | + | |
58 | +#define CMIEA 0x40 | |
59 | +#define CCLR_CMA 0x08 | |
60 | +#define CKS2 0x04 | |
61 | + | |
62 | +/* | |
63 | + * timer_interrupt() needs to keep up the real-time clock, | |
64 | + * as well as call the "do_timer()" routine every clocktick | |
65 | + */ | |
66 | + | |
67 | +static irqreturn_t timer_interrupt(int irq, void *dev_id) | |
68 | +{ | |
69 | + h8300_timer_tick(); | |
70 | + ctrl_bclr(CMFA, _8BASE + _8TCSR); | |
71 | + return IRQ_HANDLED; | |
72 | +} | |
73 | + | |
74 | +static struct irqaction timer8_irq = { | |
75 | + .name = "timer-8", | |
76 | + .handler = timer_interrupt, | |
77 | + .flags = IRQF_DISABLED | IRQF_TIMER, | |
78 | + .mask = CPU_MASK_NONE, | |
79 | +}; | |
80 | + | |
81 | +static const int __initdata divide_rate[] = {8, 64, 8192}; | |
82 | + | |
83 | +void __init h8300_timer_setup(void) | |
84 | +{ | |
85 | + unsigned int div; | |
86 | + unsigned int cnt; | |
87 | + | |
88 | + calc_param(cnt, div, divide_rate, 0x10000); | |
89 | + div++; | |
90 | + | |
91 | + setup_irq(_8IRQ, &timer8_irq); | |
92 | + | |
93 | +#if defined(CONFIG_CPU_H8S) | |
94 | + /* Timer module enable */ | |
95 | + ctrl_bclr(0, MSTPCRL) | |
96 | +#endif | |
97 | + | |
98 | + /* initalize timer */ | |
99 | + ctrl_outw(cnt, _8BASE + TCORA); | |
100 | + ctrl_outw(0x0000, _8BASE + _8TCSR); | |
101 | + ctrl_outw((CMIEA|CCLR_CMA|CKS2) << 8 | div, | |
102 | + _8BASE + _8TCR); | |
103 | +} |
arch/h8300/kernel/timer/tpu.c
1 | +/* | |
2 | + * linux/arch/h8300/kernel/timer/tpu.c | |
3 | + * | |
4 | + * Yoshinori Sato <ysato@users.sourceforge.jp> | |
5 | + * | |
6 | + * TPU Timer Handler | |
7 | + * | |
8 | + */ | |
9 | + | |
10 | +#include <linux/config.h> | |
11 | +#include <linux/errno.h> | |
12 | +#include <linux/sched.h> | |
13 | +#include <linux/kernel.h> | |
14 | +#include <linux/param.h> | |
15 | +#include <linux/string.h> | |
16 | +#include <linux/mm.h> | |
17 | +#include <linux/interrupt.h> | |
18 | +#include <linux/init.h> | |
19 | +#include <linux/timex.h> | |
20 | + | |
21 | +#include <asm/segment.h> | |
22 | +#include <asm/io.h> | |
23 | +#include <asm/irq.h> | |
24 | +#include <asm/regs267x.h> | |
25 | + | |
26 | +/* TPU */ | |
27 | +#if CONFIG_H8300_TPU_CH == 0 | |
28 | +#define TPUBASE 0xffffd0 | |
29 | +#define TPUIRQ 40 | |
30 | +#elif CONFIG_H8300_TPU_CH == 1 | |
31 | +#define TPUBASE 0xffffe0 | |
32 | +#define TPUIRQ 48 | |
33 | +#elif CONFIG_H8300_TPU_CH == 2 | |
34 | +#define TPUBASE 0xfffff0 | |
35 | +#define TPUIRQ 52 | |
36 | +#elif CONFIG_H8300_TPU_CH == 3 | |
37 | +#define TPUBASE 0xfffe80 | |
38 | +#define TPUIRQ 56 | |
39 | +#elif CONFIG_H8300_TPU_CH == 4 | |
40 | +#define TPUBASE 0xfffe90 | |
41 | +#define TPUIRQ 64 | |
42 | +#else | |
43 | +#error Unknown timer channel. | |
44 | +#endif | |
45 | + | |
46 | +#define _TCR 0 | |
47 | +#define _TMDR 1 | |
48 | +#define _TIOR 2 | |
49 | +#define _TIER 4 | |
50 | +#define _TSR 5 | |
51 | +#define _TCNT 6 | |
52 | +#define _GRA 8 | |
53 | +#define _GRB 10 | |
54 | + | |
55 | +#define CCLR0 0x20 | |
56 | + | |
57 | +static irqreturn_t timer_interrupt(int irq, void *dev_id) | |
58 | +{ | |
59 | + h8300_timer_tick(); | |
60 | + ctrl_bclr(0, TPUBASE + _TSR); | |
61 | + return IRQ_HANDLED; | |
62 | +} | |
63 | + | |
64 | +static struct irqaction tpu_irq = { | |
65 | + .name = "tpu", | |
66 | + .handler = timer_interrupt, | |
67 | + .flags = IRQF_DISABLED | IRQF_TIMER, | |
68 | + .mask = CPU_MASK_NONE, | |
69 | +}; | |
70 | + | |
71 | +const static int __initdata divide_rate[] = { | |
72 | +#if CONFIG_H8300_TPU_CH == 0 | |
73 | + 1,4,16,64,0,0,0,0, | |
74 | +#elif (CONFIG_H8300_TPU_CH == 1) || (CONFIG_H8300_TPU_CH == 5) | |
75 | + 1,4,16,64,0,0,256,0, | |
76 | +#elif (CONFIG_H8300_TPU_CH == 2) || (CONFIG_H8300_TPU_CH == 4) | |
77 | + 1,4,16,64,0,0,0,1024, | |
78 | +#elif CONFIG_H8300_TPU_CH == 3 | |
79 | + 1,4,16,64,0,1024,256,4096, | |
80 | +#endif | |
81 | +}; | |
82 | + | |
83 | +void __init h8300_timer_setup(void) | |
84 | +{ | |
85 | + unsigned int cnt; | |
86 | + unsigned int div; | |
87 | + | |
88 | + calc_param(cnt, div, divide_rate, 0x10000); | |
89 | + | |
90 | + setup_irq(TPUIRQ, &tpu_irq); | |
91 | + | |
92 | + /* TPU module enabled */ | |
93 | + ctrl_bclr(3, MSTPCRH); | |
94 | + | |
95 | + ctrl_outb(0, TSTR); | |
96 | + ctrl_outb(CCLR0 | div, TPUBASE + _TCR); | |
97 | + ctrl_outb(0, TPUBASE + _TMDR); | |
98 | + ctrl_outw(0, TPUBASE + _TIOR); | |
99 | + ctrl_outb(0x01, TPUBASE + _TIER); | |
100 | + ctrl_outw(cnt, TPUBASE + _GRA); | |
101 | + ctrl_bset(CONFIG_H8300_TPU_CH, TSTR); | |
102 | +} |
include/asm-h8300/timer.h
1 | +#ifndef __H8300_TIMER_H | |
2 | +#define __H8300_TIMER_H | |
3 | + | |
4 | +void h8300_timer_tick(void); | |
5 | +void h8300_timer_setup(void); | |
6 | +void h8300_gettod(unsigned int *year, unsigned int *mon, unsigned int *day, | |
7 | + unsigned int *hour, unsigned int *min, unsigned int *sec); | |
8 | + | |
9 | +#define TIMER_FREQ (CONFIG_CPU_CLOCK*10000) /* Timer input freq. */ | |
10 | + | |
11 | +#define calc_param(cnt, div, rate, limit) \ | |
12 | +do { \ | |
13 | + cnt = TIMER_FREQ / HZ; \ | |
14 | + for (div = 0; div < ARRAY_SIZE(divide_rate); div++) { \ | |
15 | + if (rate[div] == 0) \ | |
16 | + continue; \ | |
17 | + if ((cnt / rate[div]) > limit) \ | |
18 | + break; \ | |
19 | + } \ | |
20 | + if (div == ARRAY_SIZE(divide_rate)) \ | |
21 | + panic("Timer counter overflow"); \ | |
22 | + cnt /= divide_rate[div]; \ | |
23 | +} while(0) | |
24 | + | |
25 | +#endif |