drivers/regulator/uniphier-regulator.c

Source file repositories/reference/linux-study-clean/drivers/regulator/uniphier-regulator.c

File Facts

System
Linux kernel
Corpus path
drivers/regulator/uniphier-regulator.c
Extension
.c
Size
5937 bytes
Lines
222
Domain
Driver Families
Bucket
drivers/regulator
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 uniphier_regulator_soc_data {
	int nclks;
	const char * const *clock_names;
	int nrsts;
	const char * const *reset_names;
	const struct regulator_desc *desc;
	const struct regmap_config *regconf;
};

struct uniphier_regulator_priv {
	struct clk_bulk_data clk[MAX_CLKS];
	struct reset_control *rst[MAX_RSTS];
	const struct uniphier_regulator_soc_data *data;
};

static const struct regulator_ops uniphier_regulator_ops = {
	.enable     = regulator_enable_regmap,
	.disable    = regulator_disable_regmap,
	.is_enabled = regulator_is_enabled_regmap,
};

static int uniphier_regulator_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct uniphier_regulator_priv *priv;
	struct regulator_config config = { };
	struct regulator_dev *rdev;
	struct regmap *regmap;
	void __iomem *base;
	const char *name;
	int i, ret, nr;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->data = of_device_get_match_data(dev);
	if (WARN_ON(!priv->data))
		return -EINVAL;

	base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(base))
		return PTR_ERR(base);

	for (i = 0; i < priv->data->nclks; i++)
		priv->clk[i].id = priv->data->clock_names[i];
	ret = devm_clk_bulk_get(dev, priv->data->nclks, priv->clk);
	if (ret)
		return ret;

	for (i = 0; i < priv->data->nrsts; i++) {
		name = priv->data->reset_names[i];
		priv->rst[i] = devm_reset_control_get_shared(dev, name);
		if (IS_ERR(priv->rst[i]))
			return PTR_ERR(priv->rst[i]);
	}

	ret = clk_bulk_prepare_enable(priv->data->nclks, priv->clk);
	if (ret)
		return ret;

	for (nr = 0; nr < priv->data->nrsts; nr++) {
		ret = reset_control_deassert(priv->rst[nr]);
		if (ret)
			goto out_rst_assert;
	}

	regmap = devm_regmap_init_mmio(dev, base, priv->data->regconf);
	if (IS_ERR(regmap)) {
		ret = PTR_ERR(regmap);
		goto out_rst_assert;
	}

	config.dev = dev;
	config.driver_data = priv;
	config.of_node = dev->of_node;
	config.regmap = regmap;
	config.init_data = of_get_regulator_init_data(dev, dev->of_node,
						      priv->data->desc);
	rdev = devm_regulator_register(dev, priv->data->desc, &config);
	if (IS_ERR(rdev)) {
		ret = PTR_ERR(rdev);
		goto out_rst_assert;
	}

	platform_set_drvdata(pdev, priv);

	return 0;

out_rst_assert:

Annotation

Implementation Notes