diff options
author | Joonyoung Shim <jy0922.shim@samsung.com> | 2015-08-12 06:21:46 -0400 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@free-electrons.com> | 2015-09-05 07:19:13 -0400 |
commit | 1fb1c35f56bb6ab4a65920c648154b0f78f634a5 (patch) | |
tree | 7e1340462b02548eba9e4fda4240c6c8de8582d0 /drivers/rtc | |
parent | 80e274e96e5bc4ddf9ee4b31ab6f4a2a9fa08040 (diff) |
rtc: s3c: fix disabled clocks for alarm
The clock enable/disable codes for alarm have been removed from
commit 24e1455493da ("drivers/rtc/rtc-s3c.c: delete duplicate clock
control") and the clocks are disabled even if alarm is set, so alarm
interrupt can't happen.
The s3c_rtc_setaie function can be called several times with 'enabled'
argument having same value, so it needs to check whether clocks are
enabled or not.
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Cc: <stable@vger.kernel.org> # v4.1
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/rtc-s3c.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index a0f832362199..2e709e239dbc 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -39,6 +39,7 @@ struct s3c_rtc { | |||
39 | void __iomem *base; | 39 | void __iomem *base; |
40 | struct clk *rtc_clk; | 40 | struct clk *rtc_clk; |
41 | struct clk *rtc_src_clk; | 41 | struct clk *rtc_src_clk; |
42 | bool clk_disabled; | ||
42 | 43 | ||
43 | struct s3c_rtc_data *data; | 44 | struct s3c_rtc_data *data; |
44 | 45 | ||
@@ -71,9 +72,12 @@ static void s3c_rtc_enable_clk(struct s3c_rtc *info) | |||
71 | unsigned long irq_flags; | 72 | unsigned long irq_flags; |
72 | 73 | ||
73 | spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); | 74 | spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); |
74 | clk_enable(info->rtc_clk); | 75 | if (info->clk_disabled) { |
75 | if (info->data->needs_src_clk) | 76 | clk_enable(info->rtc_clk); |
76 | clk_enable(info->rtc_src_clk); | 77 | if (info->data->needs_src_clk) |
78 | clk_enable(info->rtc_src_clk); | ||
79 | info->clk_disabled = false; | ||
80 | } | ||
77 | spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); | 81 | spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); |
78 | } | 82 | } |
79 | 83 | ||
@@ -82,9 +86,12 @@ static void s3c_rtc_disable_clk(struct s3c_rtc *info) | |||
82 | unsigned long irq_flags; | 86 | unsigned long irq_flags; |
83 | 87 | ||
84 | spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); | 88 | spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); |
85 | if (info->data->needs_src_clk) | 89 | if (!info->clk_disabled) { |
86 | clk_disable(info->rtc_src_clk); | 90 | if (info->data->needs_src_clk) |
87 | clk_disable(info->rtc_clk); | 91 | clk_disable(info->rtc_src_clk); |
92 | clk_disable(info->rtc_clk); | ||
93 | info->clk_disabled = true; | ||
94 | } | ||
88 | spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); | 95 | spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); |
89 | } | 96 | } |
90 | 97 | ||
@@ -128,6 +135,11 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) | |||
128 | 135 | ||
129 | s3c_rtc_disable_clk(info); | 136 | s3c_rtc_disable_clk(info); |
130 | 137 | ||
138 | if (enabled) | ||
139 | s3c_rtc_enable_clk(info); | ||
140 | else | ||
141 | s3c_rtc_disable_clk(info); | ||
142 | |||
131 | return 0; | 143 | return 0; |
132 | } | 144 | } |
133 | 145 | ||