Esempio n. 1
0
/**
 * _omap_device_deactivate - decrease device readiness
 * @od: struct omap_device *
 * @ignore_lat: decrease to latency target (0) or full inactivity (1)?
 *
 * Decrease readiness of omap_device @od (thus increasing device
 * wakeup latency, but conserving power).  If @ignore_lat is
 * IGNORE_WAKEUP_LAT, make the omap_device fully inactive.  Otherwise,
 * if @ignore_lat is USE_WAKEUP_LAT, and the device's maximum wakeup
 * latency is less than the requested maximum wakeup latency, step
 * forwards in the omap_device_pm_latency table to ensure the device's
 * maximum wakeup latency is less than or equal to the requested
 * maximum wakeup latency.  Returns 0.
 */
static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
{
	struct timespec a, b, c;

	pr_debug("omap_device: %s: deactivating\n", od->pdev.name);

	while (od->pm_lat_level < od->pm_lats_cnt) {
		struct omap_device_pm_latency *odpl;
		unsigned long long deact_lat = 0;

		odpl = od->pm_lats + od->pm_lat_level;

		if (!ignore_lat &&
		    ((od->dev_wakeup_lat + odpl->activate_lat) >
		     od->_dev_wakeup_lat_limit))
			break;

		read_persistent_clock(&a);

		/* XXX check return code */
		odpl->deactivate_func(od);

		read_persistent_clock(&b);

		c = timespec_sub(b, a);
		deact_lat = timespec_to_ns(&c);

		pr_debug("omap_device: %s: pm_lat %d: deactivate: elapsed time "
			 "%llu nsec\n", od->pdev.name, od->pm_lat_level,
			 deact_lat);

		if (deact_lat > odpl->deactivate_lat) {
			odpl->deactivate_lat_worst = deact_lat;
			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
				odpl->deactivate_lat = deact_lat;
				pr_warning("omap_device: %s.%d: new worst case "
					   "deactivate latency %d: %llu\n",
					   od->pdev.name, od->pdev.id,
					   od->pm_lat_level, deact_lat);
			} else
				pr_warning("omap_device: %s.%d: deactivate "
					   "latency %d higher than exptected. "
					   "(%llu > %d)\n",
					   od->pdev.name, od->pdev.id,
					   od->pm_lat_level, deact_lat,
					   odpl->deactivate_lat);
		}


		od->dev_wakeup_lat += odpl->activate_lat;

		od->pm_lat_level++;
	}

	return 0;
}
Esempio n. 2
0
/**
 * _omap_device_activate - increase device readiness
 * @od: struct omap_device *
 * @ignore_lat: increase to latency target (0) or full readiness (1)?
 *
 * Increase readiness of omap_device @od (thus decreasing device
 * wakeup latency, but consuming more power).  If @ignore_lat is
 * IGNORE_WAKEUP_LAT, make the omap_device fully active.  Otherwise,
 * if @ignore_lat is USE_WAKEUP_LAT, and the device's maximum wakeup
 * latency is greater than the requested maximum wakeup latency, step
 * backwards in the omap_device_pm_latency table to ensure the
 * device's maximum wakeup latency is less than or equal to the
 * requested maximum wakeup latency.  Returns 0.
 */
