Re: Composite PCI devices in FreeBSD (mfd in Linux)

From: Ian Lepore <ian_at_freebsd.org>
Date: Mon, 10 Dec 2018 13:19:54 -0700
On Mon, 2018-12-10 at 14:42 -0500, Anthony Jenkins wrote:
> On 12/10/18 1:26 PM, John Baldwin wrote:
> > 
> > On 12/10/18 9:00 AM, Anthony Jenkins wrote:
> > > 
> > > Hi all,
> > > 
> > > I'm trying to port an Intel PCI I2C controller from Linux to
> > > FreeBSD.
> > > Linux represents this device as an MFD (multi-function device),
> > > meaning
> > > it has these "sub-devices" that can be handed off to other
> > > drivers to
> > > actually attach devices to the system.  The Linux "super" PCI
> > > device is
> > > the intel-lpss-pci.c, and the "sub" device is i2c-designware-
> > > platdrv.c,
> > > which represents the DesignWare driver's "platform" attachment to
> > > the
> > > Linux system.  FreeBSD also has a DesignWare I2C controller
> > > driver,
> > > ig4(4), but it only has PCI and ACPI bus attachment
> > > implementations.
> > > 
> > > I have a port of the Linux intel-lpss driver to FreeBSD, but now
> > > I'm
> > > trying to figure out the best way to give FreeBSD's ig4(4) driver
> > > access
> > > to my lpss(4) device.  I'm thinking I could add an ig4_lpss.c
> > > describing
> > > the "attachment" of an ig4(4) to an lpss(4).  Its probe() method
> > > would
> > > scan the "lpss" devclass for devices, and its attach() method
> > > would
> > > attach itself as a child to the lpss device and "grab" the
> > > portion of
> > > PCI memory and the IRQ that the lpss PCI device got.
> > > 
> > > Is this the "FreeBSD Way (TM)" of handling this type of device? 
> > > If not,
> > > can you recommend an existing FreeBSD driver I can model my code
> > > after?
> > > If my approach is acceptable, how do I fully describe the ig4(4)
> > > device's attachment to the system?  Is simply making it a child
> > > of
> > > lpss(4) sufficient?  It's "kind of" a PCI device (it is
> > > controlled via
> > > access to a PCI memory region and an IRQ), but it's a sub-device
> > > of an
> > > actual PCI device (lpss(4)) attached to PCI.
> > > How would my ig4_lpss attachment get information from the lpss(4)
> > > driver
> > > about what it probed?
> > There are some existing PCI drivers that act as "virtual" busses
> > that attach
> > child devices.  For example, vga_pci.c can have drm, agp, and
> > acpi_video
> > child devices.  There are also some SMBus drivers that are also
> > PCI-ISA
> > bridges and thus create separate child devices.
> Yeah I was hoping to avoid using video PCI devices as a model, as 
> complex as they've gotten recently.  I'll check out its bus glue
> logic.
> 
> > 
> > For a virtual bus like this, you need to figure out how your child
> > devices
> > will be enumerated.  A simple way is to let child devices use an
> > identify
> > routine that looks at each parent device and decides if a child
> > device
> > for that driver makes sense.  It can then add a child device in the
> > identify routine.
> Really an lpss parent PCI parent device can only have the following:
> 
>   * one of {I2C, UART, SPI} controller
>   * optionally an IDMA64 controller
> 
> so I was thinking a child ig4(4) device would attach to lpss iff
> 
>   * the lpss device detected an I2C controller
>   * no other ig4 device is already attached
> 
> I haven't fiddled with identify() yet, will look at that tonight.
> 

If this is just another "bus" an ig4 instance can attach to, I'd think
the recipe would be to add another DRIVER_MODULE() to ig4_iic.c naming
ig4_lpss as the parent. Then add a new ig4_lpss.c modeled after the
existing pci and acpi attachment code, its DRIVER_MODULE() would name
lpss as parent, and its probe routine would return BUS_PROBE_NOWILDCARD
(attach only if specifically added by the parent).

Then there would be a new lpss driver that does the resource managment
stuff mentioned above, and if it detects configuration for I2C it would
do a device_add_child(lpssdev, "ig4_lpss", -1) followed by
bus_generic_attach(). There'd be no need for identify() in the child in
that case, I think.

But take jhb's word over mine on any of this stuff, he's been around
since the days when these mechanisms were all invented, whereas I tend
to cut and paste that bus and driver attachment stuff in semi-ignorance 
when I'm working on drivers.

-- Ian



> > To handle things like resources, you want to have
> > bus_*_resource methods that let your child device use the normal
> > bus_*
> > functions to allocate resources.  At the simplest end you don't
> > need to
> > permit any sharing of BARs among multiple children so you can just
> > proxy
> > the requests in the "real" PCI driver.  (vga_pci.c does this)  If
> > you need
> > the BARs to be shared you have a couple of options such as just
> > using a
> > refcount on the BAR resource but letting multiple devices allocate
> > the same
> > BAR.  If you want to enforce exclusivity (once a device allocates
> > part of
> > a BAR then other children shouldn't be permitted to do so), then
> > you will
> > need a more complicated solution.
> Another homework assignment for me - bus_*_resource methods.
> 
> There are 2 or 3 mutually-exclusive sub-regions in the single memory
> BAR:
> 
>   * 0x000 - 0x200 : I2C sub-device registers
>   * 0x200 - 0x300 : lpss and I2C sub-device registers
>   * 0x800 - 0x1000 : IDMA sub-device registers (optional)
> 
> The only child (ig4(4)) of a given parent lpss device would at most
> need 
> to share access to the middle region, if at all.
> 
> > 
> > Hopefully that gives you a starting point?
> Oh definitely, thanks!  If successful, and the effort to support I2C
> HID 
> devices also comes in, it should enable a bunch of laptops to use
> more 
> stuff like touchscreens and touchpads that are currently broken in 
> FreeBSD (I'm pretty sure one of my laptop's 2 lpss devices is a 
> touchscreen I2C device).
> 
> Anthony
> _______________________________________________
> freebsd-current_at_freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscribe_at_freebsd
> .org"
> 
Received on Mon Dec 10 2018 - 19:20:04 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:19 UTC