cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Adventurer
Adventurer
603 Views
Registered: ‎03-12-2018

UIO is not listed under /proc/interrupts and mapped to IRQ_F2P

Jump to solution

Hello there,

I'm working with zc7020, and I'm having 2 pins connected to IRQ_F2P through Concat IP as shown below. Both Interrupt getting High alternately every after 5 sec, as written in verilog code. I'm receiving interrupts in Bare Metal. I want it to work with Linux.

Capture.JPG

 

 

 

 

 

Also, I did below settings in Kernel

petalinux-config -c kernel
o Device Drivers
   <*>Userspace I/O driver
       <*> Userspace I/O platform driver with generic IRQ handling
       <*> Userspace platform driver with generic IRQ handling and dynamic memory

Along with this, I've added following in system-user.dtsi

amba_pl {
		#address-cells = <0x1>;
		#size-cells = <0x1>;
		compatible = "simple-bus";
		ranges;

		uio@0{
			compatible="generic-uio";
			status="okay";
			interrupt-controller;
			interrupt-parent=<0x4>;
			interrupts=<0x0 0x1d 0x4>;
		};
		
		uio@1{
			compatible="generic-uio";
			status="okay";
			interrupt-controller;
			interrupt-parent=<0x4>;
			interrupts=<0x0 0x1e 0x4>;
		};
};

With all above settings, I'm able to see uio0 and uio1 in dev/. 

Plus, They are also present in sys/class/uio but map0 or map1 is not present.

Also, if i do cat /proc/interrupts then I don't see UIO 0 or 1 listed there.

Can anyone help me out with this.???

Do I need to do any other settings to get interrupts working in Linux.???

Thanks

Lokesh

 

 

Lokesh J.
0 Kudos
Reply
1 Solution

Accepted Solutions
Scholar
Scholar
571 Views
Registered: ‎05-28-2013

> Thanks you for your quick response. I'm new to Linux.

I'd suggest to start by reading https://www.kernel.org/doc/html/latest/driver-api/uio-howto.html
(you can ignore the part about maps, since you seem to be interested in the interrupt only)

> Could you please tell me - How to open the driver i.e. dev/uio0.??
> Is there any example code for interrupt setup and theirs handler.??

The basic idea is explained in the "Writing a driver in userspace" section of the uio-howto document.

There are lots of examples available, a quick google search found this one: https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt.html (look at the "Userspace" section).

View solution in original post

6 Replies
Scholar
Scholar
590 Views
Registered: ‎05-28-2013

> With all above settings, I'm able to see uio0 and uio1 in dev/.

That's great!

> Plus, They are also present in sys/class/uio but map0 or map1 is not present.

That is expected, because you did not define a reg = <addr size> in your devicetree. So there is nothing to map. You can still use it for interrupts without a mapping.

> Also, if i do cat /proc/interrupts then I don't see UIO 0 or 1 listed there.

You'll need to open the device (eg /dev/uio0) in order for the interrupt allocated. While it is open, you should see an entry in /proc/interrupts.

> Do I need to do any other settings to get interrupts working in Linux.???

After opening the device, you would typically perform a read() or a select() in order to wait for an interrupt.

After the interrupt occurs, your code will need to perform a write() in order to re-arm the interrupt.

0 Kudos
Reply
Adventurer
Adventurer
585 Views
Registered: ‎03-12-2018

Hi @rfs613 ,

Thanks you for your quick response. I'm new to Linux.

So, Could you please help me more.??

Could you please tell me - How to open the driver i.e. dev/uio0.??

Is there any example code for interrupt setup and theirs handler.??

Thanks

Lokesh

Lokesh J.
0 Kudos
Reply
Scholar
Scholar
572 Views
Registered: ‎05-28-2013

> Thanks you for your quick response. I'm new to Linux.

I'd suggest to start by reading https://www.kernel.org/doc/html/latest/driver-api/uio-howto.html
(you can ignore the part about maps, since you seem to be interested in the interrupt only)

> Could you please tell me - How to open the driver i.e. dev/uio0.??
> Is there any example code for interrupt setup and theirs handler.??

The basic idea is explained in the "Writing a driver in userspace" section of the uio-howto document.

There are lots of examples available, a quick google search found this one: https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt.html (look at the "Userspace" section).

View solution in original post

Adventurer
Adventurer
533 Views
Registered: ‎03-12-2018

Hi @rfs613 ,

I'm following the link what you have shared.

After Compiling the code I'm seeing following warnings

implicit declaration of function ‘write’; did you mean ‘fwrite’? [-Wimplicit-function-declaration]

implicit declaration of function ‘read’; did you mean ‘fread’? [-Wimplicit-function-declaration]

Also, if I move forward by Ignoring the warnings. I'm getting following Prints on Board Terminal

Snap.png

 

Could you please help me with this.??

Thanks

Lokesh

Lokesh J.
0 Kudos
Reply
Scholar
Scholar
505 Views
Registered: ‎05-28-2013

You can fix the warnings by adding #include <unistd.h> at the top of the file. The is from the SYNOPSIS section of the man page https://man7.org/linux/man-pages/man2/write.2.html.

The input/output error suggests that the interrupt is not configured correctly. When you call write(), the following code in kernel is being execute (see https://elixir.bootlin.com/linux/v4.4.197/source/drivers/uio/uio.c#L557

static ssize_t uio_write(struct file *filep, const char __user *buf,
			size_t count, loff_t *ppos)
{
	struct uio_listener *listener = filep->private_data;
	struct uio_device *idev = listener->dev;
	ssize_t retval;
	s32 irq_on;

	if (!idev->info->irq)
		return -EIO;              // EIO = input/output error

So the input/output error indicates that the interrupt (IRQ) has not been setup in the UIO driver. The next question of course is why is the interrupt not setup.

Assuming that you are using uio_pdrv_genirq driver, then the interrupt is obtained from the devicetree using platform_get_irq() function, see https://elixir.bootlin.com/linux/v4.4.197/source/drivers/uio/uio_pdrv_genirq.c#L149. I suspect this is failing, in which case, you should see "failed to get IRQ" error (line 154) appearing during the kernel boot.

	if (!uioinfo->irq) {
		ret = platform_get_irq(pdev, 0);
		uioinfo->irq = ret;
		if (ret == -ENXIO && pdev->dev.of_node)
			uioinfo->irq = UIO_IRQ_NONE;
		else if (ret < 0) {
			dev_err(&pdev->dev, "failed to get IRQ\n");
			return ret;
		}
	}

Check that you are specifying the correct interrupt and interrupt-parent in your device tree.

Adventurer
Adventurer
457 Views
Registered: ‎05-08-2018

Do not forget my friend that the interrupt number seen in a device tree node is not the 'real' interrupt number assigned on the SoC. There is an offset of 32. 

Let's say the interrupt number in the SoC is 121, then the number you have to put in the device-tree node will be 153. Why? Because. 

0 Kudos
Reply