static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
{
	struct timespec a, b, c;

	dev_dbg(&od->pdev->dev, "omap_device: activating\n");

	while (od->pm_lat_level > 0) {
		struct omap_device_pm_latency *odpl;
		unsigned long long act_lat = 0;

		od->pm_lat_level--;

		odpl = od->pm_lats + od->pm_lat_level;

		if (!ignore_lat &&
		    (od->dev_wakeup_lat <= od->_dev_wakeup_lat_limit))
			break;

		read_persistent_clock(&a);

		/* XXX check return code */
		odpl->activate_func(od);

		read_persistent_clock(&b);

		c = timespec_sub(b, a);
		act_lat = timespec_to_ns(&c);

		dev_dbg(&od->pdev->dev,
			"omap_device: pm_lat %d: activate: elapsed time "
			"%llu nsec\n", od->pm_lat_level, act_lat);

		if (act_lat > odpl->activate_lat) {
			odpl->activate_lat_worst = act_lat;
			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
				odpl->activate_lat = act_lat;
				dev_dbg(&od->pdev->dev,
					"new worst case activate latency "
					"%d: %llu\n",
					od->pm_lat_level, act_lat);
			} else
				dev_warn(&od->pdev->dev,
					 "activate latency %d "
					 "higher than exptected. (%llu > %d)\n",
					 od->pm_lat_level, act_lat,
					 odpl->activate_lat);
		}

		od->dev_wakeup_lat -= odpl->activate_lat;
	}

	return 0;
}
Esempio n. 3
0
static void tick_periodic(int cpu)
{
    if (tick_do_timer_cpu == cpu) {
        write_seqlock(&xtime_lock);

        /* Keep track of the next tick event */
        tick_next_period = ktime_add(tick_next_period, tick_period);

#ifdef UNDER_HYPERVISOR
        {   /* Compensate slow timer tick under hypervisor */
            static __kernel_time_t rt_sec;
            static unsigned short rt_jiffies_sec = HZ;
            static unsigned short rt_ticks_sec = HZ;
            static unsigned short rt_jiffies = 0;
            static unsigned short rt_ticks = 0;
            static unsigned short rt_count = 1;
//			static unsigned short rt_log[11] = {0};

            unsigned long tick = rt_jiffies_sec * ++rt_ticks / rt_ticks_sec - rt_jiffies;
            if (rt_jiffies + tick > rt_jiffies_sec + (HZ/4) )
                tick = (rt_jiffies + tick > rt_jiffies_sec + HZ) ? 0 : 1;

            rt_jiffies += tick;
            do_timer(tick);

            if (0 == --rt_count) {
                static int first = 2;

                struct timespec ts;
                read_persistent_clock(&ts);

                if (rt_sec != ts.tv_sec) {
                    /*					rt_log[++rt_log[0]] = rt_ticks;
                    					if (rt_log[0] == 10) {
                    						rt_log[0] = 0;
                    						printk(KERN_ERR "tick_count : %d %d %d %d %d %d %d %d %d %d\n",
                    								rt_log[1], rt_log[2], rt_log[3], rt_log[4], rt_log[5],
                    								rt_log[6], rt_log[7], rt_log[8], rt_log[9], rt_log[10]);
                    					}
                    */
                    if (!first) {
                        rt_jiffies_sec = HZ + rt_jiffies_sec - rt_jiffies;
                        rt_ticks_sec = rt_ticks ;
                    } else {
                        first--;
                    }

                    rt_sec = ts.tv_sec;
                    rt_ticks = rt_jiffies = 0;
                }

                rt_count = (!first && rt_ticks_sec > rt_ticks + 3) ? (rt_ticks_sec - rt_ticks) >> 2 : 1;
            }
        }
#else
        do_timer(1);
#endif /* End of UNDER_HYPERVISOR */

        write_sequnlock(&xtime_lock);
    }
Esempio n. 4
0
static int suspend_time_debug_show(struct seq_file *s, void *data)
{
    int bin;
    seq_printf(s, "time (secs)  count\n");
    seq_printf(s, "------------------\n");

//LGE_CHANGES [Start]
#if 1
    for (bin = 0; bin < 33; bin++) {
#else
    for (bin = 0; bin < 32; bin++) {
#endif
//LGE_CNANGES
        if (time_in_suspend_bins[bin] == 0)
            continue;
        seq_printf(s, "%4d - %4d %4u\n",
                   bin ? 1 << (bin - 1) : 0, 1 << bin,
                   time_in_suspend_bins[bin]);
    }
    return 0;
}

static int suspend_time_debug_open(struct inode *inode, struct file *file)
{
    return single_open(file, suspend_time_debug_show, NULL);
}

static const struct file_operations suspend_time_debug_fops = {
    .open		= suspend_time_debug_open,
    .read		= seq_read,
    .llseek		= seq_lseek,
    .release	= single_release,
};

static int __init suspend_time_debug_init(void)
{
    struct dentry *d;

    d = debugfs_create_file("suspend_time", 0755, NULL, NULL,
                            &suspend_time_debug_fops);
    if (!d) {
        pr_err("Failed to create suspend_time debug file\n");
        return -ENOMEM;
    }

    return 0;
}

late_initcall(suspend_time_debug_init);
#endif

static int suspend_time_syscore_suspend(void)
{
    read_persistent_clock(&suspend_time_before);

    return 0;
}
Esempio n. 5
0
static void sleep_history_syscore_resume(void)
{
	struct timespec ts;

	/* snapshot the current time at suspend */
	read_persistent_clock(&ts);
	if (ts.tv_sec == 0 && ts.tv_nsec == 0)
		return;

	sleep_history_marker(SLEEP_HISTORY_SUSPEND_PERSISTCLOCK_EXIT, &ts, NULL);
}
Esempio n. 6
0
static void suspend_time_syscore_resume(void)
{
    struct timespec after;

    read_persistent_clock(&after);

    after = timespec_sub(after, suspend_time_before);

    time_in_suspend_bins[fls(after.tv_sec)]++;

    pr_info("Suspended for %lu.%03lu seconds\n", after.tv_sec,
            after.tv_nsec / NSEC_PER_MSEC);
}
Esempio n. 7
0
static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
{
	struct gpio_button_data *bdata = dev_id;
	struct gpio_keys_button *button = bdata->button;

	BUG_ON(irq != bdata->irq);

	read_persistent_clock(&button->goog.ts);
	if (bdata->timer_debounce && !from_suspend_active(button))
		mod_timer(&bdata->timer,
			jiffies + msecs_to_jiffies(bdata->timer_debounce));
	else
		schedule_work(&bdata->work);

	return IRQ_HANDLED;
}
Esempio n. 8
0
File: sysctl.c Progetto: 274914765/C
/* Same for RTC */
int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen,
            void *oldval, size_t *oldlenp,
            void *newval, size_t newlen)
{
    int r;

    rtctmp = read_persistent_clock();
    if (rtctmp < 0)
        rtctmp = 0;
    r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
    if (r < 0)
        return r;
    if (newval && newlen)
        rtc_mips_set_mmss(rtctmp);

    return r;
}
Esempio n. 9
0
File: sysctl.c Progetto: 274914765/C
/* proc function to read/write RealTime Clock */
int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
               void *buffer, size_t *lenp, loff_t *ppos)
{
    int r;

    if (!write) {
        rtctmp = read_persistent_clock();
        /* check for time < 0 and set to 0 */
        if (rtctmp < 0)
            rtctmp = 0;
    }
    r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
    if (r)
        return r;

    if (write)
        rtc_mips_set_mmss(rtctmp);

    return 0;
}
Esempio n. 10
0
/* proc function to read/write RealTime Clock */
int proc_dolasatrtc(ctl_table *table, int write,
		       void *buffer, size_t *lenp, loff_t *ppos)
{
	struct timespec ts;
	int r;

	if (!write) {
		read_persistent_clock(&ts);
		rtctmp = ts.tv_sec;
		/* check for time < 0 and set to 0 */
		if (rtctmp < 0)
			rtctmp = 0;
	}
	r = proc_dointvec(table, write, buffer, lenp, ppos);
	if (r)
		return r;

	if (write)
		rtc_mips_set_mmss(rtctmp);

	return 0;
}
Esempio n. 11
0
void __init time_init(void)
{
	/* FIXME: xtime&wall_to_monotonic are set in timekeeping_init. */
	read_persistent_clock(&xtime);
	set_normalized_timespec(&wall_to_monotonic,
		-xtime.tv_sec, -xtime.tv_nsec);

#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
	printk("Calibrating CPU frequency ");
	platform_calibrate_ccount();
	printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ),
			(int)(ccount_per_jiffy/(10000/HZ))%100);
#endif
	ccount_clocksource.mult =
		clocksource_hz2mult(CCOUNT_PER_JIFFY * HZ,
				ccount_clocksource.shift);
	clocksource_register(&ccount_clocksource);

	/* Initialize the linux timer interrupt. */

	setup_irq(LINUX_TIMER_INT, &timer_irqaction);
	set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY);
}
Esempio n. 12
0
static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata, gpio_key_caller_t caller)
{
	struct gpio_keys_button *button = bdata->button;
	struct input_dev *input = bdata->input;
	struct timespec ts, ts_delta;
	unsigned int type = button->type ?: EV_KEY;
	int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0) ^ button->active_low;

	if (button->goog.prev_state == state && caller == GPIO_KEYS_WORK
		&& from_suspend_active(button) && !button->goog.synth_sent) {
		state = !state;
		button->goog.synth_sent = 1;
	}

	if (caller == GPIO_KEYS_WORK) {
		read_persistent_clock(&ts);
		ts_delta = timespec_sub(ts, button->goog.ts);
		dev_dbg(&input->dev, "Camera button time isr to input handling :%Ld ns\n",
			timespec_to_ns(&ts_delta));
	}

	if (type == EV_ABS) {
		if (state)
			input_event(input, type, button->code, button->value);
	} else {
		input_event(input, type, button->code, !!state);
	}
	input_sync(input);

	button->goog.prev_state = state;

	dev_info(&input->dev, "Camera button caller:::%d %s %s\n",
		caller,
		((state) ? "pressed" : "released"),
		((button->goog.synth_sent) ? "synthesized" : "polled"));
}
Esempio n. 13
0
static int suspend_time_syscore_suspend(void)
{
    read_persistent_clock(&suspend_time_before);

    return 0;
}