drivers/clk/meson/g12a.c

Source file repositories/reference/linux-study-clean/drivers/clk/meson/g12a.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/meson/g12a.c
Extension
.c
Size
150689 bytes
Lines
5474
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 g12a_cpu_clk_dyn_nb_data {
	struct notifier_block nb;
	struct clk_hw *xtal;
	struct clk_hw *cpu_clk_dyn;
	struct clk_hw *cpu_clk_postmux0;
	struct clk_hw *cpu_clk_postmux1;
	struct clk_hw *cpu_clk_premux1;
};

static int g12a_cpu_clk_dyn_notifier_cb(struct notifier_block *nb,
					unsigned long event, void *data)
{
	struct g12a_cpu_clk_dyn_nb_data *nb_data =
		container_of(nb, struct g12a_cpu_clk_dyn_nb_data, nb);

	switch (event) {
	case PRE_RATE_CHANGE:
		/*
		 * This notifier means cpu_clk_dyn0 clock will be changed
		 * to feed cpu_clk, this is the current path :
		 * cpu_clk
		 *    \- cpu_clk_dyn
		 *          \- cpu_clk_dyn0
		 *                \- cpu_clk_dyn0_div
		 *                      \- cpu_clk_dyn0_sel
		 *				\- fclk_div3 or fclk_div2
		 *		OR
		 *                \- cpu_clk_dyn0_sel
		 *			\- fclk_div3 or fclk_div2
		 */

		/* Setup cpu_clk_dyn1_sel to xtal */
		clk_hw_set_parent(nb_data->cpu_clk_premux1,
				  nb_data->xtal);

		/* Setup cpu_clk_dyn1 to bypass divider */
		clk_hw_set_parent(nb_data->cpu_clk_postmux1,
				  nb_data->cpu_clk_premux1);

		/* Switch to parking clk on cpu_clk_postmux1 */
		clk_hw_set_parent(nb_data->cpu_clk_dyn,
				  nb_data->cpu_clk_postmux1);

		/*
		 * Now, cpu_clk is 24MHz in the current path :
		 * cpu_clk
		 *    \- cpu_clk_dyn
		 *          \- cpu_clk_dyn1
		 *                \- cpu_clk_dyn1_sel
		 *                      \- xtal
		 */

		udelay(100);

		return NOTIFY_OK;

	case POST_RATE_CHANGE:
		/*
		 * The cpu_clk_dyn0 has ben updated, now switch back
		 * cpu_clk_dyn to cpu_clk_dyn0 and take the changes
		 * in account.
		 */

		/* Configure cpu_clk_dyn back to cpu_clk_postmux0 */
		clk_hw_set_parent(nb_data->cpu_clk_dyn,
				  nb_data->cpu_clk_postmux0);

		/*
		 * new path :
		 * cpu_clk
		 *    \- cpu_clk_dyn
		 *          \- cpu_clk_dyn0
		 *                \- cpu_clk_dyn0_div
		 *                      \- cpu_clk_dyn0_sel
		 *				\- fclk_div3 or fclk_div2
		 *		OR
		 *                \- cpu_clk_dyn0_sel
		 *			\- fclk_div3 or fclk_div2
		 */

		udelay(100);

		return NOTIFY_OK;

	default:
		return NOTIFY_DONE;
	}
}

static struct g12a_cpu_clk_dyn_nb_data g12a_cpu_clk_dyn0_nb_data = {

Annotation

Implementation Notes