コード例 #1
0
static int pcmcia_device_probe(struct device * dev)
{
	struct pcmcia_device *p_dev;
	struct pcmcia_driver *p_drv;
	struct pcmcia_device_id *did;
	struct pcmcia_socket *s;
	int ret = 0;

	dev = get_device(dev);
	if (!dev)
		return -ENODEV;

	p_dev = to_pcmcia_dev(dev);
	p_drv = to_pcmcia_drv(dev->driver);
	s = p_dev->socket;

	if ((!p_drv->probe) || (!try_module_get(p_drv->owner))) {
		ret = -EINVAL;
		goto put_dev;
	}

	p_dev->state &= ~CLIENT_UNBOUND;

	/* set up the device configuration, if it hasn't been done before */
	if (!s->functions) {
		cistpl_longlink_mfc_t mfc;
		if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC,
				      &mfc) == CS_SUCCESS)
			s->functions = mfc.nfn;
		else
			s->functions = 1;
		s->config = kzalloc(sizeof(config_t) * s->functions,
				    GFP_KERNEL);
		if (!s->config) {
			ret = -ENOMEM;
			goto put_module;
		}
	}

	ret = p_drv->probe(p_dev);
	if (ret)
		goto put_module;

	/* handle pseudo multifunction devices:
	 * there are at most two pseudo multifunction devices.
	 * if we're matching against the first, schedule a
	 * call which will then check whether there are two
	 * pseudo devices, and if not, add the second one.
	 */
	did = (struct pcmcia_device_id *) p_dev->dev.driver_data;
	if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
	    (p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
		pcmcia_add_pseudo_device(p_dev->socket);

 put_module:
	if (ret)
		module_put(p_drv->owner);
 put_dev:
	if (ret)
		put_device(dev);
	return (ret);
}
コード例 #2
0
void omap_dss_put_device(struct omap_dss_device *dssdev)
{
	put_device(&dssdev->dev);
}
コード例 #3
0
/**
 * chp_new - register a new channel-path
 * @chpid - channel-path ID
 *
 * Create and register data structure representing new channel-path. Return
 * zero on success, non-zero otherwise.
 */
int chp_new(struct chp_id chpid)
{
	struct channel_path *chp;
	int ret;

	if (chp_is_registered(chpid))
		return 0;
	chp = kzalloc(sizeof(struct channel_path), GFP_KERNEL);
	if (!chp)
		return -ENOMEM;

	/* fill in status, etc. */
	chp->chpid = chpid;
	chp->state = 1;
	chp->dev.parent = &channel_subsystems[chpid.cssid]->device;
	chp->dev.groups = chp_attr_groups;
	chp->dev.release = chp_release;
	mutex_init(&chp->lock);

	/* Obtain channel path description and fill it in. */
	ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc);
	if (ret)
		goto out_free;
	if ((chp->desc.flags & 0x80) == 0) {
		ret = -ENODEV;
		goto out_free;
	}
	/* Get channel-measurement characteristics. */
	if (css_chsc_characteristics.scmc && css_chsc_characteristics.secm) {
		ret = chsc_get_channel_measurement_chars(chp);
		if (ret)
			goto out_free;
	} else {
		chp->cmg = -1;
	}
	dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id);

	/* make it known to the system */
	ret = device_register(&chp->dev);
	if (ret) {
		CIO_MSG_EVENT(0, "Could not register chp%x.%02x: %d\n",
			      chpid.cssid, chpid.id, ret);
		put_device(&chp->dev);
		goto out;
	}
	mutex_lock(&channel_subsystems[chpid.cssid]->mutex);
	if (channel_subsystems[chpid.cssid]->cm_enabled) {
		ret = chp_add_cmg_attr(chp);
		if (ret) {
			device_unregister(&chp->dev);
			mutex_unlock(&channel_subsystems[chpid.cssid]->mutex);
			goto out;
		}
	}
	channel_subsystems[chpid.cssid]->chps[chpid.id] = chp;
	mutex_unlock(&channel_subsystems[chpid.cssid]->mutex);
	goto out;
out_free:
	kfree(chp);
out:
	return ret;
}
コード例 #4
0
/**
 * ccwgroup_create_from_string() - create and register a ccw group device
 * @root: parent device for the new device
 * @creator_id: identifier of creating driver
 * @cdrv: ccw driver of slave devices
 * @num_devices: number of slave devices
 * @buf: buffer containing comma separated bus ids of slave devices
 *
 * Create and register a new ccw group device as a child of @root. Slave
 * devices are obtained from the list of bus ids given in @buf and must all
 * belong to @cdrv.
 * Returns:
 *  %0 on success and an error code on failure.
 * Context:
 *  non-atomic
 */
