Estou trabalhando para conseguir um Linux mais moderno funcionando em um computador de placa única onde a empresa original faliu, mas o hardware é bem suportado pela comunidade de código aberto. Fiz um progresso muito bom, mas estou enfrentando um problema em que o módulo de driver incorreto é carregado para um dispositivo específico.
A plataforma é um Allwinner R8 (que é igual ao Allwinner A13) e o aparelho é a tela sensível ao toque resistiva. A distribuição é atual do Slackware para ARM, o que significa que não há systemd, mas usa eudev. Compilei o kernel 5.2.0-rc6 a partir do código-fonte porque queria experimentar o driver Mali lima e precisava de alguns módulos não incluídos na compilação da distribuição de qualquer maneira. As seções relevantes da árvore de dispositivos são as seguintes.
u-boot/arch/arm/dts/sun5i.dtsi:
587 rtp: rtp@1c25000 {
588 compatible = "allwinner,sun5i-a13-ts";
589 reg = <0x01c25000 0x100>;
590 interrupts = <29>;
591 #thermal-sensor-cells = <0>;
592 };
sobreposição (que é retirada da sobreposição do fabricante para um Kernel 4.4 modificado incluído em patches fora da árvore para alguns dispositivos)
76 /* Enable the touchscreen */
77 fragment@4 {
78 target = <&rtp>;
79 __overlay__ {
80 touchscreen-inverted-x;
81 touchscreen-inverted-y;
82 allwinner,ts-attached;
83 };
84 };
O problema é que osun4i-gpadcmódulo é carregado para este dispositivo quando o que eu preciso é osun4i-ts. O primeiro é o driver ADC de uso geral, enquanto o último é o driver de tela sensível ao toque de que preciso.
root@pocketslack:/etc# udevadm info -a /sys/devices/platform/soc\@1c00000/1c25000.rtp
looking at device '/devices/platform/soc@1c00000/1c25000.rtp':
KERNEL=="1c25000.rtp"
SUBSYSTEM=="platform"
DRIVER=="sun4i-gpadc"
ATTR{driver_override}=="(null)"
Se eu usar o modprobe para remover sun4i_gpadc e sun4i_ts, use-o para carregá-los começando com sun4i-ts primeiro, ele pega o dispositivo e funciona corretamente.
root@pocketslack:/etc# modprobe -r sun4i_gpadc
root@pocketslack:/etc# modprobe -r sun4i_ts
root@pocketslack:/etc# modprobe sun4i_ts
root@pocketslack:/etc# modprobe sun4i_gpadc
root@pocketslack:/etc# udevadm info -a /sys/devices/platform/soc\@1c00000/1c25000.rtp
looking at device '/devices/platform/soc@1c00000/1c25000.rtp':
KERNEL=="1c25000.rtp"
SUBSYSTEM=="platform"
DRIVER=="sun4i-ts"
ATTR{driver_override}=="(null)"
Eu tenho uma regra udev que também obtive do antigo repositório da empresa que pensei que resolveria isso, mas o dispositivo ainda é usado pelo driver gpadc.
root@pocketslack:/etc# cat /etc/udev/rules.d/10-sun4i-ts.rules
ACTION=="add", SUBSYSTEM=="input", DRIVERS=="sun4i-ts", SYMLINK+="input/sun4i-ts-%k"
Admito que sou totalmente novo no udev, então não tenho certeza exatamente do que essa regra diz para ele fazer. Meu palpite é que ele está apenas dizendo para carregar esse módulo e como nomear qualquer dispositivo ao qual ele esteja conectado. Também não tenho certeza se preciso do driver sun4i-gpadc, mas deduzo da documentação do kernel que parece ser necessário para que os sensores térmicos do SoC funcionem. Este dispositivo também possui pinos expostos para projetos, então pensei que também poderia ser útil caso alguém realmente quisesse usar o ADC incluído dessa forma. Também parece que deveria haver algum mecanismo para especificar o driver correto quando vários poderiam ser aplicados e imaginei que deveria apenas aprender como fazer isso, em vez de simplesmente não criar ou colocar o módulo gpadc na lista negra.
Responder1
Parece que neste caso específico, eu realmente quero desabilitar osun4i_gpadcmódulo. Eu notei oATTRS{driver_override}parte da udevadm info
saída acima que eu não tinha notado antes e pesquisei no Google, o que me levou a descobrir um pouco mais sobre como as entradas da árvore de dispositivos determinam o módulo por meio do atributo 'compatível'. Isso me levou a descobrir modinfo
que ambos os módulos procuram as mesmas strings compatíveis e depois de olhar a configuração do kernel novamente, vejo que os drivers não são compatíveis e, portanto, eu realmente deveria simplesmente não construir ou colocar na lista negra o driver gpadc neste caso, pois depende!TOUCHSCREEN_SUN4I.
Symbol: MFD_SUN4I_GPADC [=m] │
│ Type : tristate │
│ Prompt: Allwinner sunxi platforms' GPADC MFD driver │
│ Location: │
│ -> Device Drivers │
│ (2) -> Multifunction device drivers │
│ Defined at drivers/mfd/Kconfig:54 │
│ Depends on: HAS_IOMEM [=y] && (ARCH_SUNXI [=y] || COMPILE_TEST [=n]) && !TOUCHSCREEN_SUN4I [=m] │
│ Selects: MFD_CORE [=y] && REGMAP_MMIO [=y] && REGMAP_IRQ [=y]
Desculpas por não fazer RTFM corretamente :)