/* disp_pm_add_refcount - it is called in the early start of the
 * update_reg_handler */
int disp_pm_add_refcount(struct display_driver *dispdrv)
{
	unsigned long flags;

	if (dispdrv->platform_status == DISP_STATUS_PM0) return 0;

	if (!dispdrv->pm_status.clock_gating_on) return 0;

	if (dispdrv->decon_driver.sfb->power_state == POWER_DOWN)
		return 0;

	init_gating_idle_count(dispdrv);

	flush_kthread_worker(&dispdrv->pm_status.control_clock_gating);
	flush_kthread_worker(&dispdrv->pm_status.control_power_gating);
	if (dispdrv->decon_driver.sfb->power_state == POWER_HIBER_DOWN)
		display_hibernation_power_on(dispdrv);

	display_block_clock_on(dispdrv);

	spin_lock_irqsave(&dispdrv->pm_status.slock, flags);
	if (dispdrv->pm_status.trigger_masked) {
		disable_mask(dispdrv);
	}
	spin_unlock_irqrestore(&dispdrv->pm_status.slock, flags);
	return 0;
}
/* disp_pm_sched_power_on - it is called in the early start of the
 * fb_ioctl to exit HDM */
int disp_pm_sched_power_on(struct display_driver *dispdrv, unsigned int cmd)
{
	struct s3c_fb *sfb = dispdrv->decon_driver.sfb;

	init_gating_idle_count(dispdrv);

	if (dispdrv->platform_status < DISP_STATUS_PM1) {
		if (cmd == S3CFB_WIN_CONFIG)
			disp_pm_init_status(dispdrv);
	}

	flush_kthread_worker(&dispdrv->pm_status.control_power_gating);
	if (sfb->power_state == POWER_HIBER_DOWN) {
		switch (cmd) {
		case S3CFB_WIN_PSR_EXIT:
		case S3CFB_WIN_CONFIG:
			queue_kthread_work(&dispdrv->pm_status.control_power_gating,
				&dispdrv->pm_status.control_power_gating_work);
			break;
		default:
			return -EBUSY;
		}
	}

	return 0;
}
int disp_pm_runtime_get_sync(struct display_driver *dispdrv)
{
	if (!dispdrv->pm_status.clock_gating_on) {
		pm_runtime_get_sync(dispdrv->display_driver);
		return 0;
	}

	init_gating_idle_count(dispdrv);

	/* guarantee clock and power gating */
	flush_kthread_worker(&dispdrv->pm_status.control_clock_gating);
	flush_kthread_worker(&dispdrv->pm_status.control_power_gating);
	pm_runtime_get_sync(dispdrv->display_driver);
	display_block_clock_on(dispdrv);

	return 0;
}
int disp_pm_runtime_put_sync(struct display_driver *dispdrv)
{
	if (!dispdrv->pm_status.clock_gating_on) {
		pm_runtime_put_sync(dispdrv->display_driver);
		return 0;
	}

	flush_kthread_worker(&dispdrv->pm_status.control_clock_gating);
	pm_runtime_put_sync(dispdrv->display_driver);
	return 0;
}
Ejemplo n.º 5
0
static int __devexit bq2419x_remove(struct i2c_client *client)
{
	struct bq2419x_chip *bq2419x = i2c_get_clientdata(client);

	free_irq(bq2419x->irq, bq2419x);
	bq2419x->stop_thread = true;
	flush_kthread_worker(&bq2419x->bq_kworker);
	kthread_stop(bq2419x->bq_kworker_task);
	regulator_unregister(bq2419x->vbus_rdev);
	regulator_unregister(bq2419x->chg_rdev);
	mutex_destroy(&bq2419x->mutex);
	return 0;
}
Ejemplo n.º 6
0
Archivo: cq.c Proyecto: AK101111/linux
/**
 * rvt_cq_exit - tear down cq reources
 * @rdi: rvt dev structure
 */
