@@ -156,14 +156,107 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm)
156
156
return 0 ;
157
157
}
158
158
159
+ static irqreturn_t rzn1_rtc_alarm_irq (int irq , void * dev_id )
160
+ {
161
+ struct rzn1_rtc * rtc = dev_id ;
162
+
163
+ rtc_update_irq (rtc -> rtcdev , 1 , RTC_AF | RTC_IRQF );
164
+
165
+ return IRQ_HANDLED ;
166
+ }
167
+
168
+ static int rzn1_rtc_alarm_irq_enable (struct device * dev , unsigned int enable )
169
+ {
170
+ struct rzn1_rtc * rtc = dev_get_drvdata (dev );
171
+ u32 ctl1 = readl (rtc -> base + RZN1_RTC_CTL1 );
172
+
173
+ if (enable )
174
+ ctl1 |= RZN1_RTC_CTL1_ALME ;
175
+ else
176
+ ctl1 &= ~RZN1_RTC_CTL1_ALME ;
177
+
178
+ writel (ctl1 , rtc -> base + RZN1_RTC_CTL1 );
179
+
180
+ return 0 ;
181
+ }
182
+
183
+ static int rzn1_rtc_read_alarm (struct device * dev , struct rtc_wkalrm * alrm )
184
+ {
185
+ struct rzn1_rtc * rtc = dev_get_drvdata (dev );
186
+ struct rtc_time * tm = & alrm -> time ;
187
+ unsigned int min , hour , wday , delta_days ;
188
+ time64_t alarm ;
189
+ u32 ctl1 ;
190
+ int ret ;
191
+
192
+ ret = rzn1_rtc_read_time (dev , tm );
193
+ if (ret )
194
+ return ret ;
195
+
196
+ min = readl (rtc -> base + RZN1_RTC_ALM );
197
+ hour = readl (rtc -> base + RZN1_RTC_ALH );
198
+ wday = readl (rtc -> base + RZN1_RTC_ALW );
199
+
200
+ tm -> tm_sec = 0 ;
201
+ tm -> tm_min = bcd2bin (min );
202
+ tm -> tm_hour = bcd2bin (hour );
203
+ delta_days = ((fls (wday ) - 1 ) - tm -> tm_wday + 7 ) % 7 ;
204
+ tm -> tm_wday = fls (wday ) - 1 ;
205
+
206
+ if (delta_days ) {
207
+ alarm = rtc_tm_to_time64 (tm ) + (delta_days * 86400 );
208
+ rtc_time64_to_tm (alarm , tm );
209
+ }
210
+
211
+ ctl1 = readl (rtc -> base + RZN1_RTC_CTL1 );
212
+ alrm -> enabled = !!(ctl1 & RZN1_RTC_CTL1_ALME );
213
+
214
+ return 0 ;
215
+ }
216
+
217
+ static int rzn1_rtc_set_alarm (struct device * dev , struct rtc_wkalrm * alrm )
218
+ {
219
+ struct rzn1_rtc * rtc = dev_get_drvdata (dev );
220
+ struct rtc_time * tm = & alrm -> time , tm_now ;
221
+ unsigned long alarm , farest ;
222
+ unsigned int days_ahead , wday ;
223
+ int ret ;
224
+
225
+ ret = rzn1_rtc_read_time (dev , & tm_now );
226
+ if (ret )
227
+ return ret ;
228
+
229
+ /* We cannot set alarms more than one week ahead */
230
+ farest = rtc_tm_to_time64 (& tm_now ) + (7 * 86400 );
231
+ alarm = rtc_tm_to_time64 (tm );
232
+ if (time_after (alarm , farest ))
233
+ return - ERANGE ;
234
+
235
+ /* Convert alarm day into week day */
236
+ days_ahead = tm -> tm_mday - tm_now .tm_mday ;
237
+ wday = (tm_now .tm_wday + days_ahead ) % 7 ;
238
+
239
+ writel (bin2bcd (tm -> tm_min ), rtc -> base + RZN1_RTC_ALM );
240
+ writel (bin2bcd (tm -> tm_hour ), rtc -> base + RZN1_RTC_ALH );
241
+ writel (BIT (wday ), rtc -> base + RZN1_RTC_ALW );
242
+
243
+ rzn1_rtc_alarm_irq_enable (dev , alrm -> enabled );
244
+
245
+ return 0 ;
246
+ }
247
+
159
248
static const struct rtc_class_ops rzn1_rtc_ops = {
160
249
.read_time = rzn1_rtc_read_time ,
161
250
.set_time = rzn1_rtc_set_time ,
251
+ .read_alarm = rzn1_rtc_read_alarm ,
252
+ .set_alarm = rzn1_rtc_set_alarm ,
253
+ .alarm_irq_enable = rzn1_rtc_alarm_irq_enable ,
162
254
};
163
255
164
256
static int rzn1_rtc_probe (struct platform_device * pdev )
165
257
{
166
258
struct rzn1_rtc * rtc ;
259
+ int alarm_irq ;
167
260
int ret ;
168
261
169
262
rtc = devm_kzalloc (& pdev -> dev , sizeof (* rtc ), GFP_KERNEL );
@@ -176,14 +269,18 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
176
269
if (IS_ERR (rtc -> base ))
177
270
return dev_err_probe (& pdev -> dev , PTR_ERR (rtc -> base ), "Missing reg\n" );
178
271
272
+ alarm_irq = platform_get_irq (pdev , 0 );
273
+ if (alarm_irq < 0 )
274
+ return alarm_irq ;
275
+
179
276
rtc -> rtcdev = devm_rtc_allocate_device (& pdev -> dev );
180
277
if (IS_ERR (rtc -> rtcdev ))
181
278
return PTR_ERR (rtc );
182
279
183
280
rtc -> rtcdev -> range_min = RTC_TIMESTAMP_BEGIN_2000 ;
184
281
rtc -> rtcdev -> range_max = RTC_TIMESTAMP_END_2099 ;
185
282
rtc -> rtcdev -> ops = & rzn1_rtc_ops ;
186
- clear_bit ( RTC_FEATURE_ALARM , rtc -> rtcdev -> features );
283
+ set_bit ( RTC_FEATURE_ALARM_RES_MINUTE , rtc -> rtcdev -> features );
187
284
clear_bit (RTC_FEATURE_UPDATE_INTERRUPT , rtc -> rtcdev -> features );
188
285
189
286
devm_pm_runtime_enable (& pdev -> dev );
@@ -201,6 +298,13 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
201
298
/* Disable all interrupts */
202
299
writel (0 , rtc -> base + RZN1_RTC_CTL1 );
203
300
301
+ ret = devm_request_irq (& pdev -> dev , alarm_irq , rzn1_rtc_alarm_irq , 0 ,
302
+ dev_name (& pdev -> dev ), rtc );
303
+ if (ret ) {
304
+ dev_err (& pdev -> dev , "RTC timer interrupt not available\n" );
305
+ goto dis_runtime_pm ;
306
+ }
307
+
204
308
ret = devm_rtc_register_device (rtc -> rtcdev );
205
309
if (ret )
206
310
goto dis_runtime_pm ;
0 commit comments