void __init setup_hpet_timer(void) { unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; hpet_setup(); cd = &per_cpu(hpet_clockevent_device, cpu); cd->name = "hpet"; cd->rating = 100; cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; cd->set_state_shutdown = hpet_set_state_shutdown; cd->set_state_periodic = hpet_set_state_periodic; cd->set_state_oneshot = hpet_set_state_oneshot; cd->tick_resume = hpet_tick_resume; cd->set_next_event = hpet_next_event; cd->irq = HPET_T0_IRQ; cd->cpumask = cpumask_of(cpu); clockevent_set_clock(cd, HPET_FREQ); cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, cd); clockevents_register_device(cd); setup_irq(HPET_T0_IRQ, &hpet_irq); pr_info("hpet clock event device register\n"); }
int __init init_clockevents(void) { struct clock_event_device *cd; struct irqaction *iact; unsigned int cpu = smp_processor_id(); cd = &per_cpu(mn10300_clockevent_device, cpu); if (cpu == 0) { stop_jiffies_counter(); cd->irq = TMJCIRQ; } else { stop_jiffies_counter1(); cd->irq = TMJC1IRQ; } cd->name = "Timestamp"; cd->features = CLOCK_EVT_FEAT_ONESHOT; /* Calculate the min / max delta */ clockevent_set_clock(cd, MN10300_JCCLK); cd->max_delta_ns = clockevent_delta2ns(TMJCBR_MAX, cd); cd->min_delta_ns = clockevent_delta2ns(100, cd); cd->rating = 200; cd->cpumask = cpumask_of(smp_processor_id()); cd->set_mode = set_clock_mode; cd->event_handler = event_handler; cd->set_next_event = next_event; iact = &per_cpu(timer_irq, cpu); iact->flags = IRQF_DISABLED | IRQF_SHARED | IRQF_TIMER; iact->handler = timer_interrupt; clockevents_register_device(cd); #if defined(CONFIG_SMP) && !defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) /* setup timer irq affinity so it only runs on this cpu */ { struct irq_desc *desc; desc = irq_to_desc(cd->irq); cpumask_copy(desc->affinity, cpumask_of(cpu)); iact->flags |= IRQF_NOBALANCING; } #endif if (cpu == 0) { reload_jiffies_counter(MN10300_JC_PER_HZ - 1); iact->name = "CPU0 Timer"; } else { reload_jiffies_counter1(MN10300_JC_PER_HZ - 1); iact->name = "CPU1 Timer"; } setup_jiffies_interrupt(cd->irq, iact); return 0; }
int __init ra_systick_clockevent_init(void) { unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; unsigned int irq, i __maybe_unused; unsigned long _gic_base __maybe_unused; /* * With vectored interrupts things are getting platform specific. * get_c0_compare_int is a hook to allow a platform to return the * interrupt number of it's liking. */ irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; cd = &ra_systick; cd->features = CLOCK_EVT_FEAT_ONESHOT; cd->name = "Ralink System Tick Counter"; clockevent_set_clock(cd, 50000); cd->max_delta_ns = clockevent_delta2ns(0x7fff, cd); cd->min_delta_ns = clockevent_delta2ns(0x3, cd); #ifdef CONFIG_RALINK_MT7621 /* must be lower than MIPS original cd rating(300) to activate "broadcast mode" */ cd->rating = 250; #else /* must be higher than MIPS original cd rating(300). */ cd->rating = 350; #endif cd->irq = irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = ra_systick_next_event; cd->set_mode = ra_systick_set_clock_mode; cd->event_handler = ra_systick_event_handler; #ifdef CONFIG_RALINK_MT7621 /* Program MIPS GIC to turn off(mask) each VPE's local timer interrupt. * "_gic_base" is for GIC read/write macro. */ _gic_base = (unsigned long) ioremap_nocache(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ); for (i = 0; i < NR_CPUS /* numvpes */; i++) { GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), GIC_VPE_SMASK_TIMER_MSK); } #endif /* install timer irq handler before MIPS BSP code. */ if (!cp0_timer_irq_installed){ cp0_timer_irq_installed = 1; setup_irq(irq, &ra_c0_compare_irqaction); } clockevents_register_device(cd); /* Enable ralink system count register */ (*((volatile u32 *)(RALINK_MCNT_CFG))) = 0x3; return 0; }
int __cpuinit r4k_clockevent_init(void) { unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; unsigned int irq; if (!cpu_has_counter || !mips_hpt_frequency) return -ENXIO; if (!c0_compare_int_usable()) #ifdef CONFIG_MIPS_GOLDFISH /* FIXME: this is not a reliable test with QEMU */ ; #else return -ENXIO; #endif /* * With vectored interrupts things are getting platform specific. * get_c0_compare_int is a hook to allow a platform to return the * interrupt number of it's liking. */ irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; if (get_c0_compare_int) irq = get_c0_compare_int(); cd = &per_cpu(mips_clockevent_device, cpu); cd->name = "MIPS"; cd->features = CLOCK_EVT_FEAT_ONESHOT; clockevent_set_clock(cd, mips_hpt_frequency); /* Calculate the min / max delta */ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->rating = 300; cd->irq = irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = mips_next_event; cd->set_mode = mips_set_clock_mode; cd->event_handler = mips_event_handler; clockevents_register_device(cd); if (cp0_timer_irq_installed) return 0; cp0_timer_irq_installed = 1; setup_irq(irq, &c0_compare_irqaction); return 0; }
int __cpuinit r4k_clockevent_init(void) { unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; unsigned int irq; if (!cpu_has_counter || !mips_hpt_frequency) return -ENXIO; if (!c0_compare_int_usable()) return -ENXIO; /* */ irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; if (get_c0_compare_int) irq = get_c0_compare_int(); cd = &per_cpu(mips_clockevent_device, cpu); cd->name = "MIPS"; cd->features = CLOCK_EVT_FEAT_ONESHOT; clockevent_set_clock(cd, mips_hpt_frequency); /* */ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->rating = 300; cd->irq = irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = mips_next_event; cd->set_mode = mips_set_clock_mode; cd->event_handler = mips_event_handler; clockevents_register_device(cd); if (cp0_timer_irq_installed) return 0; cp0_timer_irq_installed = 1; setup_irq(irq, &c0_compare_irqaction); return 0; }
int __init ds1287_clockevent_init(int irq) { struct clock_event_device *cd; cd = &ds1287_clockevent; cd->rating = 100; cd->irq = irq; clockevent_set_clock(cd, 32768); cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd); clockevents_register_device(&ds1287_clockevent); return setup_irq(irq, &ds1287_irqaction); }
/* * Initialize the conversion factor and the min/max deltas of the clock event * structure and register the clock event source with the framework. */ void __init setup_pit_timer(void) { struct clock_event_device *cd = &pit_clockevent; unsigned int cpu = smp_processor_id(); /* * Start pit with the boot cpu mask and make it global after the * IO_APIC has been initialized. */ cd->cpumask = cpumask_of(cpu); clockevent_set_clock(cd, CLOCK_TICK_RATE); cd->max_delta_ns = clockevent_delta2ns(0x7FFF, cd); cd->min_delta_ns = clockevent_delta2ns(0xF, cd); clockevents_register_device(cd); setup_irq(0, &irq0); }
static int ra_systick_clockevent_init(void) { unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; unsigned int irq; /* * With vectored interrupts things are getting platform specific. * get_c0_compare_int is a hook to allow a platform to return the * interrupt number of it's liking. */ irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; cd = &ra_systick; cd->features = CLOCK_EVT_FEAT_ONESHOT; cd->name = "Ralink System Tick Counter"; clockevent_set_clock(cd, 50000); cd->max_delta_ns = clockevent_delta2ns(0x7fff, cd); cd->min_delta_ns = clockevent_delta2ns(0x3, cd); #if defined (CONFIG_RALINK_MT7621) /* must be lower than MIPS original cd rating(300) to activate "broadcast mode" */ cd->rating = 250; #else /* must be higher than MIPS original cd rating(300). */ cd->rating = 350; #endif cd->irq = irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = ra_systick_next_event; cd->set_mode = ra_systick_set_clock_mode; cd->event_handler = ra_systick_event_handler; /* install timer irq handler before MIPS BSP code. */ if (!cp0_timer_irq_installed){ cp0_timer_irq_installed = 1; setup_irq(irq, &ra_systick_irqaction); } clockevents_register_device(cd); /* Enable ralink system count register */ (*((volatile u32 *)(RALINK_MCNT_CFG))) = 0x3; return 0; }
void sb1480_clockevent_init(void) { unsigned int cpu = smp_processor_id(); unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu; struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu); struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu); unsigned char *name = per_cpu(sibyte_hpt_name, cpu); BUG_ON(cpu > 3); /* Only have 4 general purpose timers */ sprintf(name, "bcm1480-counter-%d", cpu); cd->name = name; cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; clockevent_set_clock(cd, V_SCD_TIMER_FREQ); cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd); cd->min_delta_ns = clockevent_delta2ns(2, cd); cd->rating = 200; cd->irq = irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = sibyte_next_event; cd->set_state_shutdown = sibyte_shutdown; cd->set_state_periodic = sibyte_set_periodic; cd->set_state_oneshot = sibyte_shutdown; clockevents_register_device(cd); bcm1480_mask_irq(cpu, irq); /* * Map the timer interrupt to IP[4] of this cpu */ __raw_writeq(IMR_IP4_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3))); bcm1480_unmask_irq(cpu, irq); action->handler = sibyte_counter_handler; action->flags = IRQF_PERCPU | IRQF_TIMER; action->name = name; action->dev_id = cd; irq_set_affinity(irq, cpumask_of(cpu)); setup_irq(irq, action); }
int __cpuinit gic_clockevent_init(void) { unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; unsigned int irq; if (!cpu_has_counter || !gic_frequency) return -ENXIO; irq = MIPS_GIC_IRQ_BASE; cd = &per_cpu(gic_clockevent_device, cpu); cd->name = "MIPS GIC"; cd->features = CLOCK_EVT_FEAT_ONESHOT; clockevent_set_clock(cd, gic_frequency); /* Calculate the min / max delta */ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->rating = 300; cd->irq = irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = gic_next_event; cd->set_mode = gic_set_clock_mode; cd->event_handler = gic_event_handler; clockevents_register_device(cd); GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_MAP), 0x80000002); GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), GIC_VPE_SMASK_CMP_MSK); if (gic_timer_irq_installed) return 0; gic_timer_irq_installed = 1; setup_irq(irq, &gic_compare_irqaction); irq_set_handler(irq, handle_percpu_irq); return 0; }
static int __init gt641xx_timer0_clockevent_init(void) { struct clock_event_device *cd; if (!gt641xx_base_clock) return 0; GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ); cd = >641xx_timer0_clockevent; cd->rating = 200 + gt641xx_base_clock / 10000000; clockevent_set_clock(cd, gt641xx_base_clock); cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->cpumask = cpumask_of(0); clockevents_register_device(>641xx_timer0_clockevent); return setup_irq(GT641XX_TIMER0_IRQ, >641xx_timer0_irqaction); }
void __cpuinit hub_rt_clock_event_init(void) { unsigned int cpu = smp_processor_id(); struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu); unsigned char *name = per_cpu(hub_rt_name, cpu); int irq = rt_timer_irq; sprintf(name, "hub-rt %d", cpu); cd->name = name; cd->features = CLOCK_EVT_FEAT_ONESHOT; clockevent_set_clock(cd, CYCLES_PER_SEC); cd->max_delta_ns = clockevent_delta2ns(0xfffffffffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->rating = 200; cd->irq = irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = rt_next_event; cd->set_mode = rt_set_mode; clockevents_register_device(cd); }
void __init txx9_clockevent_init(unsigned long baseaddr, int irq, unsigned int imbusclk) { struct clock_event_device *cd = &txx9tmr_clock_event_device; struct txx9_tmr_reg __iomem *tmrptr; tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg)); txx9tmr_stop_and_clear(tmrptr); __raw_writel(TIMER_CCD, &tmrptr->ccdr); __raw_writel(0, &tmrptr->itmr); txx9_tmrptr = tmrptr; clockevent_set_clock(cd, TIMER_CLK(imbusclk)); cd->max_delta_ns = clockevent_delta2ns(0xffffffff >> (32 - TXX9_TIMER_BITS), cd); cd->min_delta_ns = clockevent_delta2ns(0xf, cd); cd->irq = irq; clockevents_register_device(cd); setup_irq(irq, &txx9tmr_irq); printk(KERN_INFO "TXx9: clockevent device at 0x%lx, irq %d\n", baseaddr, irq); }
void __init plat_time_init(void) { int ret; uint32_t clk_rate; uint16_t ctrl; jz4740_timer_init(); clk_rate = jz4740_clock_bdata.ext_rate >> 4; jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ); clockevent_set_clock(&jz4740_clockevent, clk_rate); jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent); jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent); jz4740_clockevent.cpumask = cpumask_of(0); clockevents_register_device(&jz4740_clockevent); clocksource_set_clock(&jz4740_clocksource, clk_rate); ret = clocksource_register(&jz4740_clocksource); if (ret) printk(KERN_ERR "Failed to register clocksource: %d\n", ret); setup_irq(JZ4740_IRQ_TCU0, &timer_irqaction); ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT; jz4740_timer_set_ctrl(TIMER_CLOCKEVENT, ctrl); jz4740_timer_set_ctrl(TIMER_CLOCKSOURCE, ctrl); jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick); jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT); jz4740_timer_set_period(TIMER_CLOCKSOURCE, 0xffff); jz4740_timer_enable(TIMER_CLOCKEVENT); jz4740_timer_enable(TIMER_CLOCKSOURCE); }
static void __init ls1x_time_init(void) { struct clock_event_device *cd = &ls1x_clockevent; int ret; if (!mips_hpt_frequency) panic("Invalid timer clock rate"); ls1x_pwmtimer_init(); clockevent_set_clock(cd, mips_hpt_frequency); cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x000300, cd); cd->cpumask = cpumask_of(smp_processor_id()); clockevents_register_device(cd); ls1x_clocksource.rating = 200 + mips_hpt_frequency / 10000000; ret = clocksource_register_hz(&ls1x_clocksource, mips_hpt_frequency); if (ret) panic(KERN_ERR "Failed to register clocksource: %d\n", ret); setup_irq(LS1X_TIMER_IRQ, &ls1x_pwmtimer_irqaction); }
void __init setup_mfgpt0_timer(void) { u32 basehi; struct clock_event_device *cd = &mfgpt_clockevent; unsigned int cpu = smp_processor_id(); cd->cpumask = cpumask_of(cpu); clockevent_set_clock(cd, MFGPT_TICK_RATE); cd->max_delta_ns = clockevent_delta2ns(0xffff, cd); cd->min_delta_ns = clockevent_delta2ns(0xf, cd); _wrmsr(DIVIL_MSR_REG(MFGPT_IRQ), 0, 0x100); _wrmsr(DIVIL_MSR_REG(PIC_ZSEL_LOW), 0, 0x50000); _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base); clockevents_register_device(cd); setup_irq(CS5536_MFGPT_INTR, &irq5); }
/* * Initialize the conversion factor and the min/max deltas of the clock event * structure and register the clock event source with the framework. */ void __init setup_mfgpt0_timer(void) { u32 basehi; struct clock_event_device *cd = &mfgpt_clockevent; unsigned int cpu = smp_processor_id(); cd->cpumask = cpumask_of(cpu); clockevent_set_clock(cd, MFGPT_TICK_RATE); cd->max_delta_ns = clockevent_delta2ns(0xffff, cd); cd->min_delta_ns = clockevent_delta2ns(0xf, cd); /* Enable MFGPT0 Comparator 2 Output to the Interrupt Mapper */ _wrmsr(DIVIL_MSR_REG(MFGPT_IRQ), 0, 0x100); /* Enable Interrupt Gate 5 */ _wrmsr(DIVIL_MSR_REG(PIC_ZSEL_LOW), 0, 0x50000); /* get MFGPT base address */ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base); clockevents_register_device(cd); setup_irq(CS5536_MFGPT_INTR, &irq5); }