Wie gebe ich an, welcher Treiber für ein Gerät verwendet wird, wenn mehrere anwendbar sind?

Wie gebe ich an, welcher Treiber für ein Gerät verwendet wird, wenn mehrere anwendbar sind?

Ich arbeite daran, ein moderneres Linux auf einem Single-Board-Computer zum Laufen zu bringen, dessen ursprüngliche Firma zwar pleitegegangen ist, dessen Hardware aber von der Open-Source-Community gut unterstützt wird. Ich habe sehr gute Fortschritte gemacht, aber ich stoße auf ein Problem, bei dem für ein bestimmtes Gerät das falsche Treibermodul geladen wird.

Die Plattform ist ein Allwinner R8 (das ist dasselbe wie der Allwinner A13) und das Gerät ist der resistive Touchscreen. Die Distribution ist Slackware-current für ARM, was bedeutet, dass kein systemd vorhanden ist, aber eudev verwendet wird. Ich habe Kernel 5.2.0-rc6 aus dem Quellcode kompiliert, weil ich den Mali-Lima-Treiber ausprobieren wollte und einige Module brauchte, die ohnehin nicht im Distributions-Build enthalten waren. Die relevanten Abschnitte aus dem Gerätebaum sind wie folgt.

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         };

Overlay (das vom Overlay des Herstellers für einen modifizierten 4.4-Kernel abgekupfert ist und Out-of-Tree-Patches für einige Geräte enthält)

 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   };

Das Problem ist, dass diesun4i-gpadcModul für dieses Gerät geladen ist, wenn ich das brauche,sun4i-ts. Ersterer ist der allgemeine ADC-Treiber, während letzterer der Touchscreen-Treiber ist, den ich brauche.

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)"

Wenn ich modprobe verwende, um sun4i_gpadc und sun4i_ts zu entfernen und sie dann lade, wobei ich zuerst mit sun4i-ts beginne, wird das Gerät erfasst und es funktioniert ordnungsgemäß.

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)"

Ich habe eine Udev-Regel, die ich auch aus dem alten Repo des Unternehmens habe und von der ich dachte, dass sie das Problem lösen würde, aber das Gerät wird immer noch vom Gpadc-Treiber belegt.

root@pocketslack:/etc# cat /etc/udev/rules.d/10-sun4i-ts.rules 
ACTION=="add", SUBSYSTEM=="input", DRIVERS=="sun4i-ts", SYMLINK+="input/sun4i-ts-%k"

Ich muss allerdings zugeben, dass ich bei udev völlig neu bin, also bin ich mir nicht sicher, was diese Regel ihm genau sagt. Ich vermute, sie sagt ihm nur, dass es dieses Modul laden soll und wie jedes Gerät benannt werden soll, an das es angeschlossen wird. Ich bin mir auch nicht sicher, ob ich den sun4i-gpadc-Treiber überhaupt brauche, aber ich entnehme der Kernel-Dokumentation, dass er anscheinend für die Funktion der Wärmesensoren des SoC erforderlich ist. Dieses Gerät hat auch für Projekte freiliegende Pins, also dachte ich, es könnte auch nützlich sein, sie zu haben, falls man den enthaltenen ADC tatsächlich auf diese Weise verwenden möchte. Es scheint auch, als ob es einen Mechanismus geben sollte, um den richtigen Treiber anzugeben, wenn mehrere in Frage kommen, und ich dachte, ich sollte einfach lernen, wie das geht, anstatt das gpadc-Modul einfach nicht zu erstellen oder auf die schwarze Liste zu setzen.

Antwort1

Es scheint, als ob ich in diesem speziellen Fall wirklich diesun4i_gpadcModul. Mir fiel auf, dassATTRS{Treiberüberschreibung}Teil in der udevadm infoobigen Ausgabe, den ich vorher nicht bemerkt hatte, und googelte das, was dazu führte, dass ich etwas mehr darüber herausfand, wie die Gerätebaumeinträge das Modul über das Attribut „kompatibel“ bestimmen. Dadurch entdeckte ich, modinfodass beide Module nach denselben kompatiblen Zeichenfolgen suchen, und nachdem ich mir die Kernelkonfiguration noch einmal angesehen hatte, sah ich, dass die Treiber nicht kompatibel sind und ich daher in diesem Fall den gpadc-Treiber entweder nicht erstellen oder auf die schwarze Liste setzen sollte, da er davon abhängt!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]

Entschuldigen Sie, dass ich das Handbuch nicht richtig gelesen habe :)

verwandte Informationen