On Wednesday 27 July 2016 11:01 PM, Ben Hutchings wrote: > On DRA7xx chips (and maybe others), the reset configuration of the RTC > does not allow it to wake up from idle when it's ready to generate an > interrupt. It only generates an interrupt when register access takes > it out of idle, which in means most RTC operations will hang. We need > to change the IDLEMODE field to make alarm interrupts work properly. Shouldn't this be handled by hwmod? With this patch series[1], the updating of IDLEMODE must have been proper. Can you confirm if you have this series? [1] http://www.spinics.net/lists/linux-omap/msg126531.html Thanks and regards, Lokesh > --- > The following worked for me, but I don't know whether this register > field should really be set in the RTC driver or somewhere in OMAP > platform code. > > Also, given that DRA7xx is based on OMAP5 I would guess that the same > fix is needed for OMAP5, but I don't have the reference manual for it. > Can someone confirm whether it has the same register field? > > Finally, I realise that the new compatible string, whatever it should > be, will need to be documented. > > Ben. > --- > --- a/drivers/rtc/rtc-omap.c > +++ b/drivers/rtc/rtc-omap.c > @@ -69,6 +69,7 @@ > #define OMAP_RTC_KICK0_REG 0x6c > #define OMAP_RTC_KICK1_REG 0x70 > > +#define OMAP_RTC_SYSCONFIG_REG 0x78 > #define OMAP_RTC_IRQWAKEEN 0x7c > > #define OMAP_RTC_ALARM2_SECONDS_REG 0x80 > @@ -110,6 +111,13 @@ > #define OMAP_RTC_OSC_32KCLK_EN BIT(6) > #define OMAP_RTC_OSC_SEL_32KCLK_SRC BIT(3) > > +/* OMAP_RTC_SYSCONFIG_REG bit fields: */ > +#define OMAP_RTC_IDLEMODE_MASK 3 > +#define OMAP_RTC_IDLEMODE_FORCE 0 > +#define OMAP_RTC_IDLEMODE_DISABLE 1 > +#define OMAP_RTC_IDLEMODE_SMART 2 > +#define OMAP_RTC_IDLEMODE_SMART_WAKEUP 3 > + > /* OMAP_RTC_IRQWAKEEN bit fields: */ > #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN BIT(1) > > @@ -127,6 +135,7 @@ struct omap_rtc_device_type { > bool has_irqwakeen; > bool has_pmic_mode; > bool has_power_up_reset; > + bool has_idlemode; > void (*lock)(struct omap_rtc *rtc); > void (*unlock)(struct omap_rtc *rtc); > }; > @@ -496,6 +505,15 @@ static const struct omap_rtc_device_type > .unlock = am3352_rtc_unlock, > }; > > +static const struct omap_rtc_device_type omap_rtc_dra7_type = { > + .has_32kclk_en = true, > + .has_irqwakeen = true, > + .has_pmic_mode = true, > + .has_idlemode = true, > + .lock = am3352_rtc_lock, > + .unlock = am3352_rtc_unlock, > +}; > + > static const struct platform_device_id omap_rtc_id_table[] = { > { > .name = "omap_rtc", > @@ -520,6 +538,9 @@ static const struct of_device_id omap_rt > .compatible = "ti,da830-rtc", > .data = &omap_rtc_da830_type, > }, { > + .compatible = "ti,dra7-rtc", > + .data = &omap_rtc_dra7_type, > + }, { > /* sentinel */ > } > }; > @@ -650,6 +671,18 @@ static int omap_rtc_probe(struct platfor > reg | OMAP_RTC_OSC_SEL_32KCLK_SRC); > } > > + if (rtc->type->has_idlemode) { > + /* > + * Allow the RTC to come out of idle whenever it's ready to > + * generate an interrupt > + */ > + u32 sysconfig = rtc_readl(rtc, OMAP_RTC_SYSCONFIG_REG); > + > + sysconfig &= ~OMAP_RTC_IDLEMODE_MASK; > + sysconfig |= OMAP_RTC_IDLEMODE_SMART_WAKEUP; > + rtc_writel(rtc, OMAP_RTC_SYSCONFIG_REG, sysconfig); > + } > + > rtc->type->lock(rtc); > > device_init_wakeup(&pdev->dev, true); > --- a/arch/arm/boot/dts/dra7.dtsi > +++ b/arch/arm/boot/dts/dra7.dtsi > @@ -1290,7 +1290,7 @@ > }; > > rtc: rtc@48838000 { > - compatible = "ti,am3352-rtc"; > + compatible = "ti,dra7-rtc", "ti,am3352-rtc"; > reg = <0x48838000 0x100>; > interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>, > <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>; > -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html