Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
/*
 * 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);
	}
}
Ejemplo n.º 3
0
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);
	}
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
/**
 * 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);
}
Ejemplo n.º 6
0
/*
 * 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");
    }
}
Ejemplo n.º 7
0
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);
}  
Ejemplo n.º 8
0
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");
}
Ejemplo n.º 9
0
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");
}
Ejemplo n.º 10
0
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");
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
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");
}
Ejemplo n.º 13
0
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");
	}
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 15
0
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");
}
Ejemplo n.º 16
0
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");
}
Ejemplo n.º 17
0
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);
}
Ejemplo n.º 18
0
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);
}
Ejemplo n.º 19
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);
}
Ejemplo n.º 20
0
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);
}
Ejemplo n.º 21
0
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");
}
Ejemplo n.º 22
0
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);
	}
}
Ejemplo n.º 23
0
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);
}
Ejemplo n.º 24
0
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");
}
Ejemplo n.º 25
0
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;
}
Ejemplo n.º 26
0
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);
}
Ejemplo n.º 27
0
/*
 * 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;
}
Ejemplo n.º 28
0
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;
}
Ejemplo n.º 29
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);
}
Ejemplo n.º 30
0
/*
 * 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;
}