/* 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; }
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; }
/** * 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); }
/* 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; }
/* 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; }
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; }