drivers/pps/generators/pps_gen_tio.c

Source file repositories/reference/linux-study-clean/drivers/pps/generators/pps_gen_tio.c

File Facts

System
Linux kernel
Corpus path
drivers/pps/generators/pps_gen_tio.c
Extension
.c
Size
6587 bytes
Lines
269
Domain
Driver Families
Bucket
drivers/pps
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 pps_tio {
	struct pps_gen_source_info gen_info;
	struct pps_gen_device *pps_gen;
	struct hrtimer timer;
	void __iomem *base;
	u32 prev_count;
	spinlock_t lock;
	struct device *dev;
};

static inline u32 pps_tio_read(u32 offset, struct pps_tio *tio)
{
	return readl(tio->base + offset);
}

static inline void pps_ctl_write(u32 value, struct pps_tio *tio)
{
	writel(value, tio->base + TIOCTL);
}

/*
 * For COMPV register, It's safer to write
 * higher 32-bit followed by lower 32-bit
 */
static inline void pps_compv_write(u64 value, struct pps_tio *tio)
{
	hi_lo_writeq(value, tio->base + TIOCOMPV);
}

static inline ktime_t first_event(struct pps_tio *tio)
{
	return ktime_set(ktime_get_real_seconds() + 1, MAGIC_CONST);
}

static u32 pps_tio_disable(struct pps_tio *tio)
{
	u32 ctrl;

	ctrl = pps_tio_read(TIOCTL, tio);
	pps_compv_write(0, tio);

	ctrl &= ~TIOCTL_EN;
	pps_ctl_write(ctrl, tio);
	tio->pps_gen->enabled = false;
	tio->prev_count = 0;
	return ctrl;
}

static void pps_tio_enable(struct pps_tio *tio)
{
	u32 ctrl;

	ctrl = pps_tio_read(TIOCTL, tio);
	ctrl |= TIOCTL_EN;
	pps_ctl_write(ctrl, tio);
	tio->pps_gen->enabled = true;
}

static void pps_tio_direction_output(struct pps_tio *tio)
{
	u32 ctrl;

	ctrl = pps_tio_disable(tio);

	/*
	 * We enable the device, be sure that the
	 * 'compare' value is invalid
	 */
	pps_compv_write(0, tio);

	ctrl &= ~(TIOCTL_DIR | TIOCTL_EP);
	ctrl |= TIOCTL_EP_TOGGLE_EDGE;
	pps_ctl_write(ctrl, tio);
	pps_tio_enable(tio);
}

static bool pps_generate_next_pulse(ktime_t expires, struct pps_tio *tio)
{
	u64 art;

	if (!ktime_real_to_base_clock(expires, CSID_X86_ART, &art)) {
		pps_tio_disable(tio);
		return false;
	}

	pps_compv_write(art - ART_HW_DELAY_CYCLES, tio);
	return true;
}

static enum hrtimer_restart hrtimer_callback(struct hrtimer *timer)

Annotation

Implementation Notes