static void __init vexpress_sp810_init(void __iomem *base)
{
    int i;

    if (WARN_ON(!base))
        return;

    for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++) {
        char name[12];
        const char *parents[] = {
            "v2m:refclk32khz", /* REFCLK */
            "v2m:refclk1mhz" /* TIMCLK */
        };

        snprintf(name, ARRAY_SIZE(name), "timerclken%d", i);

        vexpress_sp810_timerclken[i] = clk_register_mux(NULL, name,
                                       parents, 2, 0, base + SCCTRL,
                                       SCCTRL_TIMERENnSEL_SHIFT(i), 1,
                                       0, &vexpress_sp810_lock);

        if (WARN_ON(IS_ERR(vexpress_sp810_timerclken[i])))
            break;
    }
}
Exemplo n.º 2
0
static u8 clk_sp810_timerclken_get_parent(struct clk_hw *hw)
{
	struct clk_sp810_timerclken *timerclken = to_clk_sp810_timerclken(hw);
	u32 val = readl(timerclken->sp810->base + SCCTRL);

	return !!(val & (1 << SCCTRL_TIMERENnSEL_SHIFT(timerclken->channel)));
}
Exemplo n.º 3
0
static int clk_sp810_timerclken_set_parent(struct clk_hw *hw, u8 index)
{
	struct clk_sp810_timerclken *timerclken = to_clk_sp810_timerclken(hw);
	struct clk_sp810 *sp810 = timerclken->sp810;
	u32 val, shift = SCCTRL_TIMERENnSEL_SHIFT(timerclken->channel);
	unsigned long flags = 0;

	if (WARN_ON(index > 1))
		return -EINVAL;

	spin_lock_irqsave(&sp810->lock, flags);

	val = readl(sp810->base + SCCTRL);
	val &= ~(1 << shift);
	val |= index << shift;
	writel(val, sp810->base + SCCTRL);

	spin_unlock_irqrestore(&sp810->lock, flags);

	return 0;
}