void rvt_cq_exit(struct rvt_dev_info *rdi)
{
	struct kthread_worker *worker;

	worker = rdi->worker;
	if (!worker)
		return;
	/* blocks future queuing from send_complete() */
	rdi->worker = NULL;
	smp_wmb(); /* See rdi_cq_enter */
	flush_kthread_worker(worker);
	kthread_stop(worker->task);
	kfree(worker);
}
Ejemplo n.º 7
0
/* disp_pm_sched_power_on - it is called in the early start of the
 * fb_ioctl to exit HDM */
int disp_pm_sched_power_on(struct display_driver *dispdrv, unsigned int cmd)
{
	struct s3c_fb *sfb = dispdrv->decon_driver.sfb;

	init_gating_idle_count(dispdrv);

	/* First WIN_CONFIG should be on clock and power-gating */
	if (dispdrv->platform_status < DISP_STATUS_PM1) {
		if (cmd == S3CFB_WIN_CONFIG)
			disp_pm_set_plat_status(dispdrv, true);
	}

	flush_kthread_worker(&dispdrv->pm_status.control_power_gating);
	if (sfb->power_state == POWER_HIBER_DOWN) {
		switch (cmd) {
		case S3CFB_PLATFORM_RESET:
			disp_pm_gate_lock(dispdrv, true);
			queue_kthread_work(&dispdrv->pm_status.control_power_gating,
				&dispdrv->pm_status.control_power_gating_work);
			/* Prevent next clock and power-gating */
			disp_pm_set_plat_status(dispdrv, false);
			break;
		case S3CFB_WIN_PSR_EXIT:
		case S3CFB_WIN_CONFIG:
		case S3CFB_SET_VSYNC_INT:
			request_dynamic_hotplug(false);
			disp_pm_gate_lock(dispdrv, true);
			queue_kthread_work(&dispdrv->pm_status.control_power_gating,
				&dispdrv->pm_status.control_power_gating_work);
			break;
		default:
			return -EBUSY;
		}
	} else {
		switch (cmd) {
		case S3CFB_PLATFORM_RESET:
			/* Prevent next clock and power-gating */
			disp_pm_set_plat_status(dispdrv, false);
			break;
		}
	}

	return 0;
}
static int __devexit bq2419x_remove(struct i2c_client *client)
{
	struct bq2419x_chip *bq2419x = i2c_get_clientdata(client);

	free_irq(bq2419x->irq, bq2419x);
	bq2419x->stop_thread = true;
	flush_kthread_worker(&bq2419x->bq_kworker);
	kthread_stop(bq2419x->bq_kworker_task);
	regulator_unregister(bq2419x->vbus_rdev);
	if (bq2419x->use_usb)
		power_supply_unregister(&bq2419x->usb);
	if (bq2419x->use_mains)
		power_supply_unregister(&bq2419x->ac);
	regulator_unregister(bq2419x->chg_rdev);
	mutex_destroy(&bq2419x->mutex);
	mutex_destroy(&bq2419x->otg_mutex);
	cancel_delayed_work_sync(&bq2419x->otg_reset_work);
	return 0;
}
/**
 * adf_interface_set_mode - set interface's display mode
 *
 * @intf: the interface
 * @mode: the new mode
 *
 * Returns 0 on success or -errno on failure.
 */
int adf_interface_set_mode(struct adf_interface *intf,
		struct drm_mode_modeinfo *mode)
{
	struct adf_device *dev = adf_interface_parent(intf);
	int ret = 0;

	if (!intf->ops || !intf->ops->modeset)
		return -EOPNOTSUPP;

	mutex_lock(&dev->client_lock);
	flush_kthread_worker(&dev->post_worker);

	ret = intf->ops->modeset(intf, mode);
	if (ret < 0)
		goto done;

	memcpy(&intf->current_mode, mode, sizeof(*mode));
done:
	mutex_unlock(&dev->client_lock);
	return ret;
}
Ejemplo n.º 10
0
/* disp_pm_add_refcount - it is called in the early start of the
 * update_reg_handler */
