I'm working on a board using an i.MX6 solo running a customized Linux 4.1.43 (retrieved from https://github.com/Freescale/linux-fslc 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)