Можно создать только 1 устройство generic-uio.

Я пытаюсь предоставить прерывания пользовательскому пространству с помощью драйвера uio_pdrv_genirq. Однако я могу создать экземпляр только 1 устройства в дереве устройств, все последующие устройства не проходят проверку. Система представляет собой zynq-7000, а версия ядра — 3.9.0-xilinx.

Дерево устройств:

/ {
...
amba@0 {
    ...

    gic: intc@f8f01000 {
        interrupt-controller;
        compatible = "arm,cortex-a9-gic";
        #interrupt-cells = <3>;
        reg = <0xf8f01000 0x1000>,
              <0xf8f00100 0x0100>;
    };

    interrupt_91@0x43C90000 {
        compatible = "generic-uio";
        reg = < 0x43C90000 0x1000 >;
        interrupts = < 0 59 1 >; //add 32 to get the interrupt number
        interrupt-parent = <&gic>;
    } ;

    interrupter_90@0x43CA0000 {
        compatible = "generic-uio";
        reg = < 0x43CA0000 0x1000 >;
        interrupts = < 0 58 1 >; //add 32 to get the interrupt number
        interrupt-parent = <&gic>;
    } ;
    ...
};

вывод dmesg:

dmesg | grep uio
uio_pdrv_genirq 43ca0000.interrupter_90: unable to register uio device
uio_pdrv_genirq: probe of 43ca0000.interrupter_90 failed with error 1

конфигурация ядра:

CONFIG_UIO=y
# CONFIG_UIO_CIF is not set
CONFIG_UIO_PDRV_GENIRQ=y
# CONFIG_UIO_DMEM_GENIRQ is not set
# CONFIG_UIO_AEC is not set
# CONFIG_UIO_SERCOS3 is not set
# CONFIG_UIO_PCI_GENERIC is not set
# CONFIG_UIO_NETX is not set

Я уверен, что раньше работал над Zedboard, я понятия не имею, в чем здесь может быть проблема.


person lenguador    schedule 17.02.2015    source источник


Ответы (1)


Хорошо, это оказалось проблемой в исходном коде ядра, который я использовал.

Линии:

if (ret)
    goto err_get_minor;

в drivers/uio/uio.c и строки:

if (ret) {
    dev_err(&pdev->dev, "unable to register uio device\n");
    goto bad1;
}

в drivers/uio/uio_pdrv_genirq.c оба должны быть изменены так, чтобы выражение if читалось как if (ret < 0).

Причина этого в том, что функция uio_get_minor (чье возвращаемое значение, ret, они используют) возвращает назначенный младший номер. Это 0, 1, 2, ... и т. д. Понятно, что первое устройство (дополнительный идентификатор = 0) зарегистрировалось нормально, но второе устройство (дополнительный идентификатор = 1) не удалось. Это объясняет сообщение об ошибке «сбой с ошибкой 1», которое было второстепенным идентификатором, а не EPERM, как я изначально предполагал.

Я использую репозиторий https://github.com/Trenz-Electronic/linux-te-3.9 для дальнейшего использования.

РЕДАКТИРОВАТЬ: На самом деле такая же проблема существует в основном ядре, я выложу патч.

person lenguador    schedule 18.02.2015