[Xenomai] SPI tx underflow interrupt not available

Reitinger, Peter preitinger at carl-valentin.de
Tue Aug 26 16:24:59 CEST 2014


Dear Xenomai people,


I am currently trying to write an SPI slave rtdm driver with fifo and dma support. I would like to receive an interrupt if there is an underflow in the tx fifo.

Therefore I try to request the related hardware interrupt (which is irq 125 at my emtrion board which has EDMA and 2 McSPI interfaces where I am trying McSPI1).

Unfortunately it seems that interrupt 125 is reserved by another linux driver because a list of /proc/irq/125 shows:

root at dimm-am335x:/proc# ls /proc/irq/125
53100000.sham  spurious

I am not very experienced in the configuration of a linux kernel so I have no idea how I can check which driver or kernel configuration I have to switch off to make the hardware interrupt 125 available for my own driver (at least as a shared interrupt).

BTW, I try to request the interrupt as follows which is executed directly in my module init function:

------------------------------------------------
	printk("before rtdm_dev_register[2]\n");
	code = rtdm_dev_register(&devTemplate);
	printk("after rtdm_dev_register: code=%d\n", code);

	if (code) {

		printk("rtdm_dev_register failed: code=%i\n", code);
	}

	// TODO begin for testing interrupt handling

	// begin rtdm
//	printk("try to request irq 125...\n");
//	code = rtdm_irq_request(&irq_handle, irq_no, &irq_handler, 0, "my125", NULL);
//	printk("rtdm_irq_request: code=%d\n", code);
//	code = rtdm_irq_enable(&irq_handle);
//	printk("rtdm_irq_enable: code=%d\n", code);
	// end rtdm

	// begin linux
	// TODO Warum ist 125 fuer McSpi1 blockiert aber 65 nicht? Liegt wohl an /proc/irq/125-Eintrag und dass dieser interrupt exklusiv von anderem Treiber requested wurde!
	code = request_irq(125, myLinuxHandler, 0, "meins", NULL);
	pr_info("request_irq: code=%d\n", code);
	// end linux
	// TODO end for testing interrupt handling
------------------------------------------------
The output of the code above is:

------------------------------------------------
[ 1120.658471] before rtdm_dev_register[2]
[ 1120.665603] after rtdm_dev_register: code=0
[ 1120.670294] genirq: Flags mismatch irq 125. 00000000 (meins) vs. 00000000 (53100000.sham)
[ 1120.679580] request_irq: code=-16
------------------------------------------------
 

I do not understand what "Flags mismatch irq 125" exactly means. I could imagine it has to do with the fact that irq 125 has been requested by this so-called "53100000.sham" (no idea what this is) in some exclusive way so that my rtdm driver cannot request it as well?

When I switch on "CONFIG_XENO_OPT_NATIVE_INTR=y" in the kernel and use the user interface function by calling the following function:

------------------------------------------------
static int try_rt_intr() {
	int code;

	code = rt_intr_create(&intr_desc, "tx_underflow", txUnderflowIrq, 0);
	rt_printf("After rt_intr_create:\n");

	switch (code) {
	case 0:
		break; // ok
	case -ENOMEM:
		rt_printf("ENOMEM\n");
		rt_print_flush_buffers();
		return 1;
	case -EBUSY:
		rt_printf("EBUSY\n");
		rt_print_flush_buffers();
		return 1;
	default:
		rt_printf("other error: %d\n", code);
		rt_print_flush_buffers();
		return 1;
	}

	code = rt_intr_inquire(&intr_desc, &intr_info);
	rt_printf("rt_intr_inquire: code=%d\n", code);
	rt_printf("irq=%d, hits=%d, name=%s\n", intr_info.irq, intr_info.hits, intr_info.name);


	code = rt_intr_enable(&intr_desc);
	rt_printf("After rt_intr_enable:\n");

	switch (code) {
	case 0: // ok
		break;
	case -EINVAL:
		rt_printf("EINVAL\n");
		rt_print_flush_buffers();
		return 1;
	case -EIDRM:
		rt_printf("EIDRM\n");
		rt_print_flush_buffers();
		return 1;
	}

	rt_printf("Waiting for interrupt...\n");
	rt_print_flush_buffers();
	code = rt_intr_wait(&intr_desc, TM_INFINITE);
	rt_printf("After rt_intr_wait:\n");

	switch (code) {
	case 0: //ok
		break;
	case -ETIMEDOUT:
		rt_printf("ETIMEDOUT\n");
		rt_print_flush_buffers();
		rt_intr_delete(&intr_desc);
		return 1;
	case -EINVAL:
		rt_printf("EINVAL\n");
		rt_print_flush_buffers();
		rt_intr_delete(&intr_desc);
		return 1;
	case -EIDRM:
		rt_printf("EIDRM\n");
		rt_print_flush_buffers();
		rt_intr_delete(&intr_desc);
		return 1;
	case -EINTR:
		rt_printf("EINTR\n");
		rt_print_flush_buffers();
		return 1;
	default:
		rt_printf("other error: %d\n", code);
		rt_print_flush_buffers();
		rt_intr_delete(&intr_desc);
		return 1;
	}

	rt_printf("Interrupt arrived!\n");
	rt_print_flush_buffers();
	rt_intr_delete(&intr_desc);

	return 0;
}
------------------------------------------------

... I get the following output:

------------------------------------------------
After rt_intr_create:
rt_intr_inquire: code=0
irq=125, hits=0, name=tx_underflow
After rt_intr_enable:
Waiting for interrupt...
------------------------------------------------

which means that rt_intr_inquire returns 0, but the following rt_intr_wait never returns even though I produce an underflow with a parallel program call and which is also shown to be successful because the status bits in the related tx underflow register are set. Just the interrupt never occurs.

BTW it is Texas Instruments McSPI as described in SPI__spruh73k.pdf

I am really puzzled and cannot see a way how to move on and handling this interrupt... :-(

Any help would be highly appreciated.

Kind regards
Peter Reitinger



More information about the Xenomai mailing list