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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[...]

> 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





[Index of Archives]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux