AnsweredAssumed Answered

How can I use the i.MX6 GPT to safely read a PWM?

Question asked by James Puckett on Jan 8, 2019
Latest reply on Jan 14, 2019 by James Puckett

I'm working on a board using an i.MX6 solo running a customized Linux 4.1.43 (retrieved from in September).  We need to read a PWM that we are feeding to the SD1_DAT0 pin muxed as GPT_CAPTURE1.


I've modified arch/arm/mach-imx/time.c to handle the GPT's IF1 interrupt and have been able to successfully quantify the incoming PWM at low frequencies.  I added a platform driver to time.c that made the PWM values available via sysfs entries .

However the system continually deadlocks and increasing the PWM frequency to 10kHz locks the kernel before it even finishes booting.  Sometimes it locks immediately after u-boot starts it.


When I unplug the PWM signal before booting, the system runs as expected.


To simplify the problem I went back to the original version of time.c and changed only the following:

1.  Enabled the IF1 interrupt in the GPT_IR register

2.  Cleared the OF1 and IF1 interrupts in the GPT_SR register when processing an interrupt

3.  Only called the kernel's timer event handler when the OF1 flag is set in GPT_SR

4.  Set IM1 to trigger off a rising edge in the GPT_CR register


Just enabling the input capture 1 interrupt, ignoring it and resetting it causes the system to lock up.

Is there a way to safely use the GPT_CAPTURE1 input to read a PWM?


I have attached the original time.c, my modified version and a patch file showing the differences.



Some other interesting info:


Once, after the system locked up trying to boot, I left it running and continued investigating.  After a while the system continued booting a little more before getting hung up again.


Another time I left it over lunch and came back to this output on the terminal:

INFO: rcu_preempt self-detected stall on CPU

        0: (1 ticks this GP) idle=563/1/0 softirq=5274/5274 fqs=1

         (t=143119 jiffies g=2565 c=2564 q=14226)

rcu_preempt kthread starved for 143119 jiffies!

Task dump for CPU 0:

swapper/0       R running      0     0      0 0x00000000

[<80015c48>] (unwind_backtrace) from [<80012698>] (show_stack+0x10/0x14)

[<80012698>] (show_stack) from [<80078658>] (rcu_dump_cpu_stacks+0x84/0xc8)

[<80078658>] (rcu_dump_cpu_stacks) from [<8007c5f8>] (rcu_check_callbacks+0x498/0x89c)

[<8007c5f8>] (rcu_check_callbacks) from [<8007eca8>] (update_process_times+0x38/0x64)

[<8007eca8>] (update_process_times) from [<8008ed08>] (tick_sched_timer+0x4c/0x98)

[<8008ed08>] (tick_sched_timer) from [<8007f958>] (__run_hrtimer.constprop.4+0x44/0xd8)

[<8007f958>] (__run_hrtimer.constprop.4) from [<8007fca0>] (hrtimer_interrupt+0xfc/0x2f4)

[<8007fca0>] (hrtimer_interrupt) from [<80021ffc>] (mxc_timer_interrupt+0x2c/0x48)

[<80021ffc>] (mxc_timer_interrupt) from [<800706bc>] (handle_irq_event_percpu+0x78/0x134)

[<800706bc>] (handle_irq_event_percpu) from [<800707b8>] (handle_irq_event+0x40/0x64)

[<800707b8>] (handle_irq_event) from [<800735c0>] (handle_fasteoi_irq+0xdc/0x1ac)

[<800735c0>] (handle_fasteoi_irq) from [<8006fd78>] (generic_handle_irq+0x28/0x3c)

[<8006fd78>] (generic_handle_irq) from [<80070028>] (__handle_domain_irq+0x68/0xe8)

[<80070028>] (__handle_domain_irq) from [<80009470>] (gic_handle_irq+0x2c/0x70)

[<80009470>] (gic_handle_irq) from [<80013180>] (__irq_svc+0x40/0x74)

Exception stack(0x80865f30 to 0x80865f78)

5f20:                                     80865f78 fffffff7 539c8caa 0000016f

5f40: 539c5748 0000016f 9fb26dd8 00000000 539c8caa 0000016f 8085e300 00000001

5f60: 00000017 80865f78 a6aaaaab 803fdc04 000e0013 ffffffff

[<80013180>] (__irq_svc) from [<803fdc04>] (cpuidle_enter_state+0xcc/0x1f0)

[<803fdc04>] (cpuidle_enter_state) from [<80067b24>] (cpu_startup_entry+0x1c4/0x308)

[<80067b24>] (cpu_startup_entry) from [<80805c04>] (start_kernel+0x338/0x3a4)