Пример #1
0
static int cm36686_i2c_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct cm36686_data *cm36686 = NULL;

	pr_info("%s is called.\n", __func__);
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s: i2c functionality check failed!\n", __func__);
		return ret;
	}

	cm36686 = kzalloc(sizeof(struct cm36686_data), GFP_KERNEL);
	if (!cm36686) {
		pr_err("%s: failed to alloc memory for cm36686 module data\n",
			__func__);
		return -ENOMEM;
	}

	cm36686->pdata = client->dev.platform_data;
	cm36686->i2c_client = client;
	i2c_set_clientdata(client, cm36686);
	mutex_init(&cm36686->power_lock);
	mutex_init(&cm36686->read_lock);

	if(cm36686->pdata->cm36686_light_power != NULL) {
		cm36686->cm36686_light_vddpower = cm36686->pdata->cm36686_light_power;
		if (cm36686->cm36686_light_vddpower)
			cm36686->cm36686_light_vddpower(true);
	}

	if(cm36686->pdata->cm36686_proxi_power != NULL) {
		cm36686->cm36686_proxi_vddpower = cm36686->pdata->cm36686_proxi_power;
		if (cm36686->cm36686_proxi_vddpower)
			cm36686->cm36686_proxi_vddpower(true);
	}

	/* wake lock init for proximity sensor */
	wake_lock_init(&cm36686->prx_wake_lock, WAKE_LOCK_SUSPEND,
			"prx_wake_lock");
	if (cm36686->pdata->cm36686_led_on) {
		cm36686->pdata->cm36686_led_on(true);
		msleep(20);
	}
	/* Check if the device is there or not. */
	ret = cm36686_i2c_write_word(cm36686, REG_CS_CONF1, 0x0001);
	if (ret < 0) {
		pr_err("%s: cm36686 is not connected.(%d)\n", __func__, ret);
		goto err_setup_reg;
	}

	/* setup initial registers */
	ret = cm36686_setup_reg(cm36686);
	if (ret < 0) {
		pr_err("%s: could not setup regs\n", __func__);
		goto err_setup_reg;
	}

	if (cm36686->pdata->cm36686_led_on)
		cm36686->pdata->cm36686_led_on(false);

	if (cm36686->cm36686_light_vddpower)
		cm36686->cm36686_light_vddpower(false);

	if (cm36686->cm36686_proxi_vddpower)
		cm36686->cm36686_proxi_vddpower(false);

	/* allocate proximity input_device */
	cm36686->proximity_input_dev = input_allocate_device();
	if (!cm36686->proximity_input_dev) {
		pr_err("%s: could not allocate proximity input device\n",
			__func__);
		goto err_input_allocate_device_proximity;
	}

	input_set_drvdata(cm36686->proximity_input_dev, cm36686);
	cm36686->proximity_input_dev->name = "proximity_sensor";
	input_set_capability(cm36686->proximity_input_dev, EV_ABS,
			ABS_DISTANCE);
	input_set_abs_params(cm36686->proximity_input_dev, ABS_DISTANCE, 0, 1,
			0, 0);

	ret = input_register_device(cm36686->proximity_input_dev);
	if (ret < 0) {
		input_free_device(cm36686->proximity_input_dev);
		pr_err("%s: could not register input device\n", __func__);
		goto err_input_register_device_proximity;
	}

	ret = sysfs_create_group(&cm36686->proximity_input_dev->dev.kobj,
				 &proximity_attribute_group);
	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_proximity;
	}
#if defined(CONFIG_SENSOR_USE_SYMLINK)
	ret =  sensors_initialize_symlink(cm36686->proximity_input_dev);
	if (ret < 0) {
		pr_err("%s - proximity_sensors_initialize_symlink error(%d).\n",
                        __func__, ret);
		goto err_setup_irq;
	}
#endif
	/* setup irq */
	ret = cm36686_setup_irq(cm36686);
	if (ret) {
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}

	/* For factory test mode, we use timer to get average proximity data. */
	/* prox_timer settings. we poll for light values using a timer. */
	hrtimer_init(&cm36686->prox_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	cm36686->prox_poll_delay = ns_to_ktime(2000 * NSEC_PER_MSEC);/*2 sec*/
	cm36686->prox_timer.function = cm36686_prox_timer_func;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	cm36686->prox_wq = create_singlethread_workqueue("cm36686_prox_wq");
	if (!cm36686->prox_wq) {
		ret = -ENOMEM;
		pr_err("%s: could not create prox workqueue\n", __func__);
		goto err_create_prox_workqueue;
	}
	/* this is the thread function we run on the work queue */
	INIT_WORK(&cm36686->work_prox, cm36686_work_func_prox);

	/* allocate lightsensor input_device */
	cm36686->light_input_dev = input_allocate_device();
	if (!cm36686->light_input_dev) {
		pr_err("%s: could not allocate light input device\n", __func__);
		goto err_input_allocate_device_light;
	}

	input_set_drvdata(cm36686->light_input_dev, cm36686);
	cm36686->light_input_dev->name = "light_sensor";
	input_set_capability(cm36686->light_input_dev, EV_REL, REL_MISC);
	input_set_capability(cm36686->light_input_dev, EV_REL, REL_DIAL);
	input_set_capability(cm36686->light_input_dev, EV_REL, REL_WHEEL);

	ret = input_register_device(cm36686->light_input_dev);
	if (ret < 0) {
		input_free_device(cm36686->light_input_dev);
		pr_err("%s: could not register input device\n", __func__);
		goto err_input_register_device_light;
	}

	ret = sysfs_create_group(&cm36686->light_input_dev->dev.kobj,
				 &light_attribute_group);
	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_light;
	}
#if defined(CONFIG_SENSOR_USE_SYMLINK)
	ret =  sensors_initialize_symlink(cm36686->light_input_dev);
	if (ret < 0) {
		pr_err("%s - light_sensors_initialize_symlink error(%d).\n",
                        __func__, ret);
		goto err_create_light_workqueue;
	}
#endif
	/* light_timer settings. we poll for light values using a timer. */
	hrtimer_init(&cm36686->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	cm36686->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
	cm36686->light_timer.function = cm36686_light_timer_func;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	cm36686->light_wq = create_singlethread_workqueue("cm36686_light_wq");
	if (!cm36686->light_wq) {
		ret = -ENOMEM;
		pr_err("%s: could not create light workqueue\n", __func__);
		goto err_create_light_workqueue;
	}

	/* this is the thread function we run on the work queue */
	INIT_WORK(&cm36686->work_light, cm36686_work_func_light);

	/* set sysfs for proximity sensor */
	cm36686->proximity_dev = sensors_classdev_register("proximity_sensor");
	if (IS_ERR(cm36686->proximity_dev)) {
		pr_err("%s: could not create proximity_dev\n", __func__);
		goto err_proximity_device_create;
	}

	if (device_create_file(cm36686->proximity_dev, &dev_attr_state) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_state.attr.name);
		goto err_proximity_device_create_file1;
	}

	if (device_create_file(cm36686->proximity_dev, &attr_prox_raw) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			attr_prox_raw.attr.name);
		goto err_proximity_device_create_file2;
	}

#ifdef CM36686_CANCELATION
	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_prox_cal) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_prox_cal.attr.name);
		goto err_proximity_device_create_file3;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_prox_offset_pass) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_prox_offset_pass.attr.name);
		goto err_proximity_device_create_file4;
	}
#endif
	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_prox_avg) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_prox_avg.attr.name);
		goto err_proximity_device_create_file5;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_thresh_high) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_thresh_high.attr.name);
		goto err_proximity_device_create_file6;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_vendor) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_vendor.attr.name);
		goto err_proximity_device_create_file7;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_name) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_name.attr.name);
		goto err_proximity_device_create_file8;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_thresh_low) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_thresh_low.attr.name);
		goto err_proximity_device_create_file9;
	}

	dev_set_drvdata(cm36686->proximity_dev, cm36686);

	/* set sysfs for light sensor */
	cm36686->light_dev = sensors_classdev_register("light_sensor");
	if (IS_ERR(cm36686->light_dev)) {
		pr_err("%s: could not create light_dev\n", __func__);
		goto err_light_device_create;
	}

	if (device_create_file(cm36686->light_dev, &dev_attr_lux) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_lux.attr.name);
		goto err_light_device_create_file1;
	}

	if (device_create_file(cm36686->light_dev, &dev_attr_raw_data) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_raw_data.attr.name);
		goto err_light_device_create_file2;
	}

	if (device_create_file(cm36686->light_dev, &dev_attr_vendor) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_vendor.attr.name);
		goto err_light_device_create_file3;
	}

	if (device_create_file(cm36686->light_dev, &dev_attr_name) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_name.attr.name);
		goto err_light_device_create_file4;
	}

	dev_set_drvdata(cm36686->light_dev, cm36686);

	pr_info("%s is success.\n", __func__);
	goto done;

/* error, unwind it all */
err_light_device_create_file4:
	device_remove_file(cm36686->light_dev, &dev_attr_vendor);
err_light_device_create_file3:
	device_remove_file(cm36686->light_dev, &dev_attr_raw_data);
err_light_device_create_file2:
	device_remove_file(cm36686->light_dev, &dev_attr_lux);
err_light_device_create_file1:
	sensors_classdev_unregister(cm36686->light_dev);
err_light_device_create:
	device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_low);
err_proximity_device_create_file9:
	device_remove_file(cm36686->proximity_dev, &dev_attr_name);
err_proximity_device_create_file8:
	device_remove_file(cm36686->proximity_dev, &dev_attr_vendor);
err_proximity_device_create_file7:
	device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_high);
err_proximity_device_create_file6:
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_avg);
err_proximity_device_create_file5:
#ifdef CM36686_CANCELATION
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_offset_pass);
err_proximity_device_create_file4:
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_cal);
err_proximity_device_create_file3:
#endif
	device_remove_file(cm36686->proximity_dev, &attr_prox_raw);
err_proximity_device_create_file2:
	device_remove_file(cm36686->proximity_dev, &dev_attr_state);
err_proximity_device_create_file1:
	sensors_classdev_unregister(cm36686->proximity_dev);
err_proximity_device_create:
	destroy_workqueue(cm36686->light_wq);
err_create_light_workqueue:
	sysfs_remove_group(&cm36686->light_input_dev->dev.kobj,
			   &light_attribute_group);
