[i.MX7] IRQ affinity setting for GPIO interrupts

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

[i.MX7] IRQ affinity setting for GPIO interrupts

8,815 Views
pintukumar
Contributor II

Hi,

I wanted to set IRQ affinity to some CPU for a particular GPIO interrupt.

Please let me know how can I do it.

I wanted to do it from my own kernel module.

First I tried to do it from sysfs, but it did not work.

I tried to use FUNC2 (GPIO138) for generating an interrupt.

# echo 138 > /sys/class/gpio/export

# echo "rising" > /sys/class/gpio/gpio138/edge

# root# cat /proc/interrupts | grep gpio
162: 0 0 gpio-mxc 0 Edge 30b40000.usdhc cd
172: 5 0 gpio-mxc 10 Edge usr_button_irq_handler

Thus GPIO 138 is mapped to IRQ 172

Now if I try to set affinity for 172, I get the error:

# root# echo 2 > /proc/irq/172/smp_affinity
-bash: echo: write error: Input/output error

I tried this from both user space and kernel module, but its not working.

I also tried using "irq_set_affinity_hint(irq, cpumask) from kernel driver, but this also failed.

Recently I discovered that it is not possible to set IRQ affinity to GPIO interrupt because it is not tied to a particular GIC line.

Thus GPIO bank affinity needs to be changed.

So, I know that GPIO interrupt affinity cannot be changed for a particular GPIO.

But, still I am looking for a work around or hack in kernel by which this can be still possible.

This is required only for some debug purpose.

If you have ideas please share.

Also please share some hardware document about how GPIO banks are connected on i.MX7.

And how GPIO interrupts are processed and the relation with GIC.

Like:

- How to change affinity for one of the GPIO Bank?

- Is it possible to disable CPU0 from my driver (for some time), until interrupt is served on another CPU?

- Is it possible to make CPU0 busy so that CPU1 can handle the GPIO interrupt?

Thanks,

Pintu

Labels (1)
0 Kudos
Reply
21 Replies

6,783 Views
DuanFugang
NXP Employee
NXP Employee

Firstly, imx gpio bank share one irq line, so it doesn't support hierarchy irq domain.

IRQ affinity depends on hierarchy irqchip, so it also doesn't support irq affinity for gpio subirq.

Secondly, for your requirement,  you can bind one gpio band irq to one cpu core. So you can refer below code:

The refer code bind all gpio band to cpu 2.

— a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -513,15 +513,19 @@ static int mxc_gpio_probe(struct platform_device *pdev)
                 * is more robust and easier.
                 */
                irq_set_chained_handler(port->irq, mx2_gpio_irq_handler);
+               irq_set_affinity_hint(port->irq, cpumask_of(2));
        } else {
                /* setup one handler for each entry */
                irq_set_chained_handler_and_data(port->irq,
                                                 mx3_gpio_irq_handler, port);
               if (port>irq_high > 0)
+               irq_set_affinity_hint(port->irq, cpumask_of(2));
+               if (port->irq_high > 0) {
                        /* setup handler for GPIO 16 to 31 */
                        irq_set_chained_handler_and_data(port->irq_high,
                                                         mx3_gpio_irq_handler,
                                                         port);
+                       irq_set_affinity_hint(port->irq_high, cpumask_of(2));
+               }
        }

0 Kudos
Reply

6,775 Views
pintukumar
Contributor II

Hi,

Thank you for the update.

I already tried it, but still the request goes to CPU0, when I press "usr

button1".

bash-3.2# cat /proc/interrupts

CPU0 CPU1

172: 5 0 gpio-mxc 10 Edge usr_button_irq_handler

Can you check it further.

Thanks,

Pintu

0 Kudos
Reply

6,771 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi Pintu,

BSP team provided this patch for Linux BSP 4.9.88_2.0.0 as an example which assigns the GPIO banks irqs to CPU2 from probe time. Please find attached the patch (L4.9.88_2.0.0_gpio_affinity_bank_cpu2.diff).

 

