I have been trying to use the ti-tscadc device for touch screen inputs and read the analog inputs on an AM335x.
I am letting the touch screen inputs go directly to the windows system and I am reading the analog input by reading from /sys/bus/iio/devices/iio:device0/in_voltage4_raw.
I find that doing either one separately (i.e. disconnecting the touch screen, or not reading the analog inputs) appears to work 100% of the time.
However, when I do both, it only works most of the time. Occasionally when I press the touch screen I'll get a message from the kernel and it will lock up (actually it appears to be stuck in the kernel since I can get more kernel messages if I keep pressing, but nothing else is responsive).
I'm looking for ideas on how to avoid or recover from this apparent bug.
The messages I get from the kernel are:
BUG: spinlock lockup suspected on CPU#0... or sometimes BUG: spinlock recursion on CPU#0... (titsc_irq... Exception stack... (tiadc_read_raw...
Here is the full output from one time it locked up:
[55862.321774] BUG: spinlock recursion on CPU#0, Surveyor/12677 [55862.327733] lock: 0xde0d6a28, .magic: dead4ead, .owner: Surveyor/12677, .owner_cpu: 0 [55862.336056] [<c00111f1>] (unwind_backtrace+0x1/0x9c) from [<c025ebdd>] (do_raw_spin_lock+0xf9/0x114) [55862.345640] [<c025ebdd>] (do_raw_spin_lock+0xf9/0x114) from [<c02d1107>] (regmap_write+0x1b/0x38) [55862.354947] [<c02d1107>] (regmap_write+0x1b/0x38) from [<c035a05f>] (titsc_irq+0x9f/0x234) [55862.363612] [<c035a05f>] (titsc_irq+0x9f/0x234) from [<c0072dd3>] (handle_irq_event_percpu+0x3b/0x188) [55862.373364] [<c0072dd3>] (handle_irq_event_percpu+0x3b/0x188) from [<c0072f49>] (handle_irq_event+0x29/0x3c) [55862.383661] [<c0072f49>] (handle_irq_event+0x29/0x3c) from [<c007489b>] (handle_level_irq+0x53/0x8c) [55862.393229] [<c007489b>] (handle_level_irq+0x53/0x8c) from [<c00729ff>] (generic_handle_irq+0x13/0x1c) [55862.402986] [<c00729ff>] (generic_handle_irq+0x13/0x1c) from [<c000d0df>] (handle_IRQ+0x23/0x60) [55862.412192] [<c000d0df>] (handle_IRQ+0x23/0x60) from [<c00085a9>] (omap3_intc_handle_irq+0x51/0x5c) [55862.421682] [<c00085a9>] (omap3_intc_handle_irq+0x51/0x5c) from [<c04cea9b>] (__irq_svc+0x3b/0x5c) [55862.431061] Exception stack(0xdf527e30 to 0xdf527e78) [55862.436352] 7e20: 00000000 00000004 00000000 c08aafcc [55862.444917] 7e40: de0d6a00 de0d4540 00000000 0001ffff 00000054 df0dc610 000c4a10 00001fff [55862.453482] 7e60: 00000000 df527e78 c02d0dff c02d0678 60000033 ffffffff [55862.460417] [<c04cea9b>] (__irq_svc+0x3b/0x5c) from [<c02d0678>] (_regmap_write+0xe8/0x18c) [55862.469169] [<c02d0678>] (_regmap_write+0xe8/0x18c) from [<c02d1111>] (regmap_write+0x25/0x38) [55862.478197] [<c02d1111>] (regmap_write+0x25/0x38) from [<c03ec657>] (tiadc_read_raw+0x3b/0x104) [55862.487323] [<c03ec657>] (tiadc_read_raw+0x3b/0x104) from [<c03e92c9>] (iio_read_channel_info+0x21/0x1b4) [55862.497356] [<c03e92c9>] (iio_read_channel_info+0x21/0x1b4) from [<c02c47d1>] (dev_attr_show+0x11/0x28) [55862.507203] [<c02c47d1>] (dev_attr_show+0x11/0x28) from [<c00fcf15>] (sysfs_read_file+0x65/0xc8) [55862.516413] [<c00fcf15>] (sysfs_read_file+0x65/0xc8) from [<c00bafbd>] (vfs_read+0x65/0xf8) [55862.525162] [<c00bafbd>] (vfs_read+0x65/0xf8) from [<c00bb079>] (sys_read+0x29/0x48) [55862.533277] [<c00bb079>] (sys_read+0x29/0x48) from [<c000c841>] (ret_fast_syscall+0x1/0x46) [55875.451034] BUG: spinlock lockup suspected on CPU#0, Surveyor/12677 [55875.457597] lock: 0xde0d6a28, .magic: dead4ead, .owner: Surveyor/12677, .owner_cpu: 0 [55875.465894] [<c00111f1>] (unwind_backtrace+0x1/0x9c) from [<c025eb9d>] (do_raw_spin_lock+0xb9/0x114) [55875.475464] [<c025eb9d>] (do_raw_spin_lock+0xb9/0x114) from [<c02d1107>] (regmap_write+0x1b/0x38) [55875.484760] [<c02d1107>] (regmap_write+0x1b/0x38) from [<c035a05f>] (titsc_irq+0x9f/0x234) [55875.493420] [<c035a05f>] (titsc_irq+0x9f/0x234) from [<c0072dd3>] (handle_irq_event_percpu+0x3b/0x188) [55875.503170] [<c0072dd3>] (handle_irq_event_percpu+0x3b/0x188) from [<c0072f49>] (handle_irq_event+0x29/0x3c) [55875.513464] [<c0072f49>] (handle_irq_event+0x29/0x3c) from [<c007489b>] (handle_level_irq+0x53/0x8c) [55875.523032] [<c007489b>] (handle_level_irq+0x53/0x8c) from [<c00729ff>] (generic_handle_irq+0x13/0x1c) [55875.532782] [<c00729ff>] (generic_handle_irq+0x13/0x1c) from [<c000d0df>] (handle_IRQ+0x23/0x60) [55875.541987] [<c000d0df>] (handle_IRQ+0x23/0x60) from [<c00085a9>] (omap3_intc_handle_irq+0x51/0x5c) [55875.551467] [<c00085a9>] (omap3_intc_handle_irq+0x51/0x5c) from [<c04cea9b>] (__irq_svc+0x3b/0x5c) [55875.560845] Exception stack(0xdf527e30 to 0xdf527e78) [55875.566134] 7e20: 00000000 00000004 00000000 c08aafcc [55875.574701] 7e40: de0d6a00 de0d4540 00000000 0001ffff 00000054 df0dc610 000c4a10 00001fff [55875.583265] 7e60: 00000000 df527e78 c02d0dff c02d0678 60000033 ffffffff [55875.590198] [<c04cea9b>] (__irq_svc+0x3b/0x5c) from [<c02d0678>] (_regmap_write+0xe8/0x18c) [55875.598949] [<c02d0678>] (_regmap_write+0xe8/0x18c) from [<c02d1111>] (regmap_write+0x25/0x38) [55875.607973] [<c02d1111>] (regmap_write+0x25/0x38) from [<c03ec657>] (tiadc_read_raw+0x3b/0x104) [55875.617087] [<c03ec657>] (tiadc_read_raw+0x3b/0x104) from [<c03e92c9>] (iio_read_channel_info+0x21/0x1b4) [55875.627111] [<c03e92c9>] (iio_read_channel_info+0x21/0x1b4) from [<c02c47d1>] (dev_attr_show+0x11/0x28) [55875.636953] [<c02c47d1>] (dev_attr_show+0x11/0x28) from [<c00fcf15>] (sysfs_read_file+0x65/0xc8) [55875.646157] [<c00fcf15>] (sysfs_read_file+0x65/0xc8) from [<c00bafbd>] (vfs_read+0x65/0xf8) [55875.654906] [<c00bafbd>] (vfs_read+0x65/0xf8) from [<c00bb079>] (sys_read+0x29/0x48) [55875.663019] [<c00bb079>] (sys_read+0x29/0x48) from [<c000c841>] (ret_fast_syscall+0x1/0x46)
Here is the device tree:
tscadc { compatible = "ti,ti-tscadc"; reg = <0x44e0d000 0x1000>; interrupt-parent = <&intc>; interrupts = <16>; ti,hwmods = "adc_tsc"; status = "okay"; tsc { ti,wires = <4>; ti,x-plate-resistance = <600>; ti,coordinate-readouts = <5>; ti,wire-config = <0x00 0x11 0x22 0x33>; }; adc { ti,adc-channels = <4 5 6 7>; }; };
Here is the code that reads the analog input:
bool Hardware::readAdcRaw(Adc adc, unsigned int &rawReading) { const char* const AIN4_FILE_NAME = "/sys/bus/iio/devices/iio:device0/in_voltage4_raw"; const char* const AIN5_FILE_NAME = "/sys/bus/iio/devices/iio:device0/in_voltage5_raw"; const char* ainFileName = ""; switch (adc) { case MPU_VOLTAGE: ainFileName = AIN4_FILE_NAME; break; case CORE_VOLTAGE: ainFileName = AIN5_FILE_NAME; break; } bool validReading = false; // Get reading from analog input if we can. // Note: if we can't get a reading, don't retry immediately. That causes spinlock recursion in the titsc interrupt. // Instead we just try again at our next scheduled reading time. // In an all day run about 1 in every 22 readings was missed due to this with no more than 2 in a row. std::ifstream ainFile; char lineIn[10]; //Readings are 5 characters, so this is 2x what we need. lineIn[0] = '\0'; ainFile.open(ainFileName); if (ainFile.is_open()) { ainFile.getline(lineIn, sizeof(lineIn)); ainFile.close(); if (0 != strlen(lineIn)) { validReading = true; rawReading = atoi(lineIn); } } else { LOG_ERROR() << "Error opening " << ainFileName; } return validReading; }
I also tried reading the analog input from the shell using
while true do cat in_voltage5_raw done
That didn't get the Spinlock errors. Instead, after some touch screen presses, it got stuck constantly reporting:
cat: in_voltage5_raw: Resource temporarily unavailable