Ejemplo n.º 1
0
static irqreturn_t gt_clockevent_interrupt(int irq, void *dev_id)
{
	struct clock_event_device *evt = dev_id;

	if (!(readl_relaxed(gt_base + GT_INT_STATUS) &
				GT_INT_STATUS_EVENT_FLAG))
		return IRQ_NONE;

	/**
	 * ERRATA 740657( Global Timer can send 2 interrupts for
	 * the same event in single-shot mode)
	 * Workaround:
	 *	Either disable single-shot mode.
	 *	Or
	 *	Modify the Interrupt Handler to avoid the
	 *	offending sequence. This is achieved by clearing
	 *	the Global Timer flag _after_ having incremented
	 *	the Comparator register	value to a higher value.
	 */
	if (evt->mode == CLOCK_EVT_MODE_ONESHOT)
		gt_compare_set(ULONG_MAX, 0);

	writel_relaxed(GT_INT_STATUS_EVENT_FLAG, gt_base + GT_INT_STATUS);
	evt->event_handler(evt);

	return IRQ_HANDLED;
}
Ejemplo n.º 2
0
static void gt_clockevent_set_mode(enum clock_event_mode mode,
				   struct clock_event_device *clk)
{
	unsigned long ctrl;

	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		gt_compare_set(DIV_ROUND_CLOSEST(gt_clk_rate, HZ), 1);
		break;
	case CLOCK_EVT_MODE_ONESHOT:
	case CLOCK_EVT_MODE_UNUSED:
	case CLOCK_EVT_MODE_SHUTDOWN:
		ctrl = readl(gt_base + GT_CONTROL);
		ctrl &= ~(GT_CONTROL_COMP_ENABLE |
				GT_CONTROL_IRQ_ENABLE | GT_CONTROL_AUTO_INC);
		writel(ctrl, gt_base + GT_CONTROL);
		break;
	default:
		break;
	}
}
Ejemplo n.º 3
0
static int gt_clockevent_set_next_event(unsigned long evt,
					struct clock_event_device *unused)
{
	gt_compare_set(evt, 0);
	return 0;
}
Ejemplo n.º 4
0
static int gt_clockevent_set_periodic(struct clock_event_device *evt)
{
    gt_compare_set(DIV_ROUND_CLOSEST(gt_clk_rate, HZ), 1);
    return 0;
}