Patch for L4.1.15_2.1.0 was ported and it works. Please find it attached (L4.1.15_2.0.0_gpio_affinity_bank_cpu2.diff). It was tested on i.MX6QP sabreauto.

 

root@imx6qpsabresd:~# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
16: 12243 6558 1638 1783 GIC 29 Edge twd
17: 244 0 0 0 GPC 55 Level i.MX Timer Tick
19: 0 0 0 0 GPC 20 Level snvs-secvio
23: 0 0 0 0 GPC 115 Level 20e0000.hdmi_video, soc:hdmi_cec@00120000
24: 1 0 0 0 GPC 52 Level 2004000.spdif
25: 0 0 0 0 GPC 51 Level esai
26: 0 0 0 0 GPC 47 Level 202c000.ssi
27: 0 0 0 0 GPC 50 Level 2034000.asrc
28: 0 0 0 0 GPC 3 Edge VPU_JPG_IRQ
29: 0 0 0 0 GPC 12 Level VPU_CODEC_IRQ
35: 0 0 0 0 gpio-mxc 1 Edge 2190000.usdhc cd
45: 0 0 4 0 gpio-mxc 11 Edge Home
46: 0 0 14 0 gpio-mxc 12 Edge Back
80: 0 0 4 0 gpio-mxc 12 Edge Program
83: 0 0 4 0 gpio-mxc 15 Edge Volume Up
97: 0 0 0 0 gpio-mxc 29 Edge mag3110
184: 0 0 6 0 gpio-mxc 14 Edge Volume Down
<.....>
IPI1: 0 29 32 14 Timer broadcast interrupts
IPI2: 7333 9430 13347 14014 Rescheduling interrupts
IPI3: 32 33 33 37 Function call interrupts
IPI4: 5 5 2 1 Single function call interrupts
IPI5: 0 0 0 0 CPU stop interrupts
IPI6: 0 0 0 0 IRQ work interrupts
IPI7: 0 0 0 0 completion interrupts

 

 