int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
				struct ccw_driver *cdrv, int num_devices,
				const char *buf)
{
	struct ccwgroup_device *gdev;
	int rc, i;
	char tmp_bus_id[CCW_BUS_ID_SIZE];
	const char *curr_buf;

	gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]),
		       GFP_KERNEL);
	if (!gdev)
		return -ENOMEM;

	atomic_set(&gdev->onoff, 0);
	mutex_init(&gdev->reg_mutex);
	mutex_lock(&gdev->reg_mutex);
	gdev->creator_id = creator_id;
	gdev->count = num_devices;
	gdev->dev.bus = &ccwgroup_bus_type;
	gdev->dev.parent = root;
	gdev->dev.release = ccwgroup_release;
	device_initialize(&gdev->dev);

	curr_buf = buf;
	for (i = 0; i < num_devices && curr_buf; i++) {
		rc = __get_next_bus_id(&curr_buf, tmp_bus_id);
		if (rc != 0)
			goto error;
		if (!__is_valid_bus_id(tmp_bus_id)) {
			rc = -EINVAL;
			goto error;
		}
		gdev->cdev[i] = get_ccwdev_by_busid(cdrv, tmp_bus_id);
		/*
		 * All devices have to be of the same type in
		 * order to be grouped.
		 */
		if (!gdev->cdev[i]
		    || gdev->cdev[i]->id.driver_info !=
		    gdev->cdev[0]->id.driver_info) {
			rc = -EINVAL;
			goto error;
		}
		/* Don't allow a device to belong to more than one group. */
		spin_lock_irq(gdev->cdev[i]->ccwlock);
		if (dev_get_drvdata(&gdev->cdev[i]->dev)) {
			spin_unlock_irq(gdev->cdev[i]->ccwlock);
			rc = -EINVAL;
			goto error;
		}
		dev_set_drvdata(&gdev->cdev[i]->dev, gdev);
		spin_unlock_irq(gdev->cdev[i]->ccwlock);
	}
	/* Check for sufficient number of bus ids. */
	if (i < num_devices && !curr_buf) {
		rc = -EINVAL;
		goto error;
	}
	/* Check for trailing stuff. */
	if (i == num_devices && strlen(curr_buf) > 0) {
		rc = -EINVAL;
		goto error;
	}

	dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev));

	rc = device_add(&gdev->dev);
	if (rc)
		goto error;
	get_device(&gdev->dev);
	rc = device_create_file(&gdev->dev, &dev_attr_ungroup);

	if (rc) {
		device_unregister(&gdev->dev);
		goto error;
	}

	rc = __ccwgroup_create_symlinks(gdev);
	if (!rc) {
		mutex_unlock(&gdev->reg_mutex);
		put_device(&gdev->dev);
		return 0;
	}
	device_remove_file(&gdev->dev, &dev_attr_ungroup);
	device_unregister(&gdev->dev);
error:
	for (i = 0; i < num_devices; i++)
		if (gdev->cdev[i]) {
			spin_lock_irq(gdev->cdev[i]->ccwlock);
			if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev)
				dev_set_drvdata(&gdev->cdev[i]->dev, NULL);
			spin_unlock_irq(gdev->cdev[i]->ccwlock);
			put_device(&gdev->cdev[i]->dev);
			gdev->cdev[i] = NULL;
		}
	mutex_unlock(&gdev->reg_mutex);
	put_device(&gdev->dev);
	return rc;
}
コード例 #5
0
static void acpi_processor_hotplug_notify(acpi_handle handle,
					  u32 event, void *data)
{
	struct acpi_device *device = NULL;
	struct acpi_eject_event *ej_event = NULL;
	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
	acpi_status status;
	int result;

	acpi_scan_lock_acquire();

	switch (event) {
	case ACPI_NOTIFY_BUS_CHECK:
	case ACPI_NOTIFY_DEVICE_CHECK:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
		"Processor driver received %s event\n",
		       (event == ACPI_NOTIFY_BUS_CHECK) ?
		       "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));

		if (!is_processor_present(handle))
			break;

		if (!acpi_bus_get_device(handle, &device))
			break;

		result = acpi_bus_scan(handle);
		if (result) {
			acpi_handle_err(handle, "Unable to add the device\n");
			break;
		}
		result = acpi_bus_get_device(handle, &device);
		if (result) {
			acpi_handle_err(handle, "Missing device object\n");
			break;
		}
		ost_code = ACPI_OST_SC_SUCCESS;
		break;

	case ACPI_NOTIFY_EJECT_REQUEST:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "received ACPI_NOTIFY_EJECT_REQUEST\n"));

		if (acpi_bus_get_device(handle, &device)) {
			acpi_handle_err(handle,
				"Device don't exist, dropping EJECT\n");
			break;
		}
		if (!acpi_driver_data(device)) {
			acpi_handle_err(handle,
				"Driver data is NULL, dropping EJECT\n");
			break;
		}

		ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
		if (!ej_event) {
			acpi_handle_err(handle, "No memory, dropping EJECT\n");
			break;
		}

		get_device(&device->dev);
		ej_event->device = device;
		ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
		/* The eject is carried out asynchronously. */
		status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
						 ej_event);
		if (ACPI_FAILURE(status)) {
			put_device(&device->dev);
			kfree(ej_event);
			break;
		}
		goto out;

	default:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "Unsupported event [0x%x]\n", event));

		/* non-hotplug event; possibly handled by other handler */
		goto out;
	}

	/* Inform firmware that the hotplug operation has completed */
	(void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);

 out:
	acpi_scan_lock_release();
}
コード例 #6
0
static int read_domain_devices(struct acpi_power_meter_resource *resource)
{
	int res = 0;
	int i;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object *pss;
	acpi_status status;

	status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMD", NULL,
				      &buffer);
	if (ACPI_FAILURE(status)) {
		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMD"));
		return -ENODEV;
	}

	pss = buffer.pointer;
	if (!pss ||
	    pss->type != ACPI_TYPE_PACKAGE) {
		dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME
			"Invalid _PMD data\n");
		res = -EFAULT;
		goto end;
	}

	if (!pss->package.count)
		goto end;

	resource->domain_devices = kzalloc(sizeof(struct acpi_device *) *
					   pss->package.count, GFP_KERNEL);
	if (!resource->domain_devices) {
		res = -ENOMEM;
		goto end;
	}

	resource->holders_dir = kobject_create_and_add("measures",
					&resource->acpi_dev->dev.kobj);
	if (!resource->holders_dir) {
		res = -ENOMEM;
		goto exit_free;
	}

	resource->num_domain_devices = pss->package.count;

	for (i = 0; i < pss->package.count; i++) {
		struct acpi_device *obj;
		union acpi_object *element = &(pss->package.elements[i]);

		/* Refuse non-references */
		if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
			continue;

		/* Create a symlink to domain objects */
		resource->domain_devices[i] = NULL;
		status = acpi_bus_get_device(element->reference.handle,
					     &resource->domain_devices[i]);
		if (ACPI_FAILURE(status))
			continue;

		obj = resource->domain_devices[i];
		get_device(&obj->dev);

		res = sysfs_create_link(resource->holders_dir, &obj->dev.kobj,
				      kobject_name(&obj->dev.kobj));
		if (res) {
			put_device(&obj->dev);
			resource->domain_devices[i] = NULL;
		}
	}

	res = 0;
	goto end;

