drivers/clocksource/timer-microchip-pit64b.c

Source file repositories/reference/linux-study-clean/drivers/clocksource/timer-microchip-pit64b.c

File Facts

System
Linux kernel
Corpus path
drivers/clocksource/timer-microchip-pit64b.c
Extension
.c
Size
13803 bytes
Lines
509
Domain
Driver Families
Bucket
drivers/clocksource
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 mchp_pit64b_timer {
	void __iomem	*base;
	struct clk	*pclk;
	struct clk	*gclk;
	u32		mode;
};

/**
 * struct mchp_pit64b_clkevt - PIT64B clockevent data structure
 * @timer: PIT64B timer
 * @clkevt: clockevent
 */
struct mchp_pit64b_clkevt {
	struct mchp_pit64b_timer	timer;
	struct clock_event_device	clkevt;
};

#define clkevt_to_mchp_pit64b_timer(x) \
	((struct mchp_pit64b_timer *)container_of(x,\
		struct mchp_pit64b_clkevt, clkevt))

/**
 * struct mchp_pit64b_clksrc - PIT64B clocksource data structure
 * @timer: PIT64B timer
 * @clksrc: clocksource
 */
struct mchp_pit64b_clksrc {
	struct mchp_pit64b_timer	timer;
	struct clocksource		clksrc;
};

#define clksrc_to_mchp_pit64b_timer(x) \
	((struct mchp_pit64b_timer *)container_of(x,\
		struct mchp_pit64b_clksrc, clksrc))

/* Base address for clocksource timer. */
static void __iomem *mchp_pit64b_cs_base;
/* Default cycles for clockevent timer. */
static u64 mchp_pit64b_ce_cycles;
/* Delay timer. */
static struct delay_timer mchp_pit64b_dt;

static inline u64 mchp_pit64b_cnt_read(void __iomem *base)
{
	unsigned long	flags;
	u32		low, high;

	raw_local_irq_save(flags);

	/*
	 * When using a 64 bit period TLSB must be read first, followed by the
	 * read of TMSB. This sequence generates an atomic read of the 64 bit
	 * timer value whatever the lapse of time between the accesses.
	 */
	low = readl_relaxed(base + MCHP_PIT64B_TLSBR);
	high = readl_relaxed(base + MCHP_PIT64B_TMSBR);

	raw_local_irq_restore(flags);

	return (((u64)high << 32) | low);
}

static inline void mchp_pit64b_reset(struct mchp_pit64b_timer *timer,
				     u64 cycles, u32 mode, u32 irqs)
{
	u32 low, high;

	low = cycles & MCHP_PIT64B_LSBMASK;
	high = cycles >> 32;

	writel_relaxed(MCHP_PIT64B_CR_SWRST, timer->base + MCHP_PIT64B_CR);
	writel_relaxed(mode | timer->mode, timer->base + MCHP_PIT64B_MR);
	writel_relaxed(high, timer->base + MCHP_PIT64B_MSB_PR);
	writel_relaxed(low, timer->base + MCHP_PIT64B_LSB_PR);
	writel_relaxed(irqs, timer->base + MCHP_PIT64B_IER);
	writel_relaxed(MCHP_PIT64B_CR_START, timer->base + MCHP_PIT64B_CR);
}

static void mchp_pit64b_suspend(struct mchp_pit64b_timer *timer)
{
	writel_relaxed(MCHP_PIT64B_CR_SWRST, timer->base + MCHP_PIT64B_CR);
	if (timer->mode & MCHP_PIT64B_MR_SGCLK)
		clk_disable_unprepare(timer->gclk);
	clk_disable_unprepare(timer->pclk);
}

static void mchp_pit64b_resume(struct mchp_pit64b_timer *timer)
{
	clk_prepare_enable(timer->pclk);
	if (timer->mode & MCHP_PIT64B_MR_SGCLK)

Annotation

Implementation Notes