LINUX.ORG.RU

Прерывания DMA в Linux

 ,


0

2

Добрый день!

Коллеги, подскажите пожалуйста, интересует следующий вопрос.

Вот, например, если мне нужно задать обработчик прерывания для gpio, которых у меня в системе за сотню, а прерываний от него реальных хорошо если наберется десяток, то линукс предлагает мне т.н. виртуальные прерывания, номер которых я могу запросить функцией gpio_to_irq. И в /proc/interrupts уже не существует прерываний gpio, номера которых указаны в документации, там показываются только виртуальные, которые заданы в системе. То есть все операции по считыванию флагов прерываний ось берет на себя, мне надо лишь в драйвере (модуле ядра) узнать номер прерывания(gpio_to_irq) и запросить его (request_irq). И тут возникла задача провернуть нечто аналогичное для dma - есть у меня в системе 64 dma канала, прерываний выведено само собой 1 штука. Его можно посмотреть в /proc/interrupts, счетчик увеличивается при срабатывании прерывания на любом из 64 каналов. Могу ли я не залезая в ядро и не извращаясь как-нибудь повесить обработчик прерывания на конкретный канал, не отменяя при этом уже заданные прерывания, аналогично тому, как оно происходит с gpio? Кто нибудь сталкивался с таким, может знает как это реализуется?

Могу ли я не залезая в ядро

нет

аналогично тому, как оно происходит с gpio

посмотри как реализовано для GPIO

anonymous
()
Ответ на: комментарий от anonymous

посмотри как реализовано для GPIO

Реализовано сложновато, нет никакого желания повторять это самому, если существуют более простые варианты

Aleksis_92
() автор топика
Ответ на: комментарий от Aleksis_92

Реализовано сложновато

чего там сложного ?

если существуют более простые варианты

нет

anonymous
()
Ответ на: комментарий от Aleksis_92

linux uio driver должен помочь тебе

и переписать все драйверы которые используют DMA на UIO ? прекрасный совет

anonymous
()
Ответ на: комментарий от anonymous

Спасибо за совет,

однако если задача стоит зарегистрировать прерывание, номер которого дан в документации - здесь все понятно. А что касается виртуальных прерываний, то логика понятна, но конкретная реализация в линуксе не до конца. Смотрю исходники, допустим, где объявляется функция gpio_to_irq (через http://lxr.free-electrons.com/) - и получаю ссылки либо на хедеры, либо не относящиеся к моей архитектуре (arm). То есть конечно можно перерыть все ядро и разобраться, но не зная конкретно где это все настраивается, это займет много времени.

Aleksis_92
() автор топика
Ответ на: комментарий от anonymous

и переписать все драйверы которые используют DMA на UIO ?

где я это предлагал ? может не нужно фантазировать ?

dhampire ★★★
()
Ответ на: комментарий от Aleksis_92

gpio_to_irq

зависит от реализации

То есть конечно можно перерыть все ядро и разобраться

из реализаций которые я видел виртуальные прерывания просто продолжаются после аппаратных, например 32 аппратных, 33-е - вируальное прерывание от gpio 0 и тд.

anonymous
()
Ответ на: комментарий от anonymous

из реализаций которые я видел виртуальные прерывания просто продолжаются после аппаратных, например 32 аппратных, 33-е - вируальное прерывание от gpio 0 и тд.

Хорошо, спасибо, буду разбираться с этим

Aleksis_92
() автор топика
Ответ на: комментарий от i36_zubov

Например что за процессор, что куда подключено и т.д.

Думал задача достаточно общая, чтобы не указывать аппаратную часть. Процессор ARM Cortex A-8, am3352. На gpmc шине висит ethernet контроллер wiznet w5300, прерывание заведено на gpio. Переписываю драйвер на w5300 таким образом, чтобы данные передавались посредством dma. Временное решение сделано так: когда начинается передача по dma вызывается функция mdelay с подогнанным временем. Необходимо избавиться от этого извращения и реализовать прерывание на окончание передачи данных по dma.

Aleksis_92
() автор топика
Ответ на: комментарий от anonymous

по-моему там как раз с одного прерывания куча виртуальных делается, но я не уверен.

Спасибо большое! по крайней мере точно будет полезно разобраться в примере

irq_domain_add_linear
irq_set_chained_handler_and_data(parent_irq,ts4800_ic_chained_handle_irq, data);

вроде похоже на то что надо

Aleksis_92
() автор топика
Ответ на: комментарий от Aleksis_92

По-моему проще не заморачиваться с виртуальными прерываниями а использовать флаг IRQF_SHARED при регистрации обработчиков - в обработчике читаешь флаги состояния и если прерывание не твоё возвращаешь IRQ_NONE - ядро поочереди опросит всех остальных которые висят на этом шареном прерывании.

anonymous
()
Ответ на: комментарий от anonymous

По-моему проще не заморачиваться с виртуальными прерываниями а использовать флаг IRQF_SHARED при регистрации обработчиков - в обработчике читаешь флаги состояния и если прерывание не твоё возвращаешь IRQ_NONE - ядро поочереди опросит всех остальных которые висят на этом шареном прерывании.

Тоже хороший совет, если предыдущие обработчики были зарегистрированы корректно, то не должно случиться Resource busy.

Aleksis_92
() автор топика
Ответ на: комментарий от anonymous

По-моему проще не заморачиваться с виртуальными прерываниями а использовать флаг IRQF_SHARED при регистрации обработчиков - в обработчике читаешь флаги состояния и если прерывание не твоё возвращаешь IRQ_NONE - ядро поочереди опросит всех остальных которые висят на этом шареном прерывании.

Все-таки объявлялось прерывание без флага IRQF_SHARED (0x80)

Flags mismatch irq 12. 00000080 (my_init) vs. 00000000 (edma)

Если предположить что я не имею ни малейшего понятия где именно регистрируется данное прерывание, чтобы исправить флаг в ядре, есть какой нибудь способ его найти? Попробовал grep-ом найти в папке dma «request_irq» - выдал кучу результатов, среди которых не ясно есть вообще нужный.Смотрел в настроках ParamSet dma, там вроде из периферии встречается адрес только mmc, может в ней где искать?

Aleksis_92
() автор топика
Ответ на: комментарий от intelfx

Ты бы написал, как именно решена проблема.

Использовал следующий совет

По-моему проще не заморачиваться с виртуальными прерываниями а использовать флаг IRQF_SHARED при регистрации обработчиков - в обработчике читаешь флаги состояния и если прерывание не твоё возвращаешь IRQ_NONE - ядро поочереди опросит всех остальных которые висят на этом шареном прерывании

Далее нашел место в ядре, где привязывается обработчик, добавил ему флаг IRQF_SHARED, пересобрал ядро, запилил свой обработчик с тем же флагом и теперь прерывание вызывает по очереди (скорее всего, ещё не проверял наверняка) оба обработчика

Aleksis_92
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.