drivers/rtc/rtc-loongson.c

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

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-loongson.c
Extension
.c
Size
13110 bytes
Lines
432
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 loongson_rtc_config {
	u32 pm_offset;	/* Offset of PM domain, for RTC alarm wakeup */
	u32 flags;	/* Workaround bits */
};

struct loongson_rtc_priv {
	spinlock_t lock;	/* protects PM registers access */
	u32 fix_year;		/* RTC alarm year compensation value */
	struct rtc_device *rtcdev;
	struct regmap *regmap;
	void __iomem *pm_base;	/* PM domain base, for RTC alarm wakeup */
	const struct loongson_rtc_config *config;
};

static const struct loongson_rtc_config ls1b_rtc_config = {
	.pm_offset = 0,
	.flags = 0,
};

static const struct loongson_rtc_config ls1c_rtc_config = {
	.pm_offset = 0,
	.flags = LOONGSON_RTC_CTRL_WORKAROUND | LOONGSON_RTC_ALARM_WORKAROUND,
};

static const struct loongson_rtc_config generic_rtc_config = {
	.pm_offset = 0x100,
	.flags = 0,
};

static const struct loongson_rtc_config ls2k0300_rtc_config = {
	.pm_offset = 0x0,
	.flags = LOONGSON_RTC_ALARM_WORKAROUND,
};

static const struct loongson_rtc_config ls2k1000_rtc_config = {
	.pm_offset = 0x800,
	.flags = 0,
};

static const struct regmap_config loongson_rtc_regmap_config = {
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = 4,
};

/* RTC alarm irq handler */
static irqreturn_t loongson_rtc_isr(int irq, void *id)
{
	struct loongson_rtc_priv *priv = (struct loongson_rtc_priv *)id;

	rtc_update_irq(priv->rtcdev, 1, RTC_AF | RTC_IRQF);

	/*
	 * The TOY_MATCH0_REG should be cleared 0 here,
	 * otherwise the interrupt cannot be cleared.
	 */
	regmap_write(priv->regmap, TOY_MATCH0_REG, 0);

	return IRQ_HANDLED;
}

/* For ACPI fixed event handler */
static u32 loongson_rtc_handler(void *id)
{
	struct loongson_rtc_priv *priv = (struct loongson_rtc_priv *)id;

	rtc_update_irq(priv->rtcdev, 1, RTC_AF | RTC_IRQF);

	/*
	 * The TOY_MATCH0_REG should be cleared 0 here,
	 * otherwise the interrupt cannot be cleared.
	 */
	regmap_write(priv->regmap, TOY_MATCH0_REG, 0);

	spin_lock(&priv->lock);
	/* Disable RTC alarm wakeup and interrupt */
	writel(readl(priv->pm_base + PM1_EN_REG) & ~RTC_EN,
	       priv->pm_base + PM1_EN_REG);

	/* Clear RTC interrupt status */
	writel(RTC_STS, priv->pm_base + PM1_STS_REG);
	spin_unlock(&priv->lock);

	return ACPI_INTERRUPT_HANDLED;
}

static int loongson_rtc_set_enabled(struct device *dev)
{
	struct loongson_rtc_priv *priv = dev_get_drvdata(dev);

Annotation

Implementation Notes