err_sysfs_create_group_light:
	input_unregister_device(cm36686->light_input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	destroy_workqueue(cm36686->prox_wq);
err_create_prox_workqueue:
	free_irq(cm36686->irq, cm36686);
	gpio_free(cm36686->pdata->irq);
err_setup_irq:
	sysfs_remove_group(&cm36686->proximity_input_dev->dev.kobj,
			   &proximity_attribute_group);
err_sysfs_create_group_proximity:
	input_unregister_device(cm36686->proximity_input_dev);
err_input_register_device_proximity:
err_input_allocate_device_proximity:
err_setup_reg:
	if (cm36686->pdata->cm36686_led_on)
		cm36686->pdata->cm36686_led_on(false);

	if (cm36686->cm36686_light_vddpower)
		cm36686->cm36686_light_vddpower(false);

	if (cm36686->cm36686_proxi_vddpower)
		cm36686->cm36686_proxi_vddpower(false);

	wake_lock_destroy(&cm36686->prx_wake_lock);
	mutex_destroy(&cm36686->read_lock);
	mutex_destroy(&cm36686->power_lock);
	kfree(cm36686);
done:
	return ret;
}
Пример #2
0
static int __init
init_cifs(void)
{
	int rc = 0;
	cifs_proc_init();
	INIT_LIST_HEAD(&cifs_tcp_ses_list);
#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
	INIT_LIST_HEAD(&GlobalDnotifyReqList);
	INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
/*
 *  Initialize Global counters
 */
	atomic_set(&sesInfoAllocCount, 0);
	atomic_set(&tconInfoAllocCount, 0);
	atomic_set(&tcpSesAllocCount, 0);
	atomic_set(&tcpSesReconnectCount, 0);
	atomic_set(&tconInfoReconnectCount, 0);

	atomic_set(&bufAllocCount, 0);
	atomic_set(&smBufAllocCount, 0);
#ifdef CONFIG_CIFS_STATS2
	atomic_set(&totBufAllocCount, 0);
	atomic_set(&totSmBufAllocCount, 0);
#endif /* CONFIG_CIFS_STATS2 */

	atomic_set(&midCount, 0);
	GlobalCurrentXid = 0;
	GlobalTotalActiveXid = 0;
	GlobalMaxActiveXid = 0;
	spin_lock_init(&cifs_tcp_ses_lock);
	spin_lock_init(&cifs_file_list_lock);
	spin_lock_init(&GlobalMid_Lock);

#ifdef CONFIG_CIFS_SMB2
	get_random_bytes(cifs_client_guid, SMB2_CLIENT_GUID_SIZE);
#endif

	if (cifs_max_pending < 2) {
		cifs_max_pending = 2;
		cFYI(1, "cifs_max_pending set to min of 2");
	} else if (cifs_max_pending > CIFS_MAX_REQ) {
		cifs_max_pending = CIFS_MAX_REQ;
		cFYI(1, "cifs_max_pending set to max of %u", CIFS_MAX_REQ);
	}

	cifsiod_wq = alloc_workqueue("cifsiod", WQ_FREEZABLE|WQ_MEM_RECLAIM, 0);
	if (!cifsiod_wq) {
		rc = -ENOMEM;
		goto out_clean_proc;
	}

	rc = cifs_fscache_register();
	if (rc)
		goto out_destroy_wq;

	rc = cifs_init_inodecache();
	if (rc)
		goto out_unreg_fscache;

	rc = cifs_init_mids();
	if (rc)
		goto out_destroy_inodecache;

	rc = cifs_init_request_bufs();
	if (rc)
		goto out_destroy_mids;

#ifdef CONFIG_CIFS_UPCALL
	rc = register_key_type(&cifs_spnego_key_type);
	if (rc)
		goto out_destroy_request_bufs;
#endif /* CONFIG_CIFS_UPCALL */

#ifdef CONFIG_CIFS_ACL
	rc = init_cifs_idmap();
	if (rc)
		goto out_register_key_type;
#endif /* CONFIG_CIFS_ACL */

	rc = register_filesystem(&cifs_fs_type);
	if (rc)
		goto out_init_cifs_idmap;

	return 0;

out_init_cifs_idmap:
#ifdef CONFIG_CIFS_ACL
	exit_cifs_idmap();
out_register_key_type:
#endif
#ifdef CONFIG_CIFS_UPCALL
	unregister_key_type(&cifs_spnego_key_type);
out_destroy_request_bufs:
#endif
	cifs_destroy_request_bufs();
out_destroy_mids:
	cifs_destroy_mids();
out_destroy_inodecache:
	cifs_destroy_inodecache();
out_unreg_fscache:
	cifs_fscache_unregister();
out_destroy_wq:
	destroy_workqueue(cifsiod_wq);
out_clean_proc:
	cifs_proc_clean();
	return rc;
}
Пример #3
0
static int __devinit ezx_pcap_probe(struct spi_device *spi)
{
	struct pcap_platform_data *pdata = spi->dev.platform_data;
	struct pcap_chip *pcap;
	int i, adc_irq;
	int ret = -ENODEV;

	/* platform data is required */
	if (!pdata)
		goto ret;

	pcap = kzalloc(sizeof(*pcap), GFP_KERNEL);
	if (!pcap) {
		ret = -ENOMEM;
		goto ret;
	}

	mutex_init(&pcap->io_mutex);
	mutex_init(&pcap->adc_mutex);
	INIT_WORK(&pcap->isr_work, pcap_isr_work);
	INIT_WORK(&pcap->msr_work, pcap_msr_work);
	dev_set_drvdata(&spi->dev, pcap);

	/* setup spi */
	spi->bits_per_word = 32;
	spi->mode = SPI_MODE_0 | (pdata->config & PCAP_CS_AH ? SPI_CS_HIGH : 0);
	ret = spi_setup(spi);
	if (ret)
		goto free_pcap;

	pcap->spi = spi;

	/* setup irq */
	pcap->irq_base = pdata->irq_base;
	pcap->workqueue = create_singlethread_workqueue("pcapd");
	if (!pcap->workqueue) {
		ret = -ENOMEM;
		dev_err(&spi->dev, "can't create pcap thread\n");
		goto free_pcap;
	}

	/* redirect interrupts to AP, except adcdone2 */
	if (!(pdata->config & PCAP_SECOND_PORT))
		ezx_pcap_write(pcap, PCAP_REG_INT_SEL,
					(1 << PCAP_IRQ_ADCDONE2));

	/* setup irq chip */
	for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) {
		irq_set_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq);
		irq_set_chip_data(i, pcap);
#ifdef CONFIG_ARM
		set_irq_flags(i, IRQF_VALID);
#else
		irq_set_noprobe(i);
#endif
	}

	/* mask/ack all PCAP interrupts */
	ezx_pcap_write(pcap, PCAP_REG_MSR, PCAP_MASK_ALL_INTERRUPT);
	ezx_pcap_write(pcap, PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER);
	pcap->msr = PCAP_MASK_ALL_INTERRUPT;

	irq_set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING);
	irq_set_handler_data(spi->irq, pcap);
	irq_set_chained_handler(spi->irq, pcap_irq_handler);
	irq_set_irq_wake(spi->irq, 1);

	/* ADC */
	adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ?
					PCAP_IRQ_ADCDONE2 : PCAP_IRQ_ADCDONE);

	ret = request_irq(adc_irq, pcap_adc_irq, 0, "ADC", pcap);
	if (ret)
		goto free_irqchip;

	/* setup subdevs */
	for (i = 0; i < pdata->num_subdevs; i++) {
		ret = pcap_add_subdev(pcap, &pdata->subdevs[i]);
		if (ret)
			goto remove_subdevs;
	}

	/* board specific quirks */
	if (pdata->init)
		pdata->init(pcap);

	return 0;

remove_subdevs:
	device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
/* free_adc: */
	free_irq(adc_irq, pcap);
free_irqchip:
	for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
		irq_set_chip_and_handler(i, NULL, NULL);
/* destroy_workqueue: */
	destroy_workqueue(pcap->workqueue);
free_pcap:
	kfree(pcap);
ret:
	return ret;
}
Пример #4
0
/**
 * gserial_setup - initialize TTY driver for one or more ports
 * @g: gadget to associate with these ports
 * @count: how many ports to support
 * Context: may sleep
 *
 * The TTY stack needs to know in advance how many devices it should
 * plan to manage.  Use this call to set up the ports you will be
 * exporting through USB.  Later, connect them to functions based
 * on what configuration is activated by the USB host; and disconnect
 * them as appropriate.
 *
 * An example would be a two-configuration device in which both
 * configurations expose port 0, but through different functions.
 * One configuration could even expose port 1 while the other
 * one doesn't.
 *
 * Returns negative errno or zero.
 */
