lkml.org 
[lkml]   [2016]   [Nov]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC v8 03/28] clocksource: em_sti: split clock prepare and enable steps
    Date
    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.

    Signed-off-by: Nicolai Stange <nicstange@gmail.com>
    ---

    Notes:
    Compile-only tested on ARCH=arm.

    drivers/clocksource/em_sti.c | 25 ++++++++++++++++++-------
    1 file changed, 18 insertions(+), 7 deletions(-)

    diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c
    index 19bb179..46750c0 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)
    int ret;

    /* enable clock */
    - ret = clk_prepare_enable(p->clk);
    + ret = clk_enable(p->clk);
    if (ret) {
    dev_err(&p->pdev->dev, "cannot enable clock\n");
    return ret;
    @@ -107,7 +107,7 @@ static void em_sti_disable(struct em_sti_priv *p)
    em_sti_write(p, STI_INTENCLR, 3);

    /* stop clock */
    - clk_disable_unprepare(p->clk);
    + clk_disable(p->clk);
    }

    static cycle_t em_sti_count(struct em_sti_priv *p)
    @@ -303,6 +303,7 @@ static int em_sti_probe(struct platform_device *pdev)
    struct em_sti_priv *p;
    struct resource *res;
    int irq;
    + int ret;

    p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
    if (p == NULL)
    @@ -323,6 +324,13 @@ static int em_sti_probe(struct platform_device *pdev)
    if (IS_ERR(p->base))
    return PTR_ERR(p->base);

    + if (devm_request_irq(&pdev->dev, irq, em_sti_interrupt,
    + IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
    + dev_name(&pdev->dev), p)) {
    + dev_err(&pdev->dev, "failed to request low IRQ\n");
    + return -ENOENT;
    + }
    +
    /* get hold of clock */
    p->clk = devm_clk_get(&pdev->dev, "sclk");
    if (IS_ERR(p->clk)) {
    @@ -330,17 +338,20 @@ static int em_sti_probe(struct platform_device *pdev)
    return PTR_ERR(p->clk);
    }

    - if (devm_request_irq(&pdev->dev, irq, em_sti_interrupt,
    - IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
    - dev_name(&pdev->dev), p)) {
    - dev_err(&pdev->dev, "failed to request low IRQ\n");
    - return -ENOENT;
    + ret = clk_prepare(p->clk);
    + if (ret < 0) {
    + dev_err(&pdev->dev, "cannot prepare clock\n");
    + goto err_clk_put;
    }

    raw_spin_lock_init(&p->lock);
    em_sti_register_clockevent(p);
    em_sti_register_clocksource(p);
    return 0;
    +
    +err_clk_put:
    + clk_put(p->clk);
    + return ret;
    }

    static int em_sti_remove(struct platform_device *pdev)
    --
    2.10.2
    \
     
     \ /
      Last update: 2016-11-19 17:02    [W:4.323 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site