1 /* drivers/rtc/rtc-goldfish.c
3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (C) 2017 Imagination Technologies Ltd.
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <linux/module.h>
18 #include <linux/platform_device.h>
19 #include <linux/rtc.h>
22 #define TIMER_TIME_LOW 0x00 /* get low bits of current time */
23 /* and update TIMER_TIME_HIGH */
24 #define TIMER_TIME_HIGH 0x04 /* get high bits of time at last */
25 /* TIMER_TIME_LOW read */
26 #define TIMER_ALARM_LOW 0x08 /* set low bits of alarm and */
28 #define TIMER_ALARM_HIGH 0x0c /* set high bits of next alarm */
29 #define TIMER_IRQ_ENABLED 0x10
30 #define TIMER_CLEAR_ALARM 0x14
31 #define TIMER_ALARM_STATUS 0x18
32 #define TIMER_CLEAR_INTERRUPT 0x1c
37 struct rtc_device
*rtc
;
40 static int goldfish_rtc_read_alarm(struct device
*dev
,
41 struct rtc_wkalrm
*alrm
)
47 struct goldfish_rtc
*rtcdrv
;
49 rtcdrv
= dev_get_drvdata(dev
);
52 rtc_alarm_low
= readl(base
+ TIMER_ALARM_LOW
);
53 rtc_alarm_high
= readl(base
+ TIMER_ALARM_HIGH
);
54 rtc_alarm
= (rtc_alarm_high
<< 32) | rtc_alarm_low
;
56 do_div(rtc_alarm
, NSEC_PER_SEC
);
57 memset(alrm
, 0, sizeof(struct rtc_wkalrm
));
59 rtc_time_to_tm(rtc_alarm
, &alrm
->time
);
61 if (readl(base
+ TIMER_ALARM_STATUS
))
69 static int goldfish_rtc_set_alarm(struct device
*dev
,
70 struct rtc_wkalrm
*alrm
)
72 struct goldfish_rtc
*rtcdrv
;
73 unsigned long rtc_alarm
;
79 rtcdrv
= dev_get_drvdata(dev
);
83 ret
= rtc_tm_to_time(&alrm
->time
, &rtc_alarm
);
87 rtc_alarm64
= rtc_alarm
* NSEC_PER_SEC
;
88 writel((rtc_alarm64
>> 32), base
+ TIMER_ALARM_HIGH
);
89 writel(rtc_alarm64
, base
+ TIMER_ALARM_LOW
);
92 * if this function was called with enabled=0
93 * then it could mean that the application is
94 * trying to cancel an ongoing alarm
96 rtc_status_reg
= readl(base
+ TIMER_ALARM_STATUS
);
98 writel(1, base
+ TIMER_CLEAR_ALARM
);
104 static int goldfish_rtc_alarm_irq_enable(struct device
*dev
,
105 unsigned int enabled
)
108 struct goldfish_rtc
*rtcdrv
;
110 rtcdrv
= dev_get_drvdata(dev
);
114 writel(1, base
+ TIMER_IRQ_ENABLED
);
116 writel(0, base
+ TIMER_IRQ_ENABLED
);
121 static irqreturn_t
goldfish_rtc_interrupt(int irq
, void *dev_id
)
123 struct goldfish_rtc
*rtcdrv
= dev_id
;
124 void __iomem
*base
= rtcdrv
->base
;
126 writel(1, base
+ TIMER_CLEAR_INTERRUPT
);
128 rtc_update_irq(rtcdrv
->rtc
, 1, RTC_IRQF
| RTC_AF
);
133 static int goldfish_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
135 struct goldfish_rtc
*rtcdrv
;
141 rtcdrv
= dev_get_drvdata(dev
);
144 time_low
= readl(base
+ TIMER_TIME_LOW
);
145 time_high
= readl(base
+ TIMER_TIME_HIGH
);
146 time
= (time_high
<< 32) | time_low
;
148 do_div(time
, NSEC_PER_SEC
);
150 rtc_time_to_tm(time
, tm
);
155 static int goldfish_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
157 struct goldfish_rtc
*rtcdrv
;
163 rtcdrv
= dev_get_drvdata(dev
);
166 ret
= rtc_tm_to_time(tm
, &now
);
168 now64
= now
* NSEC_PER_SEC
;
169 writel((now64
>> 32), base
+ TIMER_TIME_HIGH
);
170 writel(now64
, base
+ TIMER_TIME_LOW
);
176 static const struct rtc_class_ops goldfish_rtc_ops
= {
177 .read_time
= goldfish_rtc_read_time
,
178 .set_time
= goldfish_rtc_set_time
,
179 .read_alarm
= goldfish_rtc_read_alarm
,
180 .set_alarm
= goldfish_rtc_set_alarm
,
181 .alarm_irq_enable
= goldfish_rtc_alarm_irq_enable
184 static int goldfish_rtc_probe(struct platform_device
*pdev
)
186 struct goldfish_rtc
*rtcdrv
;
190 rtcdrv
= devm_kzalloc(&pdev
->dev
, sizeof(*rtcdrv
), GFP_KERNEL
);
194 platform_set_drvdata(pdev
, rtcdrv
);
196 r
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
200 rtcdrv
->base
= devm_ioremap_resource(&pdev
->dev
, r
);
201 if (IS_ERR(rtcdrv
->base
))
204 rtcdrv
->irq
= platform_get_irq(pdev
, 0);
208 rtcdrv
->rtc
= devm_rtc_device_register(&pdev
->dev
, pdev
->name
,
211 if (IS_ERR(rtcdrv
->rtc
))
212 return PTR_ERR(rtcdrv
->rtc
);
214 err
= devm_request_irq(&pdev
->dev
, rtcdrv
->irq
,
215 goldfish_rtc_interrupt
,
216 0, pdev
->name
, rtcdrv
);
223 static const struct of_device_id goldfish_rtc_of_match
[] = {
224 { .compatible
= "google,goldfish-rtc", },
227 MODULE_DEVICE_TABLE(of
, goldfish_rtc_of_match
);
229 static struct platform_driver goldfish_rtc
= {
230 .probe
= goldfish_rtc_probe
,
232 .name
= "goldfish_rtc",
233 .of_match_table
= goldfish_rtc_of_match
,
237 module_platform_driver(goldfish_rtc
);
239 MODULE_LICENSE("GPL v2");