[PATCH 05/13] coresight: etb: let runtime PM handle core clock

Ulf Hansson ulf.hansson at linaro.org
Fri Apr 17 02:08:58 PDT 2015


On 17 April 2015 at 10:58, Linus Walleij <linus.walleij at linaro.org> wrote:
> This uses runtime PM to manage the PCLK ("amba_pclk") instead
> of screwing around with the framework by going in and taking
> a copy from the amba device. The amba bus core will uprepare
> and disable the clock when the device is unused when
> CONFIG_PM is selected, else the clock will be always on.
>
> Prior to this patch, as the AMBA primecell bus code enables
> the PCLK, it would be left on after probe as
> the clk_prepare_enable() and clk_disable_unprepare() was
> called and thus just increase and decreas the refcount by
> one, without it reaching zero and actually disabling the
> clock. Now the runtime PM callbacks will make sure the PCLK
> is properly disabled after probe.
>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>

Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>

> ---
>  drivers/coresight/coresight-etb10.c | 35 +++++++++--------------------------
>  1 file changed, 9 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/coresight/coresight-etb10.c b/drivers/coresight/coresight-etb10.c
> index c9acd406f0d0..c4587510a826 100644
> --- a/drivers/coresight/coresight-etb10.c
> +++ b/drivers/coresight/coresight-etb10.c
> @@ -22,7 +22,7 @@
>  #include <linux/uaccess.h>
>  #include <linux/slab.h>
>  #include <linux/spinlock.h>
> -#include <linux/clk.h>
> +#include <linux/pm_runtime.h>
>  #include <linux/seq_file.h>
>  #include <linux/coresight.h>
>  #include <linux/amba/bus.h>
> @@ -68,7 +68,6 @@
>   * @dev:       the device entity associated to this component.
>   * @csdev:     component vitals needed by the framework.
>   * @miscdev:   specifics to handle "/dev/xyz.etb" entry.
> - * @clk:       the clock this component is associated to.
>   * @spinlock:  only one at a time pls.
>   * @in_use:    synchronise user space access to etb buffer.
>   * @buf:       area of memory where ETB buffer content gets sent.
> @@ -81,7 +80,6 @@ struct etb_drvdata {
>         struct device           *dev;
>         struct coresight_device *csdev;
>         struct miscdevice       miscdev;
> -       struct clk              *clk;
>         spinlock_t              spinlock;
>         atomic_t                in_use;
>         u8                      *buf;
> @@ -92,17 +90,14 @@ struct etb_drvdata {
>
>  static unsigned int etb_get_buffer_depth(struct etb_drvdata *drvdata)
>  {
> -       int ret;
>         u32 depth = 0;
>
> -       ret = clk_prepare_enable(drvdata->clk);
> -       if (ret)
> -               return ret;
> +       pm_runtime_get_sync(drvdata->dev);
>
>         /* RO registers don't need locking */
>         depth = readl_relaxed(drvdata->base + ETB_RAM_DEPTH_REG);
>
> -       clk_disable_unprepare(drvdata->clk);
> +       pm_runtime_put(drvdata->dev);
>         return depth;
>  }
>
> @@ -137,12 +132,9 @@ static void etb_enable_hw(struct etb_drvdata *drvdata)
>  static int etb_enable(struct coresight_device *csdev)
>  {
>         struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> -       int ret;
>         unsigned long flags;
>
> -       ret = clk_prepare_enable(drvdata->clk);
> -       if (ret)
> -               return ret;
> +       pm_runtime_get_sync(drvdata->dev);
>
>         spin_lock_irqsave(&drvdata->spinlock, flags);
>         etb_enable_hw(drvdata);
> @@ -252,7 +244,7 @@ static void etb_disable(struct coresight_device *csdev)
>         drvdata->enable = false;
>         spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
> -       clk_disable_unprepare(drvdata->clk);
> +       pm_runtime_put(drvdata->dev);
>
>         dev_info(drvdata->dev, "ETB disabled\n");
>  }
> @@ -339,16 +331,12 @@ static const struct file_operations etb_fops = {
>  static ssize_t status_show(struct device *dev,
>                            struct device_attribute *attr, char *buf)
>  {
> -       int ret;
>         unsigned long flags;
>         u32 etb_rdr, etb_sr, etb_rrp, etb_rwp;
>         u32 etb_trg, etb_cr, etb_ffsr, etb_ffcr;
>         struct etb_drvdata *drvdata = dev_get_drvdata(dev->parent);
>
> -       ret = clk_prepare_enable(drvdata->clk);
> -       if (ret)
> -               goto out;
> -
> +       pm_runtime_get_sync(drvdata->dev);
>         spin_lock_irqsave(&drvdata->spinlock, flags);
>         CS_UNLOCK(drvdata->base);
>
> @@ -364,7 +352,7 @@ static ssize_t status_show(struct device *dev,
>         CS_LOCK(drvdata->base);
>         spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
> -       clk_disable_unprepare(drvdata->clk);
> +       pm_runtime_put(drvdata->dev);
>
>         return sprintf(buf,
>                        "Depth:\t\t0x%x\n"
> @@ -377,7 +365,7 @@ static ssize_t status_show(struct device *dev,
>                        "Flush ctrl:\t0x%x\n",
>                        etb_rdr, etb_sr, etb_rrp, etb_rwp,
>                        etb_trg, etb_cr, etb_ffsr, etb_ffcr);
> -out:
> +
>         return -EINVAL;
>  }
>  static DEVICE_ATTR_RO(status);
> @@ -449,13 +437,8 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
>
>         spin_lock_init(&drvdata->spinlock);
>
> -       drvdata->clk = adev->pclk;
> -       ret = clk_prepare_enable(drvdata->clk);
> -       if (ret)
> -               return ret;
> -
>         drvdata->buffer_depth = etb_get_buffer_depth(drvdata);
> -       clk_disable_unprepare(drvdata->clk);
> +       pm_runtime_put(&adev->dev);
>
>         if (drvdata->buffer_depth < 0)
>                 return -EINVAL;
> --
> 1.9.3
>



More information about the linux-arm-kernel mailing list