drivers/clocksource/jcore-pit.c

Source file repositories/reference/linux-study-clean/drivers/clocksource/jcore-pit.c

File Facts

System
Linux kernel
Corpus path
drivers/clocksource/jcore-pit.c
Extension
.c
Size
6830 bytes
Lines
259
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 jcore_pit {
	struct clock_event_device	ced;
	void __iomem			*base;
	unsigned long			periodic_delta;
	u32				enable_val;
};

static void __iomem *jcore_pit_base;
static struct jcore_pit __percpu *jcore_pit_percpu;

static notrace u64 jcore_sched_clock_read(void)
{
	u32 seclo, nsec, seclo0;
	__iomem void *base = jcore_pit_base;

	seclo = readl(base + REG_SECLO);
	do {
		seclo0 = seclo;
		nsec  = readl(base + REG_NSEC);
		seclo = readl(base + REG_SECLO);
	} while (seclo0 != seclo);

	return seclo * NSEC_PER_SEC + nsec;
}

static u64 jcore_clocksource_read(struct clocksource *cs)
{
	return jcore_sched_clock_read();
}

static int jcore_pit_disable(struct jcore_pit *pit)
{
	writel(0, pit->base + REG_PITEN);
	return 0;
}

static int jcore_pit_set(unsigned long delta, struct jcore_pit *pit)
{
	jcore_pit_disable(pit);
	writel(delta, pit->base + REG_THROT);
	writel(pit->enable_val, pit->base + REG_PITEN);
	return 0;
}

static int jcore_pit_set_state_shutdown(struct clock_event_device *ced)
{
	struct jcore_pit *pit = container_of(ced, struct jcore_pit, ced);

	return jcore_pit_disable(pit);
}

static int jcore_pit_set_state_oneshot(struct clock_event_device *ced)
{
	struct jcore_pit *pit = container_of(ced, struct jcore_pit, ced);

	return jcore_pit_disable(pit);
}

static int jcore_pit_set_state_periodic(struct clock_event_device *ced)
{
	struct jcore_pit *pit = container_of(ced, struct jcore_pit, ced);

	return jcore_pit_set(pit->periodic_delta, pit);
}

static int jcore_pit_set_next_event(unsigned long delta,
				    struct clock_event_device *ced)
{
	struct jcore_pit *pit = container_of(ced, struct jcore_pit, ced);

	return jcore_pit_set(delta, pit);
}

static int jcore_pit_local_init(unsigned cpu)
{
	struct jcore_pit *pit = this_cpu_ptr(jcore_pit_percpu);
	unsigned buspd, freq;

	pr_info("Local J-Core PIT init on cpu %u\n", cpu);

	buspd = readl(pit->base + REG_BUSPD);
	freq = DIV_ROUND_CLOSEST(NSEC_PER_SEC, buspd);
	pit->periodic_delta = DIV_ROUND_CLOSEST(NSEC_PER_SEC, HZ * buspd);

	clockevents_config_and_register(&pit->ced, freq, 1, ULONG_MAX);
	enable_percpu_irq(pit->ced.irq, IRQ_TYPE_NONE);

	return 0;
}

Annotation

Implementation Notes