[go: nahoru, domu]

138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON/*
238d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
338d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON *
438d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON * This program is free software; you can redistribute it and/or modify
538d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON * it under the terms of the GNU General Public License as published by
638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON * the Free Software Foundation; either version 2 of the License, or
738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON * (at your option) any later version.
838d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON *
938d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON */
1038d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
1138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#include <linux/clk-provider.h>
1238d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#include <linux/clkdev.h>
1338d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#include <linux/clk/at91_pmc.h>
1438d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#include <linux/delay.h>
1538d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#include <linux/of.h>
1638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#include <linux/of_address.h>
1738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#include <linux/of_irq.h>
1838d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#include <linux/io.h>
1938d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#include <linux/interrupt.h>
2038d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#include <linux/irq.h>
2138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#include <linux/sched.h>
2238d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#include <linux/wait.h>
2338d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
2438d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#include "pmc.h"
2538d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
2638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#define SLOW_CLOCK_FREQ		32768
2738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#define MAINF_DIV		16
2838d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#define MAINFRDY_TIMEOUT	(((MAINF_DIV + 1) * USEC_PER_SEC) / \
2938d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON				 SLOW_CLOCK_FREQ)
3038d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#define MAINF_LOOP_MIN_WAIT	(USEC_PER_SEC / SLOW_CLOCK_FREQ)
3138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON#define MAINF_LOOP_MAX_WAIT	MAINFRDY_TIMEOUT
3238d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
3327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON#define MOR_KEY_MASK		(0xff << 16)
3427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
3527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstruct clk_main_osc {
3638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	struct clk_hw hw;
3738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	struct at91_pmc *pmc;
3838d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	unsigned int irq;
3938d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	wait_queue_head_t wait;
4038d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON};
4138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
4227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON#define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw)
4327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
4427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstruct clk_main_rc_osc {
4527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_hw hw;
4627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct at91_pmc *pmc;
4727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	unsigned int irq;
4827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	wait_queue_head_t wait;
4927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	unsigned long frequency;
5027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	unsigned long accuracy;
5127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON};
5227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
5327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON#define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw)
5427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
5527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstruct clk_rm9200_main {
5627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_hw hw;
5727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct at91_pmc *pmc;
5827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON};
5927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
6027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON#define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw)
6138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
6227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstruct clk_sam9x5_main {
6327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_hw hw;
6427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct at91_pmc *pmc;
6527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	unsigned int irq;
6627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	wait_queue_head_t wait;
6727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	u8 parent;
6827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON};
6927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
7027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON#define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw)
7127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
7227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic irqreturn_t clk_main_osc_irq_handler(int irq, void *dev_id)
7338d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON{
7427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_main_osc *osc = dev_id;
7538d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
7627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	wake_up(&osc->wait);
7727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	disable_irq_nosync(osc->irq);
7838d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
7938d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	return IRQ_HANDLED;
8038d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON}
8138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
8227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic int clk_main_osc_prepare(struct clk_hw *hw)
8338d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON{
8427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_main_osc *osc = to_clk_main_osc(hw);
8527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct at91_pmc *pmc = osc->pmc;
8638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	u32 tmp;
8738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
8827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK;
8927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (tmp & AT91_PMC_OSCBYPASS)
9027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return 0;
9127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
9227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!(tmp & AT91_PMC_MOSCEN)) {
9327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY;
9427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		pmc_write(pmc, AT91_CKGR_MOR, tmp);
9527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	}
9627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
9738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS)) {
9827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		enable_irq(osc->irq);
9927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		wait_event(osc->wait,
10038d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON			   pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS);
10138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	}
10238d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
10327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return 0;
10427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
10527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
10627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic void clk_main_osc_unprepare(struct clk_hw *hw)
10727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
10827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_main_osc *osc = to_clk_main_osc(hw);
10927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct at91_pmc *pmc = osc->pmc;
11027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	u32 tmp = pmc_read(pmc, AT91_CKGR_MOR);
11127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
11227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (tmp & AT91_PMC_OSCBYPASS)
11327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return;
11427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
11527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!(tmp & AT91_PMC_MOSCEN))
11627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return;
11727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
11827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN);
11927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
12027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
12127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
12227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic int clk_main_osc_is_prepared(struct clk_hw *hw)
12327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
12427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_main_osc *osc = to_clk_main_osc(hw);
12527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct at91_pmc *pmc = osc->pmc;
12627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	u32 tmp = pmc_read(pmc, AT91_CKGR_MOR);
12727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
12827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (tmp & AT91_PMC_OSCBYPASS)
12927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return 1;
13027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
13127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS) &&
13227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		  (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCEN));
13327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
13427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
13527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic const struct clk_ops main_osc_ops = {
13627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.prepare = clk_main_osc_prepare,
13727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.unprepare = clk_main_osc_unprepare,
13827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.is_prepared = clk_main_osc_is_prepared,
13927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON};
14027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
14127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic struct clk * __init
14227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONat91_clk_register_main_osc(struct at91_pmc *pmc,
14327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			   unsigned int irq,
14427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			   const char *name,
14527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			   const char *parent_name,
14627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			   bool bypass)
14727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
14827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	int ret;
14927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_main_osc *osc;
15027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk *clk = NULL;
15127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_init_data init;
15227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
15327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!pmc || !irq || !name || !parent_name)
15427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return ERR_PTR(-EINVAL);
15527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
15627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
15727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!osc)
15827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return ERR_PTR(-ENOMEM);
15927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
16027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.name = name;
16127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.ops = &main_osc_ops;
16227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.parent_names = &parent_name;
16327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.num_parents = 1;
16427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.flags = CLK_IGNORE_UNUSED;
16527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
16627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	osc->hw.init = &init;
16727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	osc->pmc = pmc;
16827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	osc->irq = irq;
16927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
17027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init_waitqueue_head(&osc->wait);
17127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	irq_set_status_flags(osc->irq, IRQ_NOAUTOEN);
17227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	ret = request_irq(osc->irq, clk_main_osc_irq_handler,
17327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			  IRQF_TRIGGER_HIGH, name, osc);
17427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (ret)
17527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return ERR_PTR(ret);
17627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
17727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (bypass)
17827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		pmc_write(pmc, AT91_CKGR_MOR,
17927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			  (pmc_read(pmc, AT91_CKGR_MOR) &
18027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			   ~(MOR_KEY_MASK | AT91_PMC_MOSCEN)) |
18127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			  AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
18227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
18327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	clk = clk_register(NULL, &osc->hw);
18427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (IS_ERR(clk)) {
18527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		free_irq(irq, osc);
18627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		kfree(osc);
18727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	}
18827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
18927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return clk;
19027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
19127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
19227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONvoid __init of_at91rm9200_clk_main_osc_setup(struct device_node *np,
19327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON					     struct at91_pmc *pmc)
19427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
19527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk *clk;
19627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	unsigned int irq;
19727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	const char *name = np->name;
19827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	const char *parent_name;
19927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	bool bypass;
20027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
20127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	of_property_read_string(np, "clock-output-names", &name);
20227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	bypass = of_property_read_bool(np, "atmel,osc-bypass");
20327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	parent_name = of_clk_get_parent_name(np, 0);
20427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
20527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	irq = irq_of_parse_and_map(np, 0);
20627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!irq)
20727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return;
20827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
20927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	clk = at91_clk_register_main_osc(pmc, irq, name, parent_name, bypass);
21027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (IS_ERR(clk))
21127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return;
21227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
21327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	of_clk_add_provider(np, of_clk_src_simple_get, clk);
21427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
21527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
21627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic irqreturn_t clk_main_rc_osc_irq_handler(int irq, void *dev_id)
21727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
21827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_main_rc_osc *osc = dev_id;
21927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
22027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	wake_up(&osc->wait);
22127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	disable_irq_nosync(osc->irq);
22227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
22327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return IRQ_HANDLED;
22427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
22527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
22627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic int clk_main_rc_osc_prepare(struct clk_hw *hw)
22727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
22827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
22927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct at91_pmc *pmc = osc->pmc;
23027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	u32 tmp;
23127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
23227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK;
23327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
23427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!(tmp & AT91_PMC_MOSCRCEN)) {
23527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		tmp |= AT91_PMC_MOSCRCEN | AT91_PMC_KEY;
23627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		pmc_write(pmc, AT91_CKGR_MOR, tmp);
23727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	}
23827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
23927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS)) {
24027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		enable_irq(osc->irq);
24127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		wait_event(osc->wait,
24227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			   pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS);
24327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	}
24427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
24527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return 0;
24627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
24727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
24827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic void clk_main_rc_osc_unprepare(struct clk_hw *hw)
24927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
25027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
25127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct at91_pmc *pmc = osc->pmc;
25227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	u32 tmp = pmc_read(pmc, AT91_CKGR_MOR);
25327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
25427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!(tmp & AT91_PMC_MOSCRCEN))
25527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return;
25627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
25727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	tmp &= ~(MOR_KEY_MASK | AT91_PMC_MOSCRCEN);
25827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
25927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
26027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
26127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic int clk_main_rc_osc_is_prepared(struct clk_hw *hw)
26227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
26327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
26427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct at91_pmc *pmc = osc->pmc;
26527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
26627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS) &&
26727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		  (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCRCEN));
26827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
26927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
27027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw,
27127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON						 unsigned long parent_rate)
27227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
27327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
27427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
27527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return osc->frequency;
27627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
27727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
27827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw *hw,
27927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON						     unsigned long parent_acc)
28027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
28127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
28227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
28327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return osc->accuracy;
28427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
28527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
28627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic const struct clk_ops main_rc_osc_ops = {
28727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.prepare = clk_main_rc_osc_prepare,
28827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.unprepare = clk_main_rc_osc_unprepare,
28927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.is_prepared = clk_main_rc_osc_is_prepared,
29027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.recalc_rate = clk_main_rc_osc_recalc_rate,
29127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
29227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON};
29327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
29427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic struct clk * __init
29527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONat91_clk_register_main_rc_osc(struct at91_pmc *pmc,
29627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			      unsigned int irq,
29727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			      const char *name,
29827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			      u32 frequency, u32 accuracy)
29927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
30027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	int ret;
30127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_main_rc_osc *osc;
30227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk *clk = NULL;
30327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_init_data init;
30427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
30527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!pmc || !irq || !name || !frequency)
30627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return ERR_PTR(-EINVAL);
30727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
30827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
30927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!osc)
31027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return ERR_PTR(-ENOMEM);
31127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
31227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.name = name;
31327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.ops = &main_rc_osc_ops;
31427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.parent_names = NULL;
31527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.num_parents = 0;
31627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED;
31727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
31827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	osc->hw.init = &init;
31927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	osc->pmc = pmc;
32027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	osc->irq = irq;
32127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	osc->frequency = frequency;
32227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	osc->accuracy = accuracy;
32327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
32427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init_waitqueue_head(&osc->wait);
32527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	irq_set_status_flags(osc->irq, IRQ_NOAUTOEN);
32627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	ret = request_irq(osc->irq, clk_main_rc_osc_irq_handler,
32727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			  IRQF_TRIGGER_HIGH, name, osc);
32827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (ret)
32927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return ERR_PTR(ret);
33027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
33127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	clk = clk_register(NULL, &osc->hw);
33227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (IS_ERR(clk)) {
33327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		free_irq(irq, osc);
33427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		kfree(osc);
33527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	}
33627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
33727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return clk;
33827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
33927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
34027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONvoid __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np,
34127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON						struct at91_pmc *pmc)
34227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
34327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk *clk;
34427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	unsigned int irq;
34527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	u32 frequency = 0;
34627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	u32 accuracy = 0;
34727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	const char *name = np->name;
34827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
34927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	of_property_read_string(np, "clock-output-names", &name);
35027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	of_property_read_u32(np, "clock-frequency", &frequency);
35127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	of_property_read_u32(np, "clock-accuracy", &accuracy);
35227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
35327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	irq = irq_of_parse_and_map(np, 0);
35427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!irq)
35527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return;
35627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
35727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	clk = at91_clk_register_main_rc_osc(pmc, irq, name, frequency,
35827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON					    accuracy);
35927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (IS_ERR(clk))
36027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return;
36127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
36227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	of_clk_add_provider(np, of_clk_src_simple_get, clk);
36327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
36427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
36527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
36627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic int clk_main_probe_frequency(struct at91_pmc *pmc)
36727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
36827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	unsigned long prep_time, timeout;
36927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	u32 tmp;
37038d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
37138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT);
37238d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	do {
37327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		prep_time = jiffies;
37438d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON		tmp = pmc_read(pmc, AT91_CKGR_MCFR);
37538d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON		if (tmp & AT91_PMC_MAINRDY)
37638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON			return 0;
37738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON		usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
37827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	} while (time_before(prep_time, timeout));
37938d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
38027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return -ETIMEDOUT;
38138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON}
38238d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
38327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic unsigned long clk_main_recalc_rate(struct at91_pmc *pmc,
38427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON					  unsigned long parent_rate)
38538d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON{
38627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	u32 tmp;
38727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
38827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (parent_rate)
38927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return parent_rate;
39027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
3914da66b631f6bee2dfdb77b571418f11016a7ba68Alexandre Belloni	pr_warn("Main crystal frequency not set, using approximate value\n");
39227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	tmp = pmc_read(pmc, AT91_CKGR_MCFR);
39327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!(tmp & AT91_PMC_MAINRDY))
39427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return 0;
39538d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
39627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return ((tmp & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
39738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON}
39838d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
39927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic int clk_rm9200_main_prepare(struct clk_hw *hw)
40038d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON{
40127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
40227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
40327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return clk_main_probe_frequency(clkmain->pmc);
40427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
40527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
40627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic int clk_rm9200_main_is_prepared(struct clk_hw *hw)
40727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
40827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
40927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
41027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return !!(pmc_read(clkmain->pmc, AT91_CKGR_MCFR) & AT91_PMC_MAINRDY);
41127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
41227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
41327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw,
41427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON						 unsigned long parent_rate)
41527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
41627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
41727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
41827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return clk_main_recalc_rate(clkmain->pmc, parent_rate);
41927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
42027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
42127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic const struct clk_ops rm9200_main_ops = {
42227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.prepare = clk_rm9200_main_prepare,
42327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.is_prepared = clk_rm9200_main_is_prepared,
42427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.recalc_rate = clk_rm9200_main_recalc_rate,
42527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON};
42627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
42727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic struct clk * __init
42827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONat91_clk_register_rm9200_main(struct at91_pmc *pmc,
42927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			      const char *name,
43027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			      const char *parent_name)
43127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
43227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_rm9200_main *clkmain;
43327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk *clk = NULL;
43427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_init_data init;
43527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
43627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!pmc || !name)
43727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return ERR_PTR(-EINVAL);
43827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
43927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!parent_name)
44027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return ERR_PTR(-EINVAL);
44127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
44227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
44327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!clkmain)
44427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return ERR_PTR(-ENOMEM);
44527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
44627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.name = name;
44727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.ops = &rm9200_main_ops;
44827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.parent_names = &parent_name;
44927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.num_parents = 1;
45027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.flags = 0;
45127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
45227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	clkmain->hw.init = &init;
45327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	clkmain->pmc = pmc;
45427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
45527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	clk = clk_register(NULL, &clkmain->hw);
45627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (IS_ERR(clk))
45727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		kfree(clkmain);
45827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
45927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return clk;
46027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
46127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
46227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONvoid __init of_at91rm9200_clk_main_setup(struct device_node *np,
46327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON					 struct at91_pmc *pmc)
46427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
46527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk *clk;
46627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	const char *parent_name;
46727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	const char *name = np->name;
46827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
46927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	parent_name = of_clk_get_parent_name(np, 0);
47027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	of_property_read_string(np, "clock-output-names", &name);
47127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
47227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	clk = at91_clk_register_rm9200_main(pmc, name, parent_name);
47327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (IS_ERR(clk))
47427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return;
47527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
47627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	of_clk_add_provider(np, of_clk_src_simple_get, clk);
47727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
47827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
47927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic irqreturn_t clk_sam9x5_main_irq_handler(int irq, void *dev_id)
48027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
48127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_sam9x5_main *clkmain = dev_id;
48227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
48327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	wake_up(&clkmain->wait);
48427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	disable_irq_nosync(clkmain->irq);
48527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
48627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return IRQ_HANDLED;
48727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
48827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
48927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic int clk_sam9x5_main_prepare(struct clk_hw *hw)
49027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
49127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
49238d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	struct at91_pmc *pmc = clkmain->pmc;
49338d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
49427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS)) {
49527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		enable_irq(clkmain->irq);
49627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		wait_event(clkmain->wait,
49727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			   pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS);
49827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	}
49927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
50027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return clk_main_probe_frequency(pmc);
50127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
50238d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
50327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic int clk_sam9x5_main_is_prepared(struct clk_hw *hw)
50427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
50527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
50638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
50727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return !!(pmc_read(clkmain->pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS);
50838d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON}
50938d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
51027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw,
51127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON						 unsigned long parent_rate)
51227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
51327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
51427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
51527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return clk_main_recalc_rate(clkmain->pmc, parent_rate);
51627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
51727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
51827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
51927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
52027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
52127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct at91_pmc *pmc = clkmain->pmc;
52227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	u32 tmp;
52327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
52427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (index > 1)
52527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return -EINVAL;
52627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
52727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK;
52827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
52927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (index && !(tmp & AT91_PMC_MOSCSEL))
53027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
53127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	else if (!index && (tmp & AT91_PMC_MOSCSEL))
53227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		pmc_write(pmc, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
53327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
53427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS)) {
53527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		enable_irq(clkmain->irq);
53627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		wait_event(clkmain->wait,
53727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			   pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS);
53827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	}
53927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
54027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return 0;
54127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
54227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
54327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic u8 clk_sam9x5_main_get_parent(struct clk_hw *hw)
54427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON{
54527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
54627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
54727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	return !!(pmc_read(clkmain->pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCEN);
54827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON}
54927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
55027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONstatic const struct clk_ops sam9x5_main_ops = {
55127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.prepare = clk_sam9x5_main_prepare,
55227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.is_prepared = clk_sam9x5_main_is_prepared,
55327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.recalc_rate = clk_sam9x5_main_recalc_rate,
55427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.set_parent = clk_sam9x5_main_set_parent,
55527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	.get_parent = clk_sam9x5_main_get_parent,
55638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON};
55738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
55838d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLONstatic struct clk * __init
55927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONat91_clk_register_sam9x5_main(struct at91_pmc *pmc,
56027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			      unsigned int irq,
56127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			      const char *name,
56227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			      const char **parent_names,
56327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			      int num_parents)
56438d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON{
56538d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	int ret;
56627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	struct clk_sam9x5_main *clkmain;
56738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	struct clk *clk = NULL;
56838d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	struct clk_init_data init;
56938d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
57038d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	if (!pmc || !irq || !name)
57138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON		return ERR_PTR(-EINVAL);
57238d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
57327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (!parent_names || !num_parents)
57438d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON		return ERR_PTR(-EINVAL);
57538d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
57638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
57738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	if (!clkmain)
57838d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON		return ERR_PTR(-ENOMEM);
57938d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
58038d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	init.name = name;
58127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.ops = &sam9x5_main_ops;
58227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.parent_names = parent_names;
58327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.num_parents = num_parents;
58427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	init.flags = CLK_SET_PARENT_GATE;
58538d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
58638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	clkmain->hw.init = &init;
58738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	clkmain->pmc = pmc;
58838d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	clkmain->irq = irq;
58927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	clkmain->parent = !!(pmc_read(clkmain->pmc, AT91_CKGR_MOR) &
59027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			     AT91_PMC_MOSCEN);
59138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	init_waitqueue_head(&clkmain->wait);
59238d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	irq_set_status_flags(clkmain->irq, IRQ_NOAUTOEN);
59327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	ret = request_irq(clkmain->irq, clk_sam9x5_main_irq_handler,
59427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			  IRQF_TRIGGER_HIGH, name, clkmain);
59538d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	if (ret)
59638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON		return ERR_PTR(ret);
59738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
59838d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	clk = clk_register(NULL, &clkmain->hw);
59938d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	if (IS_ERR(clk)) {
60038d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON		free_irq(clkmain->irq, clkmain);
60138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON		kfree(clkmain);
60238d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	}
60338d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
60438d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	return clk;
60538d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON}
60638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
60727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLONvoid __init of_at91sam9x5_clk_main_setup(struct device_node *np,
60827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON					 struct at91_pmc *pmc)
60938d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON{
61038d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	struct clk *clk;
61127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	const char *parent_names[2];
61227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	int num_parents;
61338d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	unsigned int irq;
61438d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	const char *name = np->name;
61527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	int i;
61627cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
61727cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells");
61827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	if (num_parents <= 0 || num_parents > 2)
61927cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		return;
62027cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
62127cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	for (i = 0; i < num_parents; ++i) {
62227cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		parent_names[i] = of_clk_get_parent_name(np, i);
62327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON		if (!parent_names[i])
62427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON			return;
62527cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	}
62638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
62738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	of_property_read_string(np, "clock-output-names", &name);
62827cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON
62938d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	irq = irq_of_parse_and_map(np, 0);
63038d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	if (!irq)
63138d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON		return;
63238d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
63327cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON	clk = at91_clk_register_sam9x5_main(pmc, irq, name, parent_names,
63427cb1c2083373a44130d50d4d2fb64cf7eff2d90Boris BREZILLON					    num_parents);
63538d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	if (IS_ERR(clk))
63638d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON		return;
63738d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON
63838d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON	of_clk_add_provider(np, of_clk_src_simple_get, clk);
63938d34c3120b5588e2bd561baa4c5cfef1a4917bbBoris BREZILLON}
640