drivers/pmdomain/imx/gpcv2.c

Source file repositories/reference/linux-study-clean/drivers/pmdomain/imx/gpcv2.c

File Facts

System
Linux kernel
Corpus path
drivers/pmdomain/imx/gpcv2.c
Extension
.c
Size
40966 bytes
Lines
1556
Domain
Driver Families
Bucket
drivers/pmdomain
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 imx_pgc_regs {
	u16 map;
	u16 pup;
	u16 pdn;
	u16 hsk;
};

struct imx_pgc_domain {
	struct generic_pm_domain genpd;
	struct regmap *regmap;
	const struct imx_pgc_regs *regs;
	struct regulator *regulator;
	struct reset_control *reset;
	struct clk_bulk_data *clks;
	int num_clks;

	unsigned long pgc;

	const struct {
		u32 pxx;
		u32 map;
		u32 hskreq;
		u32 hskack;
	} bits;

	const int voltage;
	const bool keep_clocks;
	struct device *dev;

	unsigned int pgc_sw_pup_reg;
	unsigned int pgc_sw_pdn_reg;
};

struct imx_pgc_domain_data {
	const struct imx_pgc_domain *domains;
	size_t domains_num;
	const struct regmap_access_table *reg_access_table;
	const struct imx_pgc_regs *pgc_regs;
};

static inline struct imx_pgc_domain *
to_imx_pgc_domain(struct generic_pm_domain *genpd)
{
	return container_of(genpd, struct imx_pgc_domain, genpd);
}

static int imx_pgc_power_up(struct generic_pm_domain *genpd)
{
	struct imx_pgc_domain *domain = to_imx_pgc_domain(genpd);
	u32 reg_val, pgc;
	int ret;

	ret = pm_runtime_get_sync(domain->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(domain->dev);
		return ret;
	}

	if (!IS_ERR(domain->regulator)) {
		ret = regulator_enable(domain->regulator);
		if (ret) {
			dev_err(domain->dev,
				"failed to enable regulator: %pe\n",
				ERR_PTR(ret));
			goto out_put_pm;
		}
	}

	reset_control_assert(domain->reset);

	/* Enable reset clocks for all devices in the domain */
	ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks);
	if (ret) {
		dev_err(domain->dev, "failed to enable reset clocks\n");
		goto out_regulator_disable;
	}

	/* delays for reset to propagate */
	udelay(5);

	if (domain->bits.pxx) {
		/* request the domain to power up */
		regmap_update_bits(domain->regmap, domain->regs->pup,
				   domain->bits.pxx, domain->bits.pxx);
		/*
		 * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
		 * for PUP_REQ/PDN_REQ bit to be cleared
		 */
		ret = regmap_read_poll_timeout(domain->regmap,
					       domain->regs->pup, reg_val,

Annotation

Implementation Notes