int gserial_setup(struct usb_gadget *g, unsigned count)
{
	unsigned			i;
	struct usb_cdc_line_coding	coding;
	int				status;

	if (count == 0 || count > N_PORTS)
		return -EINVAL;

	gs_tty_driver = alloc_tty_driver(count);
	if (!gs_tty_driver)
		return -ENOMEM;

	gs_tty_driver->owner = THIS_MODULE;
	gs_tty_driver->driver_name = "g_serial";
	gs_tty_driver->name = PREFIX;
	/* uses dynamically assigned dev_t values */

	gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
	gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
	gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV
				| TTY_DRIVER_RESET_TERMIOS;
	gs_tty_driver->init_termios = tty_std_termios;

	/* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on
	 * MS-Windows.  Otherwise, most of these flags shouldn't affect
	 * anything unless we were to actually hook up to a serial line.
	 */
	gs_tty_driver->init_termios.c_cflag =
			B9600 | CS8 | CREAD | HUPCL | CLOCAL;
	gs_tty_driver->init_termios.c_ispeed = 9600;
	gs_tty_driver->init_termios.c_ospeed = 9600;

	coding.dwDTERate = __constant_cpu_to_le32(480000000);
	coding.bCharFormat = USB_CDC_1_STOP_BITS;
	coding.bParityType = USB_CDC_NO_PARITY;
	coding.bDataBits = 8;

	tty_set_operations(gs_tty_driver, &gs_tty_ops);

	gserial_wq = create_singlethread_workqueue("k_gserial");
	if (!gserial_wq) {
		status = -ENOMEM;
		goto fail;
	}

	/* make devices be openable */
	for (i = 0; i < count; i++) {
		mutex_init(&ports[i].lock);
		status = gs_port_alloc(i, &coding);
		if (status) {
			count = i;
			goto fail;
		}
	}
	n_ports = count;

	/* export the driver ... */
	status = tty_register_driver(gs_tty_driver);
	if (status) {
		put_tty_driver(gs_tty_driver);
		pr_err("%s: cannot register, err %d\n",
				__func__, status);
		goto fail;
	}

	/* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */
	for (i = 0; i < count; i++) {
		struct device	*tty_dev;

		tty_dev = tty_register_device(gs_tty_driver, i, &g->dev);
		if (IS_ERR(tty_dev))
			pr_warning("%s: no classdev for port %d, err %ld\n",
				__func__, i, PTR_ERR(tty_dev));
	}

	pr_debug("%s: registered %d ttyGS* device%s\n", __func__,
			count, (count == 1) ? "" : "s");

	return status;
fail:
	while (count--)
		kfree(ports[count].port);
	destroy_workqueue(gserial_wq);
	put_tty_driver(gs_tty_driver);
	gs_tty_driver = NULL;
	return status;
}
Пример #5
0
void rds_threads_exit(void)
{
	destroy_workqueue(rds_wq);
}
Пример #6
0
static int hva_probe(struct platform_device *pdev)
{
	struct hva_dev *hva;
	struct device *dev = &pdev->dev;
	int ret;

	hva = devm_kzalloc(dev, sizeof(*hva), GFP_KERNEL);
	if (!hva) {
		ret = -ENOMEM;
		goto err;
	}

	hva->dev = dev;
	hva->pdev = pdev;
	platform_set_drvdata(pdev, hva);

	mutex_init(&hva->lock);

	/* probe hardware */
	ret = hva_hw_probe(pdev, hva);
	if (ret)
		goto err;

	/* register all available encoders */
	register_encoders(hva);

	/* register all supported formats */
	register_formats(hva);

	/* register on V4L2 */
	ret = v4l2_device_register(dev, &hva->v4l2_dev);
	if (ret) {
		dev_err(dev, "%s %s failed to register V4L2 device\n",
			HVA_PREFIX, HVA_NAME);
		goto err_hw;
	}

	hva->work_queue = create_workqueue(HVA_NAME);
	if (!hva->work_queue) {
		dev_err(dev, "%s %s failed to allocate work queue\n",
			HVA_PREFIX, HVA_NAME);
		ret = -ENOMEM;
		goto err_v4l2;
	}

	/* register device */
	ret = hva_register_device(hva);
	if (ret)
		goto err_work_queue;

	dev_info(dev, "%s %s registered as /dev/video%d\n", HVA_PREFIX,
		 HVA_NAME, hva->vdev->num);

	return 0;

err_work_queue:
	destroy_workqueue(hva->work_queue);
err_v4l2:
	v4l2_device_unregister(&hva->v4l2_dev);
err_hw:
	hva_hw_remove(hva);
err:
	return ret;
}
void diagfwd_bridge_init(void)
{
	int ret;

	pr_debug("diag: in %s\n", __func__);
	driver->diag_bridge_wq = create_singlethread_workqueue(
							"diag_bridge_wq");
	driver->read_len_mdm = 0;
	driver->write_len_mdm = 0;
	driver->num_hsic_buf_tbl_entries = 0;
	if (driver->usb_buf_mdm_out  == NULL)
		driver->usb_buf_mdm_out = kzalloc(USB_MAX_OUT_BUF,
							 GFP_KERNEL);
	if (driver->usb_buf_mdm_out == NULL)
		goto err;
	/* Only used by smux move to smux probe function */
	if (driver->write_ptr_mdm == NULL)
		driver->write_ptr_mdm = kzalloc(
		sizeof(struct diag_request), GFP_KERNEL);
	if (driver->write_ptr_mdm == NULL)
		goto err;
	if (driver->usb_read_mdm_ptr == NULL)
		driver->usb_read_mdm_ptr = kzalloc(
		sizeof(struct diag_request), GFP_KERNEL);
	if (driver->usb_read_mdm_ptr == NULL)
		goto err;

	if (driver->hsic_buf_tbl == NULL)
		driver->hsic_buf_tbl = kzalloc(NUM_HSIC_BUF_TBL_ENTRIES *
				sizeof(struct diag_write_device), GFP_KERNEL);
	if (driver->hsic_buf_tbl == NULL)
		goto err;

	driver->count_hsic_pool = 0;
	driver->count_hsic_write_pool = 0;

	driver->itemsize_hsic = READ_HSIC_BUF_SIZE;
	driver->poolsize_hsic = N_MDM_WRITE;
	driver->itemsize_hsic_write = sizeof(struct diag_request);
	driver->poolsize_hsic_write = N_MDM_WRITE;

#ifdef CONFIG_DIAG_OVER_USB
	INIT_WORK(&(driver->diag_read_mdm_work), diag_read_mdm_work_fn);
#endif
	INIT_WORK(&(driver->diag_disconnect_work), diag_disconnect_work_fn);
	INIT_WORK(&(driver->diag_usb_read_complete_work),
			diag_usb_read_complete_fn);
#ifdef CONFIG_DIAG_OVER_USB
	driver->mdm_ch = usb_diag_open(DIAG_MDM, driver,
						 diagfwd_bridge_notifier);
	if (IS_ERR(driver->mdm_ch)) {
		pr_err("diag: Unable to open USB diag MDM channel\n");
		goto err;
	}
#endif
	/* register HSIC device */
	ret = platform_driver_register(&msm_hsic_ch_driver);
	if (ret)
		pr_err("diag: could not register HSIC device, ret: %d\n", ret);
	/* register SMUX device */
	ret = platform_driver_register(&msm_diagfwd_smux_driver);
	if (ret)
		pr_err("diag: could not register SMUX device, ret: %d\n", ret);

	return;
err:
	pr_err("diag: Could not initialize for bridge forwarding\n");
	kfree(driver->usb_buf_mdm_out);
	kfree(driver->hsic_buf_tbl);
	kfree(driver->write_ptr_mdm);
	kfree(driver->usb_read_mdm_ptr);
	if (driver->diag_bridge_wq)
		destroy_workqueue(driver->diag_bridge_wq);

	return;
}
Пример #8
0
void __exit xen_pcibk_xenbus_unregister(void)
{
	destroy_workqueue(xen_pcibk_wq);
	xenbus_unregister_driver(&xen_pcibk_driver);
}
Пример #9
0
static void __exit aps_12d_exit(void)
{
	i2c_del_driver(&aps_driver);
	if (aps_wq)
		destroy_workqueue(aps_wq);
}
Пример #10
0
int ieee802154_register_hw(struct ieee802154_hw *hw)
{
	struct ieee802154_local *local = hw_to_local(hw);
	struct net_device *dev;
	int rc = -ENOSYS;

	local->workqueue =
		create_singlethread_workqueue(wpan_phy_name(local->phy));
	if (!local->workqueue) {
		rc = -ENOMEM;
		goto out;
	}

	hrtimer_init(&local->ifs_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	local->ifs_timer.function = ieee802154_xmit_ifs_timer;

	wpan_phy_set_dev(local->phy, local->hw.parent);

	ieee802154_setup_wpan_phy_pib(local->phy);

	if (!(hw->flags & IEEE802154_HW_CSMA_PARAMS)) {
		local->phy->supported.min_csma_backoffs = 4;
		local->phy->supported.max_csma_backoffs = 4;
		local->phy->supported.min_maxbe = 5;
		local->phy->supported.max_maxbe = 5;
		local->phy->supported.min_minbe = 3;
		local->phy->supported.max_minbe = 3;
	}

	if (!(hw->flags & IEEE802154_HW_FRAME_RETRIES)) {
		local->phy->supported.min_frame_retries = 3;
		local->phy->supported.max_frame_retries = 3;
	}

	if (hw->flags & IEEE802154_HW_PROMISCUOUS)
		local->phy->supported.iftypes |= BIT(NL802154_IFTYPE_MONITOR);

	rc = wpan_phy_register(local->phy);
	if (rc < 0)
		goto out_wq;

	rtnl_lock();

	dev = ieee802154_if_add(local, "wpan%d", NET_NAME_ENUM,
				NL802154_IFTYPE_NODE,
				cpu_to_le64(0x0000000000000000ULL));
	if (IS_ERR(dev)) {
		rtnl_unlock();
		rc = PTR_ERR(dev);
		goto out_phy;
	}

	rtnl_unlock();

	return 0;

out_phy:
	wpan_phy_unregister(local->phy);
out_wq:
	destroy_workqueue(local->workqueue);
out:
	return rc;
}
Пример #11
0
static struct isert_device *isert_device_create(struct ib_device *ib_dev)
{
	struct isert_device *isert_dev;
	struct ib_device_attr *dev_attr;
	int cqe_num, err;
	struct ib_pd *pd;
	struct ib_mr *mr;
	struct ib_cq *cq;
	char wq_name[64];
	int i, j;

	TRACE_ENTRY();

	isert_dev = kzalloc(sizeof(*isert_dev), GFP_KERNEL);
	if (unlikely(isert_dev == NULL)) {
		pr_err("Failed to allocate iser dev\n");
		err = -ENOMEM;
		goto out;
	}

	dev_attr = &isert_dev->device_attr;
	err = ib_query_device(ib_dev, dev_attr);
	if (unlikely(err)) {
		pr_err("Failed to query device, err: %d\n", err);
		goto fail_query;
	}

	isert_dev->num_cqs = min_t(int, num_online_cpus(),
				   ib_dev->num_comp_vectors);

	isert_dev->cq_qps = kzalloc(sizeof(*isert_dev->cq_qps) * isert_dev->num_cqs,
				    GFP_KERNEL);
	if (unlikely(isert_dev->cq_qps == NULL)) {
		pr_err("Failed to allocate iser cq_qps\n");
		err = -ENOMEM;
		goto fail_cq_qps;
	}

	isert_dev->cq_desc = vmalloc(sizeof(*isert_dev->cq_desc) * isert_dev->num_cqs);
	if (unlikely(isert_dev->cq_desc == NULL)) {
		pr_err("Failed to allocate %ld bytes for iser cq_desc\n",
		       sizeof(*isert_dev->cq_desc) * isert_dev->num_cqs);
		err = -ENOMEM;
		goto fail_alloc_cq_desc;
	}

	pd = ib_alloc_pd(ib_dev);
	if (unlikely(IS_ERR(pd))) {
		err = PTR_ERR(pd);
		pr_err("Failed to alloc iser dev pd, err:%d\n", err);
		goto fail_pd;
	}

	mr = ib_get_dma_mr(pd, IB_ACCESS_LOCAL_WRITE);
	if (unlikely(IS_ERR(mr))) {
		err = PTR_ERR(mr);
		pr_err("Failed to get dma mr, err: %d\n", err);
		goto fail_mr;
	}

	cqe_num = min(isert_dev->device_attr.max_cqe, ISER_CQ_ENTRIES);
	cqe_num = cqe_num / isert_dev->num_cqs;

#ifdef CONFIG_SCST_EXTRACHECKS
	if (isert_dev->device_attr.max_cqe == 0)
		pr_err("Zero max_cqe encountered: you may have a compilation problem\n");
#endif

	for (i = 0; i < isert_dev->num_cqs; ++i) {
		struct isert_cq *cq_desc = &isert_dev->cq_desc[i];

		cq_desc->dev = isert_dev;
		cq_desc->idx = i;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
		INIT_WORK(&cq_desc->cq_comp_work, isert_cq_comp_work_cb, NULL);
#else
		INIT_WORK(&cq_desc->cq_comp_work, isert_cq_comp_work_cb);
#endif

		snprintf(wq_name, sizeof(wq_name), "isert_cq_%p", cq_desc);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
		cq_desc->cq_workqueue = create_singlethread_workqueue(wq_name);
#else
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 36)
		cq_desc->cq_workqueue = alloc_workqueue(wq_name,
							WQ_CPU_INTENSIVE|
							WQ_RESCUER, 1);
#else
		cq_desc->cq_workqueue = alloc_workqueue(wq_name,
							WQ_CPU_INTENSIVE|
							WQ_MEM_RECLAIM, 1);
#endif
#endif
		if (unlikely(!cq_desc->cq_workqueue)) {
			pr_err("Failed to alloc iser cq work queue for dev:%s\n",
			       ib_dev->name);
			err = -ENOMEM;
			goto fail_cq;
		}

		cq = ib_create_cq(ib_dev,
				  isert_cq_comp_handler,
				  isert_async_evt_handler,
				  cq_desc, /* context */
				  cqe_num,
				  i); /* completion vector */
		if (unlikely(IS_ERR(cq))) {
			cq_desc->cq = NULL;
			err = PTR_ERR(cq);
			pr_err("Failed to create iser dev cq, err:%d\n", err);
			goto fail_cq;
		}

		cq_desc->cq = cq;
		err = ib_req_notify_cq(cq, IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS);
		if (unlikely(err)) {
			pr_err("Failed to request notify cq, err: %d\n", err);
			goto fail_cq;
		}
	}

	isert_dev->ib_dev = ib_dev;
	isert_dev->pd = pd;
	isert_dev->mr = mr;

	INIT_LIST_HEAD(&isert_dev->conn_list);

	lockdep_assert_held(&dev_list_mutex);

	isert_dev_list_add(isert_dev);

	pr_info("iser created device:%p\n", isert_dev);
	return isert_dev;

fail_cq:
	for (j = 0; j <= i; ++j) {
		if (isert_dev->cq_desc[j].cq)
			ib_destroy_cq(isert_dev->cq_desc[j].cq);
		if (isert_dev->cq_desc[j].cq_workqueue)
			destroy_workqueue(isert_dev->cq_desc[j].cq_workqueue);
	}
	ib_dereg_mr(mr);
fail_mr:
	ib_dealloc_pd(pd);
fail_pd:
	vfree(isert_dev->cq_desc);
fail_alloc_cq_desc:
	kfree(isert_dev->cq_qps);
fail_cq_qps:
fail_query:
	kfree(isert_dev);
out:
	TRACE_EXIT_RES(err);
	return ERR_PTR(err);
}
Пример #12
0
static int max77693_haptic_probe(struct platform_device *pdev)
{
	int error = 0;
	struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
	struct max77693_platform_data *max77693_pdata
		= dev_get_platdata(max77693->dev);
	struct max77693_haptic_platform_data *pdata
		= max77693_pdata->haptic_data;
	struct max77693_haptic_data *hap_data;

	pr_debug("[VIB] ++ %s\n", __func__);
	 if (pdata == NULL) {
		pr_err("%s: no pdata\n", __func__);
		return -ENODEV;
	}

	hap_data = kzalloc(sizeof(struct max77693_haptic_data), GFP_KERNEL);
	if (!hap_data)
		return -ENOMEM;

	platform_set_drvdata(pdev, hap_data);
	g_hap_data = hap_data;
	hap_data->max77693 = max77693;
	hap_data->i2c = max77693->haptic;
	hap_data->pmic_i2c = max77693->i2c;
	hap_data->pdata = pdata;

	hap_data->workqueue = create_singlethread_workqueue("hap_work");
	if (IS_ERR(hap_data->workqueue)) {
	        pr_err("[VIB] Failed to create workqueue for hap_work\n");
	        error = -EFAULT;
		goto err_create_workqueue;
	}

	INIT_WORK(&(hap_data->work), haptic_work);
	spin_lock_init(&(hap_data->lock));

	hap_data->pwm = pwm_request(hap_data->pdata->pwm_id, "vibrator");
	if (IS_ERR(hap_data->pwm)) {
		pr_err("[VIB] Failed to request pwm\n");
		error = -EFAULT;
		goto err_pwm_request;
	}
	pwm_config(hap_data->pwm, pdata->period / 2, pdata->period);

	vibetonz_clk_on(&pdev->dev, true);

	if (pdata->init_hw)
		pdata->init_hw();

	hap_data->regulator
		= regulator_get(NULL, pdata->regulator_name);

	if (IS_ERR(hap_data->regulator)) {
		pr_err("[VIB] Failed to get vmoter regulator.\n");
		error = -EFAULT;
		goto err_regulator_get;
	}

	/* hrtimer init */
	hrtimer_init(&hap_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	hap_data->timer.function = haptic_timer_func;

	/* timed_output_dev init*/
	hap_data->tout_dev.name = "vibrator";
	hap_data->tout_dev.get_time = haptic_get_time;
	hap_data->tout_dev.enable = haptic_enable;

    create_vibrator_sysfs();


#ifdef CONFIG_ANDROID_TIMED_OUTPUT
	error = timed_output_dev_register(&hap_data->tout_dev);
	if (error < 0) {
		pr_err("[VIB] Failed to register timed_output : %d\n", error);
		error = -EFAULT;
		goto err_timed_output_register;
	}

	pr_err("[VIB] timed_output device is registrated\n");

	/* User controllable pwm level */
	error = device_create_file(hap_data->tout_dev.dev, &dev_attr_pwm_value);
	if (error < 0) {
		pr_err("[VIB] create sysfs fail: pwm_value\n");
	}
#endif
	pr_debug("[VIB] -- %s\n", __func__);

	return error;

err_timed_output_register:
	regulator_put(hap_data->regulator);
err_regulator_get:
	pwm_free(hap_data->pwm);
err_pwm_request:
	destroy_workqueue(hap_data->workqueue);
err_create_workqueue:
	kfree(hap_data);
	g_hap_data = NULL;
	return error;
}
Пример #13
0
void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv)
{
	destroy_workqueue(dev_priv->mm.userptr_wq);
}
Пример #14
0
static int cm36686_i2c_remove(struct i2c_client *client)
{
	struct cm36686_data *cm36686 = i2c_get_clientdata(client);

	/* free irq */
	if (cm36686->power_state & PROXIMITY_ENABLED) {
		disable_irq_wake(cm36686->irq);
		disable_irq(cm36686->irq);
	}
	free_irq(cm36686->irq, cm36686);
	gpio_free(cm36686->pdata->irq);

	/* device off */
	if (cm36686->power_state & LIGHT_ENABLED)
		cm36686_light_disable(cm36686);
	if (cm36686->power_state & PROXIMITY_ENABLED) {
		cm36686_i2c_write_word(cm36686, REG_PS_CONF1,
					   0x0001);
		if (cm36686->pdata->cm36686_led_on)
			cm36686->pdata->cm36686_led_on(false);

		if (cm36686->cm36686_light_vddpower)
			cm36686->cm36686_light_vddpower(false);

		if (cm36686->cm36686_proxi_vddpower)
			cm36686->cm36686_proxi_vddpower(false);
	}

	/* destroy workqueue */
	destroy_workqueue(cm36686->light_wq);
	destroy_workqueue(cm36686->prox_wq);

	/* sysfs destroy */
	device_remove_file(cm36686->light_dev, &dev_attr_name);
	device_remove_file(cm36686->light_dev, &dev_attr_vendor);
	device_remove_file(cm36686->light_dev, &dev_attr_raw_data);
	device_remove_file(cm36686->light_dev, &dev_attr_lux);
	sensors_classdev_unregister(cm36686->light_dev);

	device_remove_file(cm36686->proximity_dev, &dev_attr_name);
	device_remove_file(cm36686->proximity_dev, &dev_attr_vendor);
	device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_high);
	device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_low);

	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_avg);
