How to assign interrupt number in device tree for each pcie and pci devices connected to main host bridge via pcie switch and pcie-pci bridge ? Is it require to do it manually or it will automatically assigned ?
For PCI or PCI-E devices connected via PCI or PCI-E bus, it is not required to declare each and every node in the device tree. The devices which are not connected to the PCI/PCI-E bus, need to be declared.
Related
I have multiple devices on MDIO bus (one AR8035 PHY, and 6 DP83849IFVS dual PHYs). The bus is connected to AM335x SoC with linux 4.14.40. Davinchi_mdio scans bus and finds all devices and attaches driver I think for AR8035. How can I access this bus via mdio? I want to write stand-lone (not PHY driver) kernel module, that can simply access mdio bus? How can I do that? I wanted to do that with phy_write/phy_read but I can't get struct phy_device* from my kernel module. How can I get struct phy_device* from the name of the interface ("eth0"). Will it be safe in terms of locks/mutaxes?
If you already have an subsystem for MDIO controller, then I can think of implementing an UIO driver for MDIO interface, which deals with read and write.
UIO driver is safe when compared to the messy kernel driver and complete control will be with the user application which uses that UIO.
**
*Each UIO device is accessed through a device file and several sysfs attribute files. The device file will be called /dev/uio0 for the first device, and /dev/uio1, /dev/uio2 and so on for subsequent devices.
/dev/uioX is used to access the address space of the card. Just use mmap() to access registers or RAM locations of your card.
Interrupts are handled by reading from /dev/uioX. A blocking read() from /dev/uioX will return as soon as an interrupt occurs.*
**
So I understand that a kernel driver sits on top of HW device and then to communicate with the device via user space you will need to talk to the kernel driver via CreateFile && Read && Write. I have seen the design of Window's kernel drivers and their sample codes whether it is a USB or PCI or...
Now what I want to understand is how does the kernel drive communicate with the hardware? Where is the driver code would we usually find the code responsible for reading/writing registers on a certain device? What does the driver need to communicate with the device? I was told it is the BAR0 value that maps the HW to the virtual memory area which means any address we want to access on a physical device would start at that address. Is that correct? what If I have BAR0 = 0xfc500000, do i have to find addresses of certain register on the device and then ad it as an offset?
Driver need to get HW Resources from the OS. in a PCI device example, you will get MMIO Address and the interrupt vector. the MMIO Address is a physical address the PCI Controller and the BIOS map the device too.
the driver gets this value in EvtPepareHardware callback (in KMDF) and then need to map it to kernel Virtual address using MmMapIoSpace().
once you get a kernel Virtual address theoretically it is a "pointer" to the HW memory space and you can access the registers as you wish.
but it is recommended to use the HAL macros to void caching and other issues to access that memory. e.g. READ_REGISTER_ULONG64
to find the address of a registers you the Hardware device spec
for more info read this "Reading and Writing to Device Registers"
I am looking into USB device driver code. looks like all it does is to fill a URB message then calls usb_submit_urb() to pass the message to USB core functions once probe() is called upon matching PCI vendor/product ID.
However I am not able to figure out how USB core relates the device driver to correct HCI driver (xHCI, eHCI etc.)... what I found is most of HCI drivers register themselves as a platform driver which has a unique name, is that the identifier for usb core to correlate the device driver and host driver?
When you have usb 3.0 - then kernel uses xhci driver and doesn't need uhci, ohci or ehci drivers. In such configuration you have got only one hci driver and one hci host. Earlier in the USB 2.0 era there were 2 possible configurations:
ehci with companion controller (ohci or uhci)
ehci with transaction translator (TT)
In the first situation you need to have both drivers installed - for example ehci and uhci. In the second one only dedicated ehci driver was needed.
So currently when you have only xhci - it registers itself as the only usb host driver in linux system. Second thing - it is host driver function to request anything from usb devices - so usb host generates any requests to devices and it is responsible for maintenance of the answers from device. The xhci host driver registers his interrupt and memory area for request maintenance.
I think you need to take a look at this problem from the host (xhci) point of view, not from device point of view, because the host is the master in usb communication and the host initiates any requests. Device is only answering those requests.
I am working on the lowRISC recently, and I want to add Ethernet support for it. I have added the Ethernet IP and have wired it to both AXI bus and Ethernet PHY, and I added the Ethernet interrupt to the interrupt wire just like uart and spi do.
Now I am working to write a driver in linux kernel to support my Ethernet. But I don't find the handle functions to uart and spi interrupts, just 2 interrupts called IRQ_SOFTWARE and IRQ_TIMER(which in file arch/riscv/include/asm/irq.h).
How does the lowRISC chip handle the uart and spi interrupts? And What should I do to handle the interrupt of ethernet on lowRISC chip?
I am new to Linux Device driver and trying to understand Linux device driver model which says a device must registered with its respected bus, be it the platform bus or real spi/i2c bus.
I could see the following macro which registered the i2c client device to its i2c bus.
module_i2c_driver(lm73_driver);
But I am not sure how it happen for a spi client device for example a CPLD/FPGA device sits on the spi bus.
Is such registrations based on the type of device?(block device or char device)