Index: sys/arm/arm/gic.c =================================================================== --- sys/arm/arm/gic.c +++ sys/arm/arm/gic.c @@ -188,7 +188,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) + if (!ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); device_set_desc(dev, "ARM Generic Interrupt Controller"); return (BUS_PROBE_DEFAULT); Index: sys/arm/arm/mpcore_timer.c =================================================================== --- sys/arm/arm/mpcore_timer.c +++ sys/arm/arm/mpcore_timer.c @@ -267,7 +267,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == TMR_NONE) + if (!ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); device_set_desc(dev, "ARM MPCore Timers"); @@ -398,7 +398,7 @@ } } - tmrtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data; + tmrtype = ofw_bus_compatible_lookup(dev, compat_data)->ocd_data; tc_err = ENXIO; et_err = ENXIO; Index: sys/arm/arm/pl310.c =================================================================== --- sys/arm/arm/pl310.c +++ sys/arm/arm/pl310.c @@ -429,7 +429,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) + if (!ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); device_set_desc(dev, "PL310 L2 cache controller"); return (0); Index: sys/arm/arm/pmu.c =================================================================== --- sys/arm/arm/pmu.c +++ sys/arm/arm/pmu.c @@ -151,7 +151,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) { + if (ofw_bus_compatible_lookup(dev, compat_data)) { device_set_desc(dev, "Performance Monitoring Unit"); return (BUS_PROBE_DEFAULT); } Index: sys/arm/freescale/imx/imx_gpio.c =================================================================== --- sys/arm/freescale/imx/imx_gpio.c +++ sys/arm/freescale/imx/imx_gpio.c @@ -599,7 +599,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) { + if (ofw_bus_compatible_lookup(dev, compat_data)) { device_set_desc(dev, "Freescale i.MX GPIO Controller"); return (BUS_PROBE_DEFAULT); } Index: sys/arm/freescale/imx/imx_gpt.c =================================================================== --- sys/arm/freescale/imx/imx_gpt.c +++ sys/arm/freescale/imx/imx_gpt.c @@ -123,7 +123,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) { + if (ofw_bus_compatible_lookup(dev, compat_data)) { device_set_desc(dev, "Freescale i.MX GPT timer"); return (BUS_PROBE_DEFAULT); } Index: sys/arm/freescale/imx/imx_i2c.c =================================================================== --- sys/arm/freescale/imx/imx_i2c.c +++ sys/arm/freescale/imx/imx_i2c.c @@ -281,7 +281,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + if (!ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); device_set_desc(dev, "Freescale i.MX I2C"); Index: sys/arm/freescale/imx/imx_iomux.c =================================================================== --- sys/arm/freescale/imx/imx_iomux.c +++ sys/arm/freescale/imx/imx_iomux.c @@ -187,7 +187,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) + if (!ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); device_set_desc(dev, "Freescale i.MX pin configuration"); Index: sys/arm/freescale/imx/imx_nop_usbphy.c =================================================================== --- sys/arm/freescale/imx/imx_nop_usbphy.c +++ sys/arm/freescale/imx/imx_nop_usbphy.c @@ -92,7 +92,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) { + if (ofw_bus_compatible_lookup(dev, compat_data)) { device_set_desc(dev, "Freescale USB PHY"); return (BUS_PROBE_DEFAULT); } Index: sys/arm/freescale/imx/imx_sdhci.c =================================================================== --- sys/arm/freescale/imx/imx_sdhci.c +++ sys/arm/freescale/imx/imx_sdhci.c @@ -670,9 +670,7 @@ sc->dev = dev; - sc->hwtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data; - if (sc->hwtype == HWTYPE_NONE) - panic("Impossible: not compatible in imx_sdhci_attach()"); + sc->hwtype = ofw_bus_compatible_lookup(dev, compat_data)->ocd_data; rid = 0; sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, @@ -773,7 +771,12 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) { + struct ofw_compat_data *entry; + entry = ofw_bus_compatible_lookup(dev, compat_data); + if (entry == NULL) + return (ENXIO); + + switch (entry->ocd_data) { case HWTYPE_ESDHC: device_set_desc(dev, "Freescale eSDHC controller"); return (BUS_PROBE_DEFAULT); Index: sys/arm/freescale/imx/imx_wdog.c =================================================================== --- sys/arm/freescale/imx/imx_wdog.c +++ sys/arm/freescale/imx/imx_wdog.c @@ -142,7 +142,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + if (!ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); device_set_desc(dev, "Freescale i.MX Watchdog"); Index: sys/arm/samsung/exynos/exynos5_pad.c =================================================================== --- sys/arm/samsung/exynos/exynos5_pad.c +++ sys/arm/samsung/exynos/exynos5_pad.c @@ -477,7 +477,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) { + if (ofw_bus_compatible_lookup(dev, compat_data)) { device_set_desc(dev, "Exynos Pad Control"); return (BUS_PROBE_DEFAULT); } @@ -498,7 +498,7 @@ mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); - sc->model = ofw_bus_search_compatible(dev, compat_data)->ocd_data; + sc->model = ofw_bus_compatible_lookup(dev, compat_data)->ocd_data; switch (sc->model) { case EXYNOS5250: sc->pad_spec = pad_spec_5250; Index: sys/arm/samsung/exynos/exynos5_pmu.c =================================================================== --- sys/arm/samsung/exynos/exynos5_pmu.c +++ sys/arm/samsung/exynos/exynos5_pmu.c @@ -92,7 +92,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) { + if (ofw_bus_compatible_lookup(dev, compat_data)) { device_set_desc(dev, "Samsung Exynos 5 Power Management Unit"); return (BUS_PROBE_DEFAULT); } @@ -146,7 +146,7 @@ sc = device_get_softc(dev); sc->dev = dev; - sc->model = ofw_bus_search_compatible(dev, compat_data)->ocd_data; + sc->model = ofw_bus_compatible_lookup(dev, compat_data)->ocd_data; if (bus_alloc_resources(dev, pmu_spec, sc->res)) { device_printf(dev, "could not allocate resources\n"); Index: sys/arm/ti/aintc.c =================================================================== --- sys/arm/ti/aintc.c +++ sys/arm/ti/aintc.c @@ -97,7 +97,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + if (!ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); device_set_desc(dev, "TI AINTC Interrupt Controller"); Index: sys/arm/ti/am335x/am335x_dmtimer.c =================================================================== --- sys/arm/ti/am335x/am335x_dmtimer.c +++ sys/arm/ti/am335x/am335x_dmtimer.c @@ -247,7 +247,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + if (!ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); /* Index: sys/arm/ti/am335x/am335x_dmtpps.c =================================================================== --- sys/arm/ti/am335x/am335x_dmtpps.c +++ sys/arm/ti/am335x/am335x_dmtpps.c @@ -405,7 +405,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + if (!ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); /* Index: sys/arm/ti/am335x/am335x_gpio.c =================================================================== --- sys/arm/ti/am335x/am335x_gpio.c +++ sys/arm/ti/am335x/am335x_gpio.c @@ -74,7 +74,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + if (!ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); device_set_desc(dev, "TI AM335x General Purpose I/O (GPIO)"); Index: sys/arm/ti/omap4/omap4_gpio.c =================================================================== --- sys/arm/ti/omap4/omap4_gpio.c +++ sys/arm/ti/omap4/omap4_gpio.c @@ -65,7 +65,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + if (ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); device_set_desc(dev, "TI OMAP4 General Purpose I/O (GPIO)"); Index: sys/arm/ti/omap4/omap4_prcm_clks.c =================================================================== --- sys/arm/ti/omap4/omap4_prcm_clks.c +++ sys/arm/ti/omap4/omap4_prcm_clks.c @@ -1405,8 +1405,8 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - ocd = ofw_bus_search_compatible(dev, compat_data); - if ((int)ocd->ocd_data == 0) + ocd = ofw_bus_compatible_lookup(dev, compat_data); + if (ocd == NULL) return (ENXIO); switch ((int)ocd->ocd_data) { @@ -1452,7 +1452,7 @@ sc = device_get_softc(dev); - ocd = ofw_bus_search_compatible(dev, compat_data); + ocd = ofw_bus_compatible_lookup(dev, compat_data); sc->sc_instance = (int)ocd->ocd_data; sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid, Index: sys/arm/ti/ti_sdhci.c =================================================================== --- sys/arm/ti/ti_sdhci.c +++ sys/arm/ti/ti_sdhci.c @@ -672,7 +672,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) { + if (ofw_bus_compatible_lookup(dev, compat_data)) { device_set_desc(dev, "TI MMCHS (SDHCI 2.0)"); return (BUS_PROBE_DEFAULT); } Index: sys/arm64/arm64/gic_fdt.c =================================================================== --- sys/arm64/arm64/gic_fdt.c +++ sys/arm64/arm64/gic_fdt.c @@ -126,7 +126,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) + if (!ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); device_set_desc(dev, "ARM Generic Interrupt Controller"); Index: sys/dev/ahci/ahci_generic.c =================================================================== --- sys/dev/ahci/ahci_generic.c +++ sys/dev/ahci/ahci_generic.c @@ -67,7 +67,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) + if (!ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); device_set_desc_copy(dev, "AHCI SATA controller"); Index: sys/dev/ffec/if_ffec.c =================================================================== --- sys/dev/ffec/if_ffec.c +++ sys/dev/ffec/if_ffec.c @@ -1439,7 +1439,7 @@ * There are differences in the implementation and features of the FEC * hardware on different SoCs, so figure out what type we are. */ - sc->fectype = ofw_bus_search_compatible(dev, compat_data)->ocd_data; + sc->fectype = ofw_bus_compatible_lookup(dev, compat_data)->ocd_data; /* * We have to be told what kind of electrical connection exists between @@ -1720,16 +1720,16 @@ static int ffec_probe(device_t dev) { - uintptr_t fectype; + struct ofw_compat_data *entry; if (!ofw_bus_status_okay(dev)) return (ENXIO); - fectype = ofw_bus_search_compatible(dev, compat_data)->ocd_data; - if (fectype == FECTYPE_NONE) + entry = ofw_bus_compatible_lookup(dev, compat_data); + if (entry == NULL) return (ENXIO); - device_set_desc(dev, (fectype & FECFLAG_GBE) ? + device_set_desc(dev, (entry->ocd_data & FECFLAG_GBE) ? "Freescale Gigabit Ethernet Controller" : "Freescale Fast Ethernet Controller"); Index: sys/dev/iicbus/icee.c =================================================================== --- sys/dev/iicbus/icee.c +++ sys/dev/iicbus/icee.c @@ -130,15 +130,16 @@ icee_probe(device_t dev) { struct eeprom_desc *d; + struct ofw_compat_data *entry; if (!ofw_bus_status_okay(dev)) return (ENXIO); - d = (struct eeprom_desc *) - ofw_bus_search_compatible(dev, compat_data)->ocd_data; - if (d == NULL) + entry = ofw_bus_compatible_lookup(dev, compat_data); + if (entry == NULL) return (ENXIO); + d = (struct eeprom_desc*))entry->ocd_data; device_set_desc(dev, d->name); return (BUS_PROBE_DEFAULT); } @@ -149,7 +150,7 @@ struct eeprom_desc *d; d = (struct eeprom_desc *) - ofw_bus_search_compatible(sc->dev, compat_data)->ocd_data; + ofw_bus_compatible_lookup(sc->dev, compat_data)->ocd_data; if (d == NULL) return; /* attach will see sc->size == 0 and return error */ Index: sys/dev/mmc/host/dwmmc.c =================================================================== --- sys/dev/mmc/host/dwmmc.c +++ sys/dev/mmc/host/dwmmc.c @@ -486,8 +486,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - hwtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data; - if (hwtype == HWTYPE_NONE) + if (!ofw_bus_compatible_lookup(dev, compat_data)) return (ENXIO); device_set_desc(dev, "Synopsys DesignWare Mobile " @@ -507,7 +506,7 @@ sc->dev = dev; if (sc->hwtype == HWTYPE_NONE) { sc->hwtype = - ofw_bus_search_compatible(dev, compat_data)->ocd_data; + ofw_bus_compatible_lookup(dev, compat_data)->ocd_data; } /* Why not to use Auto Stop? It save a hundred of irq per second */ Index: sys/dev/ofw/ofw_bus_subr.h =================================================================== --- sys/dev/ofw/ofw_bus_subr.h +++ sys/dev/ofw/ofw_bus_subr.h @@ -52,6 +52,10 @@ uintptr_t ocd_data; }; +#define SIMPLEBUS_PNP_DESCR "Z:compat;P:private;" +#define SIMPLEBUS_PNP_INFO(t) \ + MODULE_PNP_INFO(SIMPLEBUS_PNP_DESCR, simplebus, t, t, sizeof(t[0]), sizeof(t) / sizeof(t[0])); + /* 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 *); @@ -94,10 +98,21 @@ * table entry is returned if none of the compat strings match for the device, * giving you control over the not-found value. Will not return NULL unless the * provided table pointer is NULL. + * DEPRECATED */ const struct ofw_compat_data * ofw_bus_search_compatible(device_t, const struct ofw_compat_data *); +/* + * Helper routine to search a list of compat properties. The table is + * terminated by an entry with a NULL compat-string pointer; a pointer to that + * table entry is returned if none of the compat strings match for the device, + * giving you control over the not-found value. Will return NULL if the + * provided table pointer is NULL or no compat entry is found. + */ +const struct ofw_compat_data * + ofw_bus_compatible_lookup(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 =================================================================== --- sys/dev/ofw/ofw_bus_subr.c +++ sys/dev/ofw/ofw_bus_subr.c @@ -254,6 +254,22 @@ return (compat); } +const struct ofw_compat_data * +ofw_bus_compatible_lookup(device_t dev, const struct ofw_compat_data *compat) +{ + + if (compat == NULL) + return NULL; + + for (; compat->ocd_str != NULL; ++compat) { + if (ofw_bus_is_compatible(dev, compat->ocd_str)) + return (compat); + } + + return (NULL); +} + + int ofw_bus_has_prop(device_t dev, const char *propname) { Index: sys/dev/psci/psci.c =================================================================== --- sys/dev/psci/psci.c +++ sys/dev/psci/psci.c @@ -123,13 +123,10 @@ static int psci_probe(device_t dev) { - const struct ofw_compat_data *ocd; - if (!ofw_bus_status_okay(dev)) return (ENXIO); - ocd = ofw_bus_search_compatible(dev, compat_data); - if (ocd->ocd_str == NULL) + if(!ofw_bus_compatible_lookup(dev, compat_data); return (ENXIO); device_set_desc(dev, "ARM Power State Co-ordination Interface Driver"); @@ -148,7 +145,7 @@ if (psci_softc != NULL) return (ENXIO); - ocd = ofw_bus_search_compatible(dev, compat_data); + ocd = ofw_bus_compatible_lookup(dev, compat_data); psci_init = (psci_initfn_t)ocd->ocd_data; KASSERT(psci_init != NULL, ("PSCI init function cannot be NULL")); Index: sys/dev/uart/uart_bus_fdt.c =================================================================== --- sys/dev/uart/uart_bus_fdt.c +++ sys/dev/uart/uart_bus_fdt.c @@ -96,8 +96,8 @@ const struct ofw_compat_data *ocd; SET_FOREACH(cd, uart_fdt_class_and_device_set) { - ocd = ofw_bus_search_compatible(dev, *cd); - if (ocd->ocd_data != 0) + ocd = ofw_bus_compatible_lookup(dev, *cd); + if (ocd != NULL) return (ocd->ocd_data); } return (0); Index: sys/dev/usb/controller/ehci_imx.c =================================================================== --- sys/dev/usb/controller/ehci_imx.c +++ sys/dev/usb/controller/ehci_imx.c @@ -164,7 +164,7 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) { + if (ofw_bus_compatible_lookup(dev, compat_data)) { device_set_desc(dev, "Freescale i.MX integrated USB controller"); return (BUS_PROBE_DEFAULT); }