cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
vipersnh
Newbie
Newbie
9,150 Views
Registered: ‎12-17-2014

How to add new UIO device for software interrupts of GIC in ARM

Hi,

 

I want to access SGI interrupts of GIC in linux using UIO driver. How to add it in the devicetree so that I get it as a uio device in linux ?

 

0 Kudos
7 Replies
sampatd
Scholar
Scholar
9,147 Views
Registered: ‎09-05-2011

1. Enable UIO in kernel configuration

2. In the device tree node for GIC use "generic-uio" in the compatible property
0 Kudos
vipersnh
Newbie
Newbie
9,138 Views
Registered: ‎12-17-2014

I have tried that.. But I cant get SGI interrupts, whereas I was able to get SPI interrupts working on UIO.

I want for interrupt ID0-ID15 of GIC as UIO in linux.

 

0 Kudos
sampatd
Scholar
Scholar
9,124 Views
Registered: ‎09-05-2011

In the device tree, how does your GIC node look like? Can you post it here?
0 Kudos
linnj
Xilinx Employee
Xilinx Employee
9,113 Views
Registered: ‎09-10-2008

Last time I looked at that it seems like Linux does not make the IPIs available to users thru the interrupt API. SGIs are used by the kernel for interprocessor communication (SMP) but not all are used I know as we use them in AMP systems.  Trying to do that from user space would generally not be possible as a kernel mode driver is needed in my experience.

 

You'll notice in the GIC documentation there's no mention of IPIs so it appears there's no way to specify an IPI unless I'm missing it somewhere.

 

Thanks

John

 

http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/arm/gic.txt

 

 24   The 1st cell is the interrupt type; 0 for SPI interrupts, 1 for PPI
 25   interrupts.
 26 
 27   The 2nd cell contains the interrupt number for the interrupt type.
 28   SPI interrupts are in the range [0-987].  PPI interrupts are in the
 29   range [0-15].
 30 
 31   The 3rd cell is the flags, encoded as follows:
 32         bits[3:0] trigger type and level flags.
 33                 1 = low-to-high edge triggered
 34                 2 = high-to-low edge triggered
 35                 4 = active high level-sensitive
 36                 8 = active low level-sensitive
 37         bits[15:8] PPI interrupt cpu mask.  Each bit corresponds to each of
 38         the 8 possible cpus attached to the GIC.  A bit set to '1' indicated
 39         the interrupt is wired to that CPU.  Only valid for PPI interrupts.

 

The IPIs are used in the GIC driver, but some are not available outside of the driver (static functions) or from user space.

 

http://lxr.free-electrons.com/source/drivers/irqchip/irq-gic.c

 

#ifdef CONFIG_SMP
622 static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
623 {
624         int cpu;
625         unsigned long flags, map = 0;
626 
627         raw_spin_lock_irqsave(&irq_controller_lock, flags);
628 
629         /* Convert our logical CPU mask into a physical one. */
630         for_each_cpu(cpu, mask)
631                 map |= gic_cpu_map[cpu];
632 
633         /*
634          * Ensure that stores to Normal memory are visible to the
635          * other CPUs before they observe us issuing the IPI.
636          */
637         dmb(ishst);
638 
639         /* this always happens on GIC0 */
640         writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
641 
642         raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
643 }
644 #endif
645 
646 #ifdef CONFIG_BL_SWITCHER
647 /*
648  * gic_send_sgi - send a SGI directly to given CPU interface number
649  *
650  * cpu_id: the ID for the destination CPU interface
651  * irq: the IPI number to send a SGI for
652  */
653 void gic_send_sgi(unsigned int cpu_id, unsigned int irq)
654 {
655         BUG_ON(cpu_id >= NR_GIC_CPU_IF);
656         cpu_id = 1 << cpu_id;
657         /* this always happens on GIC0 */
658         writel_relaxed((cpu_id << 16) | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
659 }
660 

 

0 Kudos
sylvain.ellisys
Observer
Observer
8,252 Views
Registered: ‎04-10-2015

Hello,

 

I do have the exact same request as the orgininal first post.

 

Since some time elapsed since, I am asking again: does someone now knows how to have SGI working with UIO?

 

More specifically: I am on zynq: I would like to trigger a SGI from CPU1 running bare-metal to CPU0 running petalinux, and catch the interruption via UIO (like blocking-reading /dev/uio0).

 

Any idea how to configure the device tree?

 

Or is there another way to achieve what I would like?

 

Thanks a lot in advance!

0 Kudos
rankeney
Participant
Participant
8,170 Views
Registered: ‎11-26-2014

I'd be curious to hear if you find anything out. I'm considering using GPIO to get a signal across, but haven't benchmarked how fast that would be. Have a look at:

http://www.xilinx.com/member/zynq_videos/pdf/working-with-gpio-and-embedded-linux.pdf

 

0 Kudos
7,709 Views
Registered: ‎05-16-2015

0 Kudos