]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/rtc/rtc-cpcap.c
rtc: cpcap: kfreeing devm allocated memory
[karo-tx-linux.git] / drivers / rtc / rtc-cpcap.c
1 /*
2  * Motorola CPCAP PMIC RTC driver
3  *
4  * Based on cpcap-regulator.c from Motorola Linux kernel tree
5  * Copyright (C) 2009 Motorola, Inc.
6  *
7  * Rewritten for mainline kernel
8  *  - use DT
9  *  - use regmap
10  *  - use standard interrupt framework
11  *  - use managed device resources
12  *  - remove custom "secure clock daemon" helpers
13  *
14  * Copyright (C) 2017 Sebastian Reichel <sre@kernel.org>
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License version 2 as
18  * published by the Free Software Foundation.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  */
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/init.h>
28 #include <linux/device.h>
29 #include <linux/platform_device.h>
30 #include <linux/rtc.h>
31 #include <linux/err.h>
32 #include <linux/regmap.h>
33 #include <linux/mfd/motorola-cpcap.h>
34 #include <linux/slab.h>
35 #include <linux/sched.h>
36
37 #define SECS_PER_DAY 86400
38 #define DAY_MASK  0x7FFF
39 #define TOD1_MASK 0x00FF
40 #define TOD2_MASK 0x01FF
41
42 struct cpcap_time {
43         int day;
44         int tod1;
45         int tod2;
46 };
47
48 struct cpcap_rtc {
49         struct regmap *regmap;
50         struct rtc_device *rtc_dev;
51         u16 vendor;
52         int alarm_irq;
53         bool alarm_enabled;
54         int update_irq;
55         bool update_enabled;
56 };
57
58 static void cpcap2rtc_time(struct rtc_time *rtc, struct cpcap_time *cpcap)
59 {
60         unsigned long int tod;
61         unsigned long int time;
62
63         tod = (cpcap->tod1 & TOD1_MASK) | ((cpcap->tod2 & TOD2_MASK) << 8);
64         time = tod + ((cpcap->day & DAY_MASK) * SECS_PER_DAY);
65
66         rtc_time_to_tm(time, rtc);
67 }
68
69 static void rtc2cpcap_time(struct cpcap_time *cpcap, struct rtc_time *rtc)
70 {
71         unsigned long time;
72
73         rtc_tm_to_time(rtc, &time);
74
75         cpcap->day = time / SECS_PER_DAY;
76         time %= SECS_PER_DAY;
77         cpcap->tod2 = (time >> 8) & TOD2_MASK;
78         cpcap->tod1 = time & TOD1_MASK;
79 }
80
81 static int cpcap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
82 {
83         struct cpcap_rtc *rtc = dev_get_drvdata(dev);
84
85         if (rtc->alarm_enabled == enabled)
86                 return 0;
87
88         if (enabled)
89                 enable_irq(rtc->alarm_irq);
90         else
91                 disable_irq(rtc->alarm_irq);
92
93         rtc->alarm_enabled = !!enabled;
94
95         return 0;
96 }
97
98 static int cpcap_rtc_read_time(struct device *dev, struct rtc_time *tm)
99 {
100         struct cpcap_rtc *rtc;
101         struct cpcap_time cpcap_tm;
102         int temp_tod2;
103         int ret;
104
105         rtc = dev_get_drvdata(dev);
106
107         ret = regmap_read(rtc->regmap, CPCAP_REG_TOD2, &temp_tod2);
108         ret |= regmap_read(rtc->regmap, CPCAP_REG_DAY, &cpcap_tm.day);
109         ret |= regmap_read(rtc->regmap, CPCAP_REG_TOD1, &cpcap_tm.tod1);
110         ret |= regmap_read(rtc->regmap, CPCAP_REG_TOD2, &cpcap_tm.tod2);
111
112         if (temp_tod2 > cpcap_tm.tod2)
113                 ret |= regmap_read(rtc->regmap, CPCAP_REG_DAY, &cpcap_tm.day);
114
115         if (ret) {
116                 dev_err(dev, "Failed to read time\n");
117                 return -EIO;
118         }
119
120         cpcap2rtc_time(tm, &cpcap_tm);
121
122         return rtc_valid_tm(tm);
123 }
124
125 static int cpcap_rtc_set_time(struct device *dev, struct rtc_time *tm)
126 {
127         struct cpcap_rtc *rtc;
128         struct cpcap_time cpcap_tm;
129         int ret = 0;
130
131         rtc = dev_get_drvdata(dev);
132
133         rtc2cpcap_time(&cpcap_tm, tm);
134
135         if (rtc->alarm_enabled)
136                 disable_irq(rtc->alarm_irq);
137         if (rtc->update_enabled)
138                 disable_irq(rtc->update_irq);
139
140         if (rtc->vendor == CPCAP_VENDOR_ST) {
141                 /* The TOD1 and TOD2 registers MUST be written in this order
142                  * for the change to properly set.
143                  */
144                 ret |= regmap_update_bits(rtc->regmap, CPCAP_REG_TOD1,
145                                           TOD1_MASK, cpcap_tm.tod1);
146                 ret |= regmap_update_bits(rtc->regmap, CPCAP_REG_TOD2,
147                                           TOD2_MASK, cpcap_tm.tod2);
148                 ret |= regmap_update_bits(rtc->regmap, CPCAP_REG_DAY,
149                                           DAY_MASK, cpcap_tm.day);
150         } else {
151                 /* Clearing the upper lower 8 bits of the TOD guarantees that
152                  * the upper half of TOD (TOD2) will not increment for 0xFF RTC
153                  * ticks (255 seconds).  During this time we can safely write
154                  * to DAY, TOD2, then TOD1 (in that order) and expect RTC to be
155                  * synchronized to the exact time requested upon the final write
156                  * to TOD1.
157                  */
158                 ret |= regmap_update_bits(rtc->regmap, CPCAP_REG_TOD1,
159                                           TOD1_MASK, 0);
160                 ret |= regmap_update_bits(rtc->regmap, CPCAP_REG_DAY,
161                                           DAY_MASK, cpcap_tm.day);
162                 ret |= regmap_update_bits(rtc->regmap, CPCAP_REG_TOD2,
163                                           TOD2_MASK, cpcap_tm.tod2);
164                 ret |= regmap_update_bits(rtc->regmap, CPCAP_REG_TOD1,
165                                           TOD1_MASK, cpcap_tm.tod1);
166         }
167
168         if (rtc->update_enabled)
169                 enable_irq(rtc->update_irq);
170         if (rtc->alarm_enabled)
171                 enable_irq(rtc->alarm_irq);
172
173         return ret;
174 }
175
176 static int cpcap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
177 {
178         struct cpcap_rtc *rtc;
179         struct cpcap_time cpcap_tm;
180         int ret;
181
182         rtc = dev_get_drvdata(dev);
183
184         alrm->enabled = rtc->alarm_enabled;
185
186         ret = regmap_read(rtc->regmap, CPCAP_REG_DAYA, &cpcap_tm.day);
187         ret |= regmap_read(rtc->regmap, CPCAP_REG_TODA2, &cpcap_tm.tod2);
188         ret |= regmap_read(rtc->regmap, CPCAP_REG_TODA1, &cpcap_tm.tod1);
189
190         if (ret) {
191                 dev_err(dev, "Failed to read time\n");
192                 return -EIO;
193         }
194
195         cpcap2rtc_time(&alrm->time, &cpcap_tm);
196         return rtc_valid_tm(&alrm->time);
197 }
198
199 static int cpcap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
200 {
201         struct cpcap_rtc *rtc;
202         struct cpcap_time cpcap_tm;
203         int ret;
204
205         rtc = dev_get_drvdata(dev);
206
207         rtc2cpcap_time(&cpcap_tm, &alrm->time);
208
209         if (rtc->alarm_enabled)
210                 disable_irq(rtc->alarm_irq);
211
212         ret = regmap_update_bits(rtc->regmap, CPCAP_REG_DAYA, DAY_MASK,
213                                  cpcap_tm.day);
214         ret |= regmap_update_bits(rtc->regmap, CPCAP_REG_TODA2, TOD2_MASK,
215                                   cpcap_tm.tod2);
216         ret |= regmap_update_bits(rtc->regmap, CPCAP_REG_TODA1, TOD1_MASK,
217                                   cpcap_tm.tod1);
218
219         if (!ret) {
220                 enable_irq(rtc->alarm_irq);
221                 rtc->alarm_enabled = true;
222         }
223
224         return ret;
225 }
226
227 static const struct rtc_class_ops cpcap_rtc_ops = {
228         .read_time              = cpcap_rtc_read_time,
229         .set_time               = cpcap_rtc_set_time,
230         .read_alarm             = cpcap_rtc_read_alarm,
231         .set_alarm              = cpcap_rtc_set_alarm,
232         .alarm_irq_enable       = cpcap_rtc_alarm_irq_enable,
233 };
234
235 static irqreturn_t cpcap_rtc_alarm_irq(int irq, void *data)
236 {
237         struct cpcap_rtc *rtc = data;
238
239         rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
240         return IRQ_HANDLED;
241 }
242
243 static irqreturn_t cpcap_rtc_update_irq(int irq, void *data)
244 {
245         struct cpcap_rtc *rtc = data;
246
247         rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
248         return IRQ_HANDLED;
249 }
250
251 static int cpcap_rtc_probe(struct platform_device *pdev)
252 {
253         struct device *dev = &pdev->dev;
254         struct cpcap_rtc *rtc;
255         int err;
256
257         rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL);
258         if (!rtc)
259                 return -ENOMEM;
260
261         rtc->regmap = dev_get_regmap(dev->parent, NULL);
262         if (!rtc->regmap)
263                 return -ENODEV;
264
265         platform_set_drvdata(pdev, rtc);
266         rtc->rtc_dev = devm_rtc_device_register(dev, "cpcap_rtc",
267                                                 &cpcap_rtc_ops, THIS_MODULE);
268
269         if (IS_ERR(rtc->rtc_dev))
270                 return PTR_ERR(rtc->rtc_dev);
271
272         err = cpcap_get_vendor(dev, rtc->regmap, &rtc->vendor);
273         if (err)
274                 return err;
275
276         rtc->alarm_irq = platform_get_irq(pdev, 0);
277         err = devm_request_threaded_irq(dev, rtc->alarm_irq, NULL,
278                                         cpcap_rtc_alarm_irq, IRQ_NONE,
279                                         "rtc_alarm", rtc);
280         if (err) {
281                 dev_err(dev, "Could not request alarm irq: %d\n", err);
282                 return err;
283         }
284         disable_irq(rtc->alarm_irq);
285
286         /* Stock Android uses the 1 Hz interrupt for "secure clock daemon",
287          * which is not supported by the mainline kernel. The mainline kernel
288          * does not use the irq at the moment, but we explicitly request and
289          * disable it, so that its masked and does not wake up the processor
290          * every second.
291          */
292         rtc->update_irq = platform_get_irq(pdev, 1);
293         err = devm_request_threaded_irq(dev, rtc->update_irq, NULL,
294                                         cpcap_rtc_update_irq, IRQ_NONE,
295                                         "rtc_1hz", rtc);
296         if (err) {
297                 dev_err(dev, "Could not request update irq: %d\n", err);
298                 return err;
299         }
300         disable_irq(rtc->update_irq);
301
302         err = device_init_wakeup(dev, 1);
303         if (err) {
304                 dev_err(dev, "wakeup initialization failed (%d)\n", err);
305                 /* ignore error and continue without wakeup support */
306         }
307
308         return 0;
309 }
310
311 static const struct of_device_id cpcap_rtc_of_match[] = {
312         { .compatible = "motorola,cpcap-rtc", },
313         {},
314 };
315 MODULE_DEVICE_TABLE(of, cpcap_rtc_of_match);
316
317 static struct platform_driver cpcap_rtc_driver = {
318         .probe          = cpcap_rtc_probe,
319         .driver         = {
320                 .name   = "cpcap-rtc",
321                 .of_match_table = cpcap_rtc_of_match,
322         },
323 };
324
325 module_platform_driver(cpcap_rtc_driver);
326
327 MODULE_ALIAS("platform:cpcap-rtc");
328 MODULE_DESCRIPTION("CPCAP RTC driver");
329 MODULE_AUTHOR("Sebastian Reichel <sre@kernel.org>");
330 MODULE_LICENSE("GPL");