123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- /*
- * include/asm-v850/v850e_intc.h -- V850E CPU interrupt controller (INTC)
- *
- * Copyright (C) 2001,02,03 NEC Electronics Corporation
- * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
- *
- * 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.
- *
- * Written by Miles Bader <miles@gnu.org>
- */
- #ifndef __V850_V850E_INTC_H__
- #define __V850_V850E_INTC_H__
- /* There are 4 16-bit `Interrupt Mask Registers' located contiguously
- starting from this base. Each interrupt uses a single bit to
- indicated enabled/disabled status. */
- #define V850E_INTC_IMR_BASE_ADDR 0xFFFFF100
- #define V850E_INTC_IMR_ADDR(irq) (V850E_INTC_IMR_BASE_ADDR + ((irq) >> 3))
- #define V850E_INTC_IMR_BIT(irq) ((irq) & 0x7)
- /* Each maskable interrupt has a single-byte control register at this
- address. */
- #define V850E_INTC_IC_BASE_ADDR 0xFFFFF110
- #define V850E_INTC_IC_ADDR(irq) (V850E_INTC_IC_BASE_ADDR + ((irq) << 1))
- #define V850E_INTC_IC(irq) (*(volatile u8 *)V850E_INTC_IC_ADDR(irq))
- /* Encode priority PR for storing in an interrupt control register. */
- #define V850E_INTC_IC_PR(pr) (pr)
- /* Interrupt disable bit in an interrupt control register. */
- #define V850E_INTC_IC_MK_BIT 6
- #define V850E_INTC_IC_MK (1 << V850E_INTC_IC_MK_BIT)
- /* Interrupt pending flag in an interrupt control register. */
- #define V850E_INTC_IC_IF_BIT 7
- #define V850E_INTC_IC_IF (1 << V850E_INTC_IC_IF_BIT)
- /* The ISPR (In-service priority register) contains one bit for each interrupt
- priority level, which is set to one when that level is currently being
- serviced (and thus blocking any interrupts of equal or lesser level). */
- #define V850E_INTC_ISPR_ADDR 0xFFFFF1FA
- #define V850E_INTC_ISPR (*(volatile u8 *)V850E_INTC_ISPR_ADDR)
- #ifndef __ASSEMBLY__
- /* Enable interrupt handling for interrupt IRQ. */
- static inline void v850e_intc_enable_irq (unsigned irq)
- {
- __asm__ __volatile__ ("clr1 %0, [%1]"
- :: "r" (V850E_INTC_IMR_BIT (irq)),
- "r" (V850E_INTC_IMR_ADDR (irq))
- : "memory");
- }
- /* Disable interrupt handling for interrupt IRQ. Note that any
- interrupts received while disabled will be delivered once the
- interrupt is enabled again, unless they are explicitly cleared using
- `v850e_intc_clear_pending_irq'. */
- static inline void v850e_intc_disable_irq (unsigned irq)
- {
- __asm__ __volatile__ ("set1 %0, [%1]"
- :: "r" (V850E_INTC_IMR_BIT (irq)),
- "r" (V850E_INTC_IMR_ADDR (irq))
- : "memory");
- }
- /* Return true if interrupt handling for interrupt IRQ is enabled. */
- static inline int v850e_intc_irq_enabled (unsigned irq)
- {
- int rval;
- __asm__ __volatile__ ("tst1 %1, [%2]; setf z, %0"
- : "=r" (rval)
- : "r" (V850E_INTC_IMR_BIT (irq)),
- "r" (V850E_INTC_IMR_ADDR (irq)));
- return rval;
- }
- /* Disable irqs from 0 until LIMIT. LIMIT must be a multiple of 8. */
- static inline void _v850e_intc_disable_irqs (unsigned limit)
- {
- unsigned long addr;
- for (addr = V850E_INTC_IMR_BASE_ADDR; limit >= 8; addr++, limit -= 8)
- *(char *)addr = 0xFF;
- }
- /* Disable all irqs. This is purposely a macro, because NUM_MACH_IRQS
- will be only be defined later. */
- #define v850e_intc_disable_irqs() _v850e_intc_disable_irqs (NUM_MACH_IRQS)
- /* Clear any pending interrupts for IRQ. */
- static inline void v850e_intc_clear_pending_irq (unsigned irq)
- {
- __asm__ __volatile__ ("clr1 %0, 0[%1]"
- :: "i" (V850E_INTC_IC_IF_BIT),
- "r" (V850E_INTC_IC_ADDR (irq))
- : "memory");
- }
- /* Return true if interrupt IRQ is pending (but disabled). */
- static inline int v850e_intc_irq_pending (unsigned irq)
- {
- int rval;
- __asm__ __volatile__ ("tst1 %1, 0[%2]; setf nz, %0"
- : "=r" (rval)
- : "i" (V850E_INTC_IC_IF_BIT),
- "r" (V850E_INTC_IC_ADDR (irq)));
- return rval;
- }
- struct v850e_intc_irq_init {
- const char *name; /* name of interrupt type */
- /* Range of kernel irq numbers for this type:
- BASE, BASE+INTERVAL, ..., BASE+INTERVAL*NUM */
- unsigned base, num, interval;
- unsigned priority; /* interrupt priority to assign */
- };
- struct hw_interrupt_type; /* fwd decl */
- /* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
- INITS (which is terminated by an entry with the name field == 0). */
- extern void v850e_intc_init_irq_types (struct v850e_intc_irq_init *inits,
- struct hw_interrupt_type *hw_irq_types);
- #endif /* !__ASSEMBLY__ */
- #endif /* __V850_V850E_INTC_H__ */
|