aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2015-04-16 15:45:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-17 09:03:59 -0400
commit7f48b21bdfede2c06e966258317a3bb4be3e4f25 (patch)
tree97bbc064215190a72387d0607afadc92cc39c76c /drivers/rtc
parentb0c57b5941c4a42698d845ada6a76feeba2d1be9 (diff)
rtc: stmp3xxx: use optional crystal in low power states
The rtc's status register allows to determine if a 32k crystal is connected to keep the rtc running in low power states provided the corresponding fuse bits were blown correctly during production. (In case they were not, the right frequency can be stated in the device tree.) If there is no such crystal available force the 24 MHz XTAL clock to keep running to retain the right date and time. Otherwise use the crystal to save some power. It would be nice to only switch to the crystal when the XTAL clock is about to be disabled and keep the crystal off when unneeded because XTAL is always on while the chip is powered on. But as sudden power loss isn't detectable this is not save. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Cc: Alessandro Zummo <a.zummo@towertech.it> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-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 |