• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* arch/mips/mach-goldfish/goldfish-platform.c
2 **
3 ** Copyright (C) 2007 Google, Inc.
4 **
5 ** This software is licensed under the terms of the GNU General Public
6 ** License version 2, as published by the Free Software Foundation, and
7 ** may be copied, distributed, and modified under those terms.
8 **
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 ** GNU General Public License for more details.
13 **
14 */
15 
16 #include <linux/kernel.h>
17 #include <linux/init.h>
18 #include <linux/interrupt.h>
19 #include <linux/irq.h>
20 #include <linux/platform_device.h>
21 #include <linux/delay.h>
22 #include <linux/mtd/mtd.h>
23 #include <linux/mtd/nand.h>
24 #include <linux/mtd/partitions.h>
25 #include <linux/input.h>
26 
27 #include <mach/hardware.h>
28 #include <asm/io.h>
29 #include <asm/irq_cpu.h>
30 #include <asm/mach-goldfish/irq.h>
31 
32 static void __iomem *goldfish_interrupt;
33 
goldfish_mask_irq(unsigned int irq)34 void goldfish_mask_irq(unsigned int irq)
35 {
36 	writel(irq-GOLDFISH_IRQ_BASE,
37 	       goldfish_interrupt + GOLDFISH_INTERRUPT_DISABLE);
38 }
39 
goldfish_unmask_irq(unsigned int irq)40 void goldfish_unmask_irq(unsigned int irq)
41 {
42 	writel(irq-GOLDFISH_IRQ_BASE,
43 	       goldfish_interrupt + GOLDFISH_INTERRUPT_ENABLE);
44 }
45 
46 static struct irq_chip goldfish_irq_chip = {
47 	.name	= "goldfish",
48 	.mask	= goldfish_mask_irq,
49 	.mask_ack = goldfish_mask_irq,
50 	.unmask = goldfish_unmask_irq,
51 };
52 
goldfish_init_irq(void)53 void goldfish_init_irq(void)
54 {
55 	unsigned int i;
56 	goldfish_interrupt = IO_ADDRESS(GOLDFISH_INTERRUPT_BASE);
57 
58 	/*
59 	 * Disable all interrupt sources
60 	 */
61 	writel(1, goldfish_interrupt + GOLDFISH_INTERRUPT_DISABLE_ALL);
62 
63 	for (i = GOLDFISH_IRQ_BASE; i < GOLDFISH_IRQ_BASE+32; i++) {
64 		set_irq_chip(i, &goldfish_irq_chip);
65 		set_irq_handler(i, handle_level_irq);
66 #if 0
67 		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
68 #endif
69 	}
70 }
71 
goldfish_irq_dispatch(void)72 void goldfish_irq_dispatch(void)
73 {
74 	uint32_t irq;
75 	/*
76 	 * Disable all interrupt sources
77 	 */
78 	irq = readl(goldfish_interrupt + GOLDFISH_INTERRUPT_NUMBER);
79 	do_IRQ(GOLDFISH_IRQ_BASE+irq);
80 }
81 
goldfish_fiq_dispatch(void)82 void goldfish_fiq_dispatch(void)
83 {
84 	panic("goldfish_fiq_dispatch");
85 }
86 
plat_irq_dispatch(void)87 asmlinkage void plat_irq_dispatch(void)
88 {
89 	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
90 
91 	if (pending & CAUSEF_IP2)
92 		goldfish_irq_dispatch();
93 	else if (pending & CAUSEF_IP3)
94 		goldfish_fiq_dispatch();
95 	else if (pending & CAUSEF_IP7)
96 		do_IRQ(MIPS_CPU_IRQ_BASE + 7);
97 	else
98 		spurious_interrupt();
99 }
100 
101 static struct irqaction cascade = {
102 	.handler	= no_action,
103 	.mask		= CPU_MASK_NONE,
104 	.name		= "cascade",
105 };
106 
mips_timer_dispatch(void)107 static void mips_timer_dispatch(void)
108 {
109 	do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IRQ_COMPARE);
110 }
111 
arch_init_irq(void)112 void __init arch_init_irq(void)
113 {
114 	mips_cpu_irq_init();
115 	goldfish_init_irq();
116 
117 	if (cpu_has_vint) {
118 		set_vi_handler(MIPS_CPU_IRQ_PIC, goldfish_irq_dispatch);
119 		set_vi_handler(MIPS_CPU_IRQ_PIC, goldfish_fiq_dispatch);
120 	}
121 	setup_irq(MIPS_CPU_IRQ_BASE+MIPS_CPU_IRQ_PIC, &cascade);
122 	setup_irq(MIPS_CPU_IRQ_BASE+MIPS_CPU_IRQ_FIQ, &cascade);
123 
124 	if (cpu_has_vint)
125 		set_vi_handler(MIPS_CPU_IRQ_COMPARE, mips_timer_dispatch);
126 }
127