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