lkml.org 
[lkml]   [2015]   [Nov]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH (v3) 6/11] watchdog: bcm63xx_wdt: Obtain watchdog clock HZ from "periph" clk
    From
    Date
    Instead of using a fixed clock HZ in the driver, obtain it from the
    "periph" clk that the watchdog timer uses.

    Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
    ---
    Patch 7 split into two patches.

    On 24/11/15 22:42, Florian Fainelli wrote:
    > On 24/11/15 14:12, Simon Arlott wrote:
    >> Instead of using a fixed clock HZ in the driver, obtain it from the
    >> "periph" clk that the watchdog timer uses.
    >>
    >> Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
    >
    > Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
    >

    Changed because of the reordering of timer/watchdog register calls.

    drivers/watchdog/bcm63xx_wdt.c | 36 +++++++++++++++++++++++++++++++-----
    1 file changed, 31 insertions(+), 5 deletions(-)

    diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c
    index 2257924..0a19731 100644
    --- a/drivers/watchdog/bcm63xx_wdt.c
    +++ b/drivers/watchdog/bcm63xx_wdt.c
    @@ -13,6 +13,7 @@

    #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

    +#include <linux/clk.h>
    #include <linux/errno.h>
    #include <linux/io.h>
    #include <linux/kernel.h>
    @@ -32,12 +33,14 @@

    #define PFX KBUILD_MODNAME

    -#define WDT_HZ 50000000 /* Fclk */
    +#define WDT_CLK_NAME "periph"

    struct bcm63xx_wdt_hw {
    struct watchdog_device wdd;
    raw_spinlock_t lock;
    void __iomem *regs;
    + struct clk *clk;
    + unsigned long clock_hz;
    bool running;
    };

    @@ -54,7 +57,7 @@ static int bcm63xx_wdt_start(struct watchdog_device *wdd)
    unsigned long flags;

    raw_spin_lock_irqsave(&hw->lock, flags);
    - bcm_writel(wdd->timeout * WDT_HZ, hw->regs + WDT_DEFVAL_REG);
    + bcm_writel(wdd->timeout * hw->clock_hz, hw->regs + WDT_DEFVAL_REG);
    bcm_writel(WDT_START_1, hw->regs + WDT_CTL_REG);
    bcm_writel(WDT_START_2, hw->regs + WDT_CTL_REG);
    hw->running = true;
    @@ -118,7 +121,7 @@ static void bcm63xx_wdt_isr(void *data)
    die(PFX ": watchdog timer expired\n", get_irq_regs());
    }

    - ms = timeleft / (WDT_HZ / 1000);
    + ms = timeleft / (hw->clock_hz / 1000);
    dev_alert(hw->wdd.dev,
    "warning timer fired, reboot in %ums\n", ms);
    }
    @@ -162,6 +165,25 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
    return -ENXIO;
    }

    + hw->clk = devm_clk_get(&pdev->dev, WDT_CLK_NAME);
    + if (IS_ERR(hw->clk)) {
    + if (PTR_ERR(hw->clk) != -EPROBE_DEFER)
    + dev_err(&pdev->dev, "unable to request clock\n");
    + return PTR_ERR(hw->clk);
    + }
    +
    + hw->clock_hz = clk_get_rate(hw->clk);
    + if (!hw->clock_hz) {
    + dev_err(&pdev->dev, "unable to fetch clock rate\n");
    + return -EINVAL;
    + }
    +
    + ret = clk_prepare_enable(hw->clk);
    + if (ret) {
    + dev_err(&pdev->dev, "unable to enable clock\n");
    + return ret;
    + }
    +
    raw_spin_lock_init(&hw->lock);
    hw->running = false;

    @@ -169,7 +191,7 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
    wdd->ops = &bcm63xx_wdt_ops;
    wdd->info = &bcm63xx_wdt_info;
    wdd->min_timeout = 1;
    - wdd->max_timeout = 0xffffffff / WDT_HZ;
    + wdd->max_timeout = 0xffffffff / hw->clock_hz;
    wdd->timeout = min(30U, wdd->max_timeout);

    platform_set_drvdata(pdev, hw);
    @@ -180,7 +202,7 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
    ret = watchdog_register_device(wdd);
    if (ret < 0) {
    dev_err(&pdev->dev, "failed to register watchdog device\n");
    - return ret;
    + goto disable_clk;
    }

    ret = bcm63xx_timer_register(TIMER_WDT_ID, bcm63xx_wdt_isr, hw);
    @@ -198,6 +220,9 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)

    unregister_watchdog:
    watchdog_unregister_device(wdd);
    +
    +disable_clk:
    + clk_disable_unprepare(hw->clk);
    return ret;
    }

    @@ -207,6 +232,7 @@ static int bcm63xx_wdt_remove(struct platform_device *pdev)

    bcm63xx_timer_unregister(TIMER_WDT_ID);
    watchdog_unregister_device(&hw->wdd);
    + clk_disable_unprepare(hw->clk);
    return 0;
    }

    --
    2.1.4
    --
    Simon Arlott


    \
     
     \ /
      Last update: 2015-11-26 00:01    [W:4.686 / U:0.000 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site