drivers/clk/ti/autoidle.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/ti/autoidle.c
Extension
.c
Size
5454 bytes
Lines
258
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 clk_ti_autoidle {
	struct clk_omap_reg	reg;
	u8			shift;
	u8			flags;
	const char		*name;
	struct list_head	node;
};

#define AUTOIDLE_LOW		0x1

static LIST_HEAD(autoidle_clks);

/*
 * we have some non-atomic read/write
 * operations behind it, so let's
 * take one lock for handling autoidle
 * of all clocks
 */
static DEFINE_SPINLOCK(autoidle_spinlock);

static int _omap2_clk_deny_idle(struct clk_hw_omap *clk)
{
	if (clk->ops && clk->ops->deny_idle) {
		unsigned long irqflags;

		spin_lock_irqsave(&autoidle_spinlock, irqflags);
		clk->autoidle_count++;
		if (clk->autoidle_count == 1)
			clk->ops->deny_idle(clk);

		spin_unlock_irqrestore(&autoidle_spinlock, irqflags);
	}
	return 0;
}

static int _omap2_clk_allow_idle(struct clk_hw_omap *clk)
{
	if (clk->ops && clk->ops->allow_idle) {
		unsigned long irqflags;

		spin_lock_irqsave(&autoidle_spinlock, irqflags);
		clk->autoidle_count--;
		if (clk->autoidle_count == 0)
			clk->ops->allow_idle(clk);

		spin_unlock_irqrestore(&autoidle_spinlock, irqflags);
	}
	return 0;
}

/**
 * omap2_clk_deny_idle - disable autoidle on an OMAP clock
 * @clk: struct clk * to disable autoidle for
 *
 * Disable autoidle on an OMAP clock.
 */
int omap2_clk_deny_idle(struct clk *clk)
{
	struct clk_hw *hw;

	if (!clk)
		return -EINVAL;

	hw = __clk_get_hw(clk);

	if (omap2_clk_is_hw_omap(hw)) {
		struct clk_hw_omap *c = to_clk_hw_omap(hw);

		return _omap2_clk_deny_idle(c);
	}

	return -EINVAL;
}

/**
 * omap2_clk_allow_idle - enable autoidle on an OMAP clock
 * @clk: struct clk * to enable autoidle for
 *
 * Enable autoidle on an OMAP clock.
 */
int omap2_clk_allow_idle(struct clk *clk)
{
	struct clk_hw *hw;

	if (!clk)
		return -EINVAL;

	hw = __clk_get_hw(clk);

	if (omap2_clk_is_hw_omap(hw)) {

Annotation

Implementation Notes