예제 #1
0
파일: watchdog_dev.c 프로젝트: avagin/linux
static ktime_t watchdog_next_keepalive(struct watchdog_device *wdd)
{
	struct watchdog_core_data *wd_data = wdd->wd_data;
	unsigned int timeout_ms = wdd->timeout * 1000;
	ktime_t keepalive_interval;
	ktime_t last_heartbeat, latest_heartbeat;
	ktime_t virt_timeout;
	unsigned int hw_heartbeat_ms;

	virt_timeout = ktime_add(wd_data->last_keepalive,
				 ms_to_ktime(timeout_ms));
	hw_heartbeat_ms = min_not_zero(timeout_ms, wdd->max_hw_heartbeat_ms);
	keepalive_interval = ms_to_ktime(hw_heartbeat_ms / 2);

	if (!watchdog_active(wdd))
		return keepalive_interval;

	/*
	 * To ensure that the watchdog times out wdd->timeout seconds
	 * after the most recent ping from userspace, the last
	 * worker ping has to come in hw_heartbeat_ms before this timeout.
	 */
	last_heartbeat = ktime_sub(virt_timeout, ms_to_ktime(hw_heartbeat_ms));
	latest_heartbeat = ktime_sub(last_heartbeat, ktime_get());
	if (ktime_before(latest_heartbeat, keepalive_interval))
		return latest_heartbeat;
	return keepalive_interval;
}
예제 #2
0
static void pp_pong(struct pp_ctx *pp)
{
	u32 msg_data = -1, spad_data = -1;
	int pidx = 0;

	/* Read pong data */
	spad_data = ntb_spad_read(pp->ntb, 0);
	msg_data = ntb_msg_read(pp->ntb, &pidx, 0);
	ntb_msg_clear_sts(pp->ntb, -1);

	/*
	 * Scratchpad and message data may differ, since message register can't
	 * be rewritten unless status is cleared. Additionally either of them
	 * might be unsupported
	 */
	dev_dbg(&pp->ntb->dev, "Pong spad %#x, msg %#x (port %d)\n",
		spad_data, msg_data, ntb_peer_port_number(pp->ntb, pidx));

	atomic_inc(&pp->count);

	ntb_db_set_mask(pp->ntb, pp->in_db);
	ntb_db_clear(pp->ntb, pp->in_db);

	hrtimer_start(&pp->timer, ms_to_ktime(delay_ms), HRTIMER_MODE_REL);
}
예제 #3
0
파일: watchdog_dev.c 프로젝트: avagin/linux
static int __watchdog_ping(struct watchdog_device *wdd)
{
	struct watchdog_core_data *wd_data = wdd->wd_data;
	ktime_t earliest_keepalive, now;
	int err;

	earliest_keepalive = ktime_add(wd_data->last_hw_keepalive,
				       ms_to_ktime(wdd->min_hw_heartbeat_ms));
	now = ktime_get();

	if (ktime_after(earliest_keepalive, now)) {
		hrtimer_start(&wd_data->timer,
			      ktime_sub(earliest_keepalive, now),
			      HRTIMER_MODE_REL);
		return 0;
	}

	wd_data->last_hw_keepalive = now;

	if (wdd->ops->ping)
		err = wdd->ops->ping(wdd);  /* ping the watchdog */
	else
		err = wdd->ops->start(wdd); /* restart watchdog */

	watchdog_update_worker(wdd);

	return err;
}
예제 #4
0
파일: jiq.c 프로젝트: zxbuaa/ldd3
static int jiqhrtimer_seq_show(struct seq_file *m, void *v)
{
	struct clientdata *data = m->private;
	ktime_t period = ms_to_ktime(jiffies_to_msecs(delay));
	int retval;

	data->seq_file = m;
	data->ktime = ktime_get();
	data->delay = delay;
	data->count = max_count;
	data->stopped = false;

	hrtimer_init(&data->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	data->hrtimer.function = jiq_hrtimedout;

	jiq_print2(data);   /* print and go to sleep */
	hrtimer_start(&data->hrtimer, period, HRTIMER_MODE_REL);
	retval = wait_event_interruptible(jiq_wait, !data->count);
	if (retval < 0) {
		data->stopped = true;
		hrtimer_cancel(&data->hrtimer);  /* in case a signal woke us up */
	}

	return retval;
}
예제 #5
0
static void ledtrig_general_activity(struct ledtrig_t * trigger)
{
	struct ledtrig_general_pdata_t * pdat = (struct ledtrig_general_pdata_t *)trigger->priv;

	pdat->activity++;
	timer_start_now(&pdat->timer, ms_to_ktime(20));
}
예제 #6
0
파일: key-gpio.c 프로젝트: kamejoko80/xboot
static int key_gpio_timer_function(struct timer_t * timer, void * data)
{
	struct input_t * input = (struct input_t *)(data);
	struct key_gpio_private_data_t * dat = (struct key_gpio_private_data_t *)input->priv;
	struct key_gpio_data_t * rdat = (struct key_gpio_data_t *)dat->rdat;
	enum event_type_t type;
	int i, val;

	for(i = 0; i < rdat->nbutton; i++)
	{
		val = gpio_get_value(rdat->buttons[i].gpio);
		if(val != dat->state[i])
		{
			if(rdat->buttons[i].active_low)
				type = val ? EVENT_TYPE_KEY_UP : EVENT_TYPE_KEY_DOWN;
			else
				type = val ? EVENT_TYPE_KEY_DOWN : EVENT_TYPE_KEY_UP;

			if(type == EVENT_TYPE_KEY_DOWN)
				push_event_key_down(input, rdat->buttons[i].key);
			else if(type == EVENT_TYPE_KEY_UP)
				push_event_key_up(input, rdat->buttons[i].key);
		}
		dat->state[i] = val;
	}

	timer_forward_now(timer, ms_to_ktime(100));
	return 1;
}
예제 #7
0
파일: jiq.c 프로젝트: zxbuaa/ldd3
static enum hrtimer_restart jiq_hrtimedout(struct hrtimer *hrtimer)
{
	struct clientdata *data = container_of(hrtimer, struct clientdata, hrtimer);
	ktime_t period = ms_to_ktime(jiffies_to_msecs(data->delay));
	if (!jiq_print2(data))
		return HRTIMER_NORESTART;
	hrtimer_forward(hrtimer, hrtimer_get_expires(hrtimer), period);
	return HRTIMER_RESTART;
}
enum hrtimer_restart nxt_i2c_sensor_poll_timer(struct hrtimer *timer)
{
	struct nxt_i2c_sensor_data *data =
		container_of(timer, struct nxt_i2c_sensor_data, poll_timer);

	hrtimer_forward_now(timer, ms_to_ktime(data->poll_ms));
	schedule_work(&data->poll_work);

	return HRTIMER_RESTART;
}
예제 #9
0
static void ledtrig_heartbeat_init(struct ledtrig_t * trigger)
{
	struct ledtrig_heartbeat_data_t * dat = (struct ledtrig_heartbeat_data_t *)trigger->priv;

	if(dat)
	{
		dat->phase = 0;
		timer_init(&dat->timer, heartbeat_timer_function, trigger);
		timer_start_now(&dat->timer, ms_to_ktime(10));
	}
}
예제 #10
0
enum hrtimer_restart brickpi_poll_timer_function(struct hrtimer *timer)
{
	struct brickpi_data *data = container_of(timer, struct brickpi_data,
						 poll_timer);

	hrtimer_forward_now(timer, ms_to_ktime(BRICKPI_POLL_MS));
	if (data->closing)
		return HRTIMER_NORESTART;

	schedule_work(&data->poll_work);

	return HRTIMER_RESTART;
}
예제 #11
0
static int buzzer_pwm_timer_function(struct timer_t * timer, void * data)
{
	struct buzzer_t * buzzer = (struct buzzer_t *)(data);
	struct buzzer_pwm_pdata_t * pdat = (struct buzzer_pwm_pdata_t *)buzzer->priv;
	struct beep_param_t * param = queue_pop(pdat->beep);
	if(!param)
	{
		buzzer_pwm_set(buzzer, 0);
		return 0;
	}
	buzzer_pwm_set(buzzer, param->frequency);
	timer_forward_now(&pdat->timer, ms_to_ktime(param->millisecond));
	free(param);
	return 1;
}
예제 #12
0
static int ledtrig_general_timer_function(struct timer_t * timer, void * data)
{
	struct ledtrig_t * trigger = (struct ledtrig_t *)(data);
	struct ledtrig_general_pdata_t * pdat = (struct ledtrig_general_pdata_t *)trigger->priv;

	if(pdat->last_activity != pdat->activity)
	{
		pdat->last_activity = pdat->activity;
		led_set_brightness(pdat->led, CONFIG_MAX_BRIGHTNESS);
		timer_forward_now(timer, ms_to_ktime(20));
		return 1;
	}
	else
	{
		led_set_brightness(pdat->led, 0);
		return 0;
	}
}
예제 #13
0
파일: tpm_crb.c 프로젝트: fxysunshine/Linux
static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
				unsigned long timeout)
{
	ktime_t start;
	ktime_t stop;

	start = ktime_get();
	stop = ktime_add(start, ms_to_ktime(timeout));

	do {
		if ((ioread32(reg) & mask) == value)
			return true;

		usleep_range(50, 100);
	} while (ktime_before(ktime_get(), stop));

	return ((ioread32(reg) & mask) == value);
}
예제 #14
0
static void pp_setup(struct pp_ctx *pp)
{
	int ret;

	ntb_db_set_mask(pp->ntb, pp->in_db);

	hrtimer_cancel(&pp->timer);

	ret = pp_find_next_peer(pp);
	if (ret == -ENODEV) {
		dev_dbg(&pp->ntb->dev, "Got no peers, so cancel\n");
		return;
	}

	dev_dbg(&pp->ntb->dev, "Ping-pong started with port %d, db %#llx\n",
		ntb_peer_port_number(pp->ntb, pp->out_pidx), pp->out_db);

	hrtimer_start(&pp->timer, ms_to_ktime(delay_ms), HRTIMER_MODE_REL);
}
예제 #15
0
static int heartbeat_timer_function(struct timer_t * timer, void * data)
{
	struct ledtrig_t * trigger = (struct ledtrig_t *)(data);
	struct ledtrig_heartbeat_data_t * dat = (struct ledtrig_heartbeat_data_t *)trigger->priv;
	struct led_t * led = (struct led_t *)(trigger->led);
	int brightness = 0;
	u32_t delay = 0;

	/*
	 * Acts like an actual heart beat -- thump-thump-pause ...
	 */
	switch(dat->phase)
	{
	case 0:
		dat->period = 1260;
		delay = 70;
		dat->phase++;
		brightness = CONFIG_MAX_BRIGHTNESS;
		break;

	case 1:
		delay = dat->period / 4 - 70;
		dat->phase++;
		brightness = 0;
		break;

	case 2:
		delay = 70;
		dat->phase++;
		brightness = CONFIG_MAX_BRIGHTNESS;
		break;

	default:
		delay = dat->period - dat->period / 4 - 70;
		dat->phase = 0;
		brightness = 0;
		break;
	}

	led_set_brightness(led, brightness);
	timer_forward_now(timer, ms_to_ktime(delay));
	return 1;
}
예제 #16
0
파일: hw-txe.c 프로젝트: acton393/linux
/**
 * mei_txe_aliveness_poll - waits for aliveness to settle
 *
 * @dev: the device structure
 * @expected: expected aliveness value
 *
 * Polls for HICR_HOST_ALIVENESS_RESP.ALIVENESS_RESP to be set
 *
 * Return: 0 if the expected value was received, -ETIME otherwise
 */