exit_free:
	kfree(resource->domain_devices);
end:
	kfree(buffer.pointer);
	return res;
}
コード例 #7
0
ファイル: file.c プロジェクト: AshishNamdev/linux
static int __afu_open(struct inode *inode, struct file *file, bool master)
{
	struct cxl *adapter;
	struct cxl_afu *afu;
	struct cxl_context *ctx;
	int adapter_num = CXL_DEVT_ADAPTER(inode->i_rdev);
	int slice = CXL_DEVT_AFU(inode->i_rdev);
	int rc = -ENODEV;

	pr_devel("afu_open afu%i.%i\n", slice, adapter_num);

	if (!(adapter = get_cxl_adapter(adapter_num)))
		return -ENODEV;

	if (slice > adapter->slices)
		goto err_put_adapter;

	spin_lock(&adapter->afu_list_lock);
	if (!(afu = adapter->afu[slice])) {
		spin_unlock(&adapter->afu_list_lock);
		goto err_put_adapter;
	}

	/*
	 * taking a ref to the afu so that it doesn't go away
	 * for rest of the function. This ref is released before
	 * we return.
	 */
	cxl_afu_get(afu);
	spin_unlock(&adapter->afu_list_lock);

	if (!afu->current_mode)
		goto err_put_afu;

	if (!cxl_ops->link_ok(adapter, afu)) {
		rc = -EIO;
		goto err_put_afu;
	}

	if (!(ctx = cxl_context_alloc())) {
		rc = -ENOMEM;
		goto err_put_afu;
	}

	rc = cxl_context_init(ctx, afu, master);
	if (rc)
		goto err_put_afu;

	cxl_context_set_mapping(ctx, inode->i_mapping);

	pr_devel("afu_open pe: %i\n", ctx->pe);
	file->private_data = ctx;
	cxl_ctx_get();

	/* indicate success */
	rc = 0;

err_put_afu:
	/* release the ref taken earlier */
	cxl_afu_put(afu);
err_put_adapter:
	put_device(&adapter->dev);
	return rc;
}
コード例 #8
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;
	}
	put_device(tty_dev);

	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;
}
コード例 #9
0
int uart_resume_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};
	struct ktermios termios;

	mutex_lock(&port->mutex);

	tty_dev = device_find_child(uport->dev, &match, serial_match_port);
	if (!uport->suspended && device_may_wakeup(tty_dev)) {
		if (uport->irq_wake) {
			disable_irq_wake(uport->irq);
			uport->irq_wake = 0;
		}
		put_device(tty_dev);
		mutex_unlock(&port->mutex);
		return 0;
	}
	put_device(tty_dev);
	uport->suspended = 0;

	if (uart_console(uport)) {
		memset(&termios, 0, sizeof(struct ktermios));
		termios.c_cflag = uport->cons->cflag;

		if (port->tty && port->tty->termios && termios.c_cflag == 0)
			termios = *(port->tty->termios);
		if (console_suspend_enabled)
			uart_change_pm(state, 0);
		uport->ops->set_termios(uport, &termios, NULL);
		if (console_suspend_enabled)
			console_start(uport->cons);
	}

	if (port->flags & ASYNC_SUSPENDED) {
		const struct uart_ops *ops = uport->ops;
		int ret;

		uart_change_pm(state, 0);
		spin_lock_irq(&uport->lock);
		ops->set_mctrl(uport, 0);
		spin_unlock_irq(&uport->lock);
		if (console_suspend_enabled || !uart_console(uport)) {
			
			struct tty_struct *tty = port->tty;
			ret = ops->startup(uport);
			if (ret == 0) {
				if (tty)
					uart_change_speed(tty, state, NULL);
				spin_lock_irq(&uport->lock);
				ops->set_mctrl(uport, uport->mctrl);
				ops->start_tx(uport);
				spin_unlock_irq(&uport->lock);
				set_bit(ASYNCB_INITIALIZED, &port->flags);
			} else {
				uart_shutdown(tty, state);
			}
		}

		clear_bit(ASYNCB_SUSPENDED, &port->flags);
	}

	mutex_unlock(&port->mutex);

	return 0;
}
コード例 #10
0
ファイル: simple-core.c プロジェクト: Jingtian1989/simplebus
static void simple_dev_put(struct simple_device *dev)
{
	if (dev)
		put_device(&dev->device);

}
コード例 #11
0
ファイル: core.c プロジェクト: 3sOx/asuswrt-merlin
void soundbus_dev_put(struct soundbus_dev *dev)
{
	if (dev)
		put_device(&dev->ofdev.dev);
}
コード例 #12
0
ファイル: monreader.c プロジェクト: 03199618/linux
/******************************************************************************
 *                              module init/exit                              *
 *****************************************************************************/
