Skip site navigation (1)Skip section navigation (2)
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>