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 52static 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 59static struct irqaction itu_irq = { 60 .name = "itu", 61 .handler = timer_interrupt, 62 .flags = IRQF_DISABLED | IRQF_TIMER, 63}; 64 65static const int __initdata divide_rate[] = {1, 2, 4, 8}; 66 67void __init h8300_timer_setup(void) 68{ 69 unsigned int div; 70 unsigned int cnt; 71 72 calc_param(cnt, div, divide_rate, 0x10000); 73 74 setup_irq(ITUIRQ, &itu_irq); 75 76 /* initialize timer */ 77 ctrl_outb(0, TSTR); 78 ctrl_outb(CCLR0 | div, ITUBASE + TCR); 79 ctrl_outb(0x01, ITUBASE + TIER); 80 ctrl_outw(cnt, ITUBASE + GRA); 81 ctrl_bset(CONFIG_H8300_ITU_CH, TSTR); 82} 83