Commit c290b2f2b0187b5cd840b2c2803107a0207ebc2f

Authored by Linus Torvalds

Merge branch 'dt-for-linus' of git://sources.calxeda.com/kernel/linux

* 'dt-for-linus' of git://sources.calxeda.com/kernel/linux:
  of: Add Silicon Image vendor prefix
  of/irq: of_irq_init: add check for parent equal to child node

Showing 2 changed files Inline Diff

Documentation/devicetree/bindings/vendor-prefixes.txt
1 Device tree binding vendor prefix registry. Keep list in alphabetical order. 1 Device tree binding vendor prefix registry. Keep list in alphabetical order.
2 2
3 This isn't an exhaustive list, but you should add new prefixes to it before 3 This isn't an exhaustive list, but you should add new prefixes to it before
4 using them to avoid name-space collisions. 4 using them to avoid name-space collisions.
5 5
6 adi Analog Devices, Inc. 6 adi Analog Devices, Inc.
7 amcc Applied Micro Circuits Corporation (APM, formally AMCC) 7 amcc Applied Micro Circuits Corporation (APM, formally AMCC)
8 apm Applied Micro Circuits Corporation (APM) 8 apm Applied Micro Circuits Corporation (APM)
9 arm ARM Ltd. 9 arm ARM Ltd.
10 atmel Atmel Corporation 10 atmel Atmel Corporation
11 chrp Common Hardware Reference Platform 11 chrp Common Hardware Reference Platform
12 dallas Maxim Integrated Products (formerly Dallas Semiconductor) 12 dallas Maxim Integrated Products (formerly Dallas Semiconductor)
13 denx Denx Software Engineering 13 denx Denx Software Engineering
14 epson Seiko Epson Corp. 14 epson Seiko Epson Corp.
15 est ESTeem Wireless Modems 15 est ESTeem Wireless Modems
16 fsl Freescale Semiconductor 16 fsl Freescale Semiconductor
17 GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc. 17 GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
18 gef GE Fanuc Intelligent Platforms Embedded Systems, Inc. 18 gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
19 hp Hewlett Packard 19 hp Hewlett Packard
20 ibm International Business Machines (IBM) 20 ibm International Business Machines (IBM)
21 idt Integrated Device Technologies, Inc. 21 idt Integrated Device Technologies, Inc.
22 intercontrol Inter Control Group 22 intercontrol Inter Control Group
23 linux Linux-specific binding 23 linux Linux-specific binding
24 marvell Marvell Technology Group Ltd. 24 marvell Marvell Technology Group Ltd.
25 maxim Maxim Integrated Products 25 maxim Maxim Integrated Products
26 mosaixtech Mosaix Technologies, Inc. 26 mosaixtech Mosaix Technologies, Inc.
27 national National Semiconductor 27 national National Semiconductor
28 nintendo Nintendo 28 nintendo Nintendo
29 nvidia NVIDIA 29 nvidia NVIDIA
30 nxp NXP Semiconductors 30 nxp NXP Semiconductors
31 powervr Imagination Technologies 31 powervr Imagination Technologies
32 qcom Qualcomm, Inc. 32 qcom Qualcomm, Inc.
33 ramtron Ramtron International 33 ramtron Ramtron International
34 samsung Samsung Semiconductor 34 samsung Samsung Semiconductor
35 schindler Schindler 35 schindler Schindler
36 sil Silicon Image
36 simtek 37 simtek
37 sirf SiRF Technology, Inc. 38 sirf SiRF Technology, Inc.
38 stericsson ST-Ericsson 39 stericsson ST-Ericsson
39 ti Texas Instruments 40 ti Texas Instruments
40 xlnx Xilinx 41 xlnx Xilinx
41 42
1 /* 1 /*
2 * Derived from arch/i386/kernel/irq.c 2 * Derived from arch/i386/kernel/irq.c
3 * Copyright (C) 1992 Linus Torvalds 3 * Copyright (C) 1992 Linus Torvalds
4 * Adapted from arch/i386 by Gary Thomas 4 * Adapted from arch/i386 by Gary Thomas
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 * Updated and modified by Cort Dougan <cort@fsmlabs.com> 6 * Updated and modified by Cort Dougan <cort@fsmlabs.com>
7 * Copyright (C) 1996-2001 Cort Dougan 7 * Copyright (C) 1996-2001 Cort Dougan
8 * Adapted for Power Macintosh by Paul Mackerras 8 * Adapted for Power Macintosh by Paul Mackerras
9 * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) 9 * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
10 * 10 *
11 * This program is free software; you can redistribute it and/or 11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License 12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version. 14 * 2 of the License, or (at your option) any later version.
15 * 15 *
16 * This file contains the code used to make IRQ descriptions in the 16 * This file contains the code used to make IRQ descriptions in the
17 * device tree to actual irq numbers on an interrupt controller 17 * device tree to actual irq numbers on an interrupt controller
18 * driver. 18 * driver.
19 */ 19 */
20 20
21 #include <linux/errno.h> 21 #include <linux/errno.h>
22 #include <linux/list.h> 22 #include <linux/list.h>
23 #include <linux/module.h> 23 #include <linux/module.h>
24 #include <linux/of.h> 24 #include <linux/of.h>
25 #include <linux/of_irq.h> 25 #include <linux/of_irq.h>
26 #include <linux/string.h> 26 #include <linux/string.h>
27 #include <linux/slab.h> 27 #include <linux/slab.h>
28 28
29 /* For archs that don't support NO_IRQ (such as x86), provide a dummy value */ 29 /* For archs that don't support NO_IRQ (such as x86), provide a dummy value */
30 #ifndef NO_IRQ 30 #ifndef NO_IRQ
31 #define NO_IRQ 0 31 #define NO_IRQ 0
32 #endif 32 #endif
33 33
34 /** 34 /**
35 * irq_of_parse_and_map - Parse and map an interrupt into linux virq space 35 * irq_of_parse_and_map - Parse and map an interrupt into linux virq space
36 * @device: Device node of the device whose interrupt is to be mapped 36 * @device: Device node of the device whose interrupt is to be mapped
37 * @index: Index of the interrupt to map 37 * @index: Index of the interrupt to map
38 * 38 *
39 * This function is a wrapper that chains of_irq_map_one() and 39 * This function is a wrapper that chains of_irq_map_one() and
40 * irq_create_of_mapping() to make things easier to callers 40 * irq_create_of_mapping() to make things easier to callers
41 */ 41 */
42 unsigned int irq_of_parse_and_map(struct device_node *dev, int index) 42 unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
43 { 43 {
44 struct of_irq oirq; 44 struct of_irq oirq;
45 45
46 if (of_irq_map_one(dev, index, &oirq)) 46 if (of_irq_map_one(dev, index, &oirq))
47 return NO_IRQ; 47 return NO_IRQ;
48 48
49 return irq_create_of_mapping(oirq.controller, oirq.specifier, 49 return irq_create_of_mapping(oirq.controller, oirq.specifier,
50 oirq.size); 50 oirq.size);
51 } 51 }
52 EXPORT_SYMBOL_GPL(irq_of_parse_and_map); 52 EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
53 53
54 /** 54 /**
55 * of_irq_find_parent - Given a device node, find its interrupt parent node 55 * of_irq_find_parent - Given a device node, find its interrupt parent node
56 * @child: pointer to device node 56 * @child: pointer to device node
57 * 57 *
58 * Returns a pointer to the interrupt parent node, or NULL if the interrupt 58 * Returns a pointer to the interrupt parent node, or NULL if the interrupt
59 * parent could not be determined. 59 * parent could not be determined.
60 */ 60 */
61 struct device_node *of_irq_find_parent(struct device_node *child) 61 struct device_node *of_irq_find_parent(struct device_node *child)
62 { 62 {
63 struct device_node *p; 63 struct device_node *p;
64 const __be32 *parp; 64 const __be32 *parp;
65 65
66 if (!of_node_get(child)) 66 if (!of_node_get(child))
67 return NULL; 67 return NULL;
68 68
69 do { 69 do {
70 parp = of_get_property(child, "interrupt-parent", NULL); 70 parp = of_get_property(child, "interrupt-parent", NULL);
71 if (parp == NULL) 71 if (parp == NULL)
72 p = of_get_parent(child); 72 p = of_get_parent(child);
73 else { 73 else {
74 if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) 74 if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
75 p = of_node_get(of_irq_dflt_pic); 75 p = of_node_get(of_irq_dflt_pic);
76 else 76 else
77 p = of_find_node_by_phandle(be32_to_cpup(parp)); 77 p = of_find_node_by_phandle(be32_to_cpup(parp));
78 } 78 }
79 of_node_put(child); 79 of_node_put(child);
80 child = p; 80 child = p;
81 } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); 81 } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
82 82
83 return p; 83 return p;
84 } 84 }
85 85
86 /** 86 /**
87 * of_irq_map_raw - Low level interrupt tree parsing 87 * of_irq_map_raw - Low level interrupt tree parsing
88 * @parent: the device interrupt parent 88 * @parent: the device interrupt parent
89 * @intspec: interrupt specifier ("interrupts" property of the device) 89 * @intspec: interrupt specifier ("interrupts" property of the device)
90 * @ointsize: size of the passed in interrupt specifier 90 * @ointsize: size of the passed in interrupt specifier
91 * @addr: address specifier (start of "reg" property of the device) 91 * @addr: address specifier (start of "reg" property of the device)
92 * @out_irq: structure of_irq filled by this function 92 * @out_irq: structure of_irq filled by this function
93 * 93 *
94 * Returns 0 on success and a negative number on error 94 * Returns 0 on success and a negative number on error
95 * 95 *
96 * This function is a low-level interrupt tree walking function. It 96 * This function is a low-level interrupt tree walking function. It
97 * can be used to do a partial walk with synthetized reg and interrupts 97 * can be used to do a partial walk with synthetized reg and interrupts
98 * properties, for example when resolving PCI interrupts when no device 98 * properties, for example when resolving PCI interrupts when no device
99 * node exist for the parent. 99 * node exist for the parent.
100 */ 100 */
101 int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, 101 int of_irq_map_raw(struct device_node *parent, const __be32 *intspec,
102 u32 ointsize, const __be32 *addr, struct of_irq *out_irq) 102 u32 ointsize, const __be32 *addr, struct of_irq *out_irq)
103 { 103 {
104 struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; 104 struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
105 const __be32 *tmp, *imap, *imask; 105 const __be32 *tmp, *imap, *imask;
106 u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; 106 u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
107 int imaplen, match, i; 107 int imaplen, match, i;
108 108
109 pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", 109 pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
110 parent->full_name, be32_to_cpup(intspec), 110 parent->full_name, be32_to_cpup(intspec),
111 be32_to_cpup(intspec + 1), ointsize); 111 be32_to_cpup(intspec + 1), ointsize);
112 112
113 ipar = of_node_get(parent); 113 ipar = of_node_get(parent);
114 114
115 /* First get the #interrupt-cells property of the current cursor 115 /* First get the #interrupt-cells property of the current cursor
116 * that tells us how to interpret the passed-in intspec. If there 116 * that tells us how to interpret the passed-in intspec. If there
117 * is none, we are nice and just walk up the tree 117 * is none, we are nice and just walk up the tree
118 */ 118 */
119 do { 119 do {
120 tmp = of_get_property(ipar, "#interrupt-cells", NULL); 120 tmp = of_get_property(ipar, "#interrupt-cells", NULL);
121 if (tmp != NULL) { 121 if (tmp != NULL) {
122 intsize = be32_to_cpu(*tmp); 122 intsize = be32_to_cpu(*tmp);
123 break; 123 break;
124 } 124 }
125 tnode = ipar; 125 tnode = ipar;
126 ipar = of_irq_find_parent(ipar); 126 ipar = of_irq_find_parent(ipar);
127 of_node_put(tnode); 127 of_node_put(tnode);
128 } while (ipar); 128 } while (ipar);
129 if (ipar == NULL) { 129 if (ipar == NULL) {
130 pr_debug(" -> no parent found !\n"); 130 pr_debug(" -> no parent found !\n");
131 goto fail; 131 goto fail;
132 } 132 }
133 133
134 pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); 134 pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize);
135 135
136 if (ointsize != intsize) 136 if (ointsize != intsize)
137 return -EINVAL; 137 return -EINVAL;
138 138
139 /* Look for this #address-cells. We have to implement the old linux 139 /* Look for this #address-cells. We have to implement the old linux
140 * trick of looking for the parent here as some device-trees rely on it 140 * trick of looking for the parent here as some device-trees rely on it
141 */ 141 */
142 old = of_node_get(ipar); 142 old = of_node_get(ipar);
143 do { 143 do {
144 tmp = of_get_property(old, "#address-cells", NULL); 144 tmp = of_get_property(old, "#address-cells", NULL);
145 tnode = of_get_parent(old); 145 tnode = of_get_parent(old);
146 of_node_put(old); 146 of_node_put(old);
147 old = tnode; 147 old = tnode;
148 } while (old && tmp == NULL); 148 } while (old && tmp == NULL);
149 of_node_put(old); 149 of_node_put(old);
150 old = NULL; 150 old = NULL;
151 addrsize = (tmp == NULL) ? 2 : be32_to_cpu(*tmp); 151 addrsize = (tmp == NULL) ? 2 : be32_to_cpu(*tmp);
152 152
153 pr_debug(" -> addrsize=%d\n", addrsize); 153 pr_debug(" -> addrsize=%d\n", addrsize);
154 154
155 /* Now start the actual "proper" walk of the interrupt tree */ 155 /* Now start the actual "proper" walk of the interrupt tree */
156 while (ipar != NULL) { 156 while (ipar != NULL) {
157 /* Now check if cursor is an interrupt-controller and if it is 157 /* Now check if cursor is an interrupt-controller and if it is
158 * then we are done 158 * then we are done
159 */ 159 */
160 if (of_get_property(ipar, "interrupt-controller", NULL) != 160 if (of_get_property(ipar, "interrupt-controller", NULL) !=
161 NULL) { 161 NULL) {
162 pr_debug(" -> got it !\n"); 162 pr_debug(" -> got it !\n");
163 for (i = 0; i < intsize; i++) 163 for (i = 0; i < intsize; i++)
164 out_irq->specifier[i] = 164 out_irq->specifier[i] =
165 of_read_number(intspec +i, 1); 165 of_read_number(intspec +i, 1);
166 out_irq->size = intsize; 166 out_irq->size = intsize;
167 out_irq->controller = ipar; 167 out_irq->controller = ipar;
168 of_node_put(old); 168 of_node_put(old);
169 return 0; 169 return 0;
170 } 170 }
171 171
172 /* Now look for an interrupt-map */ 172 /* Now look for an interrupt-map */
173 imap = of_get_property(ipar, "interrupt-map", &imaplen); 173 imap = of_get_property(ipar, "interrupt-map", &imaplen);
174 /* No interrupt map, check for an interrupt parent */ 174 /* No interrupt map, check for an interrupt parent */
175 if (imap == NULL) { 175 if (imap == NULL) {
176 pr_debug(" -> no map, getting parent\n"); 176 pr_debug(" -> no map, getting parent\n");
177 newpar = of_irq_find_parent(ipar); 177 newpar = of_irq_find_parent(ipar);
178 goto skiplevel; 178 goto skiplevel;
179 } 179 }
180 imaplen /= sizeof(u32); 180 imaplen /= sizeof(u32);
181 181
182 /* Look for a mask */ 182 /* Look for a mask */
183 imask = of_get_property(ipar, "interrupt-map-mask", NULL); 183 imask = of_get_property(ipar, "interrupt-map-mask", NULL);
184 184
185 /* If we were passed no "reg" property and we attempt to parse 185 /* If we were passed no "reg" property and we attempt to parse
186 * an interrupt-map, then #address-cells must be 0. 186 * an interrupt-map, then #address-cells must be 0.
187 * Fail if it's not. 187 * Fail if it's not.
188 */ 188 */
189 if (addr == NULL && addrsize != 0) { 189 if (addr == NULL && addrsize != 0) {
190 pr_debug(" -> no reg passed in when needed !\n"); 190 pr_debug(" -> no reg passed in when needed !\n");
191 goto fail; 191 goto fail;
192 } 192 }
193 193
194 /* Parse interrupt-map */ 194 /* Parse interrupt-map */
195 match = 0; 195 match = 0;
196 while (imaplen > (addrsize + intsize + 1) && !match) { 196 while (imaplen > (addrsize + intsize + 1) && !match) {
197 /* Compare specifiers */ 197 /* Compare specifiers */
198 match = 1; 198 match = 1;
199 for (i = 0; i < addrsize && match; ++i) { 199 for (i = 0; i < addrsize && match; ++i) {
200 u32 mask = imask ? imask[i] : 0xffffffffu; 200 u32 mask = imask ? imask[i] : 0xffffffffu;
201 match = ((addr[i] ^ imap[i]) & mask) == 0; 201 match = ((addr[i] ^ imap[i]) & mask) == 0;
202 } 202 }
203 for (; i < (addrsize + intsize) && match; ++i) { 203 for (; i < (addrsize + intsize) && match; ++i) {
204 u32 mask = imask ? imask[i] : 0xffffffffu; 204 u32 mask = imask ? imask[i] : 0xffffffffu;
205 match = 205 match =
206 ((intspec[i-addrsize] ^ imap[i]) & mask) == 0; 206 ((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
207 } 207 }
208 imap += addrsize + intsize; 208 imap += addrsize + intsize;
209 imaplen -= addrsize + intsize; 209 imaplen -= addrsize + intsize;
210 210
211 pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); 211 pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
212 212
213 /* Get the interrupt parent */ 213 /* Get the interrupt parent */
214 if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) 214 if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
215 newpar = of_node_get(of_irq_dflt_pic); 215 newpar = of_node_get(of_irq_dflt_pic);
216 else 216 else
217 newpar = of_find_node_by_phandle(be32_to_cpup(imap)); 217 newpar = of_find_node_by_phandle(be32_to_cpup(imap));
218 imap++; 218 imap++;
219 --imaplen; 219 --imaplen;
220 220
221 /* Check if not found */ 221 /* Check if not found */
222 if (newpar == NULL) { 222 if (newpar == NULL) {
223 pr_debug(" -> imap parent not found !\n"); 223 pr_debug(" -> imap parent not found !\n");
224 goto fail; 224 goto fail;
225 } 225 }
226 226
227 /* Get #interrupt-cells and #address-cells of new 227 /* Get #interrupt-cells and #address-cells of new
228 * parent 228 * parent
229 */ 229 */
230 tmp = of_get_property(newpar, "#interrupt-cells", NULL); 230 tmp = of_get_property(newpar, "#interrupt-cells", NULL);
231 if (tmp == NULL) { 231 if (tmp == NULL) {
232 pr_debug(" -> parent lacks #interrupt-cells!\n"); 232 pr_debug(" -> parent lacks #interrupt-cells!\n");
233 goto fail; 233 goto fail;
234 } 234 }
235 newintsize = be32_to_cpu(*tmp); 235 newintsize = be32_to_cpu(*tmp);
236 tmp = of_get_property(newpar, "#address-cells", NULL); 236 tmp = of_get_property(newpar, "#address-cells", NULL);
237 newaddrsize = (tmp == NULL) ? 0 : be32_to_cpu(*tmp); 237 newaddrsize = (tmp == NULL) ? 0 : be32_to_cpu(*tmp);
238 238
239 pr_debug(" -> newintsize=%d, newaddrsize=%d\n", 239 pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
240 newintsize, newaddrsize); 240 newintsize, newaddrsize);
241 241
242 /* Check for malformed properties */ 242 /* Check for malformed properties */
243 if (imaplen < (newaddrsize + newintsize)) 243 if (imaplen < (newaddrsize + newintsize))
244 goto fail; 244 goto fail;
245 245
246 imap += newaddrsize + newintsize; 246 imap += newaddrsize + newintsize;
247 imaplen -= newaddrsize + newintsize; 247 imaplen -= newaddrsize + newintsize;
248 248
249 pr_debug(" -> imaplen=%d\n", imaplen); 249 pr_debug(" -> imaplen=%d\n", imaplen);
250 } 250 }
251 if (!match) 251 if (!match)
252 goto fail; 252 goto fail;
253 253
254 of_node_put(old); 254 of_node_put(old);
255 old = of_node_get(newpar); 255 old = of_node_get(newpar);
256 addrsize = newaddrsize; 256 addrsize = newaddrsize;
257 intsize = newintsize; 257 intsize = newintsize;
258 intspec = imap - intsize; 258 intspec = imap - intsize;
259 addr = intspec - addrsize; 259 addr = intspec - addrsize;
260 260
261 skiplevel: 261 skiplevel:
262 /* Iterate again with new parent */ 262 /* Iterate again with new parent */
263 pr_debug(" -> new parent: %s\n", newpar ? newpar->full_name : "<>"); 263 pr_debug(" -> new parent: %s\n", newpar ? newpar->full_name : "<>");
264 of_node_put(ipar); 264 of_node_put(ipar);
265 ipar = newpar; 265 ipar = newpar;
266 newpar = NULL; 266 newpar = NULL;
267 } 267 }
268 fail: 268 fail:
269 of_node_put(ipar); 269 of_node_put(ipar);
270 of_node_put(old); 270 of_node_put(old);
271 of_node_put(newpar); 271 of_node_put(newpar);
272 272
273 return -EINVAL; 273 return -EINVAL;
274 } 274 }
275 EXPORT_SYMBOL_GPL(of_irq_map_raw); 275 EXPORT_SYMBOL_GPL(of_irq_map_raw);
276 276
277 /** 277 /**
278 * of_irq_map_one - Resolve an interrupt for a device 278 * of_irq_map_one - Resolve an interrupt for a device
279 * @device: the device whose interrupt is to be resolved 279 * @device: the device whose interrupt is to be resolved
280 * @index: index of the interrupt to resolve 280 * @index: index of the interrupt to resolve
281 * @out_irq: structure of_irq filled by this function 281 * @out_irq: structure of_irq filled by this function
282 * 282 *
283 * This function resolves an interrupt, walking the tree, for a given 283 * This function resolves an interrupt, walking the tree, for a given
284 * device-tree node. It's the high level pendant to of_irq_map_raw(). 284 * device-tree node. It's the high level pendant to of_irq_map_raw().
285 */ 285 */
286 int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) 286 int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
287 { 287 {
288 struct device_node *p; 288 struct device_node *p;
289 const __be32 *intspec, *tmp, *addr; 289 const __be32 *intspec, *tmp, *addr;
290 u32 intsize, intlen; 290 u32 intsize, intlen;
291 int res = -EINVAL; 291 int res = -EINVAL;
292 292
293 pr_debug("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index); 293 pr_debug("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
294 294
295 /* OldWorld mac stuff is "special", handle out of line */ 295 /* OldWorld mac stuff is "special", handle out of line */
296 if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) 296 if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
297 return of_irq_map_oldworld(device, index, out_irq); 297 return of_irq_map_oldworld(device, index, out_irq);
298 298
299 /* Get the interrupts property */ 299 /* Get the interrupts property */
300 intspec = of_get_property(device, "interrupts", &intlen); 300 intspec = of_get_property(device, "interrupts", &intlen);
301 if (intspec == NULL) 301 if (intspec == NULL)
302 return -EINVAL; 302 return -EINVAL;
303 intlen /= sizeof(*intspec); 303 intlen /= sizeof(*intspec);
304 304
305 pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); 305 pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);
306 306
307 /* Get the reg property (if any) */ 307 /* Get the reg property (if any) */
308 addr = of_get_property(device, "reg", NULL); 308 addr = of_get_property(device, "reg", NULL);
309 309
310 /* Look for the interrupt parent. */ 310 /* Look for the interrupt parent. */
311 p = of_irq_find_parent(device); 311 p = of_irq_find_parent(device);
312 if (p == NULL) 312 if (p == NULL)
313 return -EINVAL; 313 return -EINVAL;
314 314
315 /* Get size of interrupt specifier */ 315 /* Get size of interrupt specifier */
316 tmp = of_get_property(p, "#interrupt-cells", NULL); 316 tmp = of_get_property(p, "#interrupt-cells", NULL);
317 if (tmp == NULL) 317 if (tmp == NULL)
318 goto out; 318 goto out;
319 intsize = be32_to_cpu(*tmp); 319 intsize = be32_to_cpu(*tmp);
320 320
321 pr_debug(" intsize=%d intlen=%d\n", intsize, intlen); 321 pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
322 322
323 /* Check index */ 323 /* Check index */
324 if ((index + 1) * intsize > intlen) 324 if ((index + 1) * intsize > intlen)
325 goto out; 325 goto out;
326 326
327 /* Get new specifier and map it */ 327 /* Get new specifier and map it */
328 res = of_irq_map_raw(p, intspec + index * intsize, intsize, 328 res = of_irq_map_raw(p, intspec + index * intsize, intsize,
329 addr, out_irq); 329 addr, out_irq);
330 out: 330 out:
331 of_node_put(p); 331 of_node_put(p);
332 return res; 332 return res;
333 } 333 }
334 EXPORT_SYMBOL_GPL(of_irq_map_one); 334 EXPORT_SYMBOL_GPL(of_irq_map_one);
335 335
336 /** 336 /**
337 * of_irq_to_resource - Decode a node's IRQ and return it as a resource 337 * of_irq_to_resource - Decode a node's IRQ and return it as a resource
338 * @dev: pointer to device tree node 338 * @dev: pointer to device tree node
339 * @index: zero-based index of the irq 339 * @index: zero-based index of the irq
340 * @r: pointer to resource structure to return result into. 340 * @r: pointer to resource structure to return result into.
341 */ 341 */
342 int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) 342 int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
343 { 343 {
344 int irq = irq_of_parse_and_map(dev, index); 344 int irq = irq_of_parse_and_map(dev, index);
345 345
346 /* Only dereference the resource if both the 346 /* Only dereference the resource if both the
347 * resource and the irq are valid. */ 347 * resource and the irq are valid. */
348 if (r && irq != NO_IRQ) { 348 if (r && irq != NO_IRQ) {
349 r->start = r->end = irq; 349 r->start = r->end = irq;
350 r->flags = IORESOURCE_IRQ; 350 r->flags = IORESOURCE_IRQ;
351 r->name = dev->full_name; 351 r->name = dev->full_name;
352 } 352 }
353 353
354 return irq; 354 return irq;
355 } 355 }
356 EXPORT_SYMBOL_GPL(of_irq_to_resource); 356 EXPORT_SYMBOL_GPL(of_irq_to_resource);
357 357
358 /** 358 /**
359 * of_irq_count - Count the number of IRQs a node uses 359 * of_irq_count - Count the number of IRQs a node uses
360 * @dev: pointer to device tree node 360 * @dev: pointer to device tree node
361 */ 361 */
362 int of_irq_count(struct device_node *dev) 362 int of_irq_count(struct device_node *dev)
363 { 363 {
364 int nr = 0; 364 int nr = 0;
365 365
366 while (of_irq_to_resource(dev, nr, NULL) != NO_IRQ) 366 while (of_irq_to_resource(dev, nr, NULL) != NO_IRQ)
367 nr++; 367 nr++;
368 368
369 return nr; 369 return nr;
370 } 370 }
371 371
372 /** 372 /**
373 * of_irq_to_resource_table - Fill in resource table with node's IRQ info 373 * of_irq_to_resource_table - Fill in resource table with node's IRQ info
374 * @dev: pointer to device tree node 374 * @dev: pointer to device tree node
375 * @res: array of resources to fill in 375 * @res: array of resources to fill in
376 * @nr_irqs: the number of IRQs (and upper bound for num of @res elements) 376 * @nr_irqs: the number of IRQs (and upper bound for num of @res elements)
377 * 377 *
378 * Returns the size of the filled in table (up to @nr_irqs). 378 * Returns the size of the filled in table (up to @nr_irqs).
379 */ 379 */
380 int of_irq_to_resource_table(struct device_node *dev, struct resource *res, 380 int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
381 int nr_irqs) 381 int nr_irqs)
382 { 382 {
383 int i; 383 int i;
384 384
385 for (i = 0; i < nr_irqs; i++, res++) 385 for (i = 0; i < nr_irqs; i++, res++)
386 if (of_irq_to_resource(dev, i, res) == NO_IRQ) 386 if (of_irq_to_resource(dev, i, res) == NO_IRQ)
387 break; 387 break;
388 388
389 return i; 389 return i;
390 } 390 }
391 391
392 struct intc_desc { 392 struct intc_desc {
393 struct list_head list; 393 struct list_head list;
394 struct device_node *dev; 394 struct device_node *dev;
395 struct device_node *interrupt_parent; 395 struct device_node *interrupt_parent;
396 }; 396 };
397 397
398 /** 398 /**
399 * of_irq_init - Scan and init matching interrupt controllers in DT 399 * of_irq_init - Scan and init matching interrupt controllers in DT
400 * @matches: 0 terminated array of nodes to match and init function to call 400 * @matches: 0 terminated array of nodes to match and init function to call
401 * 401 *
402 * This function scans the device tree for matching interrupt controller nodes, 402 * This function scans the device tree for matching interrupt controller nodes,
403 * and calls their initialization functions in order with parents first. 403 * and calls their initialization functions in order with parents first.
404 */ 404 */
405 void __init of_irq_init(const struct of_device_id *matches) 405 void __init of_irq_init(const struct of_device_id *matches)
406 { 406 {
407 struct device_node *np, *parent = NULL; 407 struct device_node *np, *parent = NULL;
408 struct intc_desc *desc, *temp_desc; 408 struct intc_desc *desc, *temp_desc;
409 struct list_head intc_desc_list, intc_parent_list; 409 struct list_head intc_desc_list, intc_parent_list;
410 410
411 INIT_LIST_HEAD(&intc_desc_list); 411 INIT_LIST_HEAD(&intc_desc_list);
412 INIT_LIST_HEAD(&intc_parent_list); 412 INIT_LIST_HEAD(&intc_parent_list);
413 413
414 for_each_matching_node(np, matches) { 414 for_each_matching_node(np, matches) {
415 if (!of_find_property(np, "interrupt-controller", NULL)) 415 if (!of_find_property(np, "interrupt-controller", NULL))
416 continue; 416 continue;
417 /* 417 /*
418 * Here, we allocate and populate an intc_desc with the node 418 * Here, we allocate and populate an intc_desc with the node
419 * pointer, interrupt-parent device_node etc. 419 * pointer, interrupt-parent device_node etc.
420 */ 420 */
421 desc = kzalloc(sizeof(*desc), GFP_KERNEL); 421 desc = kzalloc(sizeof(*desc), GFP_KERNEL);
422 if (WARN_ON(!desc)) 422 if (WARN_ON(!desc))
423 goto err; 423 goto err;
424 424
425 desc->dev = np; 425 desc->dev = np;
426 desc->interrupt_parent = of_irq_find_parent(np); 426 desc->interrupt_parent = of_irq_find_parent(np);
427 if (desc->interrupt_parent == np)
428 desc->interrupt_parent = NULL;
427 list_add_tail(&desc->list, &intc_desc_list); 429 list_add_tail(&desc->list, &intc_desc_list);
428 } 430 }
429 431
430 /* 432 /*
431 * The root irq controller is the one without an interrupt-parent. 433 * The root irq controller is the one without an interrupt-parent.
432 * That one goes first, followed by the controllers that reference it, 434 * That one goes first, followed by the controllers that reference it,
433 * followed by the ones that reference the 2nd level controllers, etc. 435 * followed by the ones that reference the 2nd level controllers, etc.
434 */ 436 */
435 while (!list_empty(&intc_desc_list)) { 437 while (!list_empty(&intc_desc_list)) {
436 /* 438 /*
437 * Process all controllers with the current 'parent'. 439 * Process all controllers with the current 'parent'.
438 * First pass will be looking for NULL as the parent. 440 * First pass will be looking for NULL as the parent.
439 * The assumption is that NULL parent means a root controller. 441 * The assumption is that NULL parent means a root controller.
440 */ 442 */
441 list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) { 443 list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
442 const struct of_device_id *match; 444 const struct of_device_id *match;
443 int ret; 445 int ret;
444 of_irq_init_cb_t irq_init_cb; 446 of_irq_init_cb_t irq_init_cb;
445 447
446 if (desc->interrupt_parent != parent) 448 if (desc->interrupt_parent != parent)
447 continue; 449 continue;
448 450
449 list_del(&desc->list); 451 list_del(&desc->list);
450 match = of_match_node(matches, desc->dev); 452 match = of_match_node(matches, desc->dev);
451 if (WARN(!match->data, 453 if (WARN(!match->data,
452 "of_irq_init: no init function for %s\n", 454 "of_irq_init: no init function for %s\n",
453 match->compatible)) { 455 match->compatible)) {
454 kfree(desc); 456 kfree(desc);
455 continue; 457 continue;
456 } 458 }
457 459
458 pr_debug("of_irq_init: init %s @ %p, parent %p\n", 460 pr_debug("of_irq_init: init %s @ %p, parent %p\n",
459 match->compatible, 461 match->compatible,
460 desc->dev, desc->interrupt_parent); 462 desc->dev, desc->interrupt_parent);
461 irq_init_cb = match->data; 463 irq_init_cb = match->data;
462 ret = irq_init_cb(desc->dev, desc->interrupt_parent); 464 ret = irq_init_cb(desc->dev, desc->interrupt_parent);
463 if (ret) { 465 if (ret) {
464 kfree(desc); 466 kfree(desc);
465 continue; 467 continue;
466 } 468 }
467 469
468 /* 470 /*
469 * This one is now set up; add it to the parent list so 471 * This one is now set up; add it to the parent list so
470 * its children can get processed in a subsequent pass. 472 * its children can get processed in a subsequent pass.
471 */ 473 */
472 list_add_tail(&desc->list, &intc_parent_list); 474 list_add_tail(&desc->list, &intc_parent_list);
473 } 475 }
474 476
475 /* Get the next pending parent that might have children */ 477 /* Get the next pending parent that might have children */
476 desc = list_first_entry(&intc_parent_list, typeof(*desc), list); 478 desc = list_first_entry(&intc_parent_list, typeof(*desc), list);
477 if (list_empty(&intc_parent_list) || !desc) { 479 if (list_empty(&intc_parent_list) || !desc) {
478 pr_err("of_irq_init: children remain, but no parents\n"); 480 pr_err("of_irq_init: children remain, but no parents\n");
479 break; 481 break;
480 } 482 }
481 list_del(&desc->list); 483 list_del(&desc->list);
482 parent = desc->dev; 484 parent = desc->dev;
483 kfree(desc); 485 kfree(desc);
484 } 486 }
485 487
486 list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) { 488 list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {
487 list_del(&desc->list); 489 list_del(&desc->list);
488 kfree(desc); 490 kfree(desc);
489 } 491 }
490 err: 492 err:
491 list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) { 493 list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
492 list_del(&desc->list); 494 list_del(&desc->list);
493 kfree(desc); 495 kfree(desc);
494 } 496 }
495 } 497 }
496 498