drivers/rtc/rtc-mpc5121.c

Source file repositories/reference/linux-study-clean/drivers/rtc/rtc-mpc5121.c

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-mpc5121.c
Extension
.c
Size
10326 bytes
Lines
409
Domain
Driver Families
Bucket
drivers/rtc
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 mpc5121_rtc_regs {
	u8 set_time;		/* RTC + 0x00 */
	u8 hour_set;		/* RTC + 0x01 */
	u8 minute_set;		/* RTC + 0x02 */
	u8 second_set;		/* RTC + 0x03 */

	u8 set_date;		/* RTC + 0x04 */
	u8 month_set;		/* RTC + 0x05 */
	u8 weekday_set;		/* RTC + 0x06 */
	u8 date_set;		/* RTC + 0x07 */

	u8 write_sw;		/* RTC + 0x08 */
	u8 sw_set;		/* RTC + 0x09 */
	u16 year_set;		/* RTC + 0x0a */

	u8 alm_enable;		/* RTC + 0x0c */
	u8 alm_hour_set;	/* RTC + 0x0d */
	u8 alm_min_set;		/* RTC + 0x0e */
	u8 int_enable;		/* RTC + 0x0f */

	u8 reserved1;
	u8 hour;		/* RTC + 0x11 */
	u8 minute;		/* RTC + 0x12 */
	u8 second;		/* RTC + 0x13 */

	u8 month;		/* RTC + 0x14 */
	u8 wday_mday;		/* RTC + 0x15 */
	u16 year;		/* RTC + 0x16 */

	u8 int_alm;		/* RTC + 0x18 */
	u8 int_sw;		/* RTC + 0x19 */
	u8 alm_status;		/* RTC + 0x1a */
	u8 sw_minute;		/* RTC + 0x1b */

	u8 bus_error_1;		/* RTC + 0x1c */
	u8 int_day;		/* RTC + 0x1d */
	u8 int_min;		/* RTC + 0x1e */
	u8 int_sec;		/* RTC + 0x1f */

	/*
	 * target_time:
	 *	intended to be used for hibernation but hibernation
	 *	does not work on silicon rev 1.5 so use it for non-volatile
	 *	storage of offset between the actual_time register and linux
	 *	time
	 */
	u32 target_time;	/* RTC + 0x20 */
	/*
	 * actual_time:
	 *	readonly time since VBAT_RTC was last connected
	 */
	u32 actual_time;	/* RTC + 0x24 */
	u32 keep_alive;		/* RTC + 0x28 */
};

struct mpc5121_rtc_data {
	unsigned irq;
	unsigned irq_periodic;
	struct mpc5121_rtc_regs __iomem *regs;
	struct rtc_device *rtc;
	struct rtc_wkalrm wkalarm;
};

/*
 * Update second/minute/hour registers.
 *
 * This is just so alarm will work.
 */
static void mpc5121_rtc_update_smh(struct mpc5121_rtc_regs __iomem *regs,
				   struct rtc_time *tm)
{
	out_8(&regs->second_set, tm->tm_sec);
	out_8(&regs->minute_set, tm->tm_min);
	out_8(&regs->hour_set, tm->tm_hour);

	/* set time sequence */
	out_8(&regs->set_time, 0x1);
	out_8(&regs->set_time, 0x3);
	out_8(&regs->set_time, 0x1);
	out_8(&regs->set_time, 0x0);
}

static int mpc5121_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
	unsigned long now;

	/*
	 * linux time is actual_time plus the offset saved in target_time

Annotation

Implementation Notes