static int __init mon_init(void)
{
	int rc;

	if (!MACHINE_IS_VM) {
		pr_err("The z/VM *MONITOR record device driver cannot be "
		       "loaded without z/VM\n");
		return -ENODEV;
	}

	/*
	 * Register with IUCV and connect to *MONITOR service
	 */
	rc = iucv_register(&monreader_iucv_handler, 1);
	if (rc) {
		pr_err("The z/VM *MONITOR record device driver failed to "
		       "register with IUCV\n");
		return rc;
	}

	rc = driver_register(&monreader_driver);
	if (rc)
		goto out_iucv;
	monreader_device = kzalloc(sizeof(struct device), GFP_KERNEL);
	if (!monreader_device) {
		rc = -ENOMEM;
		goto out_driver;
	}

	dev_set_name(monreader_device, "monreader-dev");
	monreader_device->bus = &iucv_bus;
	monreader_device->parent = iucv_root;
	monreader_device->driver = &monreader_driver;
	monreader_device->release = (void (*)(struct device *))kfree;
	rc = device_register(monreader_device);
	if (rc) {
		put_device(monreader_device);
		goto out_driver;
	}

	rc = segment_type(mon_dcss_name);
	if (rc < 0) {
		segment_warning(rc, mon_dcss_name);
		goto out_device;
	}
	if (rc != SEG_TYPE_SC) {
		pr_err("The specified *MONITOR DCSS %s does not have the "
		       "required type SC\n", mon_dcss_name);
		rc = -EINVAL;
		goto out_device;
	}

	rc = segment_load(mon_dcss_name, SEGMENT_SHARED,
			  &mon_dcss_start, &mon_dcss_end);
	if (rc < 0) {
		segment_warning(rc, mon_dcss_name);
		rc = -EINVAL;
		goto out_device;
	}
	dcss_mkname(mon_dcss_name, &user_data_connect[8]);

	/*
	 * misc_register() has to be the last action in module_init(), because
	 * file operations will be available right after this.
	 */
	rc = misc_register(&mon_dev);
	if (rc < 0 )
		goto out;
	return 0;

out:
	segment_unload(mon_dcss_name);
out_device:
	device_unregister(monreader_device);
out_driver:
	driver_unregister(&monreader_driver);
out_iucv:
	iucv_unregister(&monreader_iucv_handler, 1);
	return rc;
}
コード例 #13
0
ファイル: drivers.c プロジェクト: AshishNamdev/linux
static void comedi_clear_hw_dev(struct comedi_device *dev)
{
	put_device(dev->hw_dev);
	dev->hw_dev = NULL;
}
コード例 #14
0
ファイル: interface.c プロジェクト: avagin/linux
void rtc_class_close(struct rtc_device *rtc)
{
	module_put(rtc->owner);
	put_device(&rtc->dev);
}
コード例 #15
0
static inline void video_put(struct video_device *vdev)
{
	put_device(&vdev->dev);
}
コード例 #16
0
ファイル: display.c プロジェクト: ParrotSec/linux-psec
void omap_dss_put_device(struct omap_dss_device *dssdev)
{
	put_device(dssdev->dev);
	module_put(dssdev->owner);
}
コード例 #17
0
ファイル: cec-core.c プロジェクト: AshishNamdev/linux
void cec_put_device(struct cec_devnode *devnode)
{
	put_device(&devnode->dev);
}
コード例 #18
0
ファイル: usb-musb.c プロジェクト: 0rt/mpokang_kernel
void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
{
	struct omap_hwmod		*oh;
	struct omap_device		*od;
	struct platform_device		*pdev;
	struct device			*dev = NULL;
	int				bus_id = -1;
	const char			*oh_name, *name;
	struct omap_musb_board_data	*board_data;

	if (musb_board_data)
		board_data = musb_board_data;
	else
		board_data = &musb_default_board_data;

	/*
	 * REVISIT: This line can be removed once all the platforms using
	 * musb_core.c have been converted to use use clkdev.
	 */
	musb_plat.clock = "ick";
	musb_plat.board_data = board_data;
	musb_plat.power = board_data->power >> 1;
	musb_plat.mode = board_data->mode;
	musb_plat.extvbus = board_data->extvbus;

	if (cpu_is_omap44xx())
		omap4430_phy_init(dev); /* power down the phy */

	if (cpu_is_omap3517() || cpu_is_omap3505()) {
		oh_name = "am35x_otg_hs";
		name = "musb-am35x";
	} else {
		oh_name = "usb_otg_hs";
		name = "musb-omap2430";
	}

	oh = omap_hwmod_lookup(oh_name);
	if (!oh) {
		pr_err("Could not look up %s\n", oh_name);
		return;
	}

	od = omap_device_build(name, bus_id, oh, &musb_plat,
			       sizeof(musb_plat), omap_musb_latency,
			       ARRAY_SIZE(omap_musb_latency), false);
	if (IS_ERR(od)) {
		pr_err("Could not build omap_device for %s %s\n",
						name, oh_name);
		return;
	}

	pdev = &od->pdev;
	dev = &pdev->dev;
	get_device(dev);
	dev->dma_mask = &musb_dmamask;
	dev->coherent_dma_mask = musb_dmamask;
	put_device(dev);

	if (cpu_is_omap44xx())
		omap4430_phy_init(dev);
}
コード例 #19
0
ファイル: usb-musb.c プロジェクト: Bloodawn/lge-kernel-sniper
void __init usb_musb_init(struct omap_musb_board_data *board_data)
{
	char oh_name[MAX_OMAP_MUSB_HWMOD_NAME_LEN];
	struct omap_hwmod *oh;
	struct omap_device *od;
	struct platform_device *pdev;
	struct device	*dev;
	int l, bus_id = -1;
	struct musb_hdrc_platform_data *pdata;

	if (!board_data) {
		pr_err("Board data is required for hdrc device register\n");
		return;
	}
	l = snprintf(oh_name, MAX_OMAP_MUSB_HWMOD_NAME_LEN,
						"usb_otg_hs");
	WARN(l >= MAX_OMAP_MUSB_HWMOD_NAME_LEN,
			"String buffer overflow in MUSB device setup\n");

	oh = omap_hwmod_lookup(oh_name);

	if (!oh) {
		pr_err("Could not look up %s\n", oh_name);
	} else {
		/*
		 * REVISIT: This line can be removed once all the platforms
		 * using musb_core.c have been converted to use use clkdev.
		 */
		musb_plat.clock = "ick";
		musb_plat.board_data = board_data;
		musb_plat.power = board_data->power >> 1;
		musb_plat.mode = board_data->mode;
		musb_plat.device_enable = omap_device_enable;
		musb_plat.device_idle = omap_device_idle;
		musb_plat.enable_wakeup = omap_device_enable_wakeup;
		musb_plat.disable_wakeup = omap_device_disable_wakeup;
#ifdef CONFIG_PM
		musb_plat.set_min_bus_tput = omap_pm_set_min_bus_tput;
#endif
		/*
		 * Errata 1.166 idle_req/ack is broken in omap3430
		 * workaround is to disable the autodile bit for omap3430.
		 */
		if (cpu_is_omap3430() || cpu_is_omap3630())
			oh->flags |= HWMOD_NO_OCP_AUTOIDLE;

		musb_plat.oh = oh;
		oh_p = oh;
		pdata = &musb_plat;

		od = omap_device_build(name, bus_id, oh, pdata,
				       sizeof(struct musb_hdrc_platform_data),
							omap_musb_latency,
				       ARRAY_SIZE(omap_musb_latency), false);
		if (IS_ERR(od)) {
			pr_err("Could not build omap_device for %s %s\n",
						name, oh_name);
		} else {

			pdev = &od->pdev;
			dev = &pdev->dev;
			get_device(dev);
			dev->dma_mask = &musb_dmamask;
			dev->coherent_dma_mask = musb_dmamask;
			put_device(dev);
		}

		/*powerdown the phy*/
		if (board_data->interface_type == MUSB_INTERFACE_UTMI)
			omap_writel(PHY_PD, DIE_ID_REG_BASE + CONTROL_DEV_CONF);

		usb_gadget_init();
	}
}
コード例 #20
0
ファイル: ehci-arc.c プロジェクト: mrtos/Logitech-Revue
/**
 * usb_hcd_fsl_probe - initialize FSL-based HCDs
 * @drvier: Driver to be used for this HCD
 * @pdev: USB Host Controller being probed
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller.
 *
 */
