lkml.org 
[lkml]   [2012]   [Mar]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    SubjectRe: [PATCH] PM / devfreq: add relation of recommended frequency.
    From
    On Thu, Mar 8, 2012 at 2:45 AM, Turquette, Mike <mturquette@ti.com> wrote:
    > On Thu, Feb 9, 2012 at 11:19 PM, MyungJoo Ham <myungjoo.ham@samsung.com> wrote:
    >> The semantics of "target frequency" given to devfreq driver from
    >> devfreq framework has always been interpretted as "at least" or GLB
    >> (greatest lower bound). However, the framework might want the
    >> device driver to limit its max frequency (LUB: least upper bound),
    >> especially if it is given by thermal framework (it's too hot).
    >>
    >> Thus, the target fuction should have another parameter to express
    >> whether the framework wants GLB or LUB. And, the additional parameter,
    >> "u32 options", does it.
    >
    > Nitpick: changelog still refers to "options" but code reads "flags".
    >
    > Regards,
    > Mike
    >

    Thanks. That is updated in the git.infradead.org repository to be
    requested to pull.
    http://git.infradead.org/users/kmpark/linux-samsung/shortlog/refs/heads/devfreq-for-next

    As soon as infradead server gets synched, you can see the commit
    message updated.


    Cheers!
    MyungJoo.

    >>
    >> With the update, devfreq_recommended_opp() is also updated.
    >>
    >> Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
    >> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
    >> ---
    >>  drivers/devfreq/devfreq.c     |   44 ++++++++++++++++++++++++++++++----------
    >>  drivers/devfreq/exynos4_bus.c |   16 +++++++++++---
    >>  include/linux/devfreq.h       |   18 ++++++++++++++--
    >>  3 files changed, 60 insertions(+), 18 deletions(-)
    >>
    >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
    >> index a33fc6c..83392a6 100644
    >> --- a/drivers/devfreq/devfreq.c
    >> +++ b/drivers/devfreq/devfreq.c
    >> @@ -84,6 +84,7 @@ int update_devfreq(struct devfreq *devfreq)
    >>  {
    >>        unsigned long freq;
    >>        int err = 0;
    >> +       u32 options = 0;
    >>
    >>        if (!mutex_is_locked(&devfreq->lock)) {
    >>                WARN(true, "devfreq->lock must be locked by the caller.\n");
    >> @@ -104,18 +105,23 @@ int update_devfreq(struct devfreq *devfreq)
    >>         * qos_min_freq
    >>         */
    >>
    >> -       if (devfreq->qos_min_freq && freq < devfreq->qos_min_freq)
    >> +       if (devfreq->qos_min_freq && freq < devfreq->qos_min_freq) {
    >>                freq = devfreq->qos_min_freq;
    >> -       if (devfreq->max_freq && freq > devfreq->max_freq)
    >> +               options &= ~(1 << 0);
    >> +               options |= DEVFREQ_OPTION_FREQ_LUB;
    >> +       }
    >> +       if (devfreq->max_freq && freq > devfreq->max_freq) {
    >>                freq = devfreq->max_freq;
    >> -       if (devfreq->min_freq && freq < devfreq->min_freq)
    >> +               options &= ~(1 << 0);
    >> +               options |= DEVFREQ_OPTION_FREQ_GLB;
    >> +       }
    >> +       if (devfreq->min_freq && freq < devfreq->min_freq) {
    >>                freq = devfreq->min_freq;
    >> +               options &= ~(1 << 0);
    >> +               options |= DEVFREQ_OPTION_FREQ_LUB;
    >> +       }
    >>
    >> -       /*
    >> -        * TODO in the devfreq-next:
    >> -        * add relation or use rance (freq_min, freq_max)
    >> -        */
    >> -       err = devfreq->profile->target(devfreq->dev.parent, &freq);
    >> +       err = devfreq->profile->target(devfreq->dev.parent, &freq, options);
    >>        if (err)
    >>                return err;
    >>
    >> @@ -771,14 +777,30 @@ module_exit(devfreq_exit);
    >>  *                          freq value given to target callback.
    >>  * @dev                The devfreq user device. (parent of devfreq)
    >>  * @freq       The frequency given to target function
    >> + * @floor      false: find LUB first and use GLB if LUB not available.
    >> + *             true:  find GLB first and use LUB if GLB not available.
    >> + *
    >> + * LUB: least upper bound (at least this freq or above, but the least)
    >> + * GLB: greatest lower bound (at most this freq or below, but the most)
    >>  *
    >>  */
    >> -struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq)
    >> +struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq,
    >> +                                   bool floor)
    >>  {
    >> -       struct opp *opp = opp_find_freq_ceil(dev, freq);
    >> +       struct opp *opp;
    >>
    >> -       if (opp == ERR_PTR(-ENODEV))
    >> +       if (floor) {
    >>                opp = opp_find_freq_floor(dev, freq);
    >> +
    >> +               if (opp == ERR_PTR(-ENODEV))
    >> +                       opp = opp_find_freq_ceil(dev, freq);
    >> +       } else {
    >> +               opp = opp_find_freq_ceil(dev, freq);
    >> +
    >> +               if (opp == ERR_PTR(-ENODEV))
    >> +                       opp = opp_find_freq_floor(dev, freq);
    >> +       }
    >> +
    >>        return opp;
    >>  }
    >>
    >> diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c
    >> index 590d686..c0a78da 100644
    >> --- a/drivers/devfreq/exynos4_bus.c
    >> +++ b/drivers/devfreq/exynos4_bus.c
    >> @@ -619,13 +619,21 @@ static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp,
    >>        return err;
    >>  }
    >>
    >> -static int exynos4_bus_target(struct device *dev, unsigned long *_freq)
    >> +static int exynos4_bus_target(struct device *dev, unsigned long *_freq,
    >> +                             u32 options)
    >>  {
    >>        int err = 0;
    >> -       struct busfreq_data *data = dev_get_drvdata(dev);
    >> -       struct opp *opp = devfreq_recommended_opp(dev, _freq);
    >> -       unsigned long old_freq = opp_get_freq(data->curr_opp);
    >> +       unsigned long def = *_freq;
    >> +       struct platform_device *pdev = container_of(dev, struct platform_device,
    >> +                                                   dev);
    >> +       struct busfreq_data *data = platform_get_drvdata(pdev);
    >> +       struct opp *opp = devfreq_recommended_opp(dev, _freq, options &
    >> +                                                 DEVFREQ_OPTION_FREQ_GLB);
    >>        unsigned long freq = opp_get_freq(opp);
    >> +       unsigned long old_freq = opp_get_freq(data->curr_opp);
    >> +
    >> +       if (IS_ERR(opp))
    >> +               return PTR_ERR(opp);
    >>
    >>        if (old_freq == freq)
    >>                return 0;
    >> diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
    >> index b853379..1aff012 100644
    >> --- a/include/linux/devfreq.h
    >> +++ b/include/linux/devfreq.h
    >> @@ -59,6 +59,16 @@ struct devfreq_pm_qos_table {
    >>        s32 qos_value;
    >>  };
    >>
    >> +/*
    >> + * target callback, which is to provide additional information to the
    >> + * devfreq driver.
    >> + */
    >> +
    >> +/* The resulting frequency should be at least this. (least upper bound) */
    >> +#define DEVFREQ_OPTION_FREQ_LUB        0x0
    >> +/* The resulting frequency should be at most this. (greatest lower bound) */
    >> +#define DEVFREQ_OPTION_FREQ_GLB 0x1
    >> +
    >>  /**
    >>  * struct devfreq_dev_profile - Devfreq's user device profile
    >>  * @initial_freq       The operating frequency when devfreq_add_device() is
    >> @@ -76,6 +86,8 @@ struct devfreq_pm_qos_table {
    >>  *                     higher than any operable frequency, set maximum.
    >>  *                     Before returning, target function should set
    >>  *                     freq at the current frequency.
    >> + *                     The "option" parameter's possible values are
    >> + *                     explained above with "DEVFREQ_OPTION_*" macros.
    >>  * @get_dev_status     The device should provide the current performance
    >>  *                     status to devfreq, which is used by governors.
    >>  * @exit               An optional callback that is called when devfreq
    >> @@ -95,7 +107,7 @@ struct devfreq_dev_profile {
    >>        bool qos_use_max;
    >>        struct devfreq_pm_qos_table *qos_list;
    >>
    >> -       int (*target)(struct device *dev, unsigned long *freq);
    >> +       int (*target)(struct device *dev, unsigned long *freq, u32 options);
    >>        int (*get_dev_status)(struct device *dev,
    >>                              struct devfreq_dev_status *stat);
    >>        void (*exit)(struct device *dev);
    >> @@ -198,7 +210,7 @@ extern int devfreq_remove_device(struct devfreq *devfreq);
    >>
    >>  /* Helper functions for devfreq user device driver with OPP. */
    >>  extern struct opp *devfreq_recommended_opp(struct device *dev,
    >> -                                          unsigned long *freq);
    >> +                                          unsigned long *freq, bool floor);
    >>  extern int devfreq_register_opp_notifier(struct device *dev,
    >>                                         struct devfreq *devfreq);
    >>  extern int devfreq_unregister_opp_notifier(struct device *dev,
    >> @@ -253,7 +265,7 @@ static int devfreq_remove_device(struct devfreq *devfreq)
    >>  }
    >>
    >>  static struct opp *devfreq_recommended_opp(struct device *dev,
    >> -                                          unsigned long *freq)
    >> +                                          unsigned long *freq, bool floor)
    >>  {
    >>        return -EINVAL;
    >>  }
    >> --
    >> 1.7.4.1
    >>



    --
    MyungJoo Ham, Ph.D.
    Mobile Software Platform Lab, DMC Business, Samsung Electronics
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2012-03-09 08:13    [W:0.043 / U:5.504 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site