summaryrefslogtreecommitdiffstats
path: root/drivers/clocksource
diff options
context:
space:
mode:
authorNicolai Stange <nicstange@gmail.com>2017-02-06 16:12:01 -0500
committerJohn Stultz <john.stultz@linaro.org>2017-03-23 15:14:02 -0400
commit3814ae092d36da04d5fbaf777c1564dc4ee68559 (patch)
tree45a9796de826070bd5f8f0eabcac3f659b904b9c /drivers/clocksource
parentc3c0a20df9fc55e2243a31f91a943b3e8ba61289 (diff)
clocksource: em_sti: Split clock prepare and enable steps
Currently, the em_sti driver prepares and enables the needed clock in em_sti_enable(), potentially called through its clockevent device's ->set_state_oneshot(). However, the clk_prepare() step may sleep whereas tick_program_event() and thus, ->set_state_oneshot(), can be called in atomic context. Split the clk_prepare_enable() in em_sti_enable() into two steps: - prepare the clock at device probing via clk_prepare() - and enable it in em_sti_enable() via clk_enable(). Slightly reorder resource initialization in em_sti_probe() in order to facilitate error handling in later patches. Signed-off-by: Nicolai Stange <nicstange@gmail.com> Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'drivers/clocksource')
-rw-r--r--drivers/clocksource/em_sti.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c
index aff87df07449..6c0955a92f24 100644
--- a/drivers/clocksource/em_sti.c
+++ b/drivers/clocksource/em_sti.c
@@ -78,7 +78,7 @@ static int em_sti_enable(struct em_sti_priv *p)
78 int ret; 78 int ret;
79 79
80 /* enable clock */ 80 /* enable clock */
81 ret = clk_prepare_enable(p->clk); 81 ret = clk_enable(p->clk);
82 if (ret) { 82 if (ret) {
83 dev_err(&p->pdev->dev, "cannot enable clock\n"); 83 dev_err(&p->pdev->dev, "cannot enable clock\n");
84 return ret; 84 return ret;
@@ -107,7 +107,7 @@ static void em_sti_disable(struct em_sti_priv *p)
107 em_sti_write(p, STI_INTENCLR, 3); 107 em_sti_write(p, STI_INTENCLR, 3);
108 108
109 /* stop clock */ 109 /* stop clock */
110 clk_disable_unprepare(p->clk); 110 clk_disable(p->clk);
111} 111}
112 112
113static u64 em_sti_count(struct em_sti_priv *p) 113static u64 em_sti_count(struct em_sti_priv *p)
@@ -303,6 +303,7 @@ static int em_sti_probe(struct platform_device *pdev)
303 struct em_sti_priv *p; 303 struct em_sti_priv *p;
304 struct resource *res; 304 struct resource *res;
305 int irq; 305 int irq;
306 int ret;
306 307
307 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); 308 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
308 if (p == NULL) 309 if (p == NULL)
@@ -323,6 +324,13 @@ static int em_sti_probe(struct platform_device *pdev)
323 if (IS_ERR(p->base)) 324 if (IS_ERR(p->base))
324 return PTR_ERR(p->base); 325 return PTR_ERR(p->base);
325 326
327 if (devm_request_irq(&pdev->dev, irq, em_sti_interrupt,
328 IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
329 dev_name(&pdev->dev), p)) {
330 dev_err(&pdev->dev, "failed to request low IRQ\n");
331 return -ENOENT;
332 }
333
326 /* get hold of clock */ 334 /* get hold of clock */
327 p->clk = devm_clk_get(&pdev->dev, "sclk"); 335 p->clk = devm_clk_get(&pdev->dev, "sclk");
328 if (IS_ERR(p->clk)) { 336 if (IS_ERR(p->clk)) {
@@ -330,11 +338,10 @@ static int em_sti_probe(struct platform_device *pdev)
330 return PTR_ERR(p->clk); 338 return PTR_ERR(p->clk);
331 } 339 }
332 340
333 if (devm_request_irq(&pdev->dev, irq, em_sti_interrupt, 341 ret = clk_prepare(p->clk);
334 IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING, 342 if (ret < 0) {
335 dev_name(&pdev->dev), p)) { 343 dev_err(&pdev->dev, "cannot prepare clock\n");
336 dev_err(&pdev->dev, "failed to request low IRQ\n"); 344 return ret;
337 return -ENOENT;
338 } 345 }
339 346
340 raw_spin_lock_init(&p->lock); 347 raw_spin_lock_init(&p->lock);