How do I specify which driver is used for a device when more than one are applicable

BytePorter

I'm working on getting a more modern Linux working on a single board computer where the original company has gone under but the hardware is well supported by the open source community. I've made very good progress but I'm running into an issue where the incorrect driver module is loaded for a particular device.

The platform is an Allwinner R8 (Which is the same as the Allwinner A13) and the device is the resistive touchscreen. Distribution is Slackware-current for ARM, which means no systemd but it does use eudev. I've compiled kernel 5.2.0-rc6 from source because I wanted to try the Mali lima driver and needed some modules not included in the distro build anyway. The relevant sections from the device tree are as follows.

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 (which is cribbed from the manufacturer's overlay for a modified 4.4 Kernel included out of tree patches for some devices)

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

The problem is that the sun4i-gpadc module is loaded for this device when what I need is the sun4i-ts. The former is the general purpose ADC driver while the latter is the touchscreen driver that I need.

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

If I use modprobe to remove sun4i_gpadc and sun4i_ts then use it to load them starting with sun4i-ts first, it grabs the device and it works properly.

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

I have a udev rule which I also got from the company's old repo which I thought would handle this, but the device is still taken by the gpadc driver.

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

I'll admit to being totally new at udev though so I'm not sure exactly what that rule is telling it to do. My hunch is it's just telling it to load that module and how to name any device it attaches to. I'm also not sure I need the sun4i-gpadc driver at all, but I gather from the kernel documentation it seems to be needed for the SoC's thermal sensors to function. This device also has pins exposed for projects, so I thought it may also be useful to have in case one actually wanted to use the included ADC that way. It also seems like there should be some mechanism to specify the correct driver when several could apply and I figured I should just learn how to do that rather than just not build or blacklist the gpadc module.

BytePorter

It seems like in this particular case, I really do want to disable the sun4i_gpadc module. I noticed the ATTRS{driver_override} part in the udevadm info output above which I hadn't noticed before and googled that, which led to finding out a bit more about how the device tree entries determine the module via the 'compatible' attribute. This led me to discover via modinfo that both of those modules look for the same compatible strings and after looking at the kernel config again, I see that the drivers are not compatible and therefore I really should just either not build or blacklist the gpadc driver in this case as it depends on !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]

Apologies for not properly RTFMing :)

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Which `main` is used if I specify more than one

How do I specify more than one type to decode in the enum CodingKeys when using Codable?

(C++) How do I display an error when more than one "." is used in a calcualtor?

Database Design: I have a child table which might be used from more than one parent table (one-to-one). How do I design its schema

which interface will be used for outbound if i have more than one interface?

How do i specify which property will be used as default when binding with mvvmcross?

How do I find out which touchpad driver is being used?

how do I change just one character in a string when there more than one of that character?

How to specify more than one IssuerSigningKey in UseJwtBearerAuthentication?

How do I call more than one function for each case when using a "when" statement in Kotlin?

how do I fill na values when I unstack more than one level at a time

How do I get rid of a Bluebird warning when chaining more than one flatMap operator in RxJS?

How do I find available rooms using LINQ, when there are more than one of each room type?

How do I set "all windows" by default when left clicking on a application that has more than one window?

How do I display the updated element information when there is more than one element in the arrayList?

How do I play more than one video with AvPlayer?

How do I use more than one fxml with javaFX?

How do I filter with more than one letter in primefaces selectonemenu?

How do I look for more than one ID

How do I activate more than one modalbox with js?

How do I run more than one Windows Explorer?

How do I chain together several [ ] [ ] with more than one key

How do I attach more than one stylesheet to an rmarkdown document?

how do i access a param on more than one post or get

How Do I Use More Than One Style On HTML Label?

How do I return more than one item with Scrapy?

How do I get memtest to see more than one core

How do I input more than one dynamic array integer?

How Do I apply these settings to more than one sheet?