static void vibrator_enable(struct timed_output_dev *dev, int value) { unsigned long flags; spin_lock_irqsave(&vibe_lock, flags); hrtimer_cancel(&vibe_timer); if (value == 0){ timed_vibrator_off(dev); } else { value = (value > 15000 ? 15000 : value); value = (value < 20) ? 20 : value; timed_vibrator_on(dev); hrtimer_start(&vibe_timer, ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL); } spin_unlock_irqrestore(&vibe_lock, flags); }
static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) { hrtimer_init_sleeper(t, current); do { set_current_state(TASK_INTERRUPTIBLE); hrtimer_start_expires(&t->timer, mode); if (!hrtimer_active(&t->timer)) t->task = NULL; if (likely(t->task)) schedule(); hrtimer_cancel(&t->timer); mode = HRTIMER_MODE_ABS; } while (t->task && !signal_pending(current)); __set_current_state(TASK_RUNNING); return t->task == NULL; }
static void vibrator_enable(struct timed_output_dev *dev, int value) { time_value = value;//save this value as vibratting time hrtimer_cancel(&vibe_timer); if (value == 0) { mdelay(VIBRATOR_DELAY); //timed_vibrator_off(dev); pmic_vibrator_off(NULL); } else { value = (value > 15000 ? 15000 : value); value = (value < VIBRATOR_MIN ? VIBRATOR_MIN : value); //timed_vibrator_on(dev); pmic_vibrator_on(NULL);//use this function instead of timed_vibrator_on. hrtimer_start(&vibe_timer, ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL); } }
static int android_vibrator_force_set(struct timed_vibrator_data *vib, int intensity, int pwm) { struct android_vibrator_platform_data *pdata = vib->pdata; int vib_duration_ms = 0; pr_debug("%s: intensity : %d\n", __func__, intensity); if (pdata->vibe_warmup_delay > 0) { if (atomic_read(&vib->vib_status)) msleep(pdata->vibe_warmup_delay); } /* TODO: control the gain of vibrator */ if (intensity == 0) { pdata->ic_enable_set(0); pdata->pwm_set(0, 0, pwm); /* should be checked for vibrator response time */ pdata->power_set(0); atomic_set(&vib->vib_status, 0); } else { if (work_pending(&vib->work_vibrator_off)) cancel_work_sync(&vib->work_vibrator_off); hrtimer_cancel(&vib->timer); vib_duration_ms = atomic_read(&vib->ms_time); /* should be checked for vibrator response time */ pdata->power_set(1); pdata->pwm_set(1, intensity, pwm); pdata->ic_enable_set(1); atomic_set(&vib->vib_status, 1); hrtimer_start(&vib->timer, ns_to_ktime((u64)vib_duration_ms * NSEC_PER_MSEC), HRTIMER_MODE_REL); } return 0; }
static ssize_t bd2802_store_led_sync(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev)); int value; if (!count) return -EINVAL; value = simple_strtoul(buf, NULL, 10); if(led->led_state == BD2802_TEST_ON) return -EBUSY; if(led->led_state == BD2802_SEQ) return -EBUSY; if(value == 1) { if(led->led_state != BD2802_SYNC) { hrtimer_cancel(&led->ledmin_timer); flush_workqueue(led->ledmin_wq); led->blue_current = BD2802_CURRENT_000; bd2802_turn_white(led, HIDDEN1); bd2802_turn_white(led, HIDDEN2); led->led_state = BD2802_SYNC; } } else if(value == 0) { if(led->led_state == BD2802_SYNC) { led->white_current = max_current; led->blue_current = BD2802_CURRENT_000; bd2802_on(led); led->led_state = BD2802_ON; hrtimer_start(&led->ledmin_timer, ktime_set(0, led_timer*1000000), HRTIMER_MODE_REL); } } else { return -EINVAL; } return count; }
static void enable_vibetonz_from_user(struct timed_output_dev *dev, int value) { //printk(KERN_DEBUG "tspdrv: Enable time = %d msec\n", value); hrtimer_cancel(&timer); /* set_vibetonz(value); */ #ifdef CONFIG_TACTILE_ASSIST g_bOutputDataBufferEmpty = 0; #endif vibrator_work = value; schedule_work(&vibetonz_work); if (value > 0 && (value != TEST_MODE_TIME)) { if (value > max_timeout) value = max_timeout; hrtimer_start(&timer, ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL); vibrator_value = 0; } }
static int ev3_output_port_set_mode(void *context, u8 mode) { struct ev3_output_port_data *data = context; hrtimer_cancel(&data->timer); cancel_work_sync(&data->work); if (data->motor) ev3_output_port_unregister_motor(&data->work); if (data->out_port.mode == EV3_OUTPUT_PORT_MODE_RAW) ev3_output_port_disable_raw_mode(data); switch (mode) { case EV3_OUTPUT_PORT_MODE_AUTO: data->con_state = CON_STATE_INIT; hrtimer_start(&data->timer, ktime_set(0, OUTPUT_PORT_POLL_NS), HRTIMER_MODE_REL); break; case EV3_OUTPUT_PORT_MODE_TACHO_MOTOR: data->motor_type = MOTOR_TACHO; data->motor_id = LEGO_EV3_LARGE_MOTOR; ev3_output_port_register_motor(&data->work); break; case EV3_OUTPUT_PORT_MODE_DC_MOTOR: data->motor_type = MOTOR_DC; ev3_output_port_register_motor(&data->work); break; case EV3_OUTPUT_PORT_MODE_LED: data->motor_type = MOTOR_LED; ev3_output_port_register_motor(&data->work); break; case EV3_OUTPUT_PORT_MODE_RAW: ev3_output_port_enable_raw_mode(data); break; default: WARN_ON("Unknown mode."); break; } return 0; }
static void vibrator_enable(struct timed_output_dev *dev, int value) { struct pwm_vib_data *data = container_of(dev, struct pwm_vib_data, dev); unsigned long flags; spin_lock_irqsave(&data->vibe_lock, flags); hrtimer_cancel(&data->vibe_timer); if (value == 0) data->vibe_state = 0; else { data->vibe_state = 1; if( value != 3600000 ) value = (value > 15000 ? 15000 : value); hrtimer_start(&data->vibe_timer, ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL); } spin_unlock_irqrestore(&data->vibe_lock, flags); schedule_work(&data->vibrator_work); }
static int hub_proxi_suspend(struct i2c_client *client, pm_message_t mesg) { struct hub_proxi_data *data = i2c_get_clientdata(client); if (!enabled) return 0; /* LGE_CHANGE_S, [email protected], 2011-04-06, Disable Proximity Log */ //printk("%s\n", __FUNCTION__); /* LGE_CHANGE_E, [email protected], 2011-04-06, Disable Proximity Log */ if (atomic_read(&proxi_status)) return 0; #if 0 if (hrtimer_try_to_cancel(&data->timer) > 0) //timer is active hrtimer_cancel(&data->timer); #endif if (data->wakeup_while_sleep) { printk("%s() wakeup_while_sleep.\n", __FUNCTION__); // enable_irq(client->irq); } else hub_proxi_disable(client); return 0; }
static irqreturn_t hall_device_irq_n(int irq, void *handle) { struct hall_device_chip *chip = handle; //SENSOR_LOG_INFO("enter\n"); hall_device_irq_enable(&(chip->irq_n), false, false); chip->on_irq_working = true; hrtimer_cancel(&chip->unlock_wakelock_timer); if (true == chip->enabled) { hall_device_wakelock_ops(&(chip->wakeup_wakelock),true); } if (0==schedule_work(&chip->irq_work_n)) { SENSOR_LOG_INFO("schedule_work failed!\n"); } //SENSOR_LOG_INFO("exit\n"); return IRQ_HANDLED; }
static ssize_t cpu_ss_period_mode_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { char mode[20]; ktime_t ktime = ktime_set(mt_cpu_ss_period_s, mt_cpu_ss_period_ns); char *buf = _copy_from_user_for_proc(buffer, count); if (!buf) return -EINVAL; if (sscanf(buf, "%s", mode) == 1) { if (!strcmp(mode, "enable")) { printk(KERN_DEBUG "[%s]: %s cpu speed switch period mode\n", mode, __func__); mt_cpu_ss_period_mode = true; mt_cpu_ss_thread = kthread_run(mt_cpu_ss_thread_handler, 0, "cpu speed switch"); if (IS_ERR(mt_cpu_ss_thread)) printk("[%s]: failed to create cpu speed switch thread\n", __func__); hrtimer_start(&mt_cpu_ss_timer, ktime, HRTIMER_MODE_REL); } else if (!strcmp(mode, "disable")) { printk(KERN_DEBUG "[%s]: %s cpu speed switch period mode\n", mode, __func__); mt_cpu_ss_period_mode = false; kthread_stop(mt_cpu_ss_thread); mt_cpufreq_clock_switch(0, TOP_CKMUXSEL_ARMPLL); hrtimer_cancel(&mt_cpu_ss_timer); } else printk(KERN_ERR "[%s]: bad argument!! should be \"enable\" or \"disable\"\n", __func__); } else printk(KERN_ERR "[%s]: bad argument!! should be \"enable\" or \"disable\"\n", __func__); free_page((unsigned long)buf); return count; }
void set_mt65xx_mon_mode(MonitorMode mode) { ktime_t kt; printk("set_mt65xx_mon_mode (mode = %d)\n", (int) mode); mutex_lock(&mt65xx_mon_mutex); if((mode != MODE_SCHED_SWITCH) && (mode != MODE_PERIODIC) && (mode != MODE_MANUAL_TRACER)) return; monitor_mode = mode; if((monitor_mode == MODE_PERIODIC)) { if(timer_initialized == 0) { hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); timer.function = timer_isr; kt = ktime_set(0, mon_period_ns); hrtimer_start(&timer, kt, HRTIMER_MODE_REL); timer_initialized++; } else { hrtimer_restart(&timer); } } else if((monitor_mode == MODE_SCHED_SWITCH) || (monitor_mode == MODE_MANUAL_TRACER)) { if(timer_initialized > 0) hrtimer_cancel(&timer); } mutex_unlock(&mt65xx_mon_mutex); }
static void vibrator_enable(struct timed_output_dev *dev, int value) { struct i2c_client *client = this_client; struct drv2605_data *pDrv2605data = i2c_get_clientdata(client); //struct Haptics *pvibdata = container_of(dev, struct Haptics, to_dev); char mode; mutex_lock(&vibdata.lock); hrtimer_cancel(&vibdata.timer); cancel_work_sync(&vibdata.work); if (value) { wake_lock(&vibdata.wklock); mode = drv260x_read_reg(client, MODE_REG) & DRV260X_MODE_MASK; /* Only change the mode if not already in RTP mode; RTP input already set at init */ if (mode != MODE_REAL_TIME_PLAYBACK) { if (pDrv2605data->audio_haptics_enabled && mode == MODE_AUDIOHAPTIC) setAudioHapticsEnabled(client, NO); drv260x_set_rtp_val(client, REAL_TIME_PLAYBACK_STRENGTH); drv260x_change_mode(client, MODE_REAL_TIME_PLAYBACK); pDrv2605data->vibrator_is_playing = YES; switch_set_state(&pDrv2605data->sw_dev, SW_STATE_RTP_PLAYBACK); } if (value > 0) { if (value > MAX_TIMEOUT) value = MAX_TIMEOUT; hrtimer_start(&vibdata.timer, ns_to_ktime((u64)value * NSEC_PER_MSEC), HRTIMER_MODE_REL); } } else vibrator_off(client); mutex_unlock(&vibdata.lock); }
static void dc_motor_enable(struct timed_output_dev *_dev, int value) { struct dc_motor_drvdata *data = container_of(_dev, struct dc_motor_drvdata, dev); unsigned long flags; printk(KERN_DEBUG "[VIB] time = %dms\n", value); cancel_work_sync(&data->work); hrtimer_cancel(&data->timer); data->timeout = value; schedule_work(&data->work); spin_lock_irqsave(&data->lock, flags); if (value > 0) { if (value > data->max_timeout) value = data->max_timeout; hrtimer_start(&data->timer, ns_to_ktime((u64)value * NSEC_PER_MSEC), HRTIMER_MODE_REL); } spin_unlock_irqrestore(&data->lock, flags); }
static void enable_vibetonz_from_user(struct timed_output_dev *dev,int value) { printk("[VIBETONZ] %s : time = %d msec \n",__func__,value); hrtimer_cancel(&timer); set_vibetonz(value); vibrator_value = value; if (value > 0) { if (value > max_timeout) value = max_timeout; hrtimer_start(&timer, ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL); vibrator_value = 0; } }
static int al3320_set_mode(struct i2c_client *client, int mode) { struct al3320_data *data = i2c_get_clientdata(client); if (mode != al3320_get_mode(client)) { __al3320_write_reg(client, AL3320_MODE_COMMAND, AL3320_MODE_MASK, AL3320_MODE_SHIFT, mode); if (als_polling) { /* Enable/Disable ALS */ if (ALS_ACTIVE & mode) hrtimer_start(&data->light_timer, data->light_poll_delay, HRTIMER_MODE_REL); else { hrtimer_cancel(&data->light_timer); cancel_work_sync(&data->work_light); } } } return 0; }
tEplKernel PUBLIC EplTimerHighReskDelInstance(void) { tEplTimerHighReskTimerInfo *pTimerInfo; tEplKernel Ret; unsigned int uiIndex; Ret = kEplSuccessful; for (uiIndex = 0; uiIndex < TIMER_COUNT; uiIndex++) { pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[0]; pTimerInfo->m_pfnCallback = NULL; pTimerInfo->m_EventArg.m_TimerHdl = 0; /* * In this case we can not just try to cancel the timer. * We actually have to wait until its callback function * has returned. */ hrtimer_cancel(&pTimerInfo->m_Timer); } return Ret; }
static void ldo_vibrator_vib_enable(struct timed_output_dev *dev, int value) { struct ldo_vibrator_data *data = container_of(dev, struct ldo_vibrator_data, timed_dev); mutex_lock(&data->lock); hrtimer_cancel(&data->vib_timer); dev_dbg(data->dev, "%s: timer value(%d)\n", __func__, value); if (value == 0) { data->state = LDO_VIBRATOR_OFF; } else { data->state = LDO_VIBRATOR_ON; hrtimer_start(&data->vib_timer, ktime_set(value / MSEC_PER_SEC, (value % MSEC_PER_SEC) * NSEC_PER_MSEC), HRTIMER_MODE_REL); } mutex_unlock(&data->lock); schedule_work(&data->work); }
static void msm_idle_stats_pre_idle(struct msm_idle_stats_device *stats_dev) { int64_t now; int64_t interval; if (smp_processor_id() != stats_dev->cpu) { WARN_ON(1); return; } if (!atomic_read(&stats_dev->collecting)) return; hrtimer_cancel(&stats_dev->timer); now = ktime_to_us(ktime_get()); interval = now - stats_dev->stats.last_busy_start; interval = msm_idle_stats_bound_interval(interval); stats_dev->stats.busy_intervals[stats_dev->stats.nr_collected] = (__u32) interval; stats_dev->stats.last_idle_start = now; }
//停用设备 static int goodix_ts_suspend(struct i2c_client *client, pm_message_t mesg) { int ret; struct goodix_ts_data *ts = i2c_get_clientdata(client); struct goodix_i2c_rmi_platform_data *pdata = client->dev.platform_data; if (ts->use_irq) disable_irq(client->irq); else hrtimer_cancel(&ts->timer); ret = cancel_work_sync(&ts->work); //if (ret && ts->use_irq) // enable_irq(client->irq); //TODO:工作队列禁用失败,则停止发送触摸屏中断 if (ts->power) { ret = ts->power(0); if (ret < 0) printk(KERN_ERR "goodix_ts_resume power off failed\n"); }else if(pdata->gpio_shutdown){ gpio_direction_output(pdata->gpio_shutdown, 1); } return 0; }
static void enable_vibetonz_from_user(struct timed_output_dev *dev,int value) { unsigned long flags; //printk("[VIBETONZ] %s : time = %d msec \n",__func__,value); hrtimer_cancel(&timer); spin_lock_irqsave(&vib_lock, flags); value = set_vibetonz(value); /* 2009.09.13(sunday) drkim - adjust vibratonz strength */ vibrator_value = value; spin_unlock_irqrestore(&vib_lock, flags); if (value > 0) { if (value > max_timeout) value = max_timeout; hrtimer_start(&timer, ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL); vibrator_value = 0; } }
static void do_msleep(unsigned int msecs, struct hrtimer_sleeper *sleeper, int sigs) { enum hrtimer_mode mode = HRTIMER_MODE_REL; int state = sigs ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; /* * This is really just a reworked and simplified version * of do_nanosleep(). */ hrtimer_init(&sleeper->timer, CLOCK_MONOTONIC, mode); sleeper->timer._expires = ktime_set(0, msecs*NSEC_PER_MSEC); hrtimer_init_sleeper(sleeper, current); do { set_current_state(state); hrtimer_start(&sleeper->timer, sleeper->timer._expires, mode); if (sleeper->task) schedule(); hrtimer_cancel(&sleeper->timer); mode = HRTIMER_MODE_ABS; } while (sleeper->task && !(sigs && signal_pending(current))); }
static int __devexit ncp373_remove(struct platform_device *pdev) { struct ncp373_internal *dev = pncp373_internal; pncp373_internal = NULL; if (likely(dev)) { atomic_set(&dev->oc_det_state, OC_DET_STOP); hrtimer_cancel(&dev->timer); atomic_set(&dev->timeout, 1); ncp373_debugfs_cleanup(dev); ncp373_mode_disable(); mutex_lock(&dev->mutex); if (dev->pdata && dev->pdata->remove) dev->pdata->remove(); mutex_unlock(&dev->mutex); mutex_destroy(&dev->mutex); kfree(dev); } return 0; }
static int k3g_remove(struct i2c_client *client) { int err = 0; struct k3g_data *k3g_data = i2c_get_clientdata(client); device_remove_file(&k3g_data->input_dev->dev, &dev_attr_enable); device_remove_file(&k3g_data->input_dev->dev, &dev_attr_poll_delay); device_remove_file(&k3g_data->input_dev->dev, &dev_attr_gyro_data); device_remove_file(&k3g_data->input_dev->dev, &dev_attr_gyro_cnt); #ifdef SELF_TEST_ENABLED device_remove_file(&k3g_data->input_dev->dev, &dev_attr_self_test); #endif #ifdef FILE_OPS misc_deregister(&k3g_misc_device); #endif if (k3g_data->enable) err = i2c_smbus_write_byte_data(k3g_data->client, CTRL_REG1, 0x00); if (k3g_data->interruptible) { if (!k3g_data->enable) /* no disable_irq before free_irq */ enable_irq(k3g_data->client->irq); free_irq(k3g_data->client->irq, k3g_data); } else { hrtimer_cancel(&k3g_data->timer); cancel_work_sync(&k3g_data->work); destroy_workqueue(k3g_data->k3g_wq); } input_unregister_device(k3g_data->input_dev); mutex_destroy(&k3g_data->lock); kfree(k3g_data); return err; }
static void vibrator_enable(struct timed_output_dev *dev, int value) { unsigned long flags; #if 1 struct vibrator_hw* hw = get_cust_vibrator_hw(); #endif printk("[vibrator]vibrator_enable: vibrator first in value = %d\n", value); spin_lock_irqsave(&vibe_lock, flags); while(hrtimer_cancel(&vibe_timer)) { printk("[vibrator]vibrator_enable: try to cancel hrtimer \n"); } if (value == 0) vibe_state = 0; else { #if 1 printk("[vibrator]vibrator_enable: vibrator cust timer: %d \n", hw->vib_timer); if(value > 10 && value < hw->vib_timer) value = hw->vib_timer; #endif value = (value > 15000 ? 15000 : value); vibe_state = 1; hrtimer_start(&vibe_timer, ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL); } spin_unlock_irqrestore(&vibe_lock, flags); printk("[vibrator]vibrator_enable: vibrator start: %d \n", value); queue_work(vibrator_queue, &vibrator_work); }
/* * The pm8058_nc_ir detects insert / remove of the headset (for NO), * The current state of the headset is maintained in othc_ir_state variable. * Due to a hardware bug, false switch interrupts are seen during headset * insert. This is handled in the software by rejecting the switch interrupts * for a small period of time after the headset has been inserted. */ static irqreturn_t pm8058_nc_ir(int irq, void *dev_id) { #if 0 unsigned long flags, rc; struct pm8058_othc *dd = dev_id; spin_lock_irqsave(&dd->lock, flags); /* Enable the switch reject flag */ dd->switch_reject = true; spin_unlock_irqrestore(&dd->lock, flags); /* Start the HR timer if one is not active */ if (hrtimer_active(&dd->timer)) hrtimer_cancel(&dd->timer); hrtimer_start(&dd->timer, ktime_set((dd->switch_debounce_ms / 1000), (dd->switch_debounce_ms % 1000) * 1000000), HRTIMER_MODE_REL); /* disable irq, this gets enabled in the workqueue */ disable_irq_nosync(dd->othc_irq_ir); /* Check the MIC_BIAS status, to check if inserted or removed */ rc = pm8058_irq_get_rt_status(dd->pm_chip, dd->othc_irq_ir); if (rc < 0) { pr_err("Unable to read IR status\n"); goto fail_ir; } dd->othc_ir_state = rc; schedule_delayed_work(&dd->detect_work, msecs_to_jiffies(dd->detection_delay_ms)); fail_ir: #endif return IRQ_HANDLED; }
static void k3_vibrator_enable(struct timed_output_dev *dev, int value) { struct k3_vibrator_data *pdata = container_of(dev, struct k3_vibrator_data, dev); #ifdef CONFIG_ANDROID_K3_VIBRATOR_AUTO_CONTROL static int set_count; #endif printk("k3_vibrator_enable,value=%d\n",value); if (value < 0) { pr_err("error:vibrator_enable value:%d is negative\n", value); return; } /* cancel previous timer */ if (hrtimer_active(&pdata->timer)) hrtimer_cancel(&pdata->timer); if (value > 0) { #ifdef CONFIG_ANDROID_K3_VIBRATOR_AUTO_CONTROL if (time_after(jiffies, g_pre_set_time+60*HZ)) { g_pre_set_time = jiffies; set_count = 0; } if (set_count == 0) pdata->battery_power = k3_vibrator_get_iset_value(0); set_count = (set_count+1)%50; #endif if (value < TIMEOUT_MIN) value = TIMEOUT_MIN; k3_vibrator_onoff(1); hrtimer_start(&pdata->timer, ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL); } else { k3_vibrator_onoff(0); } }
/*L:060 The final piece of interface code is the close() routine. It reverses * everything done in initialize(). This is usually called because the * Launcher exited. * * Note that the close routine returns 0 or a negative error number: it can't * really fail, but it can whine. I blame Sun for this wart, and K&R C for * letting them do it. :*/ static int close(struct inode *inode, struct file *file) { struct lguest *lg = file->private_data; unsigned int i; /* If we never successfully initialized, there's nothing to clean up */ if (!lg) return 0; /* We need the big lock, to protect from inter-guest I/O and other * Launchers initializing guests. */ mutex_lock(&lguest_lock); /* Free up the shadow page tables for the Guest. */ free_guest_pagetable(lg); for (i = 0; i < lg->nr_cpus; i++) { /* Cancels the hrtimer set via LHCALL_SET_CLOCKEVENT. */ hrtimer_cancel(&lg->cpus[i].hrt); /* We can free up the register page we allocated. */ free_page(lg->cpus[i].regs_page); /* Now all the memory cleanups are done, it's safe to release * the Launcher's memory management structure. */ mmput(lg->cpus[i].mm); } /* If lg->dead doesn't contain an error code it will be NULL or a * kmalloc()ed string, either of which is ok to hand to kfree(). */ if (!IS_ERR(lg->dead)) kfree(lg->dead); /* We clear the entire structure, which also marks it as free for the * next user. */ memset(lg, 0, sizeof(*lg)); /* Release lock and exit. */ mutex_unlock(&lguest_lock); return 0; }
static ssize_t proximity_avg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct cm3663_data *cm3663 = dev_get_drvdata(dev); bool new_value; if (sysfs_streq(buf, "1")) new_value = true; else if (sysfs_streq(buf, "0")) new_value = false; else { pr_err("%s: invalid value %d\n", __func__, *buf); return -EINVAL; } mutex_lock(&cm3663->power_lock); if (new_value) { if (!(cm3663->power_state & PROXIMITY_ENABLED)) { cm3663->pdata->proximity_power(1); cm3663_i2c_write(cm3663, REGS_PS_CMD, reg_defaults[5]); } hrtimer_start(&cm3663->prox_timer, cm3663->prox_poll_delay, HRTIMER_MODE_REL); } else if (!new_value) { hrtimer_cancel(&cm3663->prox_timer); cancel_work_sync(&cm3663->work_prox); if (!(cm3663->power_state & PROXIMITY_ENABLED)) { cm3663_i2c_write(cm3663, REGS_PS_CMD, 0x01); cm3663->pdata->proximity_power(0); } } mutex_unlock(&cm3663->power_lock); return size; }
static void vib_enable(struct timed_output_dev *dev, int value) { struct vib_data *data = container_of(dev, struct vib_data, dev); unsigned long flags; spin_lock_irqsave(&data->lock, flags); hrtimer_cancel(&data->timer); if (value == 0) data->vib_state = 0; else { value = (value > data->pdata->max_timeout ? data->pdata->max_timeout : value); data->vib_state = 1; hrtimer_start(&data->timer, ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL); } spin_unlock_irqrestore(&data->lock, flags); schedule_work(&data->vib_work); }