Am 01.02.2016 um 17:05 schrieb Alexandre Belloni: > On 29/01/2016 at 09:40:01 +0100, Oleksij Rempel wrote : >> +static irqreturn_t asm9260_rtc_irq(int irq, void *dev_id) >> +{ >> + struct asm9260_rtc_priv *priv = dev_id; >> + u32 isr; >> + unsigned long events = 0; >> + >> + isr = ioread32(priv->iobase + HW_CIIR); >> + if (!isr) >> + return IRQ_NONE; >> + >> + iowrite32(0, priv->iobase + HW_CIIR); >> + >> + events |= RTC_AF | RTC_IRQF; >> + >> + rtc_update_irq(priv->rtc, 1, events); >> + >> + return IRQ_HANDLED; >> +} >> + >> +static int asm9260_rtc_read_time(struct device *dev, struct rtc_time *tm) >> +{ >> + struct asm9260_rtc_priv *priv = dev_get_drvdata(dev); >> + u32 ctime0, ctime1, ctime2; >> + unsigned long irq_flags; >> + > > It would be nice to actually use BM_RTC_OSCF and return -EINVAL if it is > set. Hm... this register was described in reference driver, but not in the documentation. Now i did some testing but i can't confirm that it is working. BM_RTC_OSCF is never set, even after completely reseted clock removed battery or shortened XTAL. So, i will remove this register from the driver. >> + spin_lock_irqsave(&priv->lock, irq_flags); >> + ctime0 = ioread32(priv->iobase + HW_CTIME0); >> + ctime1 = ioread32(priv->iobase + HW_CTIME1); >> + ctime2 = ioread32(priv->iobase + HW_CTIME2); >> + >> + if (ctime1 != ioread32(priv->iobase + HW_CTIME1)) { >> + /* >> + * woops, counter flipped right now. Now we are safe >> + * to reread. >> + */ >> + ctime0 = ioread32(priv->iobase + HW_CTIME0); >> + ctime1 = ioread32(priv->iobase + HW_CTIME1); >> + ctime2 = ioread32(priv->iobase + HW_CTIME2); >> + } >> + spin_unlock_irqrestore(&priv->lock, irq_flags); >> + >> + tm->tm_sec = (ctime0 >> BM_CTIME0_SEC_S) & BM_CTIME0_SEC_M; >> + tm->tm_min = (ctime0 >> BM_CTIME0_MIN_S) & BM_CTIME0_MIN_M; >> + tm->tm_hour = (ctime0 >> BM_CTIME0_HOUR_S) & BM_CTIME0_HOUR_M; >> + tm->tm_wday = (ctime0 >> BM_CTIME0_DOW_S) & BM_CTIME0_DOW_M; >> + >> + tm->tm_mday = (ctime1 >> BM_CTIME1_DOM_S) & BM_CTIME1_DOM_M; >> + tm->tm_mon = (ctime1 >> BM_CTIME1_MON_S) & BM_CTIME1_MON_M; >> + tm->tm_year = (ctime1 >> BM_CTIME1_YEAR_S) & BM_CTIME1_YEAR_M; >> + >> + tm->tm_yday = (ctime2 >> BM_CTIME2_DOY_S) & BM_CTIME2_DOY_M; >> + >> + return 0; >> +} >> + >> +static int asm9260_rtc_set_time(struct device *dev, struct rtc_time *tm) >> +{ >> + struct asm9260_rtc_priv *priv = dev_get_drvdata(dev); >> + unsigned long irq_flags; >> + >> + spin_lock_irqsave(&priv->lock, irq_flags); >> + /* >> + * make sure SEC counter will not flip other counter on write time, >> + * real value will be written at the enf of sequence. >> + */ >> + iowrite32(0, priv->iobase + HW_SEC); >> + >> + iowrite32(tm->tm_year, priv->iobase + HW_YEAR); >> + iowrite32(tm->tm_mon, priv->iobase + HW_MONTH); >> + iowrite32(tm->tm_mday, priv->iobase + HW_DOM); >> + iowrite32(tm->tm_wday, priv->iobase + HW_DOW); >> + iowrite32(tm->tm_yday, priv->iobase + HW_DOY); >> + iowrite32(tm->tm_hour, priv->iobase + HW_HOUR); >> + iowrite32(tm->tm_min, priv->iobase + HW_MIN); >> + iowrite32(tm->tm_sec, priv->iobase + HW_SEC); > > That would be a good time to reset BM_RTC_OSCF. Maybe it can also be > useful to enable the interrupt but there isn't much more to do than > print an error message. > >> + spin_unlock_irqrestore(&priv->lock, irq_flags); >> + >> + return 0; >> +} >> + > Thank you for review :) -- Regards, Oleksij
Attachment:
signature.asc
Description: OpenPGP digital signature