drivers/clk/samsung/clk-cpu.c

Source file repositories/reference/linux-study-clean/drivers/clk/samsung/clk-cpu.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/samsung/clk-cpu.c
Extension
.c
Size
23392 bytes
Lines
728
Domain
Driver Families
Bucket
drivers/clk
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct exynos_cpuclk_regs {
	u32 mux_sel;
	u32 mux_stat;
	u32 div_cpu0;
	u32 div_cpu1;
	u32 div_stat_cpu0;
	u32 div_stat_cpu1;

	u32 mux;
	u32 divs[4];
};

/**
 * struct exynos_cpuclk_chip - Chip specific data for CPU clock
 * @regs: register offsets for CPU related clocks
 * @pre_rate_cb: callback to run before CPU clock rate change
 * @post_rate_cb: callback to run after CPU clock rate change
 */
struct exynos_cpuclk_chip {
	const struct exynos_cpuclk_regs		*regs;
	exynos_rate_change_fn_t			pre_rate_cb;
	exynos_rate_change_fn_t			post_rate_cb;
};

/**
 * struct exynos_cpuclk - information about clock supplied to a CPU core
 * @hw:		handle between CCF and CPU clock
 * @alt_parent:	alternate parent clock to use when switching the speed
 *		of the primary parent clock
 * @base:	start address of the CPU clock registers block
 * @lock:	cpu clock domain register access lock
 * @cfg:	cpu clock rate configuration data
 * @num_cfgs:	number of array elements in @cfg array
 * @clk_nb:	clock notifier registered for changes in clock speed of the
 *		primary parent clock
 * @flags:	configuration flags for the CPU clock
 * @chip:	chip-specific data for the CPU clock
 *
 * This structure holds information required for programming the CPU clock for
 * various clock speeds.
 */
struct exynos_cpuclk {
	struct clk_hw				hw;
	const struct clk_hw			*alt_parent;
	void __iomem				*base;
	spinlock_t				*lock;
	const struct exynos_cpuclk_cfg_data	*cfg;
	const unsigned long			num_cfgs;
	struct notifier_block			clk_nb;
	unsigned long				flags;
	const struct exynos_cpuclk_chip		*chip;
};

/* ---- Common code --------------------------------------------------------- */

/* Divider stabilization time, msec */
#define MAX_STAB_TIME		10
#define MAX_DIV			8
#define DIV_MASK		GENMASK(2, 0)
#define DIV_MASK_ALL		GENMASK(31, 0)
#define MUX_MASK		GENMASK(2, 0)

/*
 * Helper function to wait until divider(s) have stabilized after the divider
 * value has changed.
 */
static void wait_until_divider_stable(void __iomem *div_reg, unsigned long mask)
{
	unsigned long timeout = jiffies + msecs_to_jiffies(MAX_STAB_TIME);

	do {
		if (!(readl(div_reg) & mask))
			return;
	} while (time_before(jiffies, timeout));

	if (!(readl(div_reg) & mask))
		return;

	pr_err("%s: timeout in divider stabilization\n", __func__);
}

/*
 * Helper function to wait until mux has stabilized after the mux selection
 * value was changed.
 */
static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
				  unsigned long mask, unsigned long mux_value)
{
	unsigned long timeout = jiffies + msecs_to_jiffies(MAX_STAB_TIME);

Annotation

Implementation Notes