static int mei_txe_aliveness_poll(struct mei_device *dev, u32 expected)
{
	struct mei_txe_hw *hw = to_txe_hw(dev);
	ktime_t stop, start;

	start = ktime_get();
	stop = ktime_add(start, ms_to_ktime(SEC_ALIVENESS_WAIT_TIMEOUT));
	do {
		hw->aliveness = mei_txe_aliveness_get(dev);
		if (hw->aliveness == expected) {
			dev->pg_event = MEI_PG_EVENT_IDLE;
			dev_dbg(dev->dev, "aliveness settled after %lld usecs\n",
				ktime_to_us(ktime_sub(ktime_get(), start)));
			return 0;
		}
		usleep_range(20, 50);
	} while (ktime_before(ktime_get(), stop));

	dev->pg_event = MEI_PG_EVENT_IDLE;
	dev_err(dev->dev, "aliveness timed out\n");
	return -ETIME;
}
예제 #17
0
static void buzzer_gpio_beep(struct buzzer_t * buzzer, int frequency, int millisecond)
{
	struct buzzer_gpio_pdata_t * pdat = (struct buzzer_gpio_pdata_t *)buzzer->priv;
	struct beep_param_t * param;

	if((frequency == 0) && (millisecond == 0))
	{
		timer_cancel(&pdat->timer);
		queue_clear(pdat->beep, iteration_beep_param);
		buzzer_gpio_set(buzzer, 0);
		return;
	}

	param = malloc(sizeof(struct beep_param_t));
	if(!param)
		return;
	param->frequency = frequency;
	param->millisecond = millisecond;

	queue_push(pdat->beep, param);
	if(queue_avail(pdat->beep) == 1)
		timer_start_now(&pdat->timer, ms_to_ktime(1));
}
예제 #18
0
파일: key-gpio.c 프로젝트: kamejoko80/xboot
static void input_init(struct input_t * input)
{
	struct key_gpio_private_data_t * dat = (struct key_gpio_private_data_t *)input->priv;
	struct key_gpio_data_t * rdat = (struct key_gpio_data_t *)dat->rdat;
	int i;

	if(!dat)
		return;

	dat->state = malloc(rdat->nbutton * sizeof(int));
	if(!dat->state)
		return;

	for(i = 0; i < rdat->nbutton; i++)
	{
		gpio_set_pull(rdat->buttons[i].gpio, rdat->buttons[i].active_low ? GPIO_PULL_UP :GPIO_PULL_DOWN);
		gpio_direction_input(rdat->buttons[i].gpio);
		dat->state[i] = gpio_get_value(rdat->buttons[i].gpio);
	}

	timer_init(&dat->timer, key_gpio_timer_function, input);
	timer_start_now(&dat->timer, ms_to_ktime(100));
}
예제 #19
0
static void cpufreq_limit_work(struct work_struct *work)
{
	struct cpufreq_limit_data *limit = container_of(work,
						struct cpufreq_limit_data, limit_work);
	struct task_struct *p = NULL, *t = NULL;
	char **s = limit->limit_name;
	char *comm = task_comm;
	int cpu, i = 0, len = limit->limit_num;

	if (!test_bit(STATE_RESUME_DONE, &limit->resume_state))
		goto _exit;

	task_comm[0] = 0;
	for_each_possible_cpu(cpu) {
     	p = curr_task(cpu);
	   	t = find_task_by_vpid(task_tgid_vnr(p));	/* parent */
     	if (t)
     		p = t;

   		if (p->flags & PF_KTHREAD)
			continue;

		if (!likely(p->mm))
			continue;

		cpufreq_cmdline(p, comm);
     	pr_debug("cpu %d  current (%d) %s\n", cpu, p->pid, comm);

		for (i = 0; len > i; i++) {
			/* boost : task is running */
			if (!strncmp(comm, s[i], strlen(s[i]))) {
				limit->time_stamp = 0;
				cpufreq_set_max_frequency(limit, 1);
				pr_debug(": run %s\n", s[i]);
				goto _exit;
			}
		}
	}

	for_each_process(p) {
   		if (p->flags & PF_KTHREAD)
			continue;

		if (!likely(p->mm))
			continue;

		cpufreq_cmdline(p, comm);
		for (i = 0; len > i; i++) {
			if (!strncmp(comm, s[i], strlen(s[i]))) {
				pr_debug("detect %s:%s [%ld.%ld ms]\n",
					s[i], comm, limit->time_stamp, limit->time_stamp%1000);

				limit->current_time_stamp = ktime_to_ms(ktime_get());
				if (0 == limit->time_stamp) {
					limit->time_stamp = limit->current_time_stamp;
				} else {
					/* restore : task is sleep status */
					if ((limit->current_time_stamp - limit->time_stamp) > limit->op_timeout)
						cpufreq_set_max_frequency(limit, 0);
				}
				goto _exit;
			}
		}
	}

	/* restore : not find task */
	cpufreq_set_max_frequency(limit, 0);
	limit->time_stamp = 0;

_exit:
	hrtimer_start(&limit->limit_timer, ms_to_ktime(limit->timer_duration),
		HRTIMER_MODE_REL_PINNED);
}
예제 #20
0
파일: button.c 프로젝트: daveyoung/linux
static int acpi_lid_notify_state(struct acpi_device *device, int state)
{
	struct acpi_button *button = acpi_driver_data(device);
	int ret;
	ktime_t next_report;
	bool do_update;

	/*
	 * In lid_init_state=ignore mode, if user opens/closes lid
	 * frequently with "open" missing, and "last_time" is also updated
	 * frequently, "close" cannot be delivered to the userspace.
	 * So "last_time" is only updated after a timeout or an actual
	 * switch.
	 */
	if (lid_init_state != ACPI_BUTTON_LID_INIT_IGNORE ||
	    button->last_state != !!state)
		do_update = true;
	else
		do_update = false;

	next_report = ktime_add(button->last_time,
				ms_to_ktime(lid_report_interval));
	if (button->last_state == !!state &&
	    ktime_after(ktime_get(), next_report)) {
		/* Complain the buggy firmware */
		pr_warn_once("The lid device is not compliant to SW_LID.\n");

		/*
		 * Send the unreliable complement switch event:
		 *
		 * On most platforms, the lid device is reliable. However
		 * there are exceptions:
		 * 1. Platforms returning initial lid state as "close" by
		 *    default after booting/resuming:
		 *     https://bugzilla.kernel.org/show_bug.cgi?id=89211
		 *     https://bugzilla.kernel.org/show_bug.cgi?id=106151
		 * 2. Platforms never reporting "open" events:
		 *     https://bugzilla.kernel.org/show_bug.cgi?id=106941
		 * On these buggy platforms, the usage model of the ACPI
		 * lid device actually is:
		 * 1. The initial returning value of _LID may not be
		 *    reliable.
		 * 2. The open event may not be reliable.
		 * 3. The close event is reliable.
		 *
		 * But SW_LID is typed as input switch event, the input
		 * layer checks if the event is redundant. Hence if the
		 * state is not switched, the userspace cannot see this
		 * platform triggered reliable event. By inserting a
		 * complement switch event, it then is guaranteed that the
		 * platform triggered reliable one can always be seen by
		 * the userspace.
		 */
		if (lid_init_state == ACPI_BUTTON_LID_INIT_IGNORE) {
			do_update = true;
			/*
			 * Do generate complement switch event for "close"
			 * as "close" is reliable and wrong "open" won't
			 * trigger unexpected behaviors.
			 * Do not generate complement switch event for
			 * "open" as "open" is not reliable and wrong
			 * "close" will trigger unexpected behaviors.
			 */
			if (!state) {
				input_report_switch(button->input,
						    SW_LID, state);
				input_sync(button->input);
			}
		}
	}
	/* Send the platform triggered reliable event */
	if (do_update) {
		acpi_handle_debug(device->handle, "ACPI LID %s\n",
				  state ? "open" : "closed");
		input_report_switch(button->input, SW_LID, !state);
		input_sync(button->input);
		button->last_state = !!state;
		button->last_time = ktime_get();
	}

	if (state)
		acpi_pm_wakeup_event(&device->dev);

	ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
	if (ret == NOTIFY_DONE)
		ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
						   device);
	if (ret == NOTIFY_DONE || ret == NOTIFY_OK) {
		/*
		 * It is also regarded as success if the notifier_chain
		 * returns NOTIFY_OK or NOTIFY_DONE.
		 */
		ret = 0;
	}
	return ret;
}