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

2018-12-19 Thread Ian Lepore
On Wed, 2018-12-19 at 14:35 -0500, Anthony Jenkins wrote:
> On 12/19/18 10:41 AM, Anthony Jenkins wrote:
> > 
> > [snip]
> > 
> > I'm not feeling too confident about the condition of the FreeBSD
> > ig4 
> > driver; the PCI attach code was calling pci_alloc_msi() wrong,
> > passing 
> > a pointer to the rid (0) instead of a pointer to a count variable,
> > and 
> > not passing bus_alloc_resource_any() an IRQ rid > 0 if it has an
> > MSI.  
> > I'd be happy(er) if ig4 created a /dev/iic0 node - I figured
> > iicbus(4) 
> > took care of all that...
> > 
> > https://github.com/ScoobiFreeBSD/freebsd-intel-lpss
> > 
> Found it!  I didn't declare ig4_iic to include the ig4_lpss as a 
> sub-device.  Now it at least /looks/ like I'm getting I2C devices
> found 
> on both my DesignWare I2C busses.
> 
> diff --git a/sys/dev/ichiic/ig4_iic.c b/sys/dev/ichiic/ig4_iic.c
> index 6bbe417..34c1adb 100644
> --- a/sys/dev/ichiic/ig4_iic.c
> +++ b/sys/dev/ichiic/ig4_iic.c
> @@ -802,3 +802,4 @@ ig4iic_dump(ig4iic_softc_t *sc)
> 
>   DRIVER_MODULE(iicbus, ig4iic_acpi, iicbus_driver, iicbus_devclass, 
> NULL, NULL);
>   DRIVER_MODULE(iicbus, ig4iic_pci, iicbus_driver, iicbus_devclass, 
> NULL, NULL);
> +DRIVER_MODULE(iicbus, ig4iic_lpss, iicbus_driver, iicbus_devclass, 
> NULL, NULL);

That new DRIVER_MODULE() statement should be in your new driver, not in
ig4_iic.c. Those other two statements should also be moved into their
corresponding source code files.

At least, that's the precedent followed by all the i2c controller
drivers except ig4_iic: the DRIVER_MODULE() statement that establishes
the connection between iicbus and the controller lives right alongside
the DRIVER_MODULE() statement that establishes the connection between
the controller and the bus it sits on. See, for example:

 sys/dev/glxiic/glxiic.c
 sys/dev/iicbus/iicoc.c

-- Ian

___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


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

2018-12-19 Thread Anthony Jenkins

On 12/19/18 10:41 AM, Anthony Jenkins wrote:

[snip]

I'm not feeling too confident about the condition of the FreeBSD ig4 
driver; the PCI attach code was calling pci_alloc_msi() wrong, passing 
a pointer to the rid (0) instead of a pointer to a count variable, and 
not passing bus_alloc_resource_any() an IRQ rid > 0 if it has an MSI.  
I'd be happy(er) if ig4 created a /dev/iic0 node - I figured iicbus(4) 
took care of all that...


https://github.com/ScoobiFreeBSD/freebsd-intel-lpss

Found it!  I didn't declare ig4_iic to include the ig4_lpss as a 
sub-device.  Now it at least /looks/ like I'm getting I2C devices found 
on both my DesignWare I2C busses.


diff --git a/sys/dev/ichiic/ig4_iic.c b/sys/dev/ichiic/ig4_iic.c
index 6bbe417..34c1adb 100644
--- a/sys/dev/ichiic/ig4_iic.c
+++ b/sys/dev/ichiic/ig4_iic.c
@@ -802,3 +802,4 @@ ig4iic_dump(ig4iic_softc_t *sc)

 DRIVER_MODULE(iicbus, ig4iic_acpi, iicbus_driver, iicbus_devclass, 
NULL, NULL);
 DRIVER_MODULE(iicbus, ig4iic_pci, iicbus_driver, iicbus_devclass, 
NULL, NULL);
+DRIVER_MODULE(iicbus, ig4iic_lpss, iicbus_driver, iicbus_devclass, 
NULL, NULL);


ajenkins@ajenkins-delllaptop ~/Projects/freebsd-intel-lpss (master)
$ ls /dev/ii*
/dev/iic0  /dev/iic1

