Skip to content

Commit 063adc7

Browse files
committed
rtc: rtc-sh: clock framework support.
This adds clock framework support to the rtc-sh driver. With this in place, platforms can default to leaving the clock disabled rather than placing it in the always enabled state. Signed-off-by: Paul Mundt <[email protected]>
1 parent 3ee8da8 commit 063adc7

File tree

2 files changed

+50
-19
lines changed

2 files changed

+50
-19
lines changed

drivers/rtc/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ config RTC_DRV_SA1100
573573

574574
config RTC_DRV_SH
575575
tristate "SuperH On-Chip RTC"
576-
depends on RTC_CLASS && SUPERH
576+
depends on RTC_CLASS && SUPERH && HAVE_CLK
577577
help
578578
Say Y here to enable support for the on-chip RTC found in
579579
most SuperH processors.

drivers/rtc/rtc-sh.c

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* SuperH On-Chip RTC Support
33
*
4-
* Copyright (C) 2006, 2007, 2008 Paul Mundt
4+
* Copyright (C) 2006 - 2009 Paul Mundt
55
* Copyright (C) 2006 Jamie Lenehan
66
* Copyright (C) 2008 Angelo Castello
77
*
@@ -25,10 +25,11 @@
2525
#include <linux/spinlock.h>
2626
#include <linux/io.h>
2727
#include <linux/log2.h>
28+
#include <linux/clk.h>
2829
#include <asm/rtc.h>
2930

3031
#define DRV_NAME "sh-rtc"
31-
#define DRV_VERSION "0.2.1"
32+
#define DRV_VERSION "0.2.2"
3233

3334
#define RTC_REG(r) ((r) * rtc_reg_size)
3435

@@ -87,16 +88,17 @@
8788
#define RCR2_START 0x01 /* Start bit */
8889

8990
struct sh_rtc {
90-
void __iomem *regbase;
91-
unsigned long regsize;
92-
struct resource *res;
93-
int alarm_irq;
94-
int periodic_irq;
95-
int carry_irq;
96-
struct rtc_device *rtc_dev;
97-
spinlock_t lock;
98-
unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */
99-
unsigned short periodic_freq;
91+
void __iomem *regbase;
92+
unsigned long regsize;
93+
struct resource *res;
94+
int alarm_irq;
95+
int periodic_irq;
96+
int carry_irq;
97+
struct clk *clk;
98+
struct rtc_device *rtc_dev;
99+
spinlock_t lock;
100+
unsigned long capabilities; /* See asm/rtc.h for cap bits */
101+
unsigned short periodic_freq;
100102
};
101103

102104
static int __sh_rtc_interrupt(struct sh_rtc *rtc)
@@ -294,10 +296,10 @@ static inline void sh_rtc_setaie(struct device *dev, unsigned int enable)
294296

295297
tmp = readb(rtc->regbase + RCR1);
296298

297-
if (!enable)
298-
tmp &= ~RCR1_AIE;
299-
else
299+
if (enable)
300300
tmp |= RCR1_AIE;
301+
else
302+
tmp &= ~RCR1_AIE;
301303

302304
writeb(tmp, rtc->regbase + RCR1);
303305

@@ -618,6 +620,7 @@ static int sh_rtc_irq_set_freq(struct device *dev, int freq)
618620
{
619621
if (!is_power_of_2(freq))
620622
return -EINVAL;
623+
621624
return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq);
622625
}
623626

@@ -637,7 +640,8 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
637640
struct sh_rtc *rtc;
638641
struct resource *res;
639642
struct rtc_time r;
640-
int ret;
643+
char clk_name[6];
644+
int clk_id, ret;
641645

642646
rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL);
643647
if (unlikely(!rtc))
@@ -652,6 +656,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
652656
dev_err(&pdev->dev, "No IRQ resource\n");
653657
goto err_badres;
654658
}
659+
655660
rtc->periodic_irq = ret;
656661
rtc->carry_irq = platform_get_irq(pdev, 1);
657662
rtc->alarm_irq = platform_get_irq(pdev, 2);
@@ -663,7 +668,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
663668
goto err_badres;
664669
}
665670

666-
rtc->regsize = res->end - res->start + 1;
671+
rtc->regsize = resource_size(res);
667672

668673
rtc->res = request_mem_region(res->start, rtc->regsize, pdev->name);
669674
if (unlikely(!rtc->res)) {
@@ -677,6 +682,26 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
677682
goto err_badmap;
678683
}
679684

685+
clk_id = pdev->id;
686+
/* With a single device, the clock id is still "rtc0" */
687+
if (clk_id < 0)
688+
clk_id = 0;
689+
690+
snprintf(clk_name, sizeof(clk_name), "rtc%d", clk_id);
691+
692+
rtc->clk = clk_get(&pdev->dev, clk_name);
693+
if (IS_ERR(rtc->clk)) {
694+
/*
695+
* No error handling for rtc->clk intentionally, not all
696+
* platforms will have a unique clock for the RTC, and
697+
* the clk API can handle the struct clk pointer being
698+
* NULL.
699+
*/
700+
rtc->clk = NULL;
701+
}
702+
703+
clk_enable(rtc->clk);
704+
680705
rtc->rtc_dev = rtc_device_register("sh", &pdev->dev,
681706
&sh_rtc_ops, THIS_MODULE);
682707
if (IS_ERR(rtc->rtc_dev)) {
@@ -759,6 +784,8 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
759784
return 0;
760785

761786
err_unmap:
787+
clk_disable(rtc->clk);
788+
clk_put(rtc->clk);
762789
iounmap(rtc->regbase);
763790
err_badmap:
764791
release_resource(rtc->res);
@@ -780,6 +807,7 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
780807
sh_rtc_setcie(&pdev->dev, 0);
781808

782809
free_irq(rtc->periodic_irq, rtc);
810+
783811
if (rtc->carry_irq > 0) {
784812
free_irq(rtc->carry_irq, rtc);
785813
free_irq(rtc->alarm_irq, rtc);
@@ -789,6 +817,9 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
789817

790818
iounmap(rtc->regbase);
791819

820+
clk_disable(rtc->clk);
821+
clk_put(rtc->clk);
822+
792823
platform_set_drvdata(pdev, NULL);
793824

794825
kfree(rtc);
@@ -802,11 +833,11 @@ static void sh_rtc_set_irq_wake(struct device *dev, int enabled)
802833
struct sh_rtc *rtc = platform_get_drvdata(pdev);
803834

804835
set_irq_wake(rtc->periodic_irq, enabled);
836+
805837
if (rtc->carry_irq > 0) {
806838
set_irq_wake(rtc->carry_irq, enabled);
807839
set_irq_wake(rtc->alarm_irq, enabled);
808840
}
809-
810841
}
811842

812843
static int sh_rtc_suspend(struct device *dev)

0 commit comments

Comments
 (0)