Blame view

drivers/irqchip/irq-mips-cpu.c 4.35 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
  /*
   * Copyright 2001 MontaVista Software Inc.
   * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
   *
   * Copyright (C) 2001 Ralf Baechle
703422879   Ralf Baechle   MIPS: Whitespace ...
6
7
   * Copyright (C) 2005  MIPS Technologies, Inc.	All rights reserved.
   *	Author: Maciej W. Rozycki <macro@mips.com>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
   *
   * This file define the irq handler for MIPS CPU interrupts.
   *
703422879   Ralf Baechle   MIPS: Whitespace ...
11
12
   * This program is free software; you can redistribute	it and/or modify it
   * under  the terms of	the GNU General	 Public License as published by the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
   * Free Software Foundation;  either version 2 of the  License, or (at your
   * option) any later version.
   */
  
  /*
   * Almost all MIPS CPUs define 8 interrupt sources.  They are typically
   * level triggered (i.e., cannot be cleared from CPU; must be cleared from
   * device).  The first two are software interrupts which we don't really
   * use or support.  The last one is usually the CPU timer interrupt if
   * counter register is present or, for CPUs with an external FPU, by
   * convention it's the FPU exception interrupt.
   *
   * Don't even think about using this on SMP.  You have been warned.
   *
   * This file exports one global function:
97dcb82de   Atsushi Nemoto   [MIPS] Define MIP...
28
   *	void mips_cpu_irq_init(void);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
30
31
32
   */
  #include <linux/init.h>
  #include <linux/interrupt.h>
  #include <linux/kernel.h>
ca4d3e674   David Howells   MIPS: Add missing...
33
  #include <linux/irq.h>
41a83e06e   Joel Porquet   irqchip: Prepare ...
34
  #include <linux/irqchip.h>
0916b4696   Gabor Juhos   MIPS: add irqdoma...
35
  #include <linux/irqdomain.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
38
  
  #include <asm/irq_cpu.h>
  #include <asm/mipsregs.h>
d03d0a577   Ralf Baechle   MT bulletproofing.
39
  #include <asm/mipsmtregs.h>
f64e55dcb   Andrew Bresticker   MIPS: Set vint ha...
40
  #include <asm/setup.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41

a93951c45   Thomas Gleixner   MIPS: irq_cpu: Co...
42
  static inline void unmask_mips_irq(struct irq_data *d)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
  {
a93951c45   Thomas Gleixner   MIPS: irq_cpu: Co...
44
  	set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
569f75bd0   Ralf Baechle   Use an irq_enable...
45
  	irq_enable_hazard();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  }
a93951c45   Thomas Gleixner   MIPS: irq_cpu: Co...
47
  static inline void mask_mips_irq(struct irq_data *d)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
  {
a93951c45   Thomas Gleixner   MIPS: irq_cpu: Co...
49
  	clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
569f75bd0   Ralf Baechle   Use an irq_enable...
50
  	irq_disable_hazard();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
  }
94dee171d   Ralf Baechle   [MIPS] Eleminate ...
52
  static struct irq_chip mips_cpu_irq_controller = {
70d21cdee   Atsushi Nemoto   [MIPS] use name i...
53
  	.name		= "MIPS",
a93951c45   Thomas Gleixner   MIPS: irq_cpu: Co...
54
55
56
57
58
  	.irq_ack	= mask_mips_irq,
  	.irq_mask	= mask_mips_irq,
  	.irq_mask_ack	= mask_mips_irq,
  	.irq_unmask	= unmask_mips_irq,
  	.irq_eoi	= unmask_mips_irq,
a3e6c1eff   Felix Fietkau   MIPS: IRQ: Fix di...
59
60
  	.irq_disable	= mask_mips_irq,
  	.irq_enable	= unmask_mips_irq,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  };
d03d0a577   Ralf Baechle   MT bulletproofing.
62
63
64
  /*
   * Basically the same as above but taking care of all the MT stuff
   */
a93951c45   Thomas Gleixner   MIPS: irq_cpu: Co...
65
  static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d)
d03d0a577   Ralf Baechle   MT bulletproofing.
66
67
  {
  	unsigned int vpflags = dvpe();
a93951c45   Thomas Gleixner   MIPS: irq_cpu: Co...
68
  	clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
d03d0a577   Ralf Baechle   MT bulletproofing.
69
  	evpe(vpflags);
a93951c45   Thomas Gleixner   MIPS: irq_cpu: Co...
70
  	unmask_mips_irq(d);
d03d0a577   Ralf Baechle   MT bulletproofing.
71
72
  	return 0;
  }
d03d0a577   Ralf Baechle   MT bulletproofing.
73
74
75
76
  /*
   * While we ack the interrupt interrupts are disabled and thus we don't need
   * to deal with concurrency issues.  Same for mips_cpu_irq_end.
   */
a93951c45   Thomas Gleixner   MIPS: irq_cpu: Co...
77
  static void mips_mt_cpu_irq_ack(struct irq_data *d)
