RE: [PATCH V5 4/4] rtc: imx-sc: add rtc alarm support

From: Aisheng Dong
Date: Mon Apr 08 2019 - 23:08:44 EST


[...]

> so I will add another API in imx-scu-irq
> driver to provide function of enabling/disabling irq, each driver can just call the
> API to enable/disable its own IRQ, ONLY need to pass the corresponding
> arguments:
>

That's exactly what I mean.

> >
> > > + msg.group = SC_IRQ_GROUP_RTC;
> > > + msg.mask = SC_IRQ_RTC;
> > > + msg.enable = enable;
> > > +
> > > + ret = imx_scu_call_rpc(rtc_ipc_handle, &msg, true);
> > > + if (ret) {
> > > + dev_err(dev, "enable rtc irq failed, ret %d\n", ret);
> > > + return ret;
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static int imx_sc_rtc_read_alarm(struct device *dev, struct
> > > +rtc_wkalrm
> > > +*alrm) {
> > > + return 0;
> > > +}
> >
> > Can't avoid define NULL function?
>
> We have to implement it as NULL function, as SCFW does NOT provide such
> feature, But rtc alarm ONLY available when .read_alarm ops is implemented:
>

If the framework mandantorily requires it, then we'd probably better to add
doc before this function and explain why it's safe to be NULL.

> 147 static ssize_t
> 148 wakealarm_store(struct device *dev, struct device_attribute *attr,
> 149 const char *buf, size_t n)
> 150 {
>
> ...
>
> 187 retval = rtc_read_alarm(rtc, &alm);
> 188 if (retval < 0)
> 189 return retval;
>
>
> >
> > > +
> > > +static int imx_sc_rtc_set_alarm(struct device *dev, struct
> > > +rtc_wkalrm
> > > +*alrm) {
> > > + struct imx_sc_msg_timer_rtc_set_alarm msg;
> > > + struct imx_sc_rpc_msg *hdr = &msg.hdr;
> > > + int ret;
> > > + struct rtc_time *alrm_tm = &alrm->time;
> > > +
> > > + hdr->ver = IMX_SC_RPC_VERSION;
> > > + hdr->svc = IMX_SC_RPC_SVC_TIMER;
> > > + hdr->func = IMX_SC_TIMER_FUNC_SET_RTC_ALARM;
> > > + hdr->size = 3;
> > > +
> > > + msg.year = alrm_tm->tm_year + 1900;
> > > + msg.mon = alrm_tm->tm_mon + 1;
> > > + msg.day = alrm_tm->tm_mday;
> > > + msg.hour = alrm_tm->tm_hour;
> > > + msg.min = alrm_tm->tm_min;
> > > + msg.sec = alrm_tm->tm_sec;
> > > +
> > > + ret = imx_scu_call_rpc(rtc_ipc_handle, &msg, true);
> > > + if (ret) {
> > > + dev_err(dev, "set rtc alarm failed, ret %d\n", ret);
> > > + return ret;
> > > + }
> > > +
> > > + ret = imx_sc_rtc_alarm_irq_enable(dev, alrm->enabled);
> >
> > Just curious we already have .alarm_irq_enable().
> > Why do we need call it again here?
>
> That is because the set_alarm function pass alarm time and alarm->enabled
> argument, it could be to enable alarm or to disable alarm, so we have to
> control the alarm function here, all other rtc drivers also do it this way.
> The .alarm_irq_enable() callback is for just enable or disable alarm.
>

Got it, thanks for the explanation.

Regards
Dong Aisheng

> Thanks,
> Anson
>
>
> >
> > Regards
> > Dong Aisheng
> >
> > > + if (ret) {
> > > + dev_err(dev, "enable rtc alarm failed, ret %d\n", ret);
> > > + return ret;
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > static const struct rtc_class_ops imx_sc_rtc_ops = {
> > > .read_time = imx_sc_rtc_read_time,
> > > .set_time = imx_sc_rtc_set_time,
> > > + .read_alarm = imx_sc_rtc_read_alarm,
> > > + .set_alarm = imx_sc_rtc_set_alarm,
> > > + .alarm_irq_enable = imx_sc_rtc_alarm_irq_enable, };
> > > +
> > > +static int imx_sc_rtc_alarm_sc_notify(struct notifier_block *nb,
> > > + unsigned long event, void *group) {
> > > + /* ignore non-rtc irq */
> > > + if (!((event & SC_IRQ_RTC) && (*(u8 *)group ==
> > SC_IRQ_GROUP_RTC)))
> > > + return 0;
> > > +
> > > + rtc_update_irq(imx_sc_rtc, 1, RTC_IRQF | RTC_AF);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static struct notifier_block imx_sc_rtc_alarm_sc_notifier = {
> > > + .notifier_call = imx_sc_rtc_alarm_sc_notify,
> > > };
> > >
> > > static int imx_sc_rtc_probe(struct platform_device *pdev) @@ -73,6
> > > +181,8 @@ static int imx_sc_rtc_probe(struct platform_device *pdev)
> > > if (ret)
> > > return ret;
> > >
> > > + device_init_wakeup(&pdev->dev, true);
> > > +
> > > imx_sc_rtc = devm_rtc_allocate_device(&pdev->dev);
> > > if (IS_ERR(imx_sc_rtc))
> > > return PTR_ERR(imx_sc_rtc);
> > > @@ -87,6 +197,8 @@ static int imx_sc_rtc_probe(struct
> > > platform_device
> > > *pdev)
> > > return ret;
> > > }
> > >
> > > + imx_scu_irq_register_notifier(&imx_sc_rtc_alarm_sc_notifier);
> > > +
> > > return 0;
> > > }
> > >
> > > --
> > > 2.7.4