
Estoy trabajando para lograr que un Linux más moderno funcione en una computadora de placa única donde la compañía original se hundió, pero el hardware cuenta con el respaldo de la comunidad de código abierto. He progresado muy bien, pero me encuentro con un problema en el que se carga el módulo de controlador incorrecto para un dispositivo en particular.
La plataforma es un Allwinner R8 (que es igual que el Allwinner A13) y el dispositivo es la pantalla táctil resistiva. La distribución es Slackware-actual para ARM, lo que significa que no tiene systemd pero sí usa eudev. Compilé el kernel 5.2.0-rc6 desde el código fuente porque quería probar el controlador Mali lima y de todos modos necesitaba algunos módulos que no estaban incluidos en la compilación de la distribución. Las secciones relevantes del árbol de dispositivos son las siguientes.
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 };
superposición (que está copiada de la superposición del fabricante para un kernel 4.4 modificado incluido en los parches del árbol para algunos 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 };
El problema es que elsun4i-gpadcEl módulo está cargado para este dispositivo cuando lo que necesito es elsun4i-ts. El primero es el controlador ADC de uso general, mientras que el segundo es el controlador de pantalla táctil que necesito.
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)"
Si uso modprobe para eliminar sun4i_gpadc y sun4i_ts, utilícelo para cargarlos comenzando con sun4i-ts primero, toma el dispositivo y funciona correctamente.
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)"
Tengo una regla udev que también obtuve del antiguo repositorio de la compañía y que pensé que manejaría esto, pero el controlador gpadc aún toma el dispositivo.
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 soy totalmente nuevo en udev, así que no estoy seguro exactamente de qué le dice esa regla que haga. Mi corazonada es que simplemente le está diciendo que cargue ese módulo y cómo nombrar cualquier dispositivo al que se conecte. Tampoco estoy seguro de necesitar el controlador sun4i-gpadc, pero deduzco de la documentación del kernel que parece ser necesario para que funcionen los sensores térmicos del SoC. Este dispositivo también tiene pines expuestos para proyectos, por lo que pensé que también podría ser útil tenerlo en caso de que uno realmente quisiera usar el ADC incluido de esa manera. También parece que debería haber algún mecanismo para especificar el controlador correcto cuando se pueden aplicar varios y pensé que debería aprender a hacerlo en lugar de simplemente no compilar ni incluir en la lista negra el módulo gpadc.
Respuesta1
Parece que en este caso particular, realmente quiero desactivar elsun4i_gpadcmódulo. noté elATTRS{driver_override}parte en el udevadm info
resultado anterior que no había notado antes y busqué en Google, lo que me llevó a descubrir un poco más sobre cómo las entradas del árbol de dispositivos determinan el módulo a través del atributo 'compatible'. Esto me llevó a descubrir modinfo
que ambos módulos buscan las mismas cadenas compatibles y después de mirar la configuración del kernel nuevamente, veo que los controladores no son compatibles y, por lo tanto, realmente no debería compilar ni incluir en la lista negra el controlador gpadc en este caso ya que depende de!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]
Disculpas por no realizar RTFM correctamente :)