summaryrefslogtreecommitdiffstats
path: root/target/linux/realtek/files/arch/rlx/kernel/irq_vec.c
blob: f060db8bd23877bf5b84b5a5036a0b313bc7105b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * Realtek Semiconductor Corp.
 *
 * This file define the irq handler for RLX CPU interrupts.
 *
 * Tony Wu (tonywu@realtek.com.tw)
 * Feb. 28, 2008
 */

#include <linux/irq.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>

#include <asm/irq_vec.h>
#include <asm/rlxregs.h>
#include <asm/system.h>
#include <net/rtl/rtl_types.h>
#include "bspchip.h"

__IRAM_GEN
static void unmask_rlx_vec_irq(unsigned int irq)
{
	set_lxc0_estatus(0x10000 << (irq - BSP_IRQ_LOPI_BASE));
	irq_enable_hazard();
}

__IRAM_GEN
static void mask_rlx_vec_irq(unsigned int irq)
{
	clear_lxc0_estatus(0x10000 << (irq - BSP_IRQ_LOPI_BASE));
	irq_disable_hazard();
}

static struct irq_chip rlx_vec_irq_controller = {
	.name		= "RLX LOPI",
	.ack		= mask_rlx_vec_irq,
	.mask		= mask_rlx_vec_irq,
	.mask_ack	= mask_rlx_vec_irq,
	.unmask		= unmask_rlx_vec_irq,
	.eoi		= unmask_rlx_vec_irq,
};

//static struct irq_desc *rlx_vec_irq_desc;

void __init rlx_vec_irq_init(int irq_base)
{
	int i;
	extern char rlx_vec_dispatch;
	#ifdef CONFIG_RTL_8198_NFBI_BOARD
	extern void setup_reboot_addr(unsigned long addr);
	#endif

	/* Mask interrupts. */
	clear_lxc0_estatus(EST0_IM);
	clear_lxc0_ecause(ECAUSEF_IP);

	//	rlx_vec_irq_desc = irq_desc + irq_base;

	for (i = irq_base; i < irq_base + BSP_IRQ_LOPI_NUM; i++)
		set_irq_chip_and_handler(i, &rlx_vec_irq_controller, handle_percpu_irq);

	write_lxc0_intvec(&rlx_vec_dispatch);

	#if 1
	/* enable global interrupt mask */
	REG32(BSP_GIMR) = BSP_TC0_IE | BSP_UART0_IE ;

	#ifdef CONFIG_SERIAL_RTL8198_UART1
	REG32(BSP_GIMR)	|= BSP_UART1_IE;
	#endif
	
	#if defined(CONFIG_RTL8192CD) || defined(CONFIG_RTL8192E)
	#if defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E)
	REG32(BSP_GIMR) |= (BSP_PCIE_IE);
	#if defined(CONFIG_RTL_8197D) || defined(CONFIG_RTL_8197DL)
	REG32(BSP_GIMR) |= (BSP_PCIE2_IE);
	#endif
	#else // !CONFIG_RTL_819XD
	#if (defined(CONFIG_RTL_8196C) || defined(CONFIG_RTL_8196CT) || defined(CONFIG_RTL_8196CS) || !defined(CONFIG_RTL_92D_DMDP))|| defined(CONFIG_RTK_VOIP_BOARD)
	REG32(BSP_GIMR) |= (BSP_PCIE_IE);
	#endif
	#if defined(CONFIG_RTL_DUAL_PCIESLOT_BIWLAN_D) || (defined(CONFIG_RTL_8198)&&defined(CONFIG_RTL_92D_SUPPORT))&&!defined(CONFIG_RTK_VOIP_BOARD)
	REG32(BSP_GIMR) |= (BSP_PCIE2_IE);
	#endif
	#endif
	#endif
	
	#if defined(CONFIG_USB)
	REG32(BSP_GIMR) |= BSP_USB_H_IE;
	#endif
	
	#if defined(CONFIG_RTL_819X) || defined(CONFIG_RTL_ICTEST_SWITCH) || defined(CONFIG_RTL_865X_ETH)
	REG32(BSP_GIMR) |= (BSP_SW_IE);
	#endif
	
	#if defined(CONFIG_RTL_NFBI_MDIO)
	REG32(BSP_GIMR) |= BSP_NFBI_IE;
	#endif

	#ifdef CONFIG_RTL_8198_NFBI_BOARD
	setup_reboot_addr(0x80700000);
	#endif
	
	#if defined(CONFIG_RTK_VOIP)
	REG32(BSP_GIMR) |= (BSP_PCM_IE | BSP_I2S_IE);
	REG32(BSP_GIMR) |= (BSP_GPIO_ABCD_IE | BSP_GPIO_EFGH_IE); 
	#endif
	#endif

}

__IRAM_GEN
asmlinkage void rlx_do_lopi_IRQ(int irq_offset)
{
	unsigned int pending;
	unsigned int cause;
	unsigned int status;

	cause = read_lxc0_ecause();
	status = read_lxc0_estatus();
	pending = cause & status & EST0_IM;
	
	if (pending & (_ULCAST_(1) << (irq_offset + 16))) {
		do_IRQ(BSP_IRQ_LOPI_BASE + irq_offset);
	} else {
	#if defined(CONFIG_RTK_VOIP) || defined(CONFIG_RTL_819X)
		spurious_interrupt(SPURIOS_INT_LOPI);
	#else
		spurious_interrupt();
	#endif
	}
}