| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame^] | 1 | /* | 
 | 2 |  *  giu.c, General-purpose I/O Unit Interrupt routines for NEC VR4100 series. | 
 | 3 |  * | 
 | 4 |  *  Copyright (C) 2002 MontaVista Software Inc. | 
 | 5 |  *    Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com> | 
 | 6 |  *  Copyright (C) 2003-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp> | 
 | 7 |  *  Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) | 
 | 8 |  * | 
 | 9 |  *  This program is free software; you can redistribute it and/or modify | 
 | 10 |  *  it under the terms of the GNU General Public License as published by | 
 | 11 |  *  the Free Software Foundation; either version 2 of the License, or | 
 | 12 |  *  (at your option) any later version. | 
 | 13 |  * | 
 | 14 |  *  This program is distributed in the hope that it will be useful, | 
 | 15 |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 | 16 |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 | 17 |  *  GNU General Public License for more details. | 
 | 18 |  * | 
 | 19 |  *  You should have received a copy of the GNU General Public License | 
 | 20 |  *  along with this program; if not, write to the Free Software | 
 | 21 |  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
 | 22 |  */ | 
 | 23 | /* | 
 | 24 |  * Changes: | 
 | 25 |  *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> | 
 | 26 |  *  - New creation, NEC VR4111, VR4121, VR4122 and VR4131 are supported. | 
 | 27 |  * | 
 | 28 |  *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp> | 
 | 29 |  *  - Added support for NEC VR4133. | 
 | 30 |  *  - Removed board_irq_init. | 
 | 31 |  */ | 
 | 32 | #include <linux/errno.h> | 
 | 33 | #include <linux/init.h> | 
 | 34 | #include <linux/irq.h> | 
 | 35 | #include <linux/kernel.h> | 
 | 36 | #include <linux/module.h> | 
 | 37 | #include <linux/smp.h> | 
 | 38 | #include <linux/types.h> | 
 | 39 |  | 
 | 40 | #include <asm/cpu.h> | 
 | 41 | #include <asm/io.h> | 
 | 42 | #include <asm/vr41xx/vr41xx.h> | 
 | 43 |  | 
 | 44 | #define GIUIOSELL_TYPE1	KSEG1ADDR(0x0b000100) | 
 | 45 | #define GIUIOSELL_TYPE2	KSEG1ADDR(0x0f000140) | 
 | 46 |  | 
 | 47 | #define GIUIOSELL	0x00 | 
 | 48 | #define GIUIOSELH	0x02 | 
 | 49 | #define GIUINTSTATL	0x08 | 
 | 50 | #define GIUINTSTATH	0x0a | 
 | 51 | #define GIUINTENL	0x0c | 
 | 52 | #define GIUINTENH	0x0e | 
 | 53 | #define GIUINTTYPL	0x10 | 
 | 54 | #define GIUINTTYPH	0x12 | 
 | 55 | #define GIUINTALSELL	0x14 | 
 | 56 | #define GIUINTALSELH	0x16 | 
 | 57 | #define GIUINTHTSELL	0x18 | 
 | 58 | #define GIUINTHTSELH	0x1a | 
 | 59 | #define GIUFEDGEINHL	0x20 | 
 | 60 | #define GIUFEDGEINHH	0x22 | 
 | 61 | #define GIUREDGEINHL	0x24 | 
 | 62 | #define GIUREDGEINHH	0x26 | 
 | 63 |  | 
 | 64 | static uint32_t giu_base; | 
 | 65 |  | 
 | 66 | static struct irqaction giu_cascade = { | 
 | 67 | 	.handler	= no_action, | 
 | 68 | 	.mask		= CPU_MASK_NONE, | 
 | 69 | 	.name		= "cascade", | 
 | 70 | }; | 
 | 71 |  | 
 | 72 | #define read_giuint(offset)		readw(giu_base + (offset)) | 
 | 73 | #define write_giuint(val, offset)	writew((val), giu_base + (offset)) | 
 | 74 |  | 
 | 75 | #define GIUINT_HIGH_OFFSET	16 | 
 | 76 |  | 
 | 77 | static inline uint16_t set_giuint(uint8_t offset, uint16_t set) | 
 | 78 | { | 
 | 79 | 	uint16_t res; | 
 | 80 |  | 
 | 81 | 	res = read_giuint(offset); | 
 | 82 | 	res |= set; | 
 | 83 | 	write_giuint(res, offset); | 
 | 84 |  | 
 | 85 | 	return res; | 
 | 86 | } | 
 | 87 |  | 
 | 88 | static inline uint16_t clear_giuint(uint8_t offset, uint16_t clear) | 
 | 89 | { | 
 | 90 | 	uint16_t res; | 
 | 91 |  | 
 | 92 | 	res = read_giuint(offset); | 
 | 93 | 	res &= ~clear; | 
 | 94 | 	write_giuint(res, offset); | 
 | 95 |  | 
 | 96 | 	return res; | 
 | 97 | } | 
 | 98 |  | 
 | 99 | static unsigned int startup_giuint_low_irq(unsigned int irq) | 
 | 100 | { | 
 | 101 | 	unsigned int pin; | 
 | 102 |  | 
 | 103 | 	pin = GIU_IRQ_TO_PIN(irq); | 
 | 104 | 	write_giuint((uint16_t)1 << pin, GIUINTSTATL); | 
 | 105 | 	set_giuint(GIUINTENL, (uint16_t)1 << pin); | 
 | 106 |  | 
 | 107 | 	return 0; | 
 | 108 | } | 
 | 109 |  | 
 | 110 | static void shutdown_giuint_low_irq(unsigned int irq) | 
 | 111 | { | 
 | 112 | 	clear_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq)); | 
 | 113 | } | 
 | 114 |  | 
 | 115 | static void enable_giuint_low_irq(unsigned int irq) | 
 | 116 | { | 
 | 117 | 	set_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq)); | 
 | 118 | } | 
 | 119 |  | 
 | 120 | #define disable_giuint_low_irq	shutdown_giuint_low_irq | 
 | 121 |  | 
 | 122 | static void ack_giuint_low_irq(unsigned int irq) | 
 | 123 | { | 
 | 124 | 	unsigned int pin; | 
 | 125 |  | 
 | 126 | 	pin = GIU_IRQ_TO_PIN(irq); | 
 | 127 | 	clear_giuint(GIUINTENL, (uint16_t)1 << pin); | 
 | 128 | 	write_giuint((uint16_t)1 << pin, GIUINTSTATL); | 
 | 129 | } | 
 | 130 |  | 
 | 131 | static void end_giuint_low_irq(unsigned int irq) | 
 | 132 | { | 
 | 133 | 	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | 
 | 134 | 		set_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq)); | 
 | 135 | } | 
 | 136 |  | 
 | 137 | static struct hw_interrupt_type giuint_low_irq_type = { | 
 | 138 | 	.typename	= "GIUINTL", | 
 | 139 | 	.startup	= startup_giuint_low_irq, | 
 | 140 | 	.shutdown	= shutdown_giuint_low_irq, | 
 | 141 | 	.enable		= enable_giuint_low_irq, | 
 | 142 | 	.disable	= disable_giuint_low_irq, | 
 | 143 | 	.ack		= ack_giuint_low_irq, | 
 | 144 | 	.end		= end_giuint_low_irq, | 
 | 145 | }; | 
 | 146 |  | 
 | 147 | static unsigned int startup_giuint_high_irq(unsigned int irq) | 
 | 148 | { | 
 | 149 | 	unsigned int pin; | 
 | 150 |  | 
 | 151 | 	pin = GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET); | 
 | 152 | 	write_giuint((uint16_t)1 << pin, GIUINTSTATH); | 
 | 153 | 	set_giuint(GIUINTENH, (uint16_t)1 << pin); | 
 | 154 |  | 
 | 155 | 	return 0; | 
 | 156 | } | 
 | 157 |  | 
 | 158 | static void shutdown_giuint_high_irq(unsigned int irq) | 
 | 159 | { | 
 | 160 | 	clear_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET)); | 
 | 161 | } | 
 | 162 |  | 
 | 163 | static void enable_giuint_high_irq(unsigned int irq) | 
 | 164 | { | 
 | 165 | 	set_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET)); | 
 | 166 | } | 
 | 167 |  | 
 | 168 | #define disable_giuint_high_irq	shutdown_giuint_high_irq | 
 | 169 |  | 
 | 170 | static void ack_giuint_high_irq(unsigned int irq) | 
 | 171 | { | 
 | 172 | 	unsigned int pin; | 
 | 173 |  | 
 | 174 | 	pin = GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET); | 
 | 175 | 	clear_giuint(GIUINTENH, (uint16_t)1 << pin); | 
 | 176 | 	write_giuint((uint16_t)1 << pin, GIUINTSTATH); | 
 | 177 | } | 
 | 178 |  | 
 | 179 | static void end_giuint_high_irq(unsigned int irq) | 
 | 180 | { | 
 | 181 | 	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | 
 | 182 | 		set_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET)); | 
 | 183 | } | 
 | 184 |  | 
 | 185 | static struct hw_interrupt_type giuint_high_irq_type = { | 
 | 186 | 	.typename	= "GIUINTH", | 
 | 187 | 	.startup	= startup_giuint_high_irq, | 
 | 188 | 	.shutdown	= shutdown_giuint_high_irq, | 
 | 189 | 	.enable		= enable_giuint_high_irq, | 
 | 190 | 	.disable	= disable_giuint_high_irq, | 
 | 191 | 	.ack		= ack_giuint_high_irq, | 
 | 192 | 	.end		= end_giuint_high_irq, | 
 | 193 | }; | 
 | 194 |  | 
 | 195 | void __init init_vr41xx_giuint_irq(void) | 
 | 196 | { | 
 | 197 | 	int i; | 
 | 198 |  | 
 | 199 | 	for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { | 
 | 200 | 		if (i < (GIU_IRQ_BASE + GIUINT_HIGH_OFFSET)) | 
 | 201 | 			irq_desc[i].handler = &giuint_low_irq_type; | 
 | 202 | 		else | 
 | 203 | 			irq_desc[i].handler = &giuint_high_irq_type; | 
 | 204 | 	} | 
 | 205 |  | 
 | 206 | 	setup_irq(GIUINT_CASCADE_IRQ, &giu_cascade); | 
 | 207 | } | 
 | 208 |  | 
 | 209 | void vr41xx_set_irq_trigger(int pin, int trigger, int hold) | 
 | 210 | { | 
 | 211 | 	uint16_t mask; | 
 | 212 |  | 
 | 213 | 	if (pin < GIUINT_HIGH_OFFSET) { | 
 | 214 | 		mask = (uint16_t)1 << pin; | 
 | 215 | 		if (trigger != TRIGGER_LEVEL) { | 
 | 216 |         		set_giuint(GIUINTTYPL, mask); | 
 | 217 | 			if (hold == SIGNAL_HOLD) | 
 | 218 | 				set_giuint(GIUINTHTSELL, mask); | 
 | 219 | 			else | 
 | 220 | 				clear_giuint(GIUINTHTSELL, mask); | 
 | 221 | 			if (current_cpu_data.cputype == CPU_VR4133) { | 
 | 222 | 				switch (trigger) { | 
 | 223 | 				case TRIGGER_EDGE_FALLING: | 
 | 224 | 					set_giuint(GIUFEDGEINHL, mask); | 
 | 225 | 					clear_giuint(GIUREDGEINHL, mask); | 
 | 226 | 					break; | 
 | 227 | 				case TRIGGER_EDGE_RISING: | 
 | 228 | 					clear_giuint(GIUFEDGEINHL, mask); | 
 | 229 | 					set_giuint(GIUREDGEINHL, mask); | 
 | 230 | 					break; | 
 | 231 | 				default: | 
 | 232 | 					set_giuint(GIUFEDGEINHL, mask); | 
 | 233 | 					set_giuint(GIUREDGEINHL, mask); | 
 | 234 | 					break; | 
 | 235 | 				} | 
 | 236 | 			} | 
 | 237 | 		} else { | 
 | 238 | 			clear_giuint(GIUINTTYPL, mask); | 
 | 239 | 			clear_giuint(GIUINTHTSELL, mask); | 
 | 240 | 		} | 
 | 241 | 		write_giuint(mask, GIUINTSTATL); | 
 | 242 | 	} else { | 
 | 243 | 		mask = (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET); | 
 | 244 | 		if (trigger != TRIGGER_LEVEL) { | 
 | 245 | 			set_giuint(GIUINTTYPH, mask); | 
 | 246 | 			if (hold == SIGNAL_HOLD) | 
 | 247 | 				set_giuint(GIUINTHTSELH, mask); | 
 | 248 | 			else | 
 | 249 | 				clear_giuint(GIUINTHTSELH, mask); | 
 | 250 | 			if (current_cpu_data.cputype == CPU_VR4133) { | 
 | 251 | 				switch (trigger) { | 
 | 252 | 				case TRIGGER_EDGE_FALLING: | 
 | 253 | 					set_giuint(GIUFEDGEINHH, mask); | 
 | 254 | 					clear_giuint(GIUREDGEINHH, mask); | 
 | 255 | 					break; | 
 | 256 | 				case TRIGGER_EDGE_RISING: | 
 | 257 | 					clear_giuint(GIUFEDGEINHH, mask); | 
 | 258 | 					set_giuint(GIUREDGEINHH, mask); | 
 | 259 | 					break; | 
 | 260 | 				default: | 
 | 261 | 					set_giuint(GIUFEDGEINHH, mask); | 
 | 262 | 					set_giuint(GIUREDGEINHH, mask); | 
 | 263 | 					break; | 
 | 264 | 				} | 
 | 265 | 			} | 
 | 266 | 		} else { | 
 | 267 | 			clear_giuint(GIUINTTYPH, mask); | 
 | 268 | 			clear_giuint(GIUINTHTSELH, mask); | 
 | 269 | 		} | 
 | 270 | 		write_giuint(mask, GIUINTSTATH); | 
 | 271 | 	} | 
 | 272 | } | 
 | 273 |  | 
 | 274 | EXPORT_SYMBOL(vr41xx_set_irq_trigger); | 
 | 275 |  | 
 | 276 | void vr41xx_set_irq_level(int pin, int level) | 
 | 277 | { | 
 | 278 | 	uint16_t mask; | 
 | 279 |  | 
 | 280 | 	if (pin < GIUINT_HIGH_OFFSET) { | 
 | 281 | 		mask = (uint16_t)1 << pin; | 
 | 282 | 		if (level == LEVEL_HIGH) | 
 | 283 | 			set_giuint(GIUINTALSELL, mask); | 
 | 284 | 		else | 
 | 285 | 			clear_giuint(GIUINTALSELL, mask); | 
 | 286 | 		write_giuint(mask, GIUINTSTATL); | 
 | 287 | 	} else { | 
 | 288 | 		mask = (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET); | 
 | 289 | 		if (level == LEVEL_HIGH) | 
 | 290 | 			set_giuint(GIUINTALSELH, mask); | 
 | 291 | 		else | 
 | 292 | 			clear_giuint(GIUINTALSELH, mask); | 
 | 293 | 		write_giuint(mask, GIUINTSTATH); | 
 | 294 | 	} | 
 | 295 | } | 
 | 296 |  | 
 | 297 | EXPORT_SYMBOL(vr41xx_set_irq_level); | 
 | 298 |  | 
 | 299 | #define GIUINT_NR_IRQS		32 | 
 | 300 |  | 
 | 301 | enum { | 
 | 302 | 	GIUINT_NO_CASCADE, | 
 | 303 | 	GIUINT_CASCADE | 
 | 304 | }; | 
 | 305 |  | 
 | 306 | struct vr41xx_giuint_cascade { | 
 | 307 | 	unsigned int flag; | 
 | 308 | 	int (*get_irq_number)(int irq); | 
 | 309 | }; | 
 | 310 |  | 
 | 311 | static struct vr41xx_giuint_cascade giuint_cascade[GIUINT_NR_IRQS]; | 
 | 312 |  | 
 | 313 | static int no_irq_number(int irq) | 
 | 314 | { | 
 | 315 | 	return -EINVAL; | 
 | 316 | } | 
 | 317 |  | 
 | 318 | int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq)) | 
 | 319 | { | 
 | 320 | 	unsigned int pin; | 
 | 321 | 	int retval; | 
 | 322 |  | 
 | 323 | 	if (irq < GIU_IRQ(0) || irq > GIU_IRQ(31)) | 
 | 324 | 		return -EINVAL; | 
 | 325 |  | 
 | 326 | 	if(!get_irq_number) | 
 | 327 | 		return -EINVAL; | 
 | 328 |  | 
 | 329 | 	pin = GIU_IRQ_TO_PIN(irq); | 
 | 330 | 	giuint_cascade[pin].flag = GIUINT_CASCADE; | 
 | 331 | 	giuint_cascade[pin].get_irq_number = get_irq_number; | 
 | 332 |  | 
 | 333 | 	retval = setup_irq(irq, &giu_cascade); | 
 | 334 | 	if (retval != 0) { | 
 | 335 | 		giuint_cascade[pin].flag = GIUINT_NO_CASCADE; | 
 | 336 | 		giuint_cascade[pin].get_irq_number = no_irq_number; | 
 | 337 | 	} | 
 | 338 |  | 
 | 339 | 	return retval; | 
 | 340 | } | 
 | 341 |  | 
 | 342 | EXPORT_SYMBOL(vr41xx_cascade_irq); | 
 | 343 |  | 
 | 344 | static inline int get_irq_pin_number(void) | 
 | 345 | { | 
 | 346 | 	uint16_t pendl, pendh, maskl, maskh; | 
 | 347 | 	int i; | 
 | 348 |  | 
 | 349 | 	pendl = read_giuint(GIUINTSTATL); | 
 | 350 | 	pendh = read_giuint(GIUINTSTATH); | 
 | 351 | 	maskl = read_giuint(GIUINTENL); | 
 | 352 | 	maskh = read_giuint(GIUINTENH); | 
 | 353 |  | 
 | 354 | 	maskl &= pendl; | 
 | 355 | 	maskh &= pendh; | 
 | 356 |  | 
 | 357 | 	if (maskl) { | 
 | 358 | 		for (i = 0; i < 16; i++) { | 
 | 359 | 			if (maskl & ((uint16_t)1 << i)) | 
 | 360 | 				return i; | 
 | 361 | 		} | 
 | 362 | 	} else if (maskh) { | 
 | 363 | 		for (i = 0; i < 16; i++) { | 
 | 364 | 			if (maskh & ((uint16_t)1 << i)) | 
 | 365 | 				return i + GIUINT_HIGH_OFFSET; | 
 | 366 | 		} | 
 | 367 | 	} | 
 | 368 |  | 
 | 369 | 	printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", | 
 | 370 | 	       maskl, pendl, maskh, pendh); | 
 | 371 |  | 
 | 372 | 	atomic_inc(&irq_err_count); | 
 | 373 |  | 
 | 374 | 	return -1; | 
 | 375 | } | 
 | 376 |  | 
 | 377 | static inline void ack_giuint_irq(int pin) | 
 | 378 | { | 
 | 379 | 	if (pin < GIUINT_HIGH_OFFSET) { | 
 | 380 | 		clear_giuint(GIUINTENL, (uint16_t)1 << pin); | 
 | 381 | 		write_giuint((uint16_t)1 << pin, GIUINTSTATL); | 
 | 382 | 	} else { | 
 | 383 | 		pin -= GIUINT_HIGH_OFFSET; | 
 | 384 | 		clear_giuint(GIUINTENH, (uint16_t)1 << pin); | 
 | 385 | 		write_giuint((uint16_t)1 << pin, GIUINTSTATH); | 
 | 386 | 	} | 
 | 387 | } | 
 | 388 |  | 
 | 389 | static inline void end_giuint_irq(int pin) | 
 | 390 | { | 
 | 391 | 	if (pin < GIUINT_HIGH_OFFSET) | 
 | 392 | 		set_giuint(GIUINTENL, (uint16_t)1 << pin); | 
 | 393 | 	else | 
 | 394 | 		set_giuint(GIUINTENH, (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET)); | 
 | 395 | } | 
 | 396 |  | 
 | 397 | void giuint_irq_dispatch(struct pt_regs *regs) | 
 | 398 | { | 
 | 399 | 	struct vr41xx_giuint_cascade *cascade; | 
 | 400 | 	unsigned int giuint_irq; | 
 | 401 | 	int pin; | 
 | 402 |  | 
 | 403 | 	pin = get_irq_pin_number(); | 
 | 404 | 	if (pin < 0) | 
 | 405 | 		return; | 
 | 406 |  | 
 | 407 | 	disable_irq(GIUINT_CASCADE_IRQ); | 
 | 408 |  | 
 | 409 | 	cascade = &giuint_cascade[pin]; | 
 | 410 | 	giuint_irq = GIU_IRQ(pin); | 
 | 411 | 	if (cascade->flag == GIUINT_CASCADE) { | 
 | 412 | 		int irq = cascade->get_irq_number(giuint_irq); | 
 | 413 | 		ack_giuint_irq(pin); | 
 | 414 | 		if (irq >= 0) | 
 | 415 | 			do_IRQ(irq, regs); | 
 | 416 | 		end_giuint_irq(pin); | 
 | 417 | 	} else { | 
 | 418 | 		do_IRQ(giuint_irq, regs); | 
 | 419 | 	} | 
 | 420 |  | 
 | 421 | 	enable_irq(GIUINT_CASCADE_IRQ); | 
 | 422 | } | 
 | 423 |  | 
 | 424 | static int __init vr41xx_giu_init(void) | 
 | 425 | { | 
 | 426 | 	int i; | 
 | 427 |  | 
 | 428 | 	switch (current_cpu_data.cputype) { | 
 | 429 | 	case CPU_VR4111: | 
 | 430 | 	case CPU_VR4121: | 
 | 431 | 		giu_base = GIUIOSELL_TYPE1; | 
 | 432 | 		break; | 
 | 433 | 	case CPU_VR4122: | 
 | 434 | 	case CPU_VR4131: | 
 | 435 | 	case CPU_VR4133: | 
 | 436 | 		giu_base = GIUIOSELL_TYPE2; | 
 | 437 | 		break; | 
 | 438 | 	default: | 
 | 439 | 		printk(KERN_ERR "GIU: Unexpected CPU of NEC VR4100 series\n"); | 
 | 440 | 		return -EINVAL; | 
 | 441 | 	} | 
 | 442 |  | 
 | 443 | 	for (i = 0; i < GIUINT_NR_IRQS; i++) { | 
 | 444 | 		if (i < GIUINT_HIGH_OFFSET) | 
 | 445 | 			clear_giuint(GIUINTENL, (uint16_t)1 << i); | 
 | 446 | 		else | 
 | 447 | 			clear_giuint(GIUINTENH, (uint16_t)1 << (i - GIUINT_HIGH_OFFSET)); | 
 | 448 | 		giuint_cascade[i].flag = GIUINT_NO_CASCADE; | 
 | 449 | 		giuint_cascade[i].get_irq_number = no_irq_number; | 
 | 450 | 	} | 
 | 451 |  | 
 | 452 | 	return 0; | 
 | 453 | } | 
 | 454 |  | 
 | 455 | early_initcall(vr41xx_giu_init); |