static int usb_hcd_fsl_probe(const struct hc_driver *driver,
			     struct platform_device *pdev)
{
	struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
	struct usb_hcd *hcd;
	struct resource *res;
	int irq;
	int retval;

	pr_debug("initializing FSL-SOC USB Controller\n");

	/* Need platform data for setup */
	if (!pdata) {
		dev_err(&pdev->dev,
			"No platform data for %s.\n", pdev->dev.bus_id);
		return -ENODEV;
	}

	retval = fsl_platform_verify(pdev);
	if (retval)
		return retval;

	/*
	 * do platform specific init: check the clock, grab/config pins, etc.
	 */
	if (pdata->platform_init && pdata->platform_init(pdev)) {
		retval = -ENODEV;
		goto err1;
	}

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(&pdev->dev,
			"Found HC with no IRQ. Check %s setup!\n",
			pdev->dev.bus_id);
		return -ENODEV;
	}
	irq = res->start;

	fsl_platform_set_vbus_power(pdata, 1);

	hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id);
	if (!hcd) {
		retval = -ENOMEM;
		goto err1;
	}

	hcd->rsrc_start = pdata->r_start;
	hcd->rsrc_len = pdata->r_len;
	hcd->regs = pdata->regs;
	vdbg("rsrc_start=0x%llx rsrc_len=0x%llx virtual=0x%x\n",
	     hcd->rsrc_start, hcd->rsrc_len, hcd->regs);

	hcd->power_budget = pdata->power_budget;

	/* DDD
	 * the following must be done by this point, otherwise the OTG
	 * host port doesn't make it thru initializtion.
	 * ehci_halt(), called by ehci_fsl_setup() returns -ETIMEDOUT
	 */
	fsl_platform_set_host_mode(hcd);

	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (retval != 0) {
		pr_debug("failed with usb_add_hcd\n");
		goto err2;
	}
