Date: Wed, 23 Oct 2013 08:45:28 -0600 From: Warner Losh <imp@bsdimp.com> To: Ian Lepore <ian@FreeBSD.org> Cc: freebsd-embedded@FreeBSD.org Subject: Re: new ofw_search_compatible() Message-ID: <38F33DD0-4D30-438A-8380-D2354444420C@bsdimp.com> In-Reply-To: <1382539150.92499.206.camel@revolution.hippie.lan> References: <1382539150.92499.206.camel@revolution.hippie.lan>
next in thread | previous in thread | raw e-mail | index | archive | help
I like this... For PC Card I took a slightly different tact where I passed in the size = of the element and returned a pointer to the element. Each element = started with a struct that described what to match. Worked well there, = but most of the time all that was looked up was a simple int. A more = general solution, but maybe not worth the extra hair, unless you combine = it with a probe routine that is 100% driven from tables (which the pc = card client drivers were). The only other nit in the interface is that it requires a NULL = terminator. I'd prefer a count of elements, but I could go either way. Warner On Oct 23, 2013, at 8:39 AM, Ian Lepore wrote: > While creating drivers that work for a variety of SoCs, I increasingly > find myself coding sequences such as: >=20 > if (ofw_bus_is_compatible(dev, "fsl,imx51-fec")) > sc->fectype =3D FECTYPE_IMX51; > else if (ofw_bus_is_compatible(dev, "fsl,imx53-fec")) > sc->fectype =3D FECTYPE_IMX53; > else if (ofw_bus_is_compatible(dev, "fsl,imx6q-fec")) > sc->fectype =3D FECTYPE_IMX6; > else > sc->fectype =3D FECTYPE_GENERIC; >=20 > That's a short list as an example, eventually that driver may support = a > dozen SoCs. I'd like to add a helper routine that turns this into a > table lookup, patch attached. Any objections? It turns sequences = such > as the above into: >=20 > static struct ofw_compat_data compat_data[] =3D { > {"fsl,imx51-fec", FECTYPE_IMX51}, > {"fsl,imx53-fec", FECTYPE_IMX53}, > {"fsl,imx6q-fec", FECTYPE_IMX6}, > {NULL, FECTYPE_NONE}, > }; > /* ... */ > sc->fectype =3D ofw_bus_search_compatible(dev, compat_data)->ocd_data; >=20 > The search routine by design can't return NULL unless you pass it a = NULL > table pointer. That lets you provide whatever "not found" value in = the > table-end sentry that works best for the way your code is structured. >=20 > -- Ian >=20 > Index: sys/dev/ofw/ofw_bus_subr.h > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- sys/dev/ofw/ofw_bus_subr.h (revision 256962) > +++ sys/dev/ofw/ofw_bus_subr.h (working copy) > @@ -47,6 +47,11 @@ struct ofw_bus_iinfo { > pcell_t opi_addrc; > }; >=20 > +struct ofw_compat_data { > + const char *ocd_str; > + uintptr_t ocd_data; > +}; > + > /* Generic implementation of ofw_bus_if.m methods and helper routines = */ > int ofw_bus_gen_setup_devinfo(struct ofw_bus_devinfo *, phandle_t); > void ofw_bus_gen_destroy_devinfo(struct ofw_bus_devinfo *); > @@ -74,6 +79,10 @@ void ofw_bus_find_iparent(phandle_t); > int ofw_bus_is_compatible(device_t, const char *); > int ofw_bus_is_compatible_strict(device_t, const char *); >=20 > +/* Helper routine to search a list of compat props. */ > +const struct ofw_compat_data * > + ofw_bus_search_compatible(device_t, const struct ofw_compat_data = *); > + > /* Helper routine for checking existence of a prop */ > int ofw_bus_has_prop(device_t, const char *); > Index: sys/dev/ofw/ofw_bus_subr.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- sys/dev/ofw/ofw_bus_subr.c (revision 256962) > +++ sys/dev/ofw/ofw_bus_subr.c (working copy) > @@ -197,6 +197,21 @@ ofw_bus_is_compatible_strict(device_t dev, const = c > return (0); > } >=20 > +const struct ofw_compat_data * > +ofw_bus_search_compatible(device_t dev, const struct ofw_compat_data = *compat) > +{ > + > + if (compat =3D=3D NULL) > + return NULL; > + > + for (; compat->ocd_str !=3D NULL; ++compat) { > + if (ofw_bus_is_compatible(dev, compat->ocd_str)) > + break; > + } > + > + return (compat); > +} > + > int > ofw_bus_has_prop(device_t dev, const char *propname) > { >=20 > _______________________________________________ > freebsd-embedded@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-embedded > To unsubscribe, send any mail to = "freebsd-embedded-unsubscribe@freebsd.org"
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?38F33DD0-4D30-438A-8380-D2354444420C>