arm:rs232 fix.
The kernel API for requesting interrupts and the associated callback have a somewhat strange behaviour. Requesting an interrupts is done by calling sys_irqsetpolicy using an interrupt and a given id. This id can be modified by the sys_irqsetpolicy and must be used for subsequent calls to sys_irqenable/sys_irqdisable. However upon an incoming call from the kernel NOTIFY_ARG contains the original value encoded in a set e.g. if 1 << id == true the interrupt was raised.
This commit is contained in:
		
							parent
							
								
									aa3db0e0e2
								
							
						
					
					
						commit
						037aeb5a13
					
				| @ -108,6 +108,7 @@ typedef struct rs232 { | |||||||
| 
 | 
 | ||||||
|   int irq;			/* irq for this line */ |   int irq;			/* irq for this line */ | ||||||
|   int irq_hook_id;		/* interrupt hook */ |   int irq_hook_id;		/* interrupt hook */ | ||||||
|  |   int irq_hook_kernel_id;	/* id as returned from sys_irqsetpolicy */ | ||||||
| 
 | 
 | ||||||
|   char ibuf[RS_IBUFSIZE];	/* input buffer */ |   char ibuf[RS_IBUFSIZE];	/* input buffer */ | ||||||
|   char obuf[RS_OBUFSIZE];	/* output buffer */ |   char obuf[RS_OBUFSIZE];	/* output buffer */ | ||||||
| @ -428,7 +429,7 @@ static void rs_config(rs232_t *rs) | |||||||
| 	 * avoid looping forever. | 	 * avoid looping forever. | ||||||
| 	 */ | 	 */ | ||||||
| 
 | 
 | ||||||
| 	if (sys_irqdisable(&rs->irq_hook_id) != OK) | 	if (sys_irqdisable(&rs->irq_hook_kernel_id) != OK) | ||||||
| 		panic("unable to disable interrupts"); | 		panic("unable to disable interrupts"); | ||||||
| 
 | 
 | ||||||
| 	/* Select the baud rate divisor registers and change the rate. */ | 	/* Select the baud rate divisor registers and change the rate. */ | ||||||
| @ -456,7 +457,7 @@ static void rs_config(rs232_t *rs) | |||||||
| 	if ((tp->tty_termios.c_lflag & IXON) && rs->oxoff != _POSIX_VDISABLE) | 	if ((tp->tty_termios.c_lflag & IXON) && rs->oxoff != _POSIX_VDISABLE) | ||||||
| 		rs->ostate &= ~ORAW; | 		rs->ostate &= ~ORAW; | ||||||
| 	(void) serial_in(rs, OMAP3_IIR); | 	(void) serial_in(rs, OMAP3_IIR); | ||||||
| 	if (sys_irqenable(&rs->irq_hook_id) != OK) | 	if (sys_irqenable(&rs->irq_hook_kernel_id) != OK) | ||||||
| 		panic("unable to enable interrupts"); | 		panic("unable to enable interrupts"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -519,16 +520,27 @@ rs_init(tty_t *tp) | |||||||
| 
 | 
 | ||||||
| 	/* Configure IRQ */ | 	/* Configure IRQ */ | ||||||
| 	rs->irq = this_omap3.irq; | 	rs->irq = this_omap3.irq; | ||||||
| 	rs->irq_hook_id = 1 << line;	/* call back with irq line number */ | 
 | ||||||
| 	if (sys_irqsetpolicy(rs->irq, 0, &rs->irq_hook_id) != OK) { | 	/* callback with irq line number + 1 because using line number 0 
 | ||||||
|  | 	   fails eslewhere */ | ||||||
|  | 	rs->irq_hook_kernel_id = rs->irq_hook_id = line + 1;	 | ||||||
|  | 
 | ||||||
|  | 	/* sys_irqsetpolicy modifies irq_hook_kernel_id. this modified id
 | ||||||
|  | 	 * needs to be used in sys_irqenable and similar calls. | ||||||
|  | 	 */ | ||||||
|  | 	if (sys_irqsetpolicy(rs->irq, 0, &rs->irq_hook_kernel_id) != OK) { | ||||||
| 		printf("RS232: Couldn't obtain hook for irq %d\n", rs->irq); | 		printf("RS232: Couldn't obtain hook for irq %d\n", rs->irq); | ||||||
| 	} else { | 	} else { | ||||||
| 		if (sys_irqenable(&rs->irq_hook_id) != OK)  { | 		if (sys_irqenable(&rs->irq_hook_kernel_id) != OK)  { | ||||||
| 			printf("RS232: Couldn't enable irq %d (hooked)\n", | 			printf("RS232: Couldn't enable irq %d (hooked)\n", | ||||||
| 				rs->irq); | 				rs->irq); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	rs_irq_set |= (1 << (rs->irq_hook_id + 1)); | 
 | ||||||
|  | 	/* When we get called back we get called back using the original 
 | ||||||
|  | 	 * hook_id bit set. e.g. if we register with hook_id 5 the callback | ||||||
|  | 	 * calls us with the 5 th bit set */ | ||||||
|  | 	rs_irq_set |= (1 << (rs->irq_hook_id )); | ||||||
| 
 | 
 | ||||||
| 	/* Enable interrupts */ | 	/* Enable interrupts */ | ||||||
| 	rs_reset(rs); | 	rs_reset(rs); | ||||||
| @ -559,9 +571,9 @@ rs_interrupt(message *m) | |||||||
| 
 | 
 | ||||||
| 	irq_set = m->NOTIFY_ARG; | 	irq_set = m->NOTIFY_ARG; | ||||||
| 	for (line = 0, rs = rs_lines; line < NR_RS_LINES; line++, rs++) { | 	for (line = 0, rs = rs_lines; line < NR_RS_LINES; line++, rs++) { | ||||||
| 		if (irq_set & (1 << (rs->irq_hook_id+1))) { | 		if (irq_set & (1 << rs->irq_hook_id)) { | ||||||
| 			rs232_handler(rs); | 			rs232_handler(rs); | ||||||
| 			if (sys_irqenable(&rs->irq_hook_id) != OK) | 			if (sys_irqenable(&rs->irq_hook_kernel_id) != OK) | ||||||
| 				panic("unable to enable interrupts"); | 				panic("unable to enable interrupts"); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Kees Jongenburger
						Kees Jongenburger