#if defined(CONFIG_USB_OTG)
	if (pdata->does_otg) {
		struct ehci_hcd *ehci = hcd_to_ehci(hcd);

		dbg("pdev=0x%p  hcd=0x%p  ehci=0x%p\n", pdev, hcd, ehci);

		ehci->transceiver = otg_get_transceiver();
		dbg("ehci->transceiver=0x%p\n", ehci->transceiver);

		if (ehci->transceiver) {
			retval = otg_set_host(ehci->transceiver,
					      &ehci_to_hcd(ehci)->self);
			if (retval) {
				if (ehci->transceiver)
					put_device(ehci->transceiver->dev);
				goto err2;
			}
		} else {
			printk(KERN_ERR "can't find transceiver\n");
			retval = -ENODEV;
			goto err2;
		}
	}
#endif

	return retval;

err2:
	usb_put_hcd(hcd);
err1:
	dev_err(&pdev->dev, "init %s fail, %d\n", pdev->dev.bus_id, retval);
	if (pdata->platform_uninit)
		pdata->platform_uninit(pdata);
	return retval;
}
コード例 #21
0
ファイル: otg.c プロジェクト: 404992361/mi1_kernel
/**
 * usb_put_transceiver - release the (single) USB transceiver
 * @x: the transceiver returned by usb_get_transceiver()
 *
 * Releases a refcount the caller received from usb_get_transceiver().
 *
 * For use by USB host and peripheral drivers.
 */