#ifdef CM36686_CANCELATION
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_cal);
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_offset_pass);
#endif
	device_remove_file(cm36686->proximity_dev, &attr_prox_raw);
	device_remove_file(cm36686->proximity_dev, &dev_attr_state);
	sensors_classdev_unregister(cm36686->proximity_dev);

	/* input device destroy */
	sysfs_remove_group(&cm36686->light_input_dev->dev.kobj,
				&light_attribute_group);
	input_unregister_device(cm36686->light_input_dev);
	sysfs_remove_group(&cm36686->proximity_input_dev->dev.kobj,
				&proximity_attribute_group);
	input_unregister_device(cm36686->proximity_input_dev);

	/* lock destroy */
	mutex_destroy(&cm36686->read_lock);
	mutex_destroy(&cm36686->power_lock);
	wake_lock_destroy(&cm36686->prx_wake_lock);

	kfree(cm36686);

	return 0;
}
Пример #15
0
void adf_exit_aer(void)
{
	if (device_reset_wq)
		destroy_workqueue(device_reset_wq);
	device_reset_wq = NULL;
}
static int lge_hsd_probe(struct platform_device *pdev)
{
    int ret;
    struct gpio_switch_platform_data *pdata = pdev->dev.platform_data;

    HSD_DBG("%s\n", pdata->name);

    if (!pdata) {
        HSD_ERR("The platform data is null\n");
        return -EBUSY;
    }

    hi = kzalloc(sizeof(struct hsd_info), GFP_KERNEL);
    if (!hi) {
        HSD_ERR("Failed to allloate headset per device info\n");
        return -ENOMEM;
    }

    hi->gpio = pdata->gpio;
    mutex_init(&hi->mutex_lock);
    hi->sdev.name = pdata->name;
    hi->sdev.print_state = lge_hsd_print_state;
    hi->sdev.print_name = lge_hsd_print_name;

    ret = switch_dev_register(&hi->sdev);
    if (ret < 0) {
        HSD_ERR("Failed to register switch device\n");
        goto err_switch_dev_register;
    }

    hs_detect_work_queue = create_workqueue("hs_detect");
    if (hs_detect_work_queue == NULL) {
        HSD_ERR("Failed to create workqueue\n");
        goto err_create_work_queue;
    }

    ret = gpio_request(hi->gpio, pdev->name);
    if (ret < 0) {
        HSD_ERR("Failed to request gpio%d\n", hi->gpio);
        goto err_request_detect_gpio;
    }

    ret = gpio_direction_input(hi->gpio);
    if (ret < 0) {
        HSD_ERR("Failed to set gpio%d as input\n", hi->gpio);
        goto err_set_detect_gpio;
    }

    if (hi->gpio == LGE_HEADSET_DETECT_GPIO) {
        ret = gpio_tlmm_config(GPIO_CFG(hi->gpio, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
                                        GPIO_CFG_2MA), GPIO_CFG_ENABLE);
        if (ret < 0) {
            HSD_ERR("Failed to configure gpio%d tlmm\n", hi->gpio);
            goto err_set_detect_gpio;
        }
    }

    hi->irq = gpio_to_irq(pdata->gpio);
    if (hi->irq < 0) {
        HSD_ERR("Failed to get interrupt number\n");
        ret = hi->irq;
        goto err_get_irq_num_failed;
    }

    ret = request_irq(hi->irq, gpio_irq_handler,
                      IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, pdev->name, NULL);

    if (ret < 0) {
        HSD_ERR("Failed to request interrupt handler\n");
        goto err_request_detect_irq;
    }

    ret = irq_set_irq_wake(hi->irq, 1);
    if (ret < 0) {
        HSD_ERR("Failed to set interrupt wake\n");
        goto err_request_input_dev;
    }

    hi->input = input_allocate_device();
    if (!hi->input) {
        HSD_ERR("Failed to allocate input device\n");
        ret = -ENOMEM;
        goto err_request_input_dev;
    }

    if (pdev->dev.platform_data)
        hi->input->name = "7k_headset";
    else
        hi->input->name = "hsd_headset";

    hi->input->id.vendor	= 0x0001;
    hi->input->id.product	= 1;
    hi->input->id.version	= 1;

    input_set_capability(hi->input, EV_SW, SW_HEADPHONE_INSERT);

    ret = input_register_device(hi->input);
    if (ret) {
        HSD_ERR("Failed to register input device\n");
        goto err_register_input_dev;
    }

    /* Perform initial detection */
    return 0;

err_register_input_dev:
    input_free_device(hi->input);
err_request_input_dev:
    free_irq(hi->irq, 0);
err_request_detect_irq:
err_get_irq_num_failed:
err_set_detect_gpio:
    gpio_free(hi->gpio);
err_request_detect_gpio:
    destroy_workqueue(hs_detect_work_queue);
err_create_work_queue:
    switch_dev_unregister(&hi->sdev);
err_switch_dev_register:
    HSD_ERR("Failed to register driver\n");

    return ret;
}
Пример #17
0
static void __exit test_exit(void)
{
  destroy_workqueue(queue);
}
Пример #18
0
static void __exit appledisplay_exit(void)
{
	flush_workqueue(wq);
	destroy_workqueue(wq);
	usb_deregister(&appledisplay_driver);
}
static int mxhci_hsic_probe(struct platform_device *pdev)
{
	struct hc_driver *driver;
	struct device_node *node = pdev->dev.of_node;
	struct mxhci_hsic_hcd *mxhci;
	struct xhci_hcd		*xhci;
	struct resource *res;
	struct usb_hcd *hcd;
	unsigned int reg;
	int ret;
	int irq;
	u32 tmp[3];

	if (usb_disabled())
		return -ENODEV;

	driver = &mxhci_hsic_hc_driver;

	pdev->dev.dma_mask = &dma_mask;

	/* dbg log event settings */
	dbg_hsic.log_events =  enable_dbg_log;
	dbg_hsic.log_payload = enable_payload_log;
	dbg_hsic.inep_log_mask = ep_addr_rxdbg_mask;
	dbg_hsic.outep_log_mask = ep_addr_rxdbg_mask;

	/* usb2.0 root hub */
	driver->hcd_priv_size =	sizeof(struct mxhci_hsic_hcd);
	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd)
		return -ENOMEM;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		ret = -ENODEV;
		goto put_hcd;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		ret = -ENODEV;
		goto put_hcd;
	}

	hcd_to_bus(hcd)->skip_resume = true;
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);

	hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "error mapping memory\n");
		ret = -EFAULT;
		goto put_hcd;
	}

	mxhci = hcd_to_hsic(hcd);
	mxhci->dev = &pdev->dev;

	mxhci->strobe = of_get_named_gpio(node, "hsic,strobe-gpio", 0);
	if (mxhci->strobe < 0) {
		ret = -EINVAL;
		goto put_hcd;
	}

	mxhci->data  = of_get_named_gpio(node, "hsic,data-gpio", 0);
	if (mxhci->data < 0) {
		ret = -EINVAL;
		goto put_hcd;
	}

	ret = of_property_read_u32_array(node, "qcom,vdd-voltage-level",
							tmp, ARRAY_SIZE(tmp));
	if (!ret) {
		mxhci->vdd_no_vol_level = tmp[0];
		mxhci->vdd_low_vol_level = tmp[1];
		mxhci->vdd_high_vol_level = tmp[2];
	} else {
		dev_err(&pdev->dev,
			"failed to read qcom,vdd-voltage-level property\n");
		ret = -EINVAL;
		goto put_hcd;
	}

	ret = mxhci_msm_config_gdsc(mxhci, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to configure hsic gdsc\n");
		goto put_hcd;
	}

	ret = mxhci_hsic_init_clocks(mxhci, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize clocks\n");
		goto put_hcd;
	}

	ret = mxhci_hsic_init_vddcx(mxhci, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize vddcx\n");
		goto deinit_clocks;
	}

	mxhci_hsic_reset(mxhci);

	/* HSIC phy caliberation:set periodic caliberation interval ~2.048sec */
	mxhci_hsic_ulpi_write(mxhci, 0xFF, MSM_HSIC_IO_CAL_PER);

	/* Enable periodic IO calibration in HSIC_CFG register */
	mxhci_hsic_ulpi_write(mxhci, 0xA8, MSM_HSIC_CFG);

	/* Configure Strobe and Data GPIOs to enable HSIC */
	ret = mxhci_hsic_config_gpios(mxhci);
	if (ret) {
		dev_err(mxhci->dev, " gpio configuarion failed\n");
		goto deinit_vddcx;
	}

	/* enable STROBE_PAD_CTL */
	reg = readl_relaxed(TLMM_GPIO_HSIC_STROBE_PAD_CTL);
	writel_relaxed(reg | 0x2000000, TLMM_GPIO_HSIC_STROBE_PAD_CTL);

	/* enable DATA_PAD_CTL */
	reg = readl_relaxed(TLMM_GPIO_HSIC_DATA_PAD_CTL);
	writel_relaxed(reg | 0x2000000, TLMM_GPIO_HSIC_DATA_PAD_CTL);

	mb();

	/* Enable LPM in Sleep mode and suspend mode */
	reg = readl_relaxed(MSM_HSIC_CTRL_REG);
	reg |= CTRLREG_PLL_CTRL_SLEEP | CTRLREG_PLL_CTRL_SUSP;
	writel_relaxed(reg, MSM_HSIC_CTRL_REG);

	if (of_property_read_bool(node, "qti,disable-hw-clk-gating")) {
		reg = readl_relaxed(MSM_HSIC_GCTL);
		writel_relaxed((reg | GCTL_DSBLCLKGTNG), MSM_HSIC_GCTL);
	}

	/* enable pwr event irq for LPM_IN_L2_IRQ */
	writel_relaxed(LPM_IN_L2_IRQ_MASK, MSM_HSIC_PWR_EVNT_IRQ_MASK);

	mxhci->wakeup_irq = platform_get_irq_byname(pdev, "wakeup_irq");
	if (mxhci->wakeup_irq < 0) {
		mxhci->wakeup_irq = 0;
		dev_err(&pdev->dev, "failed to init wakeup_irq\n");
	} else {
		/* enable wakeup irq only when entering lpm */
		irq_set_status_flags(mxhci->wakeup_irq, IRQ_NOAUTOEN);
		ret = devm_request_irq(&pdev->dev, mxhci->wakeup_irq,
			mxhci_hsic_wakeup_irq, 0, "mxhci_hsic_wakeup", mxhci);
		if (ret) {
			dev_err(&pdev->dev,
					"request irq failed (wakeup irq)\n");
			goto deinit_vddcx;
		}
	}

	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (ret)
		goto deinit_vddcx;

	hcd = dev_get_drvdata(&pdev->dev);
	xhci = hcd_to_xhci(hcd);

	/* USB 3.0 roothub */

	/* no need for another instance of mxhci */
	driver->hcd_priv_size = sizeof(struct xhci_hcd *);

	xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev,
			dev_name(&pdev->dev), hcd);
	if (!xhci->shared_hcd) {
		ret = -ENOMEM;
		goto remove_usb2_hcd;
	}

	hcd_to_bus(xhci->shared_hcd)->skip_resume = true;
	/*
	 * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset)
	 * is called by usb_add_hcd().
	 */
	*((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci;

	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
	if (ret)
		goto put_usb3_hcd;

	spin_lock_init(&mxhci->wakeup_lock);

	mxhci->pwr_event_irq = platform_get_irq_byname(pdev, "pwr_event_irq");
	if (mxhci->pwr_event_irq < 0) {
		dev_err(&pdev->dev,
				"platform_get_irq for pwr_event_irq failed\n");
		goto remove_usb3_hcd;
	}

	ret = devm_request_irq(&pdev->dev, mxhci->pwr_event_irq,
				mxhci_hsic_pwr_event_irq,
				0, "mxhci_hsic_pwr_evt", mxhci);
	if (ret) {
		dev_err(&pdev->dev, "request irq failed (pwr event irq)\n");
		goto remove_usb3_hcd;
	}

	init_completion(&mxhci->phy_in_lpm);

	mxhci->wq = create_singlethread_workqueue("mxhci_wq");
	if (!mxhci->wq) {
		dev_err(&pdev->dev, "unable to create workqueue\n");
		ret = -ENOMEM;
		goto remove_usb3_hcd;
	}

	INIT_WORK(&mxhci->bus_vote_w, mxhci_hsic_bus_vote_w);

	mxhci->bus_scale_table = msm_bus_cl_get_pdata(pdev);
	if (!mxhci->bus_scale_table) {
		dev_dbg(&pdev->dev, "bus scaling is disabled\n");
	} else {
		mxhci->bus_perf_client =
			msm_bus_scale_register_client(mxhci->bus_scale_table);
		/* Configure BUS performance parameters for MAX bandwidth */
		if (mxhci->bus_perf_client) {
			mxhci->bus_vote = true;
			queue_work(mxhci->wq, &mxhci->bus_vote_w);
		} else {
			dev_err(&pdev->dev, "%s: bus scaling client reg err\n",
					__func__);
			ret = -ENODEV;
			goto delete_wq;
		}
	}

	ret = device_create_file(&pdev->dev, &dev_attr_config_imod);
	if (ret)
		dev_dbg(&pdev->dev, "%s: unable to create imod sysfs entry\n",
					__func__);

	/* Enable HSIC PHY */
	mxhci_hsic_ulpi_write(mxhci, 0x01, MSM_HSIC_CFG_SET);

	device_init_wakeup(&pdev->dev, 1);
	wakeup_source_init(&mxhci->ws, dev_name(&pdev->dev));
	pm_stay_awake(mxhci->dev);

	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	return 0;

delete_wq:
	destroy_workqueue(mxhci->wq);
remove_usb3_hcd:
	usb_remove_hcd(xhci->shared_hcd);
put_usb3_hcd:
	usb_put_hcd(xhci->shared_hcd);
remove_usb2_hcd:
	usb_remove_hcd(hcd);
deinit_vddcx:
	mxhci_hsic_init_vddcx(mxhci, 0);
deinit_clocks:
	mxhci_hsic_init_clocks(mxhci, 0);
put_hcd:
	usb_put_hcd(hcd);

	return ret;
}
Пример #20
0
static ssize_t debug_flag_store(struct device *dev,
                                struct device_attribute *attr,
                                const char *buf, size_t count)
{
    unsigned long state = 0;

    HS_DBG();

    if (strncmp(buf, "enable", count - 1) == 0) {
        if (hi->debug_flag & DEBUG_FLAG_ADC) {
            HS_LOG("Debug work is already running");
            return count;
        }
        if (!debug_wq) {
            debug_wq = create_workqueue("debug");
            if (!debug_wq) {
                HS_LOG("Failed to create debug workqueue");
                return count;
            }
        }
        HS_LOG("Enable headset debug");
        mutex_lock(&hi->mutex_lock);
        hi->debug_flag |= DEBUG_FLAG_ADC;
        mutex_unlock(&hi->mutex_lock);
        queue_work(debug_wq, &debug_work);
    } else if (strncmp(buf, "disable", count - 1) == 0) {
        if (!(hi->debug_flag & DEBUG_FLAG_ADC)) {
            HS_LOG("Debug work has been stopped");
            return count;
        }
        HS_LOG("Disable headset debug");
        mutex_lock(&hi->mutex_lock);
        hi->debug_flag &= ~DEBUG_FLAG_ADC;
        mutex_unlock(&hi->mutex_lock);
        if (debug_wq) {
            flush_workqueue(debug_wq);
            destroy_workqueue(debug_wq);
            debug_wq = NULL;
        }
    } else if (strncmp(buf, "debug_log_enable", count - 1) == 0) {
        HS_LOG("Enable headset debug log");
        hi->debug_flag |= DEBUG_FLAG_LOG;
    } else if (strncmp(buf, "debug_log_disable", count - 1) == 0) {
        HS_LOG("Disable headset debug log");
        hi->debug_flag &= ~DEBUG_FLAG_LOG;
    } else if (strncmp(buf, "no_headset", count - 1) == 0) {
        HS_LOG("Headset simulation: no_headset");
        state = BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_35MM_HEADSET |
                BIT_USB_AUDIO_OUT;
        switch_send_event(state, 0);
    } else if (strncmp(buf, "35mm_mic", count - 1) == 0) {
        HS_LOG("Headset simulation: 35mm_mic");
        state = BIT_HEADSET | BIT_35MM_HEADSET;
        switch_send_event(state, 1);
    } else if (strncmp(buf, "35mm_no_mic", count - 1) == 0) {
        HS_LOG("Headset simulation: 35mm_no_mic");
        state = BIT_HEADSET_NO_MIC | BIT_35MM_HEADSET;
        switch_send_event(state, 1);
    } else if (strncmp(buf, "usb_audio", count - 1) == 0) {
        HS_LOG("Headset simulation: usb_audio");
        state = BIT_USB_AUDIO_OUT;
        switch_send_event(state, 1);
    } else {
        HS_LOG("Invalid parameter");
        return count;
    }

    return count;
}
Пример #21
0
static int fimg2d_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct fimg2d_platdata *pdata;
	int ret;

	pdata = to_fimg2d_plat(&pdev->dev);
	if (!pdata) {
		printk(KERN_ERR "FIMG2D failed to get platform data\n");
		ret = -ENOMEM;
		goto err_plat;
	}

	/* global structure */
	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		printk(KERN_ERR "FIMG2D failed to allocate memory for controller\n");
		ret = -ENOMEM;
		goto err_plat;
	}

	/* setup global info */
	ret = fimg2d_setup_controller(info);
	if (ret) {
		printk(KERN_ERR "FIMG2D failed to setup controller\n");
		goto err_setup;
	}
	info->dev = &pdev->dev;

	/* memory region */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		printk(KERN_ERR "FIMG2D failed to get resource\n");
		ret = -ENOENT;
		goto err_res;
	}

	info->mem = request_mem_region(res->start, resource_size(res),
					pdev->name);
	if (!info->mem) {
		printk(KERN_ERR "FIMG2D failed to request memory region\n");
		ret = -ENOMEM;
		goto err_region;
	}

	/* ioremap */
	info->regs = ioremap(res->start, resource_size(res));
	if (!info->regs) {
		printk(KERN_ERR "FIMG2D failed to ioremap for SFR\n");
		ret = -ENOENT;
		goto err_map;
	}
	fimg2d_debug("device name: %s base address: 0x%lx\n",
			pdev->name, (unsigned long)res->start);

	/* irq */
	info->irq = platform_get_irq(pdev, 0);
	if (!info->irq) {
		printk(KERN_ERR "FIMG2D failed to get irq resource\n");
		ret = -ENOENT;
		goto err_map;
	}
	fimg2d_debug("irq: %d\n", info->irq);

	ret = request_irq(info->irq, fimg2d_irq, IRQF_DISABLED, pdev->name, info);
	if (ret) {
		printk(KERN_ERR "FIMG2D failed to request irq\n");
		ret = -ENOENT;
		goto err_irq;
	}

	ret = fimg2d_clk_setup(info);
	if (ret) {
		printk(KERN_ERR "FIMG2D failed to setup clk\n");
		ret = -ENOENT;
		goto err_clk;
	}

