drivers/clk/ti/clk-dra7-atl.c

Source file repositories/reference/linux-study-clean/drivers/clk/ti/clk-dra7-atl.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/ti/clk-dra7-atl.c
Extension
.c
Size
7068 bytes
Lines
303
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 dra7_atl_desc {
	struct clk *clk;
	struct clk_hw hw;
	struct dra7_atl_clock_info *cinfo;
	int id;

	bool probed;		/* the driver for the IP has been loaded */
	bool valid;		/* configured */
	bool enabled;
	u32 bws;		/* Baseband Word Select Mux */
	u32 aws;		/* Audio Word Select Mux */
	u32 divider;		/* Cached divider value */
};

struct dra7_atl_clock_info {
	struct device *dev;
	void __iomem *iobase;

	struct dra7_atl_desc *cdesc;
};

#define to_atl_desc(_hw)	container_of(_hw, struct dra7_atl_desc, hw)

static inline void atl_write(struct dra7_atl_clock_info *cinfo, u32 reg,
			     u32 val)
{
	__raw_writel(val, cinfo->iobase + reg);
}

static inline int atl_read(struct dra7_atl_clock_info *cinfo, u32 reg)
{
	return __raw_readl(cinfo->iobase + reg);
}

static int atl_clk_enable(struct clk_hw *hw)
{
	struct dra7_atl_desc *cdesc = to_atl_desc(hw);

	if (!cdesc->probed)
		goto out;

	if (unlikely(!cdesc->valid))
		dev_warn(cdesc->cinfo->dev, "atl%d has not been configured\n",
			 cdesc->id);
	pm_runtime_get_sync(cdesc->cinfo->dev);

	atl_write(cdesc->cinfo, DRA7_ATL_ATLCR_REG(cdesc->id),
		  cdesc->divider - 1);
	atl_write(cdesc->cinfo, DRA7_ATL_SWEN_REG(cdesc->id), DRA7_ATL_SWEN);

out:
	cdesc->enabled = true;

	return 0;
}

static void atl_clk_disable(struct clk_hw *hw)
{
	struct dra7_atl_desc *cdesc = to_atl_desc(hw);

	if (!cdesc->probed)
		goto out;

	atl_write(cdesc->cinfo, DRA7_ATL_SWEN_REG(cdesc->id), 0);
	pm_runtime_put_sync(cdesc->cinfo->dev);

out:
	cdesc->enabled = false;
}

static int atl_clk_is_enabled(struct clk_hw *hw)
{
	struct dra7_atl_desc *cdesc = to_atl_desc(hw);

	return cdesc->enabled;
}

static unsigned long atl_clk_recalc_rate(struct clk_hw *hw,
					 unsigned long parent_rate)
{
	struct dra7_atl_desc *cdesc = to_atl_desc(hw);

	return parent_rate / cdesc->divider;
}

static int atl_clk_determine_rate(struct clk_hw *hw,
				  struct clk_rate_request *req)
{
	unsigned divider;

Annotation

Implementation Notes