void usb_put_transceiver(struct usb_phy *x)
{
	if (x)
		put_device(x->dev);
}
コード例 #22
0
static int cc2520_spi_add_to_bus(void)
{
    struct spi_master *spi_master;
    struct spi_device *spi_device;
    struct device *pdev;
    char buff[64];
    int status = 0;

    spi_master = spi_busnum_to_master(SPI_BUS);
    if (!spi_master) {
        ERR((KERN_ALERT "[cc2520] - spi_busnum_to_master(%d) returned NULL\n",
            SPI_BUS));
        ERR((KERN_ALERT "[cc2520] - Missing modprobe spi-bcm2708?\n"));
        return -1;
    }

    spi_device = spi_alloc_device(spi_master);
    if (!spi_device) {
        put_device(&spi_master->dev);
        ERR((KERN_ALERT "[cc2520] - spi_alloc_device() failed\n"));
        return -1;
    }

    spi_device->chip_select = SPI_BUS_CS0;

    /* Check whether this SPI bus.cs is already claimed */
    snprintf(buff, sizeof(buff), "%s.%u",
            dev_name(&spi_device->master->dev),
            spi_device->chip_select);

    pdev = bus_find_device_by_name(spi_device->dev.bus, NULL, buff);

    if (pdev) {
        if (pdev->driver != NULL) {
            ERR((KERN_INFO
                "[cc2520] - Driver [%s] already registered for %s. \
Nuking from orbit.\n",
                pdev->driver->name, buff));
        }
        else {
            ERR((KERN_INFO
                "[cc2520] - Previous driver registered with no loaded module. \
Nuking from orbit.\n"));
        }

        device_unregister(pdev);
    }

    spi_device->max_speed_hz = SPI_BUS_SPEED;
    spi_device->mode = SPI_MODE_0;
    spi_device->bits_per_word = 8;
    spi_device->irq = -1;

    spi_device->controller_state = NULL;
    spi_device->controller_data = NULL;
    strlcpy(spi_device->modalias, cc2520_name, SPI_NAME_SIZE);

    status = spi_add_device(spi_device);
    if (status < 0) {
        spi_dev_put(spi_device);
        ERR((KERN_ALERT "[cc2520] - spi_add_device() failed: %d\n",
            status));
    }

    put_device(&spi_master->dev);
    return status;
}
コード例 #23
0
void macio_dev_put(struct macio_dev *dev)
{
	if (dev)
		put_device(&dev->ofdev.dev);
}
コード例 #24
0
void of_dev_put(struct of_device *dev)
{
	if (dev)
		put_device(&dev->dev);
}
コード例 #25
0
ファイル: tiocx.c プロジェクト: erik96/Samsung-Galaxy-S-Plus
/**
 * cx_device_unregister - Unregister a device.
 * @cx_dev: part/mfg id for the device
 */
int cx_device_unregister(struct cx_dev *cx_dev)
{
	put_device(&cx_dev->dev);
	device_unregister(&cx_dev->dev);
	return 0;
}
コード例 #26
0
ファイル: a6xx_gmu.c プロジェクト: grate-driver/linux
int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
{
	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
	struct platform_device *pdev = of_find_device_by_node(node);
	int ret;

	if (!pdev)
		return -ENODEV;

	gmu->dev = &pdev->dev;

	of_dma_configure(gmu->dev, node, true);

	/* Fow now, don't do anything fancy until we get our feet under us */
	gmu->idle_level = GMU_IDLE_STATE_ACTIVE;

	pm_runtime_enable(gmu->dev);

	/* Get the list of clocks */
	ret = a6xx_gmu_clocks_probe(gmu);
	if (ret)
		goto err_put_device;

	/* Set up the IOMMU context bank */
	ret = a6xx_gmu_memory_probe(gmu);
	if (ret)
		goto err_put_device;

	/* Allocate memory for for the HFI queues */
	gmu->hfi = a6xx_gmu_memory_alloc(gmu, SZ_16K);
	if (IS_ERR(gmu->hfi))
		goto err_memory;

	/* Allocate memory for the GMU debug region */
	gmu->debug = a6xx_gmu_memory_alloc(gmu, SZ_16K);
	if (IS_ERR(gmu->debug))
		goto err_memory;

	/* Map the GMU registers */
	gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu");
	if (IS_ERR(gmu->mmio))
		goto err_memory;

	/* Get the HFI and GMU interrupts */
	gmu->hfi_irq = a6xx_gmu_get_irq(gmu, pdev, "hfi", a6xx_hfi_irq);
	gmu->gmu_irq = a6xx_gmu_get_irq(gmu, pdev, "gmu", a6xx_gmu_irq);

	if (gmu->hfi_irq < 0 || gmu->gmu_irq < 0)
		goto err_mmio;

	/*
	 * Get a link to the GX power domain to reset the GPU in case of GMU
	 * crash
	 */
	gmu->gxpd = dev_pm_domain_attach_by_name(gmu->dev, "gx");

	/* Get the power levels for the GMU and GPU */
	a6xx_gmu_pwrlevels_probe(gmu);

	/* Set up the HFI queues */
	a6xx_hfi_init(gmu);

	gmu->initialized = true;

	return 0;

err_mmio:
	iounmap(gmu->mmio);
	free_irq(gmu->gmu_irq, gmu);
	free_irq(gmu->hfi_irq, gmu);
err_memory:
	a6xx_gmu_memory_free(gmu, gmu->hfi);

	if (gmu->domain) {
		iommu_detach_device(gmu->domain, gmu->dev);

		iommu_domain_free(gmu->domain);
	}
	ret = -ENODEV;

err_put_device:
	/* Drop reference taken in of_find_device_by_node */
	put_device(gmu->dev);

	return ret;
}
コード例 #27
0
/**
 * usb_put_intf - release a use of the usb interface structure
 * @intf: interface that's been decremented
 *
 * Must be called when a user of an interface is finished with it.  When the
 * last user of the interface calls this function, the memory of the interface
 * is freed.
 */