#ifdef CONFIG_PM_RUNTIME
	pm_runtime_enable(info->dev);
	fimg2d_debug("enable runtime pm\n");
#endif

#ifdef CONFIG_BUSFREQ_OPP
#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
	/* To lock bus frequency in OPP mode */
	info->bus_dev = dev_get("exynos-busfreq");
#endif
#endif
	s5p_sysmmu_set_fault_handler(info->dev, fimg2d_sysmmu_fault_handler);
	fimg2d_debug("register sysmmu page fault handler\n");

	/* misc register */
	ret = misc_register(&fimg2d_dev);
	if (ret) {
		printk(KERN_ERR "FIMG2D failed to register misc driver\n");
		goto err_reg;
	}

	printk(KERN_INFO "Samsung Graphics 2D driver, (c) 2011 Samsung Electronics\n");
	return 0;

err_reg:
	fimg2d_clk_release(info);

err_clk:
	free_irq(info->irq, NULL);

err_irq:
	iounmap(info->regs);

err_map:
	kfree(info->mem);

err_region:
	release_resource(info->mem);

err_res:
	destroy_workqueue(info->work_q);

err_setup:
	kfree(info);

err_plat:
	return ret;
}
Пример #22
0
static int htc_headset_mgr_probe(struct platform_device *pdev)
{
    int ret;

    struct htc_headset_mgr_platform_data *pdata = pdev->dev.platform_data;

    HS_LOG("++++++++++++++++++++");

    hi = kzalloc(sizeof(struct htc_headset_mgr_info), GFP_KERNEL);
    if (!hi)
        return -ENOMEM;

    hi->pdata.driver_flag = pdata->driver_flag;
    hi->pdata.headset_devices_num = pdata->headset_devices_num;
    hi->pdata.headset_devices = pdata->headset_devices;

    hi->driver_init_seq = 0;

    wake_lock_init(&hi->hs_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME);

    hi->hpin_jiffies = jiffies;
    hi->usb_headset.type = USB_NO_HEADSET;
    hi->usb_headset.status = STATUS_DISCONNECTED;

    hi->ext_35mm_status = HTC_35MM_UNPLUG;
    hi->h2w_35mm_status = HTC_35MM_UNPLUG;
    hi->is_ext_insert = 0;
    hi->mic_bias_state = 0;
    hi->mic_detect_counter = 0;
    hi->key_level_flag = -1;

    atomic_set(&hi->btn_state, 0);

    hi->tty_enable_flag = 0;
    hi->fm_flag = 0;
    hi->debug_flag = 0;

    mutex_init(&hi->mutex_lock);

    hi->sdev.name = "h2w";
    hi->sdev.print_name = h2w_print_name;

    ret = switch_dev_register(&hi->sdev);
    if (ret < 0)
        goto err_switch_dev_register;

    detect_wq = create_workqueue("detect");
    if (detect_wq == NULL) {
        ret = -ENOMEM;
        HS_ERR("Failed to create detect workqueue");
        goto err_create_detect_work_queue;
    }

    button_wq = create_workqueue("button");
    if (button_wq  == NULL) {
        ret = -ENOMEM;
        HS_ERR("Failed to create button workqueue");
        goto err_create_button_work_queue;
    }

    hi->input = input_allocate_device();
    if (!hi->input) {
        ret = -ENOMEM;
        goto err_request_input_dev;
    }

    hi->input->name = "h2w headset";
    set_bit(EV_SYN, hi->input->evbit);
    set_bit(EV_KEY, hi->input->evbit);
    set_bit(KEY_END, hi->input->keybit);
    set_bit(KEY_MUTE, hi->input->keybit);
    set_bit(KEY_VOLUMEDOWN, hi->input->keybit);
    set_bit(KEY_VOLUMEUP, hi->input->keybit);
    set_bit(KEY_NEXTSONG, hi->input->keybit);
    set_bit(KEY_PLAYPAUSE, hi->input->keybit);
    set_bit(KEY_PREVIOUSSONG, hi->input->keybit);
    set_bit(KEY_MEDIA, hi->input->keybit);
    set_bit(KEY_SEND, hi->input->keybit);

    ret = input_register_device(hi->input);
    if (ret < 0)
        goto err_register_input_dev;

    ret = register_attributes();
    if (ret)
        goto err_register_attributes;

    if (hi->pdata.driver_flag & DRIVER_HS_MGR_RPC_SERVER) {
        /* Create RPC server */
        ret = msm_rpc_create_server(&hs_rpc_server);
        if (ret < 0) {
            HS_ERR("Failed to create RPC server");
            goto err_create_rpc_server;
        }
        HS_LOG("Create RPC server successfully");
    }

    hs_notify_driver_ready(DRIVER_NAME);

    HS_LOG("--------------------");

    return 0;

err_create_rpc_server:

err_register_attributes:
    input_unregister_device(hi->input);

err_register_input_dev:
    input_free_device(hi->input);

err_request_input_dev:
    destroy_workqueue(button_wq);

err_create_button_work_queue:
    destroy_workqueue(detect_wq);

err_create_detect_work_queue:
    switch_dev_unregister(&hi->sdev);

err_switch_dev_register:
    mutex_destroy(&hi->mutex_lock);
    wake_lock_destroy(&hi->hs_wake_lock);
    kfree(hi);

    HS_ERR("Failed to register %s driver", DRIVER_NAME);

    return ret;
}
Пример #23
0
void mlx5_health_cleanup(struct mlx5_core_dev *dev)
{
	struct mlx5_core_health *health = &dev->priv.health;

	destroy_workqueue(health->wq);
}
Пример #24
0
static void ksuspend_usb_cleanup(void)
{
	destroy_workqueue(ksuspend_usb_wq);
}
Пример #25
0
static void __exit bridge_exit(void)
{
	data_bridge_debugfs_exit();
	destroy_workqueue(bridge_wq);
	usb_deregister(&bridge_driver);
}
static int __init bridge_init(void)
{
	struct data_bridge	*dev;
	int			ret;
	int			i = 0;

	ret = ctrl_bridge_init();
	if (ret)
		return ret;

	bridge_wq  = create_singlethread_workqueue("mdm_bridge");
	if (!bridge_wq) {
		pr_err("%s: Unable to create workqueue:bridge\n", __func__);
		ret = -ENOMEM;
		goto free_ctrl;
	}

	for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {

		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
		if (!dev) {
			err("%s: unable to allocate dev\n", __func__);
			ret = -ENOMEM;
			goto error;
		}

		dev->wq = bridge_wq;

		init_usb_anchor(&dev->tx_active);
		init_usb_anchor(&dev->rx_active);

		INIT_LIST_HEAD(&dev->rx_idle);

		skb_queue_head_init(&dev->rx_done);

		INIT_WORK(&dev->kevent, defer_kevent);
		INIT_WORK(&dev->process_rx_w, data_bridge_process_rx);

		__dev[i] = dev;
	}

	ret = usb_register(&bridge_driver);
	if (ret) {
		err("%s: unable to register mdm_bridge driver", __func__);
		goto error;
	}

	data_bridge_debugfs_init();

	return 0;

error:
	while (--i >= 0) {
		kfree(__dev[i]);
		__dev[i] = NULL;
	}
	destroy_workqueue(bridge_wq);
free_ctrl:
	ctrl_bridge_exit();
	return ret;
}
Пример #27
0
static int __devinit therm_est_probe(struct platform_device *pdev)
{
	int i;
	struct therm_estimator *est;
	struct therm_est_data *data;

	est = kzalloc(sizeof(struct therm_estimator), GFP_KERNEL);
	if (IS_ERR_OR_NULL(est))
		return -ENOMEM;

	platform_set_drvdata(pdev, est);

	data = therm_est_get_pdata(&pdev->dev);

	est->devs = data->devs;
	est->ndevs = data->ndevs;
	est->toffset = data->toffset;
	est->polling_period = data->polling_period;
	est->tc1 = data->tc1;
	est->tc2 = data->tc2;
	est->cur_temp = DEFAULT_TEMP;
	est->ntemp = HIST_UNINIT;

	/* initialize timer trips */
	est->num_timer_trips = data->num_timer_trips;
	est->timer_trips = data->timer_trips;
	therm_est_init_timer_trips(est);
	mutex_init(&est->timer_trip_lock);
	INIT_DELAYED_WORK(&est->timer_trip_work,
			  therm_est_timer_trip_work_func);

	est->workqueue = alloc_workqueue(dev_name(&pdev->dev),
				    WQ_HIGHPRI | WQ_UNBOUND | WQ_RESCUER, 1);
	if (!est->workqueue)
		goto err;

	INIT_DELAYED_WORK(&est->therm_est_work, therm_est_work_func);

	queue_delayed_work(est->workqueue,
				&est->therm_est_work,
				msecs_to_jiffies(est->polling_period));

	est->num_trips = data->num_trips;
	est->trips = data->trips;
	est->tzp = data->tzp;

	est->thz = thermal_zone_device_register(dev_name(&pdev->dev),
						est->num_trips,
						(1 << est->num_trips) - 1,
						est,
						&therm_est_ops,
						est->tzp,
						data->passive_delay,
						0);
	if (IS_ERR_OR_NULL(est->thz))
		goto err;

	for (i = 0; i < ARRAY_SIZE(therm_est_nodes); i++)
		device_create_file(&pdev->dev, &therm_est_nodes[i].dev_attr);

#ifdef CONFIG_PM
	est->pm_nb.notifier_call = therm_est_pm_notify,
	register_pm_notifier(&est->pm_nb);
#endif

	return 0;
err:
	cancel_delayed_work_sync(&est->therm_est_work);
	if (est->workqueue)
		destroy_workqueue(est->workqueue);
	kfree(est);
	return -EINVAL;
}
Пример #28
0
static __devinit int sec_battery_probe(struct platform_device *pdev)
{
    struct sec_battery_platform_data *pdata = pdev->dev.platform_data;
    struct chg_data *chg;
    int ret = 0;

    pr_info("%s : Samsung Battery Driver Loading\n", __func__);

    chg = kzalloc(sizeof(*chg), GFP_KERNEL);
    if (!chg)
        return -ENOMEM;

    chg->pdata = pdata;

    if (!chg->pdata || !chg->pdata->adc_table) {
        pr_err("%s : No platform data & adc_table supplied\n", __func__);
        ret = -EINVAL;
        goto err_bat_table;
    }

    chg->psy_bat.name = "battery",
                 chg->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY,
                              chg->psy_bat.properties = sec_battery_props,
                                           chg->psy_bat.num_properties = ARRAY_SIZE(sec_battery_props),
                                                        chg->psy_bat.get_property = sec_bat_get_property,

                                                                     chg->psy_usb.name = "usb",
                                                                                  chg->psy_usb.type = POWER_SUPPLY_TYPE_USB,
                                                                                               chg->psy_usb.supplied_to = supply_list,
                                                                                                            chg->psy_usb.num_supplicants = ARRAY_SIZE(supply_list),
                                                                                                                         chg->psy_usb.properties = sec_power_properties,
                                                                                                                                      chg->psy_usb.num_properties = ARRAY_SIZE(sec_power_properties),
                                                                                                                                                   chg->psy_usb.get_property = sec_usb_get_property,

                                                                                                                                                                chg->psy_ac.name = "ac",
                                                                                                                                                                            chg->psy_ac.type = POWER_SUPPLY_TYPE_MAINS,
                                                                                                                                                                                        chg->psy_ac.supplied_to = supply_list,
                                                                                                                                                                                                    chg->psy_ac.num_supplicants = ARRAY_SIZE(supply_list),
                                                                                                                                                                                                                chg->psy_ac.properties = sec_power_properties,
                                                                                                                                                                                                                            chg->psy_ac.num_properties = ARRAY_SIZE(sec_power_properties),
                                                                                                                                                                                                                                        chg->psy_ac.get_property = sec_ac_get_property,

                                                                                                                                                                                                                                                    chg->present = 1;
    chg->polling_interval = POLLING_INTERVAL;
    chg->bat_info.batt_health = POWER_SUPPLY_HEALTH_GOOD;
    chg->bat_info.batt_is_full = false;
    chg->set_charge_timeout = false;
    chg->bat_info.batt_improper_ta = false;
    chg->is_recharging = false;
#ifdef CONFIG_BATTERY_MAX17042
    // Get battery type from fuelgauge driver.
    if(chg->pdata && chg->pdata->fuelgauge_cb)
        chg->battery_type = (battery_type_t)chg->pdata->fuelgauge_cb(
                                REQ_TEST_MODE_INTERFACE, TEST_MODE_BATTERY_TYPE_CHECK, 0);

    // Check UV charging case.
    if(chg->pdata && chg->pdata->pmic_charger &&
            chg->pdata->pmic_charger->get_connection_status) {
        if(chg->pdata->pmic_charger->get_connection_status() &&
                check_UV_charging_case(chg))
            chg->low_batt_boot_flag = true;
    }
    else
        chg->low_batt_boot_flag = false;

    // init delayed work
    INIT_DELAYED_WORK(&chg->full_chg_work, full_comp_work_handler);

    // Init low batt check threshold values.
    if(chg->battery_type == SDI_BATTERY_TYPE)
        chg->check_start_vol = 3550;  // Under 3.55V
    else if(chg->battery_type == ATL_BATTERY_TYPE)
        chg->check_start_vol = 3450;  // Under 3.45V
#endif

    chg->cable_status = CABLE_TYPE_NONE;
    chg->charging_status = CHARGING_STATUS_NONE;

    mutex_init(&chg->mutex);

    platform_set_drvdata(pdev, chg);

    wake_lock_init(&chg->vbus_wake_lock, WAKE_LOCK_SUSPEND,
                   "vbus_present");
    wake_lock_init(&chg->work_wake_lock, WAKE_LOCK_SUSPEND,
                   "sec_battery_work");

    INIT_WORK(&chg->bat_work, sec_bat_work);

    chg->monitor_wqueue =
        create_freezeable_workqueue(dev_name(&pdev->dev));
    if (!chg->monitor_wqueue) {
        pr_err("Failed to create freezeable workqueue\n");
        ret = -ENOMEM;
        goto err_wake_lock;
    }

    chg->last_poll = alarm_get_elapsed_realtime();
    alarm_init(&chg->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
               sec_battery_alarm);

    /* init power supplier framework */
    ret = power_supply_register(&pdev->dev, &chg->psy_bat);
    if (ret) {
        pr_err("Failed to register power supply psy_bat\n");
        goto err_wqueue;
    }

    ret = power_supply_register(&pdev->dev, &chg->psy_usb);
    if (ret) {
        pr_err("Failed to register power supply psy_usb\n");
        goto err_supply_unreg_bat;
    }

    ret = power_supply_register(&pdev->dev, &chg->psy_ac);
    if (ret) {
        pr_err("Failed to register power supply psy_ac\n");
        goto err_supply_unreg_usb;
    }

    sec_bat_create_attrs(chg->psy_bat.dev);

    chg->callbacks.set_cable = sec_bat_set_cable;
    chg->callbacks.set_status = sec_bat_set_status;
    chg->callbacks.force_update = sec_bat_force_update;
    if (chg->pdata->register_callbacks)
        chg->pdata->register_callbacks(&chg->callbacks);

    wake_lock(&chg->work_wake_lock);
    queue_work(chg->monitor_wqueue, &chg->bat_work);

    p1_lpm_mode_check(chg);

    return 0;

err_supply_unreg_ac:
    power_supply_unregister(&chg->psy_ac);
err_supply_unreg_usb:
    power_supply_unregister(&chg->psy_usb);
err_supply_unreg_bat:
    power_supply_unregister(&chg->psy_bat);
err_wqueue:
    destroy_workqueue(chg->monitor_wqueue);
    cancel_work_sync(&chg->bat_work);
    alarm_cancel(&chg->alarm);
err_wake_lock:
    wake_lock_destroy(&chg->work_wake_lock);
    wake_lock_destroy(&chg->vbus_wake_lock);
    mutex_destroy(&chg->mutex);
err_bat_table:
    kfree(chg);
    return ret;
}
Пример #29
0
static void ks7010_sdio_remove(struct sdio_func *func)
{
	int ret;
	struct ks_sdio_card *card;
	struct ks_wlan_private *priv;
	struct net_device *netdev;
	DPRINTK(1, "ks7010_sdio_remove()\n");

	card = sdio_get_drvdata(func);

	if (card == NULL)
		return;

	DPRINTK(1, "priv = card->priv\n");
	priv = card->priv;
	netdev = priv->net_dev;
	if (priv) {
		ks_wlan_net_stop(netdev);
		DPRINTK(1, "ks_wlan_net_stop\n");

		/* interrupt disable */
		sdio_claim_host(func);
		sdio_writeb(func, 0, INT_ENABLE, &ret);
		sdio_writeb(func, 0xff, INT_PENDING, &ret);
		sdio_release_host(func);
		DPRINTK(1, "interrupt disable\n");

		/* send stop request to MAC */
		{
			struct hostif_stop_request_t *pp;
			pp = (struct hostif_stop_request_t *)
			    kzalloc(hif_align_size(sizeof(*pp)), GFP_KERNEL);
			if (pp == NULL) {
				DPRINTK(3, "allocate memory failed..\n");
				return;	/* to do goto ni suru */
			}
			pp->header.size =
			    cpu_to_le16((uint16_t)
					(sizeof(*pp) -
					 sizeof(pp->header.size)));
			pp->header.event = cpu_to_le16((uint16_t) HIF_STOP_REQ);

			sdio_claim_host(func);
			write_to_device(priv, (unsigned char *)pp,
					hif_align_size(sizeof(*pp)));
			sdio_release_host(func);
			kfree(pp);
		}
		DPRINTK(1, "STOP Req\n");

		if (priv->ks_wlan_hw.ks7010sdio_wq) {
			flush_workqueue(priv->ks_wlan_hw.ks7010sdio_wq);
			destroy_workqueue(priv->ks_wlan_hw.ks7010sdio_wq);
		}
		DPRINTK(1,
			"destroy_workqueue(priv->ks_wlan_hw.ks7010sdio_wq);\n");

		hostif_exit(priv);
		DPRINTK(1, "hostif_exit\n");

		unregister_netdev(netdev);

		trx_device_exit(priv);
		if (priv->ks_wlan_hw.read_buf) {
			kfree(priv->ks_wlan_hw.read_buf);
		}
		free_netdev(priv->net_dev);
		card->priv = NULL;
	}

	sdio_claim_host(func);
	sdio_release_irq(func);
	DPRINTK(1, "sdio_release_irq()\n");
	sdio_disable_func(func);
	DPRINTK(1, "sdio_disable_func()\n");
	sdio_release_host(func);

	sdio_set_drvdata(func, NULL);

	kfree(card);
	DPRINTK(1, "kfree()\n");

	DPRINTK(5, " Bye !!\n");
	return;
}
Пример #30
0
static int __init mt7697spi_init(void)
{
	char str[32];
	struct spi_master *master = NULL;
	struct device *dev;
	struct spi_device *spi;
	struct mt7697q_info *qinfo = NULL;
	int bus_num = MT7697_SPI_BUS_NUM;
	int ret = 0;

	pr_info(DRVNAME" %s(): '%s' initialize\n", __func__, DRVNAME);

	while (!master && (bus_num >= 0)) {
		master = spi_busnum_to_master(bus_num);
		if (!master)
			bus_num--;
	}

	if (!master) {
		pr_err(DRVNAME" spi_busnum_to_master() failed\n");
		ret = -EINVAL;
		goto cleanup;
	}

	ret = cp2130_update_ch_config(master, MT7697_SPI_CONFIG);
	if (ret < 0) {
		dev_err(&master->dev,
		        "%s(): cp2130_update_ch_config() failed(%d)\n",
		        __func__, ret);
		goto cleanup;
	}

	snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev),
	         MT7697_SPI_CS);
	dev_info(&master->dev, "%s(): find SPI device('%s')\n", __func__, str);
	dev = bus_find_device_by_name(&spi_bus_type, NULL, str);
	if (!dev) {
		dev_err(&master->dev,
		        "%s(): bus_find_device_by_name('%s') failed\n",
		        __func__, str);

		ret = -EINVAL;
		goto cleanup;
	}

	spi = to_spi_device(dev);
	if (!spi) {
		dev_err(&master->dev, "%s(): get SPI device failed\n",
		        __func__);
		ret = -EINVAL;
		goto cleanup;
	}

	dev_info(&master->dev, "%s(): dev('%s') mode(%d) max speed(%d) "
	         "CS(%d) bits/word(%d)\n",
	         __func__, spi->modalias, spi->mode, spi->max_speed_hz,
	         spi->chip_select, spi->bits_per_word);

	qinfo = kzalloc(sizeof(struct mt7697q_info), GFP_KERNEL);
	if (!qinfo) {
		dev_err(&master->dev, "%s(): create queue info failed\n",
		        __func__);
		ret = -ENOMEM;
		goto cleanup;
	}

	qinfo->dev = &spi->dev;

	qinfo->hw_priv = spi;
	qinfo->hw_ops = &hw_ops;

	mutex_init(&qinfo->mutex);
	INIT_DELAYED_WORK(&qinfo->irq_delayed_work, mt7697q_irq_delayed_work);
	INIT_WORK(&qinfo->irq_work, mt7697q_irq_work);

	qinfo->irq_workq = alloc_workqueue(DRVNAME"wq",
	                                   WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1);
	if (!qinfo->irq_workq) {
		dev_err(qinfo->dev, "%s(): alloc_workqueue() failed\n",
		        __func__);
		ret = -ENOMEM;
		goto cleanup;
	}

	qinfo->gpio_pin = MT7697_SPI_INTR_GPIO_PIN;
	ret = gpio_request(qinfo->gpio_pin, MT7697_SPI_GPIO_IRQ_NAME);
	if (ret < 0) {
		if (ret != -EBUSY) {
			dev_err(qinfo->dev, "%s(): gpio_request() failed(%d)",
			        __func__, ret);
			goto failed_workqueue;
		}

		qinfo->irq = gpio_to_irq(qinfo->gpio_pin);
		qinfo->gpio_pin = MT7697_SPI_INTR_GPIO_PIN_INVALID;
	} else {
		gpio_direction_input(qinfo->gpio_pin);
		qinfo->irq = gpio_to_irq(qinfo->gpio_pin);
	}

	dev_info(qinfo->dev, "%s(): request irq(%d)\n", __func__, qinfo->irq);
	ret = request_irq(qinfo->irq, mt7697q_isr, 0, DRVNAME, qinfo);
	if (ret < 0) {
		dev_err(qinfo->dev, "%s(): request_irq() failed(%d)",
		        __func__, ret);
		goto failed_gpio_req;
	}

	irq_set_irq_type(qinfo->irq, IRQ_TYPE_EDGE_BOTH);

	spi_set_drvdata(spi, qinfo);

	dev_info(qinfo->dev, "%s(): '%s' initialized\n", __func__, DRVNAME);
	return 0;

failed_gpio_req:
	if (qinfo->gpio_pin > 0) gpio_free(qinfo->gpio_pin);

failed_workqueue:
	destroy_workqueue(qinfo->irq_workq);

cleanup:
	if (qinfo) kfree(qinfo);
	return ret;
}