Exemplo n.º 1
0
static bool_t ce_init(struct clockevent_t * ce)
{
	struct clockevent_pdata_t * pdat = (struct clockevent_pdata_t *)ce->priv;

	clockevent_calc_mult_shift(ce, arm64_timer_frequecy(), 10);
	ce->min_delta_ns = clockevent_delta2ns(ce, 0x1);
	ce->max_delta_ns = clockevent_delta2ns(ce, 0xffffffff);

	if(!request_irq(pdat->irq, ce_interrupt, IRQ_TYPE_NONE, ce))
		return FALSE;
	arm64_timer_interrupt_disable();
	return TRUE;
}
Exemplo n.º 2
0
static bool_t s5p4418_ce_init(struct clockevent_t * ce)
{
	u64_t rate;

	s5p4418_timer_reset();

	if(!request_irq("TIMER0", s5p4418_ce_interrupt, IRQ_TYPE_NONE, ce))
	{
		LOG("can't request irq 'TIMER0'");
		return FALSE;
	}

	/* 9.375MHZ - 107ns */
	s5p4418_timer_enable(CE_TIMER_CHANNEL, 1);
	rate = s5p4418_timer_calc_tin(CE_TIMER_CHANNEL, 107);
	clockevent_calc_mult_shift(ce, rate, 10);
	ce->min_delta_ns = clockevent_delta2ns(ce, 0x1);
	ce->max_delta_ns = clockevent_delta2ns(ce, 0xffffffff);
	s5p4418_timer_count(CE_TIMER_CHANNEL, 0);
	s5p4418_timer_stop(CE_TIMER_CHANNEL);

	return TRUE;
}
Exemplo n.º 3
0
static struct device_t * ce_samsung_timer_probe(struct driver_t * drv, struct dtnode_t * n)
{
	struct ce_samsung_timer_pdata_t * pdat;
	struct clockevent_t * ce;
	struct device_t * dev;
	virtual_addr_t virt = phys_to_virt(dt_read_address(n));
	char * clk = dt_read_string(n, "clock-name", NULL);
	int irq = dt_read_int(n, "interrupt", -1);
	int channel = dt_read_int(n, "timer-channel", -1);
	u64_t rate;

	if(!search_clk(clk))
		return NULL;

	if(!irq_is_valid(irq))
		return NULL;

	if(channel < 0 || channel > 3)
		return NULL;

	pdat = malloc(sizeof(struct ce_samsung_timer_pdata_t));
	if(!pdat)
		return NULL;

	ce = malloc(sizeof(struct clockevent_t));
	if(!ce)
	{
		free(pdat);
		return NULL;
	}

	pdat->virt = virt;
	pdat->clk = strdup(clk);
	pdat->irq = irq;
	pdat->channel = channel;

	clk_enable(pdat->clk);
	rate = samsung_timer_calc_tin(pdat->virt, pdat->clk, pdat->channel, 107);
	clockevent_calc_mult_shift(ce, rate, 10);
	ce->name = alloc_device_name(dt_read_name(n), -1);
	ce->min_delta_ns = clockevent_delta2ns(ce, 0x1);
	ce->max_delta_ns = clockevent_delta2ns(ce, 0xffffffff);
	ce->next = ce_samsung_timer_next,
	ce->priv = pdat;

	if(!request_irq(pdat->irq, ce_samsung_timer_interrupt, IRQ_TYPE_NONE, ce))
	{
		clk_disable(pdat->clk);
		free(pdat->clk);

		free(ce->priv);
		free(ce);
		return NULL;
	}
	samsung_timer_enable(pdat->virt, pdat->channel, 1);
	samsung_timer_count(pdat->virt, pdat->channel, 0);
	samsung_timer_stop(pdat->virt, pdat->channel);

	if(!register_clockevent(&dev, ce))
	{
		samsung_timer_irq_clear(pdat->virt, pdat->channel);
		samsung_timer_stop(pdat->virt, pdat->channel);
		samsung_timer_disable(pdat->virt, pdat->channel);
		clk_disable(pdat->clk);
		free_irq(pdat->irq);
		free(pdat->clk);

		free_device_name(ce->name);
		free(ce->priv);
		free(ce);
		return NULL;
	}
	dev->driver = drv;

	return dev;
}