drivers/clk/clk-conf.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/clk-conf.c
Extension
.c
Size
4748 bytes
Lines
184
Domain
Driver Families
Bucket
drivers/clk
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (rc < 0) {
			/* skip empty (null) phandles */
			if (rc == -ENOENT)
				continue;
			else
				return rc;
		}
		if (clkspec.np == node && !clk_supplier) {
			of_node_put(clkspec.np);
			return 0;
		}
		pclk = of_clk_get_from_provider(&clkspec);
		of_node_put(clkspec.np);
		if (IS_ERR(pclk)) {
			if (PTR_ERR(pclk) != -EPROBE_DEFER)
				pr_warn("clk: couldn't get parent clock %d for %pOF\n",
					index, node);
			return PTR_ERR(pclk);
		}

		rc = of_parse_phandle_with_args(node, "assigned-clocks",
					"#clock-cells", index, &clkspec);
		if (rc < 0)
			goto err;
		if (clkspec.np == node && !clk_supplier) {
			of_node_put(clkspec.np);
			rc = 0;
			goto err;
		}
		clk = of_clk_get_from_provider(&clkspec);
		of_node_put(clkspec.np);
		if (IS_ERR(clk)) {
			if (PTR_ERR(clk) != -EPROBE_DEFER)
				pr_warn("clk: couldn't get assigned clock %d for %pOF\n",
					index, node);
			rc = PTR_ERR(clk);
			goto err;
		}

		rc = clk_set_parent(clk, pclk);
		if (rc < 0)
			pr_err("clk: failed to reparent %s to %s: %d\n",
			       __clk_get_name(clk), __clk_get_name(pclk), rc);
		clk_put(clk);
		clk_put(pclk);
	}
	return 0;
err:
	clk_put(pclk);
	return rc;
}

static int __set_clk_rates(struct device_node *node, bool clk_supplier)
{
	struct of_phandle_args clkspec;
	int rc, count, count_64, index;
	struct clk *clk;
	u64 *rates_64 __free(kfree) = NULL;
	u32 *rates __free(kfree) = NULL;

	count = of_property_count_u32_elems(node, "assigned-clock-rates");
	count_64 = of_property_count_u64_elems(node, "assigned-clock-rates-u64");
	if (count_64 > 0) {
		count = count_64;
		rates_64 = kcalloc(count, sizeof(*rates_64), GFP_KERNEL);
		if (!rates_64)
			return -ENOMEM;

		rc = of_property_read_u64_array(node,
						"assigned-clock-rates-u64",
						rates_64, count);
	} else if (count > 0) {
		rates = kcalloc(count, sizeof(*rates), GFP_KERNEL);
		if (!rates)
			return -ENOMEM;

		rc = of_property_read_u32_array(node, "assigned-clock-rates",
						rates, count);
	} else {
		return 0;
	}

	if (rc)
		return rc;

	for (index = 0; index < count; index++) {
		unsigned long rate;

		if (rates_64)
			rate = rates_64[index];

Annotation

Implementation Notes