• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/linux/linux-2.6/arch/mips/momentum/ocelot_c/
1/*
2 * Copyright 2002 Momentum Computer
3 * Author: mdharm@momenco.com
4 *
5 * arch/mips/momentum/ocelot_c/uart-irq.c
6 *     Interrupt routines for UARTs.  Interrupt numbers are assigned from
7 *     80 to 81 (2 interrupt sources).
8 *
9 * This program is free software; you can redistribute  it and/or modify it
10 * under  the terms of  the GNU General  Public License as published by the
11 * Free Software Foundation;  either version 2 of the  License, or (at your
12 * option) any later version.
13 */
14
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/irq.h>
18#include <linux/kernel.h>
19#include <linux/sched.h>
20#include <linux/kernel_stat.h>
21#include <asm/io.h>
22#include <asm/irq.h>
23#include "ocelot_c_fpga.h"
24
25static inline int ls1bit8(unsigned int x)
26{
27        int b = 7, s;
28
29        s =  4; if (((unsigned char)(x << 4)) == 0) s = 0; b -= s; x <<= s;
30        s =  2; if (((unsigned char)(x << 2)) == 0) s = 0; b -= s; x <<= s;
31        s =  1; if (((unsigned char)(x << 1)) == 0) s = 0; b -= s;
32
33        return b;
34}
35
36/* mask off an interrupt -- 0 is enable, 1 is disable */
37static inline void mask_uart_irq(unsigned int irq)
38{
39	uint8_t value;
40
41	value = OCELOT_FPGA_READ(UART_INTMASK);
42	value |= 1 << (irq - 74);
43	OCELOT_FPGA_WRITE(value, UART_INTMASK);
44
45	/* read the value back to assure that it's really been written */
46	value = OCELOT_FPGA_READ(UART_INTMASK);
47}
48
49/* unmask an interrupt -- 0 is enable, 1 is disable */
50static inline void unmask_uart_irq(unsigned int irq)
51{
52	uint8_t value;
53
54	value = OCELOT_FPGA_READ(UART_INTMASK);
55	value &= ~(1 << (irq - 74));
56	OCELOT_FPGA_WRITE(value, UART_INTMASK);
57
58	/* read the value back to assure that it's really been written */
59	value = OCELOT_FPGA_READ(UART_INTMASK);
60}
61
62/*
63 * Interrupt handler for interrupts coming from the FPGA chip.
64 */
65void ll_uart_irq(void)
66{
67	unsigned int irq_src, irq_mask;
68
69	/* read the interrupt status registers */
70	irq_src = OCELOT_FPGA_READ(UART_INTSTAT);
71	irq_mask = OCELOT_FPGA_READ(UART_INTMASK);
72
73	/* mask for just the interrupts we want */
74	irq_src &= ~irq_mask;
75
76	do_IRQ(ls1bit8(irq_src) + 74);
77}
78
79struct irq_chip uart_irq_type = {
80	.name = "UART/FPGA",
81	.ack = mask_uart_irq,
82	.mask = mask_uart_irq,
83	.mask_ack = mask_uart_irq,
84	.unmask = unmask_uart_irq,
85};
86
87void uart_irq_init(void)
88{
89	set_irq_chip_and_handler(80, &uart_irq_type, handle_level_irq);
90	set_irq_chip_and_handler(81, &uart_irq_type, handle_level_irq);
91}
92