You will have to set the affinity for your platform (i.MX7D for second cpu: irq_set_affinity_hint(port->irq_high, cpumask_of(1));

 

Please note that this patch customizes the GPIO driver for this usecase, but according to BSP team feedback, there are no plans to add official support for irq affinity in GPIO driver in order to allow to set the affinity from userspace.

 

Best regards,

Carlos

0 Kudos
Reply

6,783 Views
pintukumar
Contributor II

Dear Carlos,

We are working on some features that requires one of the devices connected to GPIO to be processed only by non-master CPU (CPU 1).

So first we wanted to check if this method works for USR_BUTTON1 (FUNC2 button on i.MX7) which is mapped to GPIO5_IO10.

Yes, I know that IRQ affinity cannot be set for individual GPIO interrupt.

So, I also know that IRQ affinity can be set to the entire GPIO Bank (in this case bank 5).

So, could you ask your development team to find out how IRQ affinity can be set to GPIO Bank for i.MX7 ?

Thank You!

Pintu

0 Kudos
Reply

6,783 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi Pintu,

Current version of GPIO driver does not allow to set the GPIO IRQ affinity, even for GPIO Bank. It was not requested until now.

Current driver does not implement irq_set_affinity, because the implementation does not take into consideration IRQ hierarchy in GPIO driver, so GPIO Interrupt Controller does not see its parent (GIC) in current GPIO driver.

 

Theoretically, it is possible, because GPIO Interrupt Controller is cascaded to GIC, but it has to be implemented.

This week, people in the applications team have tried to implement this feature, but it is not working for the moment, so this feature request has been forwarded to development team. Depending on their roadmap and priorities, they will decide when to schedule it. 

After this, applications team can back port it to Linux Kernel 4.1.15 GA from 4.9.11 GA.

The internal Jira Feature Request Ticket is MLK-18468. If you want to know about the progress on this ticket you can submit a private Support Request Ticket at www.nxp.com/support  and ask about it.

Regards,

Carlos

0 Kudos
Reply

6,783 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi Pintu,

I have forwarded your comments to development team.

If you could provide more detail an why is it required to have interrupts being executed by non-master CPU their comments may be more helpful, useful, and come faster.

Regards,

Carlos

0 Kudos
Reply

6,783 Views
pintukumar
Contributor II

Dear Carlos,

Can you reply to my message. Its a quite long time now.

Could you happen to find the root cause about GPIO Bank affinity setting, for example GPIO5_IO10

Thanks,

Pintu

0 Kudos
Reply

6,783 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi Pintu,

I have contacted the one person of the development team about this case and this is what they answered.

I have discussed with development team and current version of GPIO driver does not allow configuring the CPU affinity for GPIO interrupt. 

 

Could you obtain more details about customer's usecase? Why do they need to set the GPIO IRQs on other core than master core 0? Have they encountered issues having the GPIO IRQs on default core?

In your original post you stated that this is required only for some debug purpose. and you asked:

- Is it possible to disable CPU0 from my driver (for some time), until interrupt is served on another CPU?

- Is it possible to make CPU0 busy so that CPU1 can handle the GPIO interrupt?

If you explain the usecase probably they can help to find a work around.

Regards,

Carlos

0 Kudos
Reply

6,783 Views
pintukumar
Contributor II

Dear Carlos,

Thank you so much for your support. Please keep updating me about the test progress.

Regarding your query, I hope you are reading my full post from the beginning.

when I give:

echo 2 > /proc/irq/172/smp_affinity

bash: echo: write error: Input/output error

So, it says input/output error.

When I checked more, I found that this error is coming because there is no handler (irq_set_affinity) defined for GPIO interrupts.

So, its not possible to set affinity to individual GPIO.

When I discussed in the mainline linux kernel also they said the same.

But they told me that I can change the affinity for the entire GPIO bank.

So, please help me, how to set the affinity for the entire GPIO bank.

Thanks,

Pintu

0 Kudos
Reply

6,783 Views
pintukumar
Contributor II

OK Carlos, I will be eagerly waiting for your reply.

This is becoming worse now.

I have been told by the customer to find some way. It seems they need it badly.

I am even ok if I can hard code the default affinity to CPU 1.

Can you tell me how to change the cpumask value for 

irq_default_affinity

Thanks,
Pintu
0 Kudos
Reply

6,783 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi Pintu,

I ran some tests today without success, I am now in touch with the i.MX applications team. I just wonder what do you mean when you say

echo 2 > /proc/irq/172/smp_affinity does not work for me.

 

irq_set_affinity_hint(..) => did not work for me.

Which is the problem or error you are getting?

Reagrds,

Carlos

0 Kudos
Reply

6,783 Views
pintukumar
Contributor II

Hi,

Please reply to me query. Please do not close this ticket.

I need your help.

Thanks,

Pintu

0 Kudos
Reply

6,783 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi,

I am very sorry I did not have a chance to run the tests today as I told you. But now I am building the image to run the tests and I will check it tomorrow.

If am am not able to change the affinity of a GPIO bank I will need to make deeper investigation and ask the applications team whether this is possible or not.

Regards,

Carlos

0 Kudos
Reply

6,783 Views
pintukumar
Contributor II

Hi,

Can you at least reply here and tell me how to change affinity for the GPIO Bank itself ?

Is it possible to do here: kernel/irq/irqdesc.c => desc_smp_init

{{{

cpumask_set_cpu(1, irq_default_affinity);
cpumask_copy(desc->irq_data.affinity, irq_default_affinity);

}}}

I tried this but it did not work, since cpu=1 is still not online here.

Thanks,

Pintu

0 Kudos
Reply

6,783 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi PINTU,

please take a look to following posts:

Interrupts with GPIO1 INT0-7 

i.mx6 Linux CPU IRQ affinity 

https://community.nxp.com/thread/379939 

Regards,

Carlos

0 Kudos
Reply

6,783 Views
pintukumar
Contributor II

Dear Carlos,

Thank you for the reference.

I looked into some of the discussions. Specially this thread:

https://community.nxp.com/thread/303144

From this discussion it seems, it is possible to set CPU affinity for GPIO

interrupt on IMX6 board.

Is this true for IMX7DL boards also ? Because I have only IMX7 board.

Actually I don't have lot of time to go through every thread and gather the

important point for my implementation.

I need to provide quick update to our customer, which will help them to

decide about which board to choose.

Can you summarize all the post for me here, about what are the steps

required to set CPU affinity for a particular GPIO IRQ.

I think it will be a good reference for all others as well.

My requirement on IMX7DL Sabre is as follows:

- I want to set CPU affinity for FUNC2 button, which is mapped to GPIO138,

that is: GPIO5_IO10 on IMX7 board.

-> This is getting mapped to IRQ;172

-> Is it possible to set affinity for this IRQ number: 172 ?

- Similarly, I want to set affinity for GPIO2_21 to CPU:2 . Is it possible ?

For IRQ: 172, I am doing this from my driver, but it did not work.

#define IOMUXC_SW_MUX_CTL_PAD_SD2_WP 0x303301B0

#define IOMUXC_SW_PAD_CTL_PAD_SD2_WP 0x30330420

static unsigned int gpiono = 138;

u32 * iomuxc_sdp2_wp_pad_ctrl = ioremap(IOMUXC_SW_PAD_CTL_PAD_SD2_WP,4);

u32 * iomuxc_sdp2_wp_mux_ctrl = ioremap(IOMUXC_SW_MUX_CTL_PAD_SD2_WP,4);

iowrite32(0x05,iomuxc_sdp2_wp_mux_ctrl);

iowrite32(0x7c,iomuxc_sdp2_wp_pad_ctrl);

gpio_request(gpiono, "usr-button-func2");

gpio_direction_input(gpiono);

gpio_set_debounce(gpiono, 200);

gpio_export(gpiono, false);

irqno = gpio_to_irq(gpiono);

ret = request_irq(irqno, (irq_handler_t) usr_button_irq_handler,

IRQF_TRIGGER_RISING, "usr_button_irq_handler",

NULL);

cpu=1;

irq_set_affinity_hint(irqno, get_cpu_mask(cpu));

I also tried from user space, but did not work for me.

This is the output from dmesg:

0 Kudos
Reply

6,783 Views
pintukumar
Contributor II

Hi,

At first trial I am fine with setting CPU affinity to one of the GPIO Bank.

Can you guide me how to do it ?

Thanks,

Pintu

0 Kudos
Reply

6,783 Views
Carlos_Musich
NXP Employee
NXP Employee

you should do this:

echo CPU_NUMBER > /proc/irq/IRQ_NUMBER/smp_affinity

E.g.

echo 4 > /proc/irq/99/smp_affinity

0 Kudos
Reply

6,783 Views
pintukumar
Contributor II

Dear Carlos,

I am using GPIO5_IO10 (GPIO number: 138), which is getting mapped to IRQ

number: 172.

So, when I do:

echo 2 > /proc/irq/172/smp_affinity

It did not work for me.

Hope you have checked my previous post.

echo 4 > /proc/irq/99/smp_affinity

99 GPIO1 Combined interrupt indication for GPIO1 signals 16 - 31.

By this you means to say, setting affinity to 99 will result into setting

affinity of GPIO1 -> IO(16-31) ?

Sorry I could not understand this. If there is any reference document

please let me know.

Also, can you explain, how GPIO138 could generate IRQ 172 ?

So, now I wanted to change the affinity of entire GPIO bank from

drivers/gpio/gpio-mxc.c driver directly.

Here I found out that we can set affinity using: desc->irq_data->affinity

But I still could not figure out how and where to set it from gpio-mxc.c

driver.

Can you guide me on this ?

Thanks,

Pintu

On Fri, May 18, 2018 at 11:04 PM, Carlos_Musich <admin@community.nxp.com>

0 Kudos
Reply

6,783 Views
Carlos_Musich
NXP Employee
NXP Employee

That should work, if it doesn't I will need to run some tests.

I will have time to build a new image on tuesday and run tests on wednesday.

0 Kudos
Reply