drivers/clocksource/timer-ralink.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clocksource/timer-ralink.c
Extension
.c
Size
3876 bytes
Lines
158
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 systick_device {
	void __iomem *membase;
	struct clock_event_device dev;
	int irq_requested;
	int freq_scale;
};

static int systick_set_oneshot(struct clock_event_device *evt);
static int systick_shutdown(struct clock_event_device *evt);

static int systick_next_event(unsigned long delta,
			      struct clock_event_device *evt)
{
	struct systick_device *sdev;
	u32 count;

	sdev = container_of(evt, struct systick_device, dev);
	count = ioread32(sdev->membase + SYSTICK_COUNT);
	count = (count + delta) % SYSTICK_FREQ;
	iowrite32(count, sdev->membase + SYSTICK_COMPARE);

	return 0;
}

static void systick_event_handler(struct clock_event_device *dev)
{
	/* noting to do here */
}

static irqreturn_t systick_interrupt(int irq, void *dev_id)
{
	struct clock_event_device *dev = (struct clock_event_device *)dev_id;

	dev->event_handler(dev);

	return IRQ_HANDLED;
}

static struct systick_device systick = {
	.dev = {
		/*
		 * cevt-r4k uses 300, make sure systick
		 * gets used if available
		 */
		.rating			= 310,
		.features		= CLOCK_EVT_FEAT_ONESHOT,
		.set_next_event		= systick_next_event,
		.set_state_shutdown	= systick_shutdown,
		.set_state_oneshot	= systick_set_oneshot,
		.event_handler		= systick_event_handler,
	},
};

static int systick_shutdown(struct clock_event_device *evt)
{
	struct systick_device *sdev;

	sdev = container_of(evt, struct systick_device, dev);

	if (sdev->irq_requested)
		free_irq(systick.dev.irq, &systick.dev);
	sdev->irq_requested = 0;
	iowrite32(0, systick.membase + SYSTICK_CONFIG);

	return 0;
}

static int systick_set_oneshot(struct clock_event_device *evt)
{
	const char *name = systick.dev.name;
	struct systick_device *sdev;
	int irq = systick.dev.irq;

	sdev = container_of(evt, struct systick_device, dev);

	if (!sdev->irq_requested) {
		if (request_irq(irq, systick_interrupt,
				IRQF_PERCPU | IRQF_TIMER, name, &systick.dev))
			pr_err("Failed to request irq %d (%s)\n", irq, name);
	}
	sdev->irq_requested = 1;
	iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,
		  systick.membase + SYSTICK_CONFIG);

	return 0;
}

static int __init ralink_systick_init(struct device_node *np)
{
	int ret;

Annotation

Implementation Notes