ajenkins@ajenkins-delllaptop ~/Projects/freebsd-intel-lpss (master)
$ for i2cbus in iic0 iic1; do sudo i2c -s -f "/dev/${i2cbus}"; done
Hardware may not support START/STOP scanning; trying less-reliable read 
method.

Scanning I2C devices on /dev/iic0: 0a
Hardware may not support START/STOP scanning; trying less-reliable read 
method.

Scanning I2C devices on /dev/iic1: 2c

Anthony
___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


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

2018-12-19 Thread Anthony Jenkins



On 12/10/18 3:57 PM, John Baldwin wrote:

On 12/10/18 12:19 PM, Ian Lepore wrote:

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.

Doing the device_add_child in the parent driver's attach routine is also
fine instead of using an identify routine.  It's mostly a matter of which
driver should be in charge of adding the child device (e.g. would you want
lpss self-contained or should the parent driver know about it explicitly).

If you have an existing ig4 driver you are going to reuse, then you will
need to ensure you fake up the resource stuff so that the existing code
works perhaps, though that depends on where the bus_alloc_resource calls
occur.  If they are in shared code you have to fake more.  If they are in
the bus-specific attach routines, then you can just put lpss specific
logic in the lpss-specific attach routine.


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

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

2018-12-11 Thread Anthony Jenkins

On 12/11/18 9:02 AM, Emiel Kollof wrote:

Anthony Jenkins schreef op 2018-12-10 18:00:


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.


Might this also be relevant for i2c-hid devices, like some touchpads 
(Elantech for example)?


Theoretically, yes.  Once this I2C controller is added, then the 
parallel effort to add support for I2C HID devices should add support 
for Elantech I2C touchpads.


The bit I'm doing (support for an Intel MFD I2C controller) is based on 
an old thread on mobile@.  I just recently obtained a laptop that has a 
couple such I2C controllers (touchpad works, but touchscreen doesn't).


Original Elantech touchpad support thread - 
https://lists.freebsd.org/pipermail/freebsd-mobile/2017-August/013617.html

FreeBSD i2c-hid support - https://reviews.freebsd.org/D16698

Anthony



Cheers,
Emiel


___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


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

2018-12-11 Thread Emiel Kollof

Anthony Jenkins schreef op 2018-12-10 18:00:


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.


Might this also be relevant for i2c-hid devices, like some touchpads 
(Elantech for example)?


Cheers,
Emiel
___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


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

2018-12-10 Thread John Baldwin
On 12/10/18 12:19 PM, Ian Lepore wrote:
> 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.

Doing the device_add_child in the parent driver's attach routine is also
fine instead of using an identify routine.  It's mostly a matter of which
driver should be in charge of adding the child device (e.g. would you want
lpss self-contained or should the parent driver know about it explicitly).

If you have an existing ig4 driver you are going to reuse, then you will
need to ensure you fake up the resource stuff so that the existing code
works perhaps, though that depends on where the bus_alloc_resource calls
occur.  If they are in shared code you have to fake more.  If they are in
the bus-specific attach routines, then you can just put lpss specific
logic in the lpss-specific attach routine.

>>> To handle things like resources, you want to have
>>> bus_*_resource 

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

2018-12-10 Thread Ian Lepore
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 

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

2018-12-10 Thread Anthony Jenkins

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.


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@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


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

2018-12-10 Thread John Baldwin
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.

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.  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.

Hopefully that gives you a starting point?

-- 
John Baldwin


___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Composite PCI devices in FreeBSD (mfd in Linux)

2018-12-10 Thread Anthony Jenkins

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?


Thanks,
Anthony Jenkins

References:
 - intel-lpss.c - 
https://github.com/torvalds/linux/blob/master/drivers/mfd/intel-lpss.c
 - intel-lpss-pci.c - 
https://github.com/torvalds/linux/blob/master/drivers/mfd/intel-lpss-pci.c
 - i2c-designware-platdrv.c - 
https://github.com/torvalds/linux/blob/master/drivers/i2c/busses/i2c-designware-platdrv.c
 - "mfd: introduce a driver for LPSS devices on SPT" - 
https://lwn.net/Articles/645819/

 - FreeBSD port - https://github.com/ScoobiFreeBSD/freebsd-intel-lpss
___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"