Commit e0b0f9e4ead2468f84c26332ec42b118e76af572

Authored by Yoshinori Sato
Committed by Linus Torvalds
1 parent 4b6aba51fb

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
  1 +# h8300 internal timer handler
  2 +
  3 +obj-$(CONFIG_H8300_TIMER8) := timer8.o
  4 +obj-$(CONFIG_H8300_TIMER16) := timer16.o
  5 +obj-$(CONFIG_H8300_ITU) := itu.o
  6 +obj-$(CONFIG_H8300_TPU) := tpu.o
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