Source code organization

Billie Alsup (balsup) balsup at cisco.com
Fri Oct 21 11:45:09 EDT 2022


> From: Greg KH <greg at kroah.com>

> Platform drivers are the "catch all" for where you have to talk to tiny
> hardware-specific devices.  That's normally not an i2c controller.

I always thought of these as hardware specific devices, as the FPGA images
are hardware specific.  Yes, the top level is currently a "real" driver,
and the MFD drivers are all platform drivers (as required by the MFD
infrastructure).  Certainly we integrate with standard subsystems in
those drivers (off the top of my head: i2c, gpio, spi, mdio, led, watchdog,
 and reboot notifier). 

> So you are creating platform devices for a dynamic device that is on
> another bus?  Please no, that is an abuse of the platform device code.
> That's the biggest reason NOT to use MFD for your code.

I was not aware of the alternatives.  I inherited the first set of drivers from
a proof of concept implementation, and just went with it.  Originally,
all of this code was in user space, with no integration with standard
kernel infrastructure.  Movement to standard kernel integration started
with the 4.9.168 kernel in the SONiC 201811 branch.

> Just make normal drivers for these, no need for MFD at all, why do you
> want to use that api here?

I will need to read up on the auxiliary bus code and see what it takes to
move to it, or another bus driver implementation.

> Do you have a pointer to the source for these?  That might make it
> easier to discuss than general concepts here.

The first subset of drivers (meant for out-of-tree builds for OpenBMC)
are publicly available in github.com:cisco-open/cisco-8000-kernel-modules.
This set accesses the FPGA through an i2c bus, and provides only a subset
of drivers that are explicitly needed by OpenBMC.  Note that the same
FPGA will be accessed via PCI by an X86 processor in the same chassis
running a different kernel instance from the OpenBMC ARM instance.

The top level in this case is cisco-fpga-bmc.ko.  There is a "library" of 
shared functions in libcisco.ko, including the code to walk the FPGA,
discover the IP blocks, and setup the struct mfd_cell array (other common
code shared between the blocks include routines to integrate with
the reboot notifier, and some arbitration code between the ARM
and X86 processors when accessing the same i2c IP block)..  The IP blocks
being used with OpenBMC include

cisco-fpga-gpio.ko
cisco-fpga-i2c.ko 
cisco-fpga-i2c-ext.ko
cisco-fpga-info.ko
cisco-fpga-msd.ko
cisco-fpga-xil.ko

Note that there are two different i2c implementations provided in this
repository, and there are two more that will eventually be published here.
They each have different register specifications and have different
capabilities. For example, one type is meant for small SMB accesses, as 
might be the case with a sensor. Another is meant for larger read/writes,
such as might be the case with an eeprom.  Another provides for
automatic polling of transceivers and providing quick access to the
shadow data so read from the transceivers.  etc. 

Walking the FPGA to setup the struct mfd_cell array is within 

https://github.com/cisco-open/cisco-8000-kernel-modules/blob/main/drivers/cisco/mfd.c

One other thing to note, which may be a bit weird, is how we setup regmap.
As previously indicated, each IP block (with its own MFD instantiated platform driver)
can be accessed in multiple ways, e.g. PCI, I2C, SLPC, and P2PM.  The parent driver
provides a function for the child device to create a new child specific regmap.  As you
will see in 

https://github.com/cisco-open/cisco-8000-kernel-modules/blob/main/drivers/cisco/cisco-fpga-bmc.c

there are read/write functions that are used in the child's regmap registration.  Similar is done
for PCI, SLPC, and P2PM, although those drivers are not in this repository yet.


More information about the Kernelnewbies mailing list