arch/mips/ath79/clock.c

Source file repositories/reference/linux-study-clean/arch/mips/ath79/clock.c

File Facts

System
Linux kernel
Corpus path
arch/mips/ath79/clock.c
Extension
.c
Size
20853 bytes
Lines
674
Domain
Architecture Layer
Bucket
arch/mips
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 *  Atheros AR71XX/AR724X/AR913X common routines
 *
 *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
 *  Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
 *
 *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <dt-bindings/clock/ath79-clk.h>

#include <asm/div64.h>

#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
#include "common.h"

#define AR71XX_BASE_FREQ	40000000
#define AR724X_BASE_FREQ	40000000

static struct clk *clks[ATH79_CLK_END];
static struct clk_onecell_data clk_data = {
	.clks = clks,
	.clk_num = ARRAY_SIZE(clks),
};

static const char * const clk_names[ATH79_CLK_END] = {
	[ATH79_CLK_CPU] = "cpu",
	[ATH79_CLK_DDR] = "ddr",
	[ATH79_CLK_AHB] = "ahb",
	[ATH79_CLK_REF] = "ref",
	[ATH79_CLK_MDIO] = "mdio",
};

static const char * __init ath79_clk_name(int type)
{
	BUG_ON(type >= ARRAY_SIZE(clk_names) || !clk_names[type]);
	return clk_names[type];
}

static void __init __ath79_set_clk(int type, const char *name, struct clk *clk)
{
	if (IS_ERR(clk))
		panic("failed to allocate %s clock structure", clk_names[type]);

	clks[type] = clk;
	clk_register_clkdev(clk, name, NULL);
}

static struct clk * __init ath79_set_clk(int type, unsigned long rate)
{
	const char *name = ath79_clk_name(type);
	struct clk *clk;

	clk = clk_register_fixed_rate(NULL, name, NULL, 0, rate);
	__ath79_set_clk(type, name, clk);
	return clk;
}

static struct clk * __init ath79_set_ff_clk(int type, const char *parent,
					    unsigned int mult, unsigned int div)
{
	const char *name = ath79_clk_name(type);
	struct clk *clk;

	clk = clk_register_fixed_factor(NULL, name, parent, 0, mult, div);
	__ath79_set_clk(type, name, clk);
	return clk;
}

static unsigned long __init ath79_setup_ref_clk(unsigned long rate)
{
	struct clk *clk = clks[ATH79_CLK_REF];

	if (clk)
		rate = clk_get_rate(clk);
	else
		clk = ath79_set_clk(ATH79_CLK_REF, rate);

	return rate;

Annotation

Implementation Notes