int disp_pm_add_refcount(struct display_driver *dispdrv)
{
	if (dispdrv->platform_status == DISP_STATUS_PM0) return 0;

	if (!dispdrv->pm_status.clock_gating_on) return 0;

	if (dispdrv->decon_driver.sfb->power_state == POWER_DOWN)
		return 0;

	init_gating_idle_count(dispdrv);

	flush_kthread_worker(&dispdrv->pm_status.control_power_gating);
	if (dispdrv->decon_driver.sfb->power_state == POWER_HIBER_DOWN) {
		request_dynamic_hotplug(false);
		display_hibernation_power_on(dispdrv);
	}

	display_block_clock_on(dispdrv);

	return 0;
}
/**
 * adf_interface_blank - set interface's DPMS state
 *
 * @intf: the interface
 * @state: one of %DRM_MODE_DPMS_*
 *
 * Returns 0 on success or -errno on failure.
 */
int adf_interface_blank(struct adf_interface *intf, u8 state)
{
	struct adf_device *dev = adf_interface_parent(intf);
	u8 prev_state;
	bool disable_vsync;
	bool enable_vsync;
	int ret = 0;
	struct adf_event_refcount *vsync_refcount;

	if (!intf->ops || !intf->ops->blank)
		return -EOPNOTSUPP;

	if (state > DRM_MODE_DPMS_OFF)
		return -EINVAL;

	mutex_lock(&dev->client_lock);
	if (state != DRM_MODE_DPMS_ON)
		flush_kthread_worker(&dev->post_worker);
	mutex_lock(&intf->base.event_lock);

	vsync_refcount = adf_obj_find_event_refcount(&intf->base,
			ADF_EVENT_VSYNC);
	if (!vsync_refcount) {
		ret = -ENOMEM;
		goto done;
	}

	prev_state = intf->dpms_state;
	if (prev_state == state) {
		ret = -EBUSY;
		goto done;
	}

	disable_vsync = vsync_active(prev_state) &&
			!vsync_active(state) &&
			vsync_refcount->refcount;
	enable_vsync = !vsync_active(prev_state) &&
			vsync_active(state) &&
			vsync_refcount->refcount;

	if (disable_vsync)
		intf->base.ops->set_event(&intf->base, ADF_EVENT_VSYNC,
				false);

	ret = intf->ops->blank(intf, state);
	if (ret < 0) {
		if (disable_vsync)
			intf->base.ops->set_event(&intf->base, ADF_EVENT_VSYNC,
					true);
		goto done;
	}

	if (enable_vsync)
		intf->base.ops->set_event(&intf->base, ADF_EVENT_VSYNC,
				true);

	intf->dpms_state = state;
done:
	mutex_unlock(&intf->base.event_lock);
	mutex_unlock(&dev->client_lock);
	return ret;
}
Ejemplo n.º 12
0
static int __devinit bq2419x_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	struct bq2419x_chip *bq2419x;
	struct bq2419x_platform_data *pdata;
	int ret = 0;

	pdata = client->dev.platform_data;
	if (!pdata) {
		dev_err(&client->dev, "No Platform data");
		return -EINVAL;
	}

	bq2419x = devm_kzalloc(&client->dev, sizeof(*bq2419x), GFP_KERNEL);
	if (!bq2419x) {
		dev_err(&client->dev, "Memory allocation failed\n");
		return -ENOMEM;
	}

	bq2419x->regmap = devm_regmap_init_i2c(client, &bq2419x_regmap_config);
	if (IS_ERR(bq2419x->regmap)) {
		ret = PTR_ERR(bq2419x->regmap);
		dev_err(&client->dev, "regmap init failed with err %d\n", ret);
		return ret;
	}

	bq2419x->dev = &client->dev;

	if (pdata->bcharger_pdata) {
		bq2419x->update_status	= pdata->bcharger_pdata->update_status;
		bq2419x->rtc_alarm_time	= pdata->bcharger_pdata->rtc_alarm_time;
		bq2419x->wdt_time_sec	= pdata->bcharger_pdata->wdt_timeout;
		bq2419x->chg_restart_time =
					pdata->bcharger_pdata->chg_restart_time;
		bq2419x->chg_enable	= true;
	}

	bq2419x->wdt_refresh_timeout = 25;
	i2c_set_clientdata(client, bq2419x);
	bq2419x->irq = client->irq;

	if (bq2419x->rtc_alarm_time)
		bq2419x->rtc = alarmtimer_get_rtcdev();

	mutex_init(&bq2419x->mutex);
	bq2419x->suspended = 0;
	bq2419x->chg_restart_timeout = 0;

	ret = bq2419x_show_chip_version(bq2419x);
	if (ret < 0) {
		dev_err(&client->dev, "version read failed %d\n", ret);
		return ret;
	}

	ret = bq2419x_charger_init(bq2419x);
	if (ret < 0) {
		dev_err(bq2419x->dev, "Charger init failed: %d\n", ret);
		return ret;
	}

	ret = bq2419x_init_charger_regulator(bq2419x, pdata);
	if (ret < 0) {
		dev_err(&client->dev,
			"Charger regualtor init failed %d\n", ret);
		return ret;
	}

	ret = bq2419x_init_vbus_regulator(bq2419x, pdata);
	if (ret < 0) {
		dev_err(&client->dev,
			"VBUS regualtor init failed %d\n", ret);
		goto scrub_chg_reg;
	}

	init_kthread_worker(&bq2419x->bq_kworker);
	bq2419x->bq_kworker_task = kthread_run(kthread_worker_fn,
				&bq2419x->bq_kworker,
				dev_name(bq2419x->dev));
	if (IS_ERR(bq2419x->bq_kworker_task)) {
		ret = PTR_ERR(bq2419x->bq_kworker_task);
		dev_err(&client->dev, "Kworker task creation failed %d\n", ret);
		goto scrub_vbus_reg;
	}

	init_kthread_work(&bq2419x->bq_wdt_work, bq2419x_work_thread);
	sched_setscheduler(bq2419x->bq_kworker_task,
			SCHED_FIFO, &bq2419x_param);
	queue_kthread_work(&bq2419x->bq_kworker, &bq2419x->bq_wdt_work);

	ret = bq2419x_watchdog_init(bq2419x, bq2419x->wdt_time_sec, "PROBE");
	if (ret < 0) {
		dev_err(bq2419x->dev, "BQWDT init failed %d\n", ret);
		goto scrub_kthread;
	}

	ret = bq2419x_fault_clear_sts(bq2419x);
	if (ret < 0) {
		dev_err(bq2419x->dev, "fault clear status failed %d\n", ret);
		goto scrub_kthread;
	}

	ret = request_threaded_irq(bq2419x->irq, NULL,
		bq2419x_irq, IRQF_TRIGGER_FALLING,
			dev_name(bq2419x->dev), bq2419x);
	if (ret < 0) {
		dev_err(bq2419x->dev, "request IRQ %d fail, err = %d\n",
				bq2419x->irq, ret);
		goto scrub_kthread;
	}

	/* enable charging */
	ret = bq2419x_charger_enable(bq2419x);
	if (ret < 0)
		goto scrub_irq;

	return 0;
scrub_irq:
	free_irq(bq2419x->irq, bq2419x);
scrub_kthread:
	bq2419x->stop_thread = true;
	flush_kthread_worker(&bq2419x->bq_kworker);
	kthread_stop(bq2419x->bq_kworker_task);
scrub_vbus_reg:
	regulator_unregister(bq2419x->vbus_rdev);
scrub_chg_reg:
	regulator_unregister(bq2419x->chg_rdev);
	mutex_destroy(&bq2419x->mutex);
	return ret;
}