/* * This function does write synchronization for writes to the lp srtc block. * To take care of the asynchronous CKIL clock, all writes from the IP domain * will be synchronized to the CKIL domain. * The caller should hold the pdata->lock
*/ staticvoid mxc_rtc_sync_lp_locked(struct device *dev, void __iomem *ioaddr)
{ unsignedint i;
/* Wait for 3 CKIL cycles */ for (i = 0; i < 3; i++) { const u32 count = readl(ioaddr + SRTC_LPSCLR); unsignedint timeout = REG_READ_TIMEOUT;
while ((readl(ioaddr + SRTC_LPSCLR)) == count) { if (!--timeout) {
dev_err_once(dev, "SRTC_LPSCLR stuck! Check your hw.\n"); return;
}
}
}
}
/* This function is the RTC interrupt service routine. */ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
{ struct device *dev = dev_id; struct mxc_rtc_data *pdata = dev_get_drvdata(dev); void __iomem *ioaddr = pdata->ioaddr;
u32 lp_status;
u32 lp_cr;
spin_lock(&pdata->lock); if (clk_enable(pdata->clk)) {
spin_unlock(&pdata->lock); return IRQ_NONE;
}
/* * This function reads the current RTC time into tm in Gregorian date. * * @param tm contains the RTC time value upon return * * @return 0 if successful; non-zero otherwise.
*/ staticint mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ struct mxc_rtc_data *pdata = dev_get_drvdata(dev); constint clk_failed = clk_enable(pdata->clk);
if (!clk_failed) { const time64_t now = readl(pdata->ioaddr + SRTC_LPSCMR);
/* * This function sets the internal RTC time based on tm in Gregorian date. * * @param tm the time value to be set in the RTC * * @return 0 if successful; non-zero otherwise.
*/ staticint mxc_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
time64_t time = rtc_tm_to_time64(tm); int ret;
/* * This function reads the current alarm value into the passed in \b alrm * argument. It updates the \b alrm's pending field value based on the whether * an alarm interrupt occurs or not. * * @param alrm contains the RTC alarm value upon return * * @return 0 if successful; non-zero otherwise.
*/ staticint mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ struct mxc_rtc_data *pdata = dev_get_drvdata(dev); void __iomem *ioaddr = pdata->ioaddr; int ret;
/* * This function sets the RTC alarm based on passed in alrm. * * @param alrm the alarm value to be set in the RTC * * @return 0 if successful; non-zero otherwise.
*/ staticint mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ const time64_t time = rtc_tm_to_time64(&alrm->time); struct mxc_rtc_data *pdata = dev_get_drvdata(dev); int ret = mxc_rtc_lock(pdata);
if (ret) return ret;
writel((u32)time, pdata->ioaddr + SRTC_LPSAR);
/* clear alarm interrupt status bit */
writel(SRTC_LPSR_ALP, pdata->ioaddr + SRTC_LPSR);
mxc_rtc_sync_lp_locked(dev, pdata->ioaddr);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.