d03d0a577   Ralf Baechle   MT bulletproofing.
78
79
  {
  	unsigned int vpflags = dvpe();
a93951c45   Thomas Gleixner   MIPS: irq_cpu: Co...
80
  	clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
d03d0a577   Ralf Baechle   MT bulletproofing.
81
  	evpe(vpflags);
a93951c45   Thomas Gleixner   MIPS: irq_cpu: Co...
82
  	mask_mips_irq(d);
d03d0a577   Ralf Baechle   MT bulletproofing.
83
  }
94dee171d   Ralf Baechle   [MIPS] Eleminate ...
84
  static struct irq_chip mips_mt_cpu_irq_controller = {
70d21cdee   Atsushi Nemoto   [MIPS] use name i...
85
  	.name		= "MIPS",
a93951c45   Thomas Gleixner   MIPS: irq_cpu: Co...
86
87
88
89
90
91
  	.irq_startup	= mips_mt_cpu_irq_startup,
  	.irq_ack	= mips_mt_cpu_irq_ack,
  	.irq_mask	= mask_mips_irq,
  	.irq_mask_ack	= mips_mt_cpu_irq_ack,
  	.irq_unmask	= unmask_mips_irq,
  	.irq_eoi	= unmask_mips_irq,
a3e6c1eff   Felix Fietkau   MIPS: IRQ: Fix di...
92
93
  	.irq_disable	= mask_mips_irq,
  	.irq_enable	= unmask_mips_irq,
d03d0a577   Ralf Baechle   MT bulletproofing.
94
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95

85f7cdacb   Andrew Bresticker   MIPS: Provide a g...
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
  asmlinkage void __weak plat_irq_dispatch(void)
  {
  	unsigned long pending = read_c0_cause() & read_c0_status() & ST0_IM;
  	int irq;
  
  	if (!pending) {
  		spurious_interrupt();
  		return;
  	}
  
  	pending >>= CAUSEB_IP;
  	while (pending) {
  		irq = fls(pending) - 1;
  		do_IRQ(MIPS_CPU_IRQ_BASE + irq);
  		pending &= ~BIT(irq);
  	}
  }
0916b4696   Gabor Juhos   MIPS: add irqdoma...
113
114
115
116
117
118
119
120
121
122
123
  static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq,
  			     irq_hw_number_t hw)
  {
  	static struct irq_chip *chip;
  
  	if (hw < 2 && cpu_has_mipsmt) {
  		/* Software interrupts are used for MT/CMT IPI */
  		chip = &mips_mt_cpu_irq_controller;
  	} else {
  		chip = &mips_cpu_irq_controller;
  	}
f64e55dcb   Andrew Bresticker   MIPS: Set vint ha...
124
125
  	if (cpu_has_vint)
  		set_vi_handler(hw, plat_irq_dispatch);
0916b4696   Gabor Juhos   MIPS: add irqdoma...
126
127
128
129
130
131
132
133
134
  	irq_set_chip_and_handler(irq, chip, handle_percpu_irq);
  
  	return 0;
  }
  
  static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = {
  	.map = mips_cpu_intc_map,
  	.xlate = irq_domain_xlate_onecell,
  };
0f84c3053   Andrew Bresticker   MIPS: Always use ...
135
  static void __init __mips_cpu_irq_init(struct device_node *of_node)
0916b4696   Gabor Juhos   MIPS: add irqdoma...
136
137
138
139
140
141
142
143
144
145
  {
  	struct irq_domain *domain;
  
  	/* Mask interrupts. */
  	clear_c0_status(ST0_IM);
  	clear_c0_cause(CAUSEF_IP);
  
  	domain = irq_domain_add_legacy(of_node, 8, MIPS_CPU_IRQ_BASE, 0,
  				       &mips_cpu_intc_irq_domain_ops, NULL);
  	if (!domain)
f7777dcc7   Ralf Baechle   MIPS: Panic messa...
146
  		panic("Failed to add irqdomain for MIPS CPU");
0f84c3053   Andrew Bresticker   MIPS: Always use ...
147
148
149
150
151
152
  }
  
  void __init mips_cpu_irq_init(void)
  {
  	__mips_cpu_irq_init(NULL);
  }
0916b4696   Gabor Juhos   MIPS: add irqdoma...
153

afe8dc254   Andrew Bresticker   MIPS: Rename mips...
154
155
  int __init mips_cpu_irq_of_init(struct device_node *of_node,
  				struct device_node *parent)
0f84c3053   Andrew Bresticker   MIPS: Always use ...
156
157
  {
  	__mips_cpu_irq_init(of_node);
0916b4696   Gabor Juhos   MIPS: add irqdoma...
158
159
  	return 0;
  }
892b8cf06   Paul Burton   IRQCHIP: irq_cpu:...
160
  IRQCHIP_DECLARE(cpu_intc, "mti,cpu-interrupt-controller", mips_cpu_irq_of_init);