aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/mtk_timer.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2015-10-20 06:37:45 -0400
committerThomas Gleixner <tglx@linutronix.de>2015-10-20 06:37:45 -0400
commit3bc2159faf897bab51e4f1144b525d21823832a6 (patch)
tree97e28296005957f4ae15b83ae0d5998ebb9f4dcf /drivers/clocksource/mtk_timer.c
parentb2c280bdd6ea31be66c9b6a666e71daa49beef75 (diff)
parentcb0f2538039c65f2bb64a9d427dbe9dd7d0f71a6 (diff)
Merge branch 'clockevents/4.4' of http://git.linaro.org/people/daniel.lezcano/linux into timers/core
clockevent updates from Daniel Lezcano: - Remove unneeded memset in em_sti, sh_cmt and h8300 because there are already zeroed by a kzalloc (Alexey Klimov) - Optimize code by replacing this_cpu_ptr by container_of on the exynos_mct (Alexey Klimov) - Get immune from a spurious interrupt when enabling the mtk_timer (Daniel Lezcano) - Use the dynamic irq affinity to optimize wakeup and useless IPI timer on the imx timer (Lucas Stach) - Add new timer for Tango SoCs (Marc Gonzalez) - Implement the timer delay for armada-370-xp (Russell King) - Use GPT as clock source (Yingjoe Chen)
Diffstat (limited to 'drivers/clocksource/mtk_timer.c')
-rw-r--r--drivers/clocksource/mtk_timer.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
index 50f0641c65b6..fbfc74685e6a 100644
--- a/drivers/clocksource/mtk_timer.c
+++ b/drivers/clocksource/mtk_timer.c
@@ -24,6 +24,7 @@
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/of_address.h> 25#include <linux/of_address.h>
26#include <linux/of_irq.h> 26#include <linux/of_irq.h>
27#include <linux/sched_clock.h>
27#include <linux/slab.h> 28#include <linux/slab.h>
28 29
29#define GPT_IRQ_EN_REG 0x00 30#define GPT_IRQ_EN_REG 0x00
@@ -59,6 +60,13 @@ struct mtk_clock_event_device {
59 struct clock_event_device dev; 60 struct clock_event_device dev;
60}; 61};
61 62
63static void __iomem *gpt_sched_reg __read_mostly;
64
65static u64 notrace mtk_read_sched_clock(void)
66{
67 return readl_relaxed(gpt_sched_reg);
68}
69
62static inline struct mtk_clock_event_device *to_mtk_clk( 70static inline struct mtk_clock_event_device *to_mtk_clk(
63 struct clock_event_device *c) 71 struct clock_event_device *c)
64{ 72{
@@ -141,14 +149,6 @@ static irqreturn_t mtk_timer_interrupt(int irq, void *dev_id)
141 return IRQ_HANDLED; 149 return IRQ_HANDLED;
142} 150}
143 151
144static void mtk_timer_global_reset(struct mtk_clock_event_device *evt)
145{
146 /* Disable all interrupts */
147 writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
148 /* Acknowledge all interrupts */
149 writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
150}
151
152static void 152static void
153mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option) 153mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
154{ 154{
@@ -168,6 +168,12 @@ static void mtk_timer_enable_irq(struct mtk_clock_event_device *evt, u8 timer)
168{ 168{
169 u32 val; 169 u32 val;
170 170
171 /* Disable all interrupts */
172 writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
173
174 /* Acknowledge all spurious pending interrupts */
175 writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
176
171 val = readl(evt->gpt_base + GPT_IRQ_EN_REG); 177 val = readl(evt->gpt_base + GPT_IRQ_EN_REG);
172 writel(val | GPT_IRQ_ENABLE(timer), 178 writel(val | GPT_IRQ_ENABLE(timer),
173 evt->gpt_base + GPT_IRQ_EN_REG); 179 evt->gpt_base + GPT_IRQ_EN_REG);
@@ -220,8 +226,6 @@ static void __init mtk_timer_init(struct device_node *node)
220 } 226 }
221 rate = clk_get_rate(clk); 227 rate = clk_get_rate(clk);
222 228
223 mtk_timer_global_reset(evt);
224
225 if (request_irq(evt->dev.irq, mtk_timer_interrupt, 229 if (request_irq(evt->dev.irq, mtk_timer_interrupt,
226 IRQF_TIMER | IRQF_IRQPOLL, "mtk_timer", evt)) { 230 IRQF_TIMER | IRQF_IRQPOLL, "mtk_timer", evt)) {
227 pr_warn("failed to setup irq %d\n", evt->dev.irq); 231 pr_warn("failed to setup irq %d\n", evt->dev.irq);
@@ -234,6 +238,8 @@ static void __init mtk_timer_init(struct device_node *node)
234 mtk_timer_setup(evt, GPT_CLK_SRC, TIMER_CTRL_OP_FREERUN); 238 mtk_timer_setup(evt, GPT_CLK_SRC, TIMER_CTRL_OP_FREERUN);
235 clocksource_mmio_init(evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC), 239 clocksource_mmio_init(evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC),
236 node->name, rate, 300, 32, clocksource_mmio_readl_up); 240 node->name, rate, 300, 32, clocksource_mmio_readl_up);
241 gpt_sched_reg = evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC);
242 sched_clock_register(mtk_read_sched_clock, 32, rate);
237 243
238 /* Configure clock event */ 244 /* Configure clock event */
239 mtk_timer_setup(evt, GPT_CLK_EVT, TIMER_CTRL_OP_REPEAT); 245 mtk_timer_setup(evt, GPT_CLK_EVT, TIMER_CTRL_OP_REPEAT);