void usb_put_intf(struct usb_interface *intf)
{
	if (intf)
		put_device(&intf->dev);
}
コード例 #28
0
ファイル: qeth_proc.c プロジェクト: FatSunHYS/OSCourseDesign
static int
qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
{
	struct device *device;
	struct qeth_card *card;


	if (it == SEQ_START_TOKEN)
		return 0;

	device = (struct device *) it;
	card = device->driver_data;
	seq_printf(s, "For card with devnos %s/%s/%s (%s):\n",
			CARD_RDEV_ID(card),
			CARD_WDEV_ID(card),
			CARD_DDEV_ID(card),
			QETH_CARD_IFNAME(card)
		  );
	if (!card->options.performance_stats)
		seq_printf(s, "Performance statistics are deactivated.\n");
	seq_printf(s, "  Skb's/buffers received                 : %lu/%u\n"
		      "  Skb's/buffers sent                     : %lu/%u\n\n",
		        card->stats.rx_packets -
				card->perf_stats.initial_rx_packets,
			card->perf_stats.bufs_rec,
		        card->stats.tx_packets -
				card->perf_stats.initial_tx_packets,
			card->perf_stats.bufs_sent
		  );
	seq_printf(s, "  Skb's/buffers sent without packing     : %lu/%u\n"
		      "  Skb's/buffers sent with packing        : %u/%u\n\n",
		   card->stats.tx_packets - card->perf_stats.initial_tx_packets
					  - card->perf_stats.skbs_sent_pack,
		   card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack,
		   card->perf_stats.skbs_sent_pack,
		   card->perf_stats.bufs_sent_pack
		  );
	seq_printf(s, "  Skbs sent in SG mode                   : %u\n"
		      "  Skb fragments sent in SG mode          : %u\n\n",
		      card->perf_stats.sg_skbs_sent,
		      card->perf_stats.sg_frags_sent);
	seq_printf(s, "  large_send tx (in Kbytes)              : %u\n"
		      "  large_send count                       : %u\n\n",
		      card->perf_stats.large_send_bytes >> 10,
		      card->perf_stats.large_send_cnt);
	seq_printf(s, "  Packing state changes no pkg.->packing : %u/%u\n"
		      "  Watermarks L/H                         : %i/%i\n"
		      "  Current buffer usage (outbound q's)    : "
		      "%i/%i/%i/%i\n\n",
		        card->perf_stats.sc_dp_p, card->perf_stats.sc_p_dp,
			QETH_LOW_WATERMARK_PACK, QETH_HIGH_WATERMARK_PACK,
			atomic_read(&card->qdio.out_qs[0]->used_buffers),
			(card->qdio.no_out_queues > 1)?
				atomic_read(&card->qdio.out_qs[1]->used_buffers)
				: 0,
			(card->qdio.no_out_queues > 2)?
				atomic_read(&card->qdio.out_qs[2]->used_buffers)
				: 0,
			(card->qdio.no_out_queues > 3)?
				atomic_read(&card->qdio.out_qs[3]->used_buffers)
				: 0
		  );
	seq_printf(s, "  Inbound handler time (in us)           : %u\n"
		      "  Inbound handler count                  : %u\n"
		      "  Inbound do_QDIO time (in us)           : %u\n"
		      "  Inbound do_QDIO count                  : %u\n\n"
		      "  Outbound handler time (in us)          : %u\n"
		      "  Outbound handler count                 : %u\n\n"
		      "  Outbound time (in us, incl QDIO)       : %u\n"
		      "  Outbound count                         : %u\n"
		      "  Outbound do_QDIO time (in us)          : %u\n"
		      "  Outbound do_QDIO count                 : %u\n\n",
		        card->perf_stats.inbound_time,
			card->perf_stats.inbound_cnt,
		        card->perf_stats.inbound_do_qdio_time,
			card->perf_stats.inbound_do_qdio_cnt,
			card->perf_stats.outbound_handler_time,
			card->perf_stats.outbound_handler_cnt,
			card->perf_stats.outbound_time,
			card->perf_stats.outbound_cnt,
		        card->perf_stats.outbound_do_qdio_time,
			card->perf_stats.outbound_do_qdio_cnt
		  );
	put_device(device);
	return 0;
}
コード例 #29
0
ファイル: usb.c プロジェクト: arshull/GalaTab3_KK_Kernel_T310
/**
 * usb_put_dev - release a use of the usb device structure
 * @dev: device that's been disconnected
 *
 * Must be called when a user of a device is finished with it.  When the last
 * user of the device calls this function, the memory of the device is freed.
 */
void usb_put_dev(struct usb_device *dev)
{
	if (dev)
		put_device(&dev->dev);
}
コード例 #30
0
void pcmcia_put_dev(struct pcmcia_device *p_dev)
{
	if (p_dev)
		put_device(&p_dev->dev);
}