Linux device driver startup dependencies - linux-kernel

I'm working on an embedded Linux device (based on an NXP i.MX8 mini SoC) and it needs to support microphone audio input using the NXP "micfil" driver (sound/soc/fsl/fsl_micfil.c).
As a part of initializing the microphone, we have added code (to the driver's fsl_micfil_probe function) to set a GPIO line necessary to enable the microphone (by calling devm_gpiod_get_optional)
Our current Linux BSP (based on Yocto's "sumo" release) works great with this patch.
When upgrading to a newer BSP (based on Yocto's "hardknott" release), we find that the GPIO setup call fails. It appears to be happening because the driver's probe function is called before the GPIO subsystem is available. I think we can hack around this by making the GPIO call from some other driver callback (e.g. after an application opens the device), but I would prefer to simply defer this driver's probe operation until after GPIO is available.
Is there a way to do this? To tell Linux that this driver should not be probed until after GPIO starts up? Or maybe have the probe function explicitly call the GPIO startup function?
Or is there a better solution that I haven't thought of yet?

The device driver's probe function can return -EPROBE_DEFER (after any necessary clean-up) to indicate that a resource it requires is not available yet. The driver core will then add the device to a "deferred probe" list and try to call the probe function after a successful probe of some other device.
See the documentation for further information, and heed the warning about not returning -EPROBE_DEFER if any child devices have been created by the probe function.
devm_gpiod_get_optional and similar devm_gpiod_get_ and gpiod_get_ functions that return a struct gpio_desc * value will return ERR_PTR(-EPROBE_DEFER) if the requested GPIO is not yet available. (This is different to the GPIO not being found, which will result in the _optional variants returning NULL and the non-_optional variants returning ERR_PTR(-ENOENT).) The caller can propogate the -EPROBE_DEFER error to its own caller, but again the warning about not returning -EPROBE_DEFER if any child devices have been created should be heeded.

Related

Serializing the driver's init call order, which were registered at the same init level

I have come across a scenario where two drivers (driver1 and driver2) are registering with kernel using module_init(). driver1 is configuring the chip and driver2 is accessing that chip, so driver1's module_init() has to be called before driver2's module_init() call. How we can create this order, as both driver1 and driver2 are registering at the same init call level (i.e using module_init()).
Can driver2 somehow determine that the chip has been properly configured, using either device status (preferred) or the value of a shared variable (messy)?
If so, then driver2's probe routine should return with -EPROBE_DEFER when the chip has not yet been configured (by driver1).
See https://lwn.net/Articles/485194/
drivercore: Add driver probe deferral mechanism
Allow drivers to report at probe time that they cannot get all the resources
required by the device, and should be retried at a later time.
This should completely solve the problem of getting devices
initialized in the right order. Right now this is mostly handled by
mucking about with initcall ordering which is a complete hack, and
doesn't even remotely handle the case where device drivers are in
modules. This approach completely sidesteps the issues by allowing
driver registration to occur in any order, and any driver can request
to be retried after a few more other drivers get probed.

How is a device file created while interfacing with external device in linux environment?

I am a newbie to linux kernel. While interfacing with the external device, I made the required changes in bsp file. The bsp file device name and platform_driver name should match in order to invoke probe(). I have heard that probe will check whether h/w exists and probe() will create device file (/dev/rtc1) for a new external device. I am not sure about the functionality of the probe(). Can someone explain me how device file is created in this context?Thank you in advance!
probe() is a callback function that gets called, irrespective of h/w presence, when the bus_match_driver() routine returns success. The probe function is called when a device is installed that the driver-core thinks it should handle; the probe function should perform checks on the information passed to it about the device and decide whether the driver is really appropriate for that device. A device file is created either manually by mknod or automatically by udev and is not directly related to probe function. The book https://lwn.net/Kernel/LDD3/ (highly recommended) has all the details regarding creating a device node.

Accessing Platform Device from Userpace

From a general standpoint, I am trying to figure out how to access a platform device from userspace. To be more specific, I have a EMIF controller on and SoC of which I have added to my device tree and I believe it is correctly bound to a pre-written EMIF platform device driver. Now I am trying to figure out how I can access this EMIF device from a userspace application. I have come accross a couple different topics that seem to have some connection to this issue but I cannot quite find out how they relate.
1) As I read it seems like most I/O is done through the use of device nodes which are created by mknod(), do I need to create a device node in order to access this device?
2) I have read a couple threads that talk about writting a Kernel module (Character?, Block?) that can interface with both userspace and the platform device driver, and use it as an intermediary.
3) I have read about the possibility of using mmap() to map the memory of my platform device into my virtual memory space. Is this possible?
4) It seems that when the EMIF driver is instantiated, it calls the probe() fucntion. What functions would a userpace application call in the driver?
It's not completely clear what you're needing to do (and I should caveat that I have no experience with EMIF or with "platform devices" specifically), but here's some overview to help you get started:
Yes, the usual way of providing access to a device is via a device node. Usually this access is provided by a character device driver unless there's some more specific way of providing it. Most of the time if an application is talking "directly" to your driver, it's a character device. Most other types of devices are used in interfacing with other kernel subsystems: for example, a block device is typically used to provide access from a file system driver (say) to an underlying disk drive; a network driver provides access to the network from the in-kernel TCP/IP stack, etc.
There are several char device methods or entry points that can be supported by your driver, but the most common are "read" (i.e. if a user-space program opens your device and does a read(2) from it), "write" (analogous for write(2)) and "ioctl" (often used for configuration/administrative tasks that don't fall naturally into either a read or write). Note that mknod(2) only creates the user-space side of the device. There needs to be a corresponding device driver in the kernel (the "major device number" given in the mknod call links the user-space node with the driver).
For actually creating the device node in the file system, this can be automated (i.e. the node will automatically show up in /dev) if you call the right kernel functions while setting up your device. There's a special daemon that gets notifications from the kernel and responds by executing the mknod(2) system call.
A kernel module is merely a dynamically loadable way of creating a driver or other kernel extension. It can create a character, block or network device (et al.), but then so can a statically linked module. There are some differences in capability mostly because not all kernel functions you might want to use are "exported" to (i.e. visible to) dynamically loaded modules.
It's possible to support mapping of the device memory into user virtual memory space. This would be implemented by yet another driver entry point (mmap). See struct file_operations for all the entry points a char driver can support.
This is pretty much up to you: it depends on what the application needs to be able to do. There are many drivers in the kernel that provide no direct function to user-space, only to other kernel code. As to "probe", there are many probe functions defined in various interfaces. In most cases, these are called by the kernel (or perhaps by a 'higher level "class" driver') to allow the specific driver to discover, identify and "claim" individual devices. They (probe functions) don't usually have anything directly to do with providing access from user-space but I might well be missing something in a particular interface.
You need to create a device node in order to access the device.
The probe function is called when the driver finds a matching device.
For information on platform device API, the following articles could be useful.
The platform device API
Platform devices and device trees

Can Linux USB probe order be changed or controlled?

I am new to Linux and I need to write a USB driver for a device with 2 interfaces. One interface is HID class (3/0/0) with one interrupt in endpoint and a report descriptor. The other interface is vendor defined with 3 bulk endpoints. In my usb_device_id table I have a USB_DEVICE entry with the VID and PID.
When I plug in the device, my xxx_probe function is called for the vendor defined interface but not for the HID interface. Instead, it appears that a built-in driver called 'generic-usb' is taking control of the HID interface.
Is there a way to ensure that my driver probe function is called first?
Why doesn't Linux make multiple passes looking for a more specific driver first (like Windows does)?
Alternatively, can the 'generic-usb' driver be used to receive data on the interrupt endpoint and to set reports and features on the control pipe?
It appears that libusb-1.0.8 allows an application to take control of interfaces on an attached device without the need of a custom driver. So far it appears to provide all the support that I need.

In Linux 2.6 device driver model, what's the entry point of the creation of struct device?

If a USB device driver is loaded, and at some time the device plugs in, then which part of the kernel will create struct device and register it?
When the driver is loaded, the system calls the function, which you assigned in module_init. You will want to call there usb_register(struct usb_driver skel_driver), where skel_driver is a struct with pointers to methods servicing the device, like the probe method.
The probe method is the one which is called, when a new usb device is introduced in to the system. In this place you can fill your struct (usb_skel) with what you will need in the future, initiate a char device or whatever you do, when the device is introduced.
The system mostly won't create anything by itself, it has to have most of the structs prepared and filled with device specific data.
Please see usb-skeleton in lxr for reference and learn to use it, besides read writing usb drivers from LDD.
Cheers

Resources