static int gic_next_event(unsigned long delta, struct clock_event_device *evt) { u64 cnt; int res; cnt = gic_read_count(); cnt += (u64)delta; gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask)); res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; return res; }
static int gic_next_event(unsigned long delta, struct clock_event_device *evt) { int cpu = cpumask_first(evt->cpumask); u64 cnt; int res; cnt = gic_read_count(); cnt += (u64)delta; if (cpu == raw_smp_processor_id()) { write_gic_vl_compare(cnt); } else { write_gic_vl_other(mips_cm_vp_id(cpu)); write_gic_vo_compare(cnt); } res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; return res; }
/* * Estimate CPU and GIC frequencies. */ static void __init estimate_frequencies(void) { unsigned long flags; unsigned int count, start; cycle_t giccount = 0, gicstart = 0; #if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ mips_hpt_frequency = CONFIG_KVM_GUEST_TIMER_FREQ * 1000000; return; #endif local_irq_save(flags); /* Start counter exactly on falling edge of update flag. */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); /* Initialize counters. */ start = read_c0_count(); if (gic_present) { gic_start_count(); gicstart = gic_read_count(); } /* Read counter exactly on falling edge of update flag. */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); count = read_c0_count(); if (gic_present) giccount = gic_read_count(); local_irq_restore(flags); count -= start; mips_hpt_frequency = count; if (gic_present) { giccount -= gicstart; gic_frequency = giccount; } }
static cycle_t gic_hpt_read(struct clocksource *cs) { return gic_read_count(); }
/* * Estimate CPU and GIC frequencies. */ static void __init estimate_frequencies(void) { unsigned long flags; unsigned int count, start; unsigned char secs1, secs2, ctrl; int secs; u64 giccount = 0, gicstart = 0; #if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ mips_hpt_frequency = CONFIG_KVM_GUEST_TIMER_FREQ * 1000000; return; #endif local_irq_save(flags); if (gic_present) gic_start_count(); /* * Read counters exactly on rising edge of update flag. * This helps get an accurate reading under virtualisation. */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); start = read_c0_count(); if (gic_present) gicstart = gic_read_count(); /* Wait for falling edge before reading RTC. */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); secs1 = CMOS_READ(RTC_SECONDS); /* Read counters again exactly on rising edge of update flag. */ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); count = read_c0_count(); if (gic_present) giccount = gic_read_count(); /* Wait for falling edge before reading RTC again. */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); secs2 = CMOS_READ(RTC_SECONDS); ctrl = CMOS_READ(RTC_CONTROL); local_irq_restore(flags); if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { secs1 = bcd2bin(secs1); secs2 = bcd2bin(secs2); } secs = secs2 - secs1; if (secs < 1) secs += 60; count -= start; count /= secs; mips_hpt_frequency = count; if (gic_present) { giccount = div_u64(giccount - gicstart, secs); gic_frequency = giccount; } }