Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru

Способы оплаты

User Info


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

ПользователейПользователей:2
Поисковых ботовПоисковых ботов:3
ГостейГостей:1

ОбновитьПодробнееВсегоВсего:6
Форум » starterkit.ru » Embedded Linux
i.MX233 SPI драйвер из Linux 2.6.35 релиза
Arm-a-bot
Добавлено 28.12.2013 14:24
0
Сообщение: 1
Arm-a-bot
0

Пункты: 1540
Регистрация: 16.01.2012
Программа из 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
Код

static ssize_t
spidev_sync(struct spidev_data *spidev, struct spi_message *message)
{
DECLARE_COMPLETION_ONSTACK(done);
int status;

message->complete = spidev_complete;
message->context = &done;

spin_lock_irq(&spidev->spi_lock);
printk(KERN_INFO "SPIDEV_SYNC LOCK\n");
if (spidev->spi == NULL)
status = -ESHUTDOWN;
else
status = spi_async(spidev->spi, message);

spin_unlock_irq(&spidev->spi_lock);

if (status == 0) {
wait_for_completion(&done);
status = message->status;
if (status == 0)
status = message->actual_length;
}
return status;
}

Проблема в wait_for_completion.
spi_async должен только отправлять данные в очередь.
Сам процесс коммуникаци должен выполняться в отдельной нити.
Этого и в помине нет в spi_mxs драйвере.
Если посылка короткая (используется прямая запись в регистры),
то mxs_spi_transfer отправляет данные и только потом возвращает управление.
И еще хуже, mxs_spi_transfer не сигнализирует о завершении операции.
"actual_length" не считается вообще.

Чтобы драйвер заработал надо добавить
Код

static int mxs_spi_transfer(struct spi_device *spi, struct spi_message *m)
{
...
int length =0;

....
list_for_each_entry_safe(t, tmp_t, &m->transfers, transfer_list) {
length += t->len;
...
m->actual_length = length;
m->status = status;
m->complete(m->context);
return 0;
}

После этого фикса операции коротких отсылок работают нормально.
Т.е. без 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.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 28.12.2013 18:05 Сообщение: 2
sasamy
4.71

Пункты: 83558
Регистрация: 14.08.2009
Сдается мне что вы с моим драйвером spi воюете :) это не "настоящий" фрискейловский драйвер и вообще не драйвер spi linux, это специально переделанный под ускорение работы ks8851 драйвер - кроме как с ks8851 он не предназначен ни для чего. Вам надо просто взять из репозитория фрискейловский драйвер и заменить то что в ядре у вас сейчас.

http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/drivers/spi/spi_mxs.c?h=imx_2.6.35_maintain
Спуститься к концу Подняться к началу
Персональная информация
Arm-a-bot
Добавлено 28.12.2013 19:24 Сообщение: 3
Arm-a-bot
0

Пункты: 1540
Регистрация: 16.01.2012
Теперь все встало на свои места :-)
Попробую "родной" скоро.
Спуститься к концу Подняться к началу
Персональная информация
Arm-a-bot
Добавлено 28.12.2013 19:56 Сообщение: 4
Arm-a-bot
0

Пункты: 1540
Регистрация: 16.01.2012
Драйвер "из коробки" запустился сразу и без проблем.
Спасибо sasamy за помощь
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Embedded Linux