static void mdio_identify(driver_t *driver, device_t parent) { if (device_find_child(parent, mdio_driver.name, -1) == NULL) BUS_ADD_CHILD(parent, 0, mdio_driver.name, -1); }
/* * hotplug_device tries to find changes in the device page. */ static void hotplug_devices(struct work_struct *dummy) { unsigned int i; struct kvm_device_desc *d; struct device *dev; for (i = 0; i < PAGE_SIZE; i += desc_size(d)) { d = kvm_devices + i; /* end of list */ if (d->type == 0) break; /* device already exists */ dev = device_find_child(kvm_root, d, match_desc); if (dev) { /* XXX check for hotplug remove */ put_device(dev); continue; } /* new device */ printk(KERN_INFO "Adding new virtio device %p\n", d); add_kvm_device(d, i); } }
static void chromebook_i2c_identify(driver_t *driver, device_t bus) { device_t controller; device_t child; int i; /* * A stopgap approach to preserve the status quo. * A more intelligent approach is required to correctly * identify a machine model and hardware available on it. * For instance, DMI could be used. * See http://lxr.free-electrons.com/source/drivers/platform/chrome/chromeos_laptop.c */ controller = device_get_parent(bus); if (strcmp(device_get_name(controller), "ig4iic_pci") != 0) return; for (i = 0; i < nitems(slaves); i++) { if (device_find_child(bus, slaves[i].name, -1) != NULL) continue; if (slaves[i].pci_id != pci_get_devid(controller)) continue; child = BUS_ADD_CHILD(bus, 0, slaves[i].name, -1); if (child != NULL) iicbus_set_addr(child, slaves[i].addr); } }
static void iic_identify(driver_t *driver, device_t parent) { if (device_find_child(parent, "iic", -1) == NULL) BUS_ADD_CHILD(parent, 0, "iic", -1); }
/** * Find an NVRAM child device on @p dev, if any. * * @retval device_t An NVRAM device. * @retval NULL If no NVRAM device is found. */ static device_t find_nvram_child(device_t dev) { device_t chipc, nvram; /* Look for a directly-attached NVRAM child */ nvram = device_find_child(dev, devclass_get_name(bhnd_nvram_devclass), -1); if (nvram == NULL) return (NULL); /* Further checks require a bhnd(4) bus */ if (device_get_devclass(dev) != bhnd_devclass) return (NULL); /* Look for a ChipCommon-attached OTP device */ if ((chipc = bhnd_find_child(dev, BHND_DEVCLASS_CC, -1)) != NULL) { /* Recursively search the ChipCommon device */ if ((nvram = find_nvram_child(chipc)) != NULL) return (nvram); } /* Not found */ return (NULL); }
/* * Look for an ICH LPC interface bridge. If one is found, register an * ichwd device. There can be only one. */ static void ichwd_identify(driver_t *driver, device_t parent) { struct ichwd_device *id_p; device_t ich = NULL; device_t dev; uint32_t rcba; int rc; ich = ichwd_find_ich_lpc_bridge(&id_p); if (ich == NULL) return; /* good, add child to bus */ if ((dev = device_find_child(parent, driver->name, 0)) == NULL) dev = BUS_ADD_CHILD(parent, 0, driver->name, 0); if (dev == NULL) return; device_set_desc_copy(dev, id_p->desc); if (id_p->version >= 6) { /* get RCBA (root complex base address) */ rcba = pci_read_config(ich, ICH_RCBA, 4); rc = bus_set_resource(ich, SYS_RES_MEMORY, 0, (rcba & 0xffffc000) + ICH_GCS_OFFSET, ICH_GCS_SIZE); if (rc) ichwd_verbose_printf(dev, "Can not set memory resource for RCBA\n"); } }
static void disable_dss(void) { struct device *dev; struct platform_device *plat_dev; struct device_driver *drv; struct platform_driver *plat_drv; pm_message_t pt; dev = device_find_child(&platform_bus, "omapdss", find_my_dev); if (!dev) { printk("Could not find omapdss device\n"); return; } drv = dev->driver; if (!drv) { printk("Could not find omapdss driver\n"); return; } plat_drv = to_platform_driver(drv); plat_dev = to_platform_device(dev); if (!plat_drv->suspend) { printk("Could not find suspend in omapdss driver\n"); return; } pt.event = 0; plat_drv->suspend(plat_dev, pt); }
static void dfs_identify(driver_t *driver, device_t parent) { uint16_t vers; vers = mfpvr() >> 16; /* Check for an MPC 7447A or 7448 CPU */ switch (vers) { case MPC7447A: case MPC7448: break; default: return; } /* Make sure we're not being doubly invoked. */ if (device_find_child(parent, "dfs", -1) != NULL) return; /* * We attach a child for every CPU since settings need to * be performed on every CPU in the SMP case. */ if (BUS_ADD_CHILD(parent, 10, "dfs", -1) == NULL) device_printf(parent, "add dfs child failed\n"); }
static void acpi_perf_identify(driver_t *driver, device_t parent) { ACPI_HANDLE handle; device_t dev; /* Make sure we're not being doubly invoked. */ if (device_find_child(parent, "acpi_perf", -1) != NULL) return; /* Get the handle for the Processor object and check for perf states. */ handle = acpi_get_handle(parent); if (handle == NULL) return; if (ACPI_FAILURE(AcpiEvaluateObject(handle, "_PSS", NULL, NULL))) return; /* * Add a child to every CPU that has the right methods. In future * versions of the ACPI spec, CPUs can have different settings. * We probe this child now so that other devices that depend * on it (i.e., for info about supported states) will see it. */ if ((dev = BUS_ADD_CHILD(parent, 0, "acpi_perf", -1)) != NULL) device_probe_and_attach(dev); else device_printf(parent, "add acpi_perf child failed\n"); }
static void amdsbwd_identify(driver_t *driver, device_t parent) { device_t child; device_t smb_dev; if (resource_disabled("amdsbwd", 0)) return; if (device_find_child(parent, "amdsbwd", -1) != NULL) return; /* * Try to identify SB600/SB7xx by PCI Device ID of SMBus device * that should be present at bus 0, device 20, function 0. */ smb_dev = pci_find_bsf(0, 20, 0); if (smb_dev == NULL) return; if (pci_get_devid(smb_dev) != AMDSB_SMBUS_DEVID) return; child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "amdsbwd", -1); if (child == NULL) device_printf(parent, "add amdsbwd child failed\n"); }
int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) { struct uart_state *state = drv->state + uport->line; struct tty_port *port = &state->port; struct device *tty_dev; struct uart_match match = {uport, drv}; mutex_lock(&port->mutex); tty_dev = device_find_child(uport->dev, &match, serial_match_port); if (device_may_wakeup(tty_dev)) { if (!enable_irq_wake(uport->irq)) uport->irq_wake = 1; put_device(tty_dev); mutex_unlock(&port->mutex); return 0; } if (console_suspend_enabled || !uart_console(uport)) uport->suspended = 1; if (port->flags & ASYNC_INITIALIZED) { const struct uart_ops *ops = uport->ops; int tries; if (console_suspend_enabled || !uart_console(uport)) { set_bit(ASYNCB_SUSPENDED, &port->flags); clear_bit(ASYNCB_INITIALIZED, &port->flags); spin_lock_irq(&uport->lock); ops->stop_tx(uport); ops->set_mctrl(uport, 0); ops->stop_rx(uport); spin_unlock_irq(&uport->lock); } for (tries = 3; !ops->tx_empty(uport) && tries; tries--) msleep(10); if (!tries) printk(KERN_ERR "%s%s%s%d: Unable to drain " "transmitter\n", uport->dev ? dev_name(uport->dev) : "", uport->dev ? ": " : "", drv->dev_name, drv->tty_driver->name_base + uport->line); if (console_suspend_enabled || !uart_console(uport)) ops->shutdown(uport); } if (console_suspend_enabled && uart_console(uport)) console_stop(uport->cons); if (console_suspend_enabled || !uart_console(uport)) uart_change_pm(state, 3); mutex_unlock(&port->mutex); return 0; }
static void spigen_identify(driver_t *driver, device_t parent) { if (device_find_child(parent, "spigen", -1) != NULL) return; if (BUS_ADD_CHILD(parent, 0, "spigen", -1) == NULL) device_printf(parent, "add child failed\n"); }
static void canbus_identify(driver_t *drv, device_t parent) { if (device_find_child(parent, "canbus", 0) == NULL) { if (BUS_ADD_CHILD(parent, 33, "canbus", 0) == NULL) device_printf(parent, "canbus cannot attach\n"); } }
static void ipmi_smbus_identify(driver_t *driver, device_t parent) { struct ipmi_get_info info; if (ipmi_smbios_identify(&info) && info.iface_type == SSIF_MODE && device_find_child(parent, "ipmi", -1) == NULL) BUS_ADD_CHILD(parent, 0, "ipmi", -1); }
static void tegra124_coretemp_identify(driver_t *driver, device_t parent) { if (device_find_child(parent, "tegra124_coretemp", -1) != NULL) return; if (BUS_ADD_CHILD(parent, 0, "tegra124_coretemp", -1) == NULL) device_printf(parent, "add child failed\n"); }
static void rdrand_identify(driver_t *drv, device_t parent) { /* NB: order 10 is so we get attached after h/w devices */ if (device_find_child(parent, "rdrand", -1) == NULL && BUS_ADD_CHILD(parent, parent, 10, "rdrand", -1) == 0) panic("rdrand: could not attach"); }
static void km_identify(driver_t *driver, struct device *parent) { if (km_probe(parent) == ENXIO) return; if (device_find_child(parent, driver->name, -1) != NULL) return; device_add_child(parent, driver->name, -1); }
static void ps3pic_identify(driver_t *driver, device_t parent) { if (strcmp(installed_platform(), "ps3") != 0) return; if (device_find_child(parent, "ps3pic", -1) == NULL) BUS_ADD_CHILD(parent, 0, "ps3pic", 0); }
static void fdtbus_identify(driver_t *driver, device_t parent) { debugf("%s(driver=%p, parent=%p)\n", __func__, driver, parent); if (device_find_child(parent, "fdtbus", -1) == NULL) BUS_ADD_CHILD(parent, 0, "fdtbus", -1); }
static void vpo_identify(driver_t *driver, device_t parent) { device_t dev; dev = device_find_child(parent, "vpo", -1); if (!dev) BUS_ADD_CHILD(parent, 0, "vpo", -1); }
static void bcm2835_cpufreq_identify(driver_t *driver, device_t parent) { DPRINTF("driver=%p, parent=%p\n", driver, parent); if (device_find_child(parent, "bcm2835_cpufreq", -1) != NULL) return; if (BUS_ADD_CHILD(parent, 0, "bcm2835_cpufreq", -1) == NULL) device_printf(parent, "add child failed\n"); }
static void mic_scan_devices(struct mic_driver *mdrv, bool remove) { s8 type; unsigned int i; struct mic_device_desc __iomem *d; struct mic_device_ctrl __iomem *dc; struct device *dev; int ret; for (i = sizeof(struct mic_bootparam); i < MIC_DP_SIZE; i += mic_total_desc_size(d)) { d = mdrv->dp + i; dc = (void __iomem *)d + mic_aligned_desc_size(d); /* * This read barrier is paired with the corresponding write * barrier on the host which is inserted before adding or * removing a virtio device descriptor, by updating the type. */ rmb(); type = ioread8(&d->type); /* end of list */ if (type == 0) break; if (type == -1) continue; /* device already exists */ dev = device_find_child(mdrv->dev, (void __force *)d, mic_match_desc); if (dev) { if (remove) iowrite8(MIC_VIRTIO_PARAM_DEV_REMOVE, &dc->config_change); put_device(dev); mic_handle_config_change(d, i, mdrv); ret = mic_remove_device(d, i, mdrv); if (!ret && !remove) iowrite8(-1, &d->type); if (remove) { iowrite8(0, &dc->config_change); iowrite8(0, &dc->guest_ack); } continue; } /* new device */ dev_dbg(mdrv->dev, "%s %d Adding new virtio device %p\n", __func__, __LINE__, d); if (!remove) mic_add_device(d, i, mdrv); } }
static void ofwbus_identify(driver_t *driver, device_t parent) { /* Check if Open Firmware has been instantiated */ if (OF_peer(0) == 0) return; if (device_find_child(parent, "ofwbus", -1) == NULL) BUS_ADD_CHILD(parent, 0, "ofwbus", -1); }
static void efirtc_identify(driver_t *driver, device_t parent) { /* Don't add the driver unless we have working runtime services. */ if (efi_rt_ok() != 0) return; if (device_find_child(parent, "efirtc", -1) != NULL) return; if (BUS_ADD_CHILD(parent, 0, "efirtc", -1) == NULL) device_printf(parent, "add child failed\n"); }
static struct fsl_mc_device *fsl_mc_device_lookup(struct dprc_obj_desc *obj_desc, struct fsl_mc_device *mc_bus_dev) { struct device *dev; dev = device_find_child(&mc_bus_dev->dev, obj_desc, __fsl_mc_device_match); return dev ? to_fsl_mc_device(dev) : NULL; }
static void del_conn(struct work_struct *work) { struct device *dev; struct hci_conn *conn = container_of(work, struct hci_conn, work); while (dev = device_find_child(&conn->dev, NULL, __match_tty)) { device_move(dev, NULL); put_device(dev); } device_del(&conn->dev); put_device(&conn->dev); }
/* * create an rpmsg channel using its name and address info. * this function will be used to create both static and dynamic * channels. */ static struct rpmsg_channel *__rpmsg_create_channel(struct virtproc_info *vrp, struct rpmsg_channel_info *chinfo) { struct rpmsg_channel *rpdev; struct device *tmp, *dev = &vrp->vdev->dev; int ret; /* make sure a similar channel doesn't already exist */ tmp = device_find_child(dev, chinfo, rpmsg_channel_match); if (tmp) { /* decrement the matched device's refcount back */ put_device(tmp); dev_err(dev, "channel %s:%x:%x already exist\n", chinfo->name, chinfo->src, chinfo->dst); return NULL; } rpdev = kzalloc(sizeof(struct rpmsg_channel), GFP_KERNEL); if (!rpdev) { pr_err("kzalloc failed\n"); return NULL; } rpdev->vrp = vrp; rpdev->src = chinfo->src; rpdev->dst = chinfo->dst; /* * rpmsg server channels has predefined local address (for now), * and their existence needs to be announced remotely */ rpdev->announce = rpdev->src != RPMSG_ADDR_ANY ? true : false; strncpy(rpdev->id.name, chinfo->name, RPMSG_NAME_SIZE); /* very simple device indexing plumbing which is enough for now */ dev_set_name(&rpdev->dev, "rpmsg%d", rpmsg_dev_index++); rpdev->dev.parent = &vrp->vdev->dev; rpdev->dev.bus = &rpmsg_bus; rpdev->dev.release = rpmsg_release_device; ret = device_register(&rpdev->dev); if (ret) { dev_err(dev, "device_register failed: %d\n", ret); put_device(&rpdev->dev); return NULL; } return rpdev; }
static int rpmsg_destroy_channel_by_info(struct virtproc_info *vrp, struct rpmsg_channel_info *chinfo) { struct virtio_device *vdev = vrp->vdev; struct device *dev; dev = device_find_child(&vdev->dev, chinfo, rpmsg_channel_match); if (!dev) return -EINVAL; rpmsg_destroy_channel(to_rpmsg_channel(dev)); return 0; }
static int ichss_probe(device_t dev) { device_t est_dev, perf_dev; int error, type; /* * If the ACPI perf driver has attached and is not just offering * info, let it manage things. Also, if Enhanced SpeedStep is * available, don't attach. */ perf_dev = device_find_child(device_get_parent(dev), "acpi_perf", -1); if (perf_dev && device_is_attached(perf_dev)) { error = CPUFREQ_DRV_TYPE(perf_dev, &type); if (error == 0 && (type & CPUFREQ_FLAG_INFO_ONLY) == 0) return (ENXIO); } est_dev = device_find_child(device_get_parent(dev), "est", -1); if (est_dev && device_is_attached(est_dev)) return (ENXIO); device_set_desc(dev, "SpeedStep ICH"); return (-1000); }
/* * find an existing channel using its name + address properties, * and destroy it */ static int __rpmsg_destroy_channel(struct virtproc_info *vrp, struct rpmsg_channel_info *chinfo) { struct virtio_device *vdev = vrp->vdev; struct device *dev; dev = device_find_child(&vdev->dev, chinfo, rpmsg_channel_match); if (!dev) return -EINVAL; device_unregister(dev); put_device(dev); return 0; }