aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-stmp3xxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-stmp3xxx.c')
-rw-r--r--drivers/rtc/rtc-stmp3xxx.c66
1 files changed, 60 insertions, 6 deletions
diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c
index 2939cdcb2688..eb09eddf39b8 100644
--- a/drivers/rtc/rtc-stmp3xxx.c
+++ b/drivers/rtc/rtc-stmp3xxx.c
@@ -42,6 +42,8 @@
42#define STMP3XXX_RTC_STAT 0x10 42#define STMP3XXX_RTC_STAT 0x10
43#define STMP3XXX_RTC_STAT_STALE_SHIFT 16 43#define STMP3XXX_RTC_STAT_STALE_SHIFT 16
44#define STMP3XXX_RTC_STAT_RTC_PRESENT 0x80000000 44#define STMP3XXX_RTC_STAT_RTC_PRESENT 0x80000000
45#define STMP3XXX_RTC_STAT_XTAL32000_PRESENT 0x10000000
46#define STMP3XXX_RTC_STAT_XTAL32768_PRESENT 0x08000000
45 47
46#define STMP3XXX_RTC_SECONDS 0x30 48#define STMP3XXX_RTC_SECONDS 0x30
47 49
@@ -52,9 +54,13 @@
52#define STMP3XXX_RTC_PERSISTENT0 0x60 54#define STMP3XXX_RTC_PERSISTENT0 0x60
53#define STMP3XXX_RTC_PERSISTENT0_SET 0x64 55#define STMP3XXX_RTC_PERSISTENT0_SET 0x64
54#define STMP3XXX_RTC_PERSISTENT0_CLR 0x68 56#define STMP3XXX_RTC_PERSISTENT0_CLR 0x68
55#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN 0x00000002 57#define STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE (1 << 0)
56#define STMP3XXX_RTC_PERSISTENT0_ALARM_EN 0x00000004 58#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN (1 << 1)
57#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE 0x00000080 59#define STMP3XXX_RTC_PERSISTENT0_ALARM_EN (1 << 2)
60#define STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP (1 << 4)
61#define STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP (1 << 5)
62#define STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ (1 << 6)
63#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE (1 << 7)
58 64
59#define STMP3XXX_RTC_PERSISTENT1 0x70 65#define STMP3XXX_RTC_PERSISTENT1 0x70
60/* missing bitmask in headers */ 66/* missing bitmask in headers */
@@ -248,6 +254,9 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev)
248{ 254{
249 struct stmp3xxx_rtc_data *rtc_data; 255 struct stmp3xxx_rtc_data *rtc_data;
250 struct resource *r; 256 struct resource *r;
257 u32 rtc_stat;
258 u32 pers0_set, pers0_clr;
259 u32 crystalfreq = 0;
251 int err; 260 int err;
252 261
253 rtc_data = devm_kzalloc(&pdev->dev, sizeof(*rtc_data), GFP_KERNEL); 262 rtc_data = devm_kzalloc(&pdev->dev, sizeof(*rtc_data), GFP_KERNEL);
@@ -268,8 +277,8 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev)
268 277
269 rtc_data->irq_alarm = platform_get_irq(pdev, 0); 278 rtc_data->irq_alarm = platform_get_irq(pdev, 0);
270 279
271 if (!(readl(STMP3XXX_RTC_STAT + rtc_data->io) & 280 rtc_stat = readl(rtc_data->io + STMP3XXX_RTC_STAT);
272 STMP3XXX_RTC_STAT_RTC_PRESENT)) { 281 if (!(rtc_stat & STMP3XXX_RTC_STAT_RTC_PRESENT)) {
273 dev_err(&pdev->dev, "no device onboard\n"); 282 dev_err(&pdev->dev, "no device onboard\n");
274 return -ENODEV; 283 return -ENODEV;
275 } 284 }
@@ -282,9 +291,54 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev)
282 return err; 291 return err;
283 } 292 }
284 293
294 /*
295 * Obviously the rtc needs a clock input to be able to run.
296 * This clock can be provided by an external 32k crystal. If that one is
297 * missing XTAL must not be disabled in suspend which consumes a
298 * lot of power. Normally the presence and exact frequency (supported
299 * are 32000 Hz and 32768 Hz) is detectable from fuses, but as reality
300 * proves these fuses are not blown correctly on all machines, so the
301 * frequency can be overridden in the device tree.
302 */
303 if (rtc_stat & STMP3XXX_RTC_STAT_XTAL32000_PRESENT)
304 crystalfreq = 32000;
305 else if (rtc_stat & STMP3XXX_RTC_STAT_XTAL32768_PRESENT)
306 crystalfreq = 32768;
307
308 of_property_read_u32(pdev->dev.of_node, "stmp,crystal-freq",
309 &crystalfreq);
310
311 switch (crystalfreq) {
312 case 32000:
313 /* keep 32kHz crystal running in low-power mode */
314 pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ |
315 STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP |
316 STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE;
317 pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP;
318 break;
319 case 32768:
320 /* keep 32.768kHz crystal running in low-power mode */
321 pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP |
322 STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE;
323 pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP |
324 STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ;
325 break;
326 default:
327 dev_warn(&pdev->dev,
328 "invalid crystal-freq specified in device-tree. Assuming no crystal\n");
329 /* fall-through */
330 case 0:
331 /* keep XTAL on in low-power mode */
332 pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP;
333 pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP |
334 STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE;
335 }
336
337 writel(pers0_set, rtc_data->io + STMP3XXX_RTC_PERSISTENT0_SET);
338
285 writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 339 writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN |
286 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | 340 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN |
287 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, 341 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE | pers0_clr,
288 rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); 342 rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR);
289 343
290 writel(STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN | 344 writel(STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN |