On Wednesday, June 12, 2013 11:36:04 pm Ryan Stone wrote:
> At $WORK we have some custom boards with multi-port uarts managed by puc.
> The uart devices happen to provide some GPIOs, and our hardware designers
> have appropriated those GPIOs for various purposes entirely unrelated to
> the uart.
> 
> I'm looking for a clean way to provide access to the GPIOs.  It occurred to
> me that this was a problem that should be solved through newbus, and lo and
> behold I have discovered that FreeBSD provides a gpiobus driver that seems
> suitable.  I've been playing around with this for a couple of days and I
> have a solutions that is working, but there are aspects that I am unhappy
> with.  I also quite unfamiliar with newbus, so there easily could be better
> ways to approach the problem that I haven't thought of.
> 
> What I ended up doing was making gpiobus and gpioc children of the puc
> bus.  In puc_bfe_attach() I create two new child devices of the puc device
> with device_add_child(), one with the gpioc devclass and one with the
> gpiobus devclass.  I then attach both children with
> device_probe_and_attach().  I make the puc_pci driver itself provide
> implementations of the various gpio methods (like gpio_pin_get) so they can
> be inherited by the child devices.
> 
> Things start to get somewhat messy in the gpio client code.  I have the
> same image running on many different hardware types, so I can't use device
> hints to create a child device of the gpiobus.  Instead my kernel module
> tracks down the device_t for the puc, finds the gpiobus child, and uses
> BUS_ADD_CHILD to create a child of the gpiobus.  I had to add a new gpiobus
> method to allocate GPIO pins to my driver instance.  Once that's done, I
> can toggle GPIOs and whatnot using methods on my driver instance.
> 
> The things that I'm most unhappy with (newbus-wise, anyway) are:
> 
> 1) By default the gpioc and gpiobus drivers were claiming the uart children
> of the puc.  I had to decrease their priority in bus_probe to
> BUS_PROBE_LOW_PRIORITY to work around the problem.  I really don't think
> that was the right solution.  I guess I could introduce a new device that
> is a child of the puc, make sure that it will not claim the uarts, and then
> make the gpioc and gpiobus children of this device.
> 
> 2) I'm not sure how to clean up my child device when my module is
> unloaded.  Currently I am checking if it already exists on load and reusing
> it if so.  I may be missing something obvious here.

Just leave the device around and reuse it.  In your identify routine do
something like this:

static void
agp_i810_identify(driver_t *driver, device_t parent)
{

        if (device_find_child(parent, "agp", -1) == NULL &&
            agp_i810_match(parent))
                device_add_child(parent, "agp", -1);
}

> 
> 3) I really don't like the way that I am adding my child to gpiobus.  Upon
> writing this it occurs to me that device_identify would be the canonical
> way to do this.  Previously it wasn't clear to me how to fit
> device_identify into the current architecture of the gpio client but I see
> how it can be done now.

Yes, device_identify is what you want.  I think it will also solve problem 1
for you as well.

-- 
John Baldwin
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"

Reply via email to