Программа из user space ( например, echo "1" > /dev/spidev1.0) виснет.
Осциллографом вижу правильную посылку на SPI линиях.
Т.е. трансфер отработал нормально. Но операция не может завершиться.
Начал "копать" SPI драйвера. Удалось решить все проблемы.
Но был удивлен "качеством" драйвера от FreeScale. Похоже, что он никогда не работал с "spidev".
Драйвер SPI (spi_mxs.c) имеет 2 основных режима с DMA и прямой записью в регистры.
Если посылка короткая (<10 байт), то используется прямая запись в регистры с последущим поллингом.
Если > 10, то используется DMA.
В любом случае вызывается spidev_sync -> spi_async -> mxs_spi_transfer
Проблема в wait_for_completion.
spi_async должен только отправлять данные в очередь.
Сам процесс коммуникаци должен выполняться в отдельной нити.
Этого и в помине нет в spi_mxs драйвере.
Если посылка короткая (используется прямая запись в регистры),
то mxs_spi_transfer отправляет данные и только потом возвращает управление.
И еще хуже, mxs_spi_transfer не сигнализирует о завершении операции.
"actual_length" не считается вообще.
Чтобы драйвер заработал надо добавить
После этого фикса операции коротких отсылок работают нормально.
Т.е. без DMA все работает. С DMA есть дополнительные проблемы.
Драйвер использует прерывания DMA. Но поскольку это не multi-thread,
то прерывания запрещены в spidev_sync во время выполгения этой single thread.
Напомню, что spi_async совсем не "async".
Чтобы заработал драйвер с DMA можно применить "костыль"
(закомментировать "spin_lock_irq").
Но это плохая идея, если в системе есть еще SPI устройства.
Кто-то сталкивался с подобными проблемами ?
Похоже, что надо кардинально переписывать драйвер.
Этот Linux 2.6.35 уже достаточно много "допилен" до моего железа.
Не хочется переключаться на более новые версии Linux.
К тому же похоже, что более новых BSP нет для i.MX233.
Сдается мне что вы с моим драйвером spi воюете :) это не "настоящий" фрискейловский драйвер и вообще не драйвер spi linux, это специально переделанный под ускорение работы ks8851 драйвер - кроме как с ks8851 он не предназначен ни для чего. Вам надо просто взять из репозитория фрискейловский драйвер и заменить то что в ядре у вас сейчас.