Linux Audio

Check our new training course

Real-Time Linux with PREEMPT_RT training

Feb 18-20, 2025
Register
Loading...
Note: File does not exist in v6.8.
  1/*
  2 * linux/arch/h8300/kernel/irq.c
  3 *
  4 * Copyright 2007 Yoshinori Sato <ysato@users.sourceforge.jp>
  5 */
  6
  7#include <linux/module.h>
  8#include <linux/types.h>
  9#include <linux/kernel.h>
 10#include <linux/sched.h>
 11#include <linux/kernel_stat.h>
 12#include <linux/seq_file.h>
 13#include <linux/init.h>
 14#include <linux/random.h>
 15#include <linux/bootmem.h>
 16#include <linux/irq.h>
 17#include <linux/interrupt.h>
 18
 19#include <asm/system.h>
 20#include <asm/traps.h>
 21#include <asm/io.h>
 22#include <asm/setup.h>
 23#include <asm/errno.h>
 24
 25/*#define DEBUG*/
 26
 27extern unsigned long *interrupt_redirect_table;
 28extern const int h8300_saved_vectors[];
 29extern const h8300_vector h8300_trap_table[];
 30int h8300_enable_irq_pin(unsigned int irq);
 31void h8300_disable_irq_pin(unsigned int irq);
 32
 33#define CPU_VECTOR ((unsigned long *)0x000000)
 34#define ADDR_MASK (0xffffff)
 35
 36static inline int is_ext_irq(unsigned int irq)
 37{
 38	return (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS));
 39}
 40
 41static void h8300_enable_irq(struct irq_data *data)
 42{
 43	if (is_ext_irq(data->irq))
 44		IER_REGS |= 1 << (data->irq - EXT_IRQ0);
 45}
 46
 47static void h8300_disable_irq(struct irq_data *data)
 48{
 49	if (is_ext_irq(data->irq))
 50		IER_REGS &= ~(1 << (data->irq - EXT_IRQ0));
 51}
 52
 53static unsigned int h8300_startup_irq(struct irq_data *data)
 54{
 55	if (is_ext_irq(data->irq))
 56		return h8300_enable_irq_pin(data->irq);
 57	else
 58		return 0;
 59}
 60
 61static void h8300_shutdown_irq(struct irq_data *data)
 62{
 63	if (is_ext_irq(data->irq))
 64		h8300_disable_irq_pin(data->irq);
 65}
 66
 67/*
 68 * h8300 interrupt controller implementation
 69 */
 70struct irq_chip h8300irq_chip = {
 71	.name		= "H8300-INTC",
 72	.irq_startup	= h8300_startup_irq,
 73	.irq_shutdown	= h8300_shutdown_irq,
 74	.irq_enable	= h8300_enable_irq,
 75	.irq_disable	= h8300_disable_irq,
 76};
 77
 78#if defined(CONFIG_RAMKERNEL)
 79static unsigned long __init *get_vector_address(void)
 80{
 81	unsigned long *rom_vector = CPU_VECTOR;
 82	unsigned long base,tmp;
 83	int vec_no;
 84
 85	base = rom_vector[EXT_IRQ0] & ADDR_MASK;
 86
 87	/* check romvector format */
 88	for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) {
 89		if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK))
 90			return NULL;
 91	}
 92
 93	/* ramvector base address */
 94	base -= EXT_IRQ0*4;
 95
 96	/* writerble check */
 97	tmp = ~(*(volatile unsigned long *)base);
 98	(*(volatile unsigned long *)base) = tmp;
 99	if ((*(volatile unsigned long *)base) != tmp)
100		return NULL;
101	return (unsigned long *)base;
102}
103
104static void __init setup_vector(void)
105{
106	int i;
107	unsigned long *ramvec,*ramvec_p;
108	const h8300_vector *trap_entry;
109	const int *saved_vector;
110
111	ramvec = get_vector_address();
112	if (ramvec == NULL)
113		panic("interrupt vector serup failed.");
114	else
115		printk(KERN_INFO "virtual vector at 0x%08lx\n",(unsigned long)ramvec);
116
117	/* create redirect table */
118	ramvec_p = ramvec;
119	trap_entry = h8300_trap_table;
120	saved_vector = h8300_saved_vectors;
121	for ( i = 0; i < NR_IRQS; i++) {
122		if (i == *saved_vector) {
123			ramvec_p++;
124			saved_vector++;
125		} else {
126			if ( i < NR_TRAPS ) {
127				if (*trap_entry)
128					*ramvec_p = VECTOR(*trap_entry);
129				ramvec_p++;
130				trap_entry++;
131			} else
132				*ramvec_p++ = REDIRECT(interrupt_entry);
133		}
134	}
135	interrupt_redirect_table = ramvec;
136#ifdef DEBUG
137	ramvec_p = ramvec;
138	for (i = 0; i < NR_IRQS; i++) {
139		if ((i % 8) == 0)
140			printk(KERN_DEBUG "\n%p: ",ramvec_p);
141		printk(KERN_DEBUG "%p ",*ramvec_p);
142		ramvec_p++;
143	}
144	printk(KERN_DEBUG "\n");
145#endif
146}
147#else
148#define setup_vector() do { } while(0)
149#endif
150
151void __init init_IRQ(void)
152{
153	int c;
154
155	setup_vector();
156
157	for (c = 0; c < NR_IRQS; c++)
158		irq_set_chip_and_handler(c, &h8300irq_chip, handle_simple_irq);
159}
160
161asmlinkage void do_IRQ(int irq)
162{
163	irq_enter();
164	generic_handle_irq(irq);
165	irq_exit();
166}