13 Feb, 2019

1 commit

  • [ Upstream commit 90e3577b5feb42bac1269e16bb3d2bdd8f6df40f ]

    The value of opp_table->regulator_count is not very consistent right now
    and it may end up being 0 while we do have a "opp-microvolt" property in
    the OPP table. It was kept that way as we used to check if any
    regulators are set with the OPP core for a device or not using value of
    regulator_count.

    Lets use opp_table->regulators for that purpose as the meaning of
    regulator_count is going to change in the later patches.

    Reported-by: Quentin Perret
    Signed-off-by: Viresh Kumar
    Signed-off-by: Sasha Levin

    Viresh Kumar
     

01 Dec, 2018

2 commits

  • commit 622fecbccfe86a8052dea6b512d3821dcce29994 upstream.

    _get_optimal_vdd_voltage call provides new_supply_vbb->u_volt
    as the reference voltage while it should be really new_supply_vdd->u_volt.

    Cc: 4.16+ # v4.16+
    Fixes: 9a835fa6e47 ("PM / OPP: Add ti-opp-supply driver")
    Signed-off-by: Keerthy
    Acked-by: Dave Gerlach
    Signed-off-by: Viresh Kumar
    Signed-off-by: Greg Kroah-Hartman

    Keerthy
     
  • commit ba038546ff9e15d54d1134b5c5d2355648c00dec upstream.

    The voltage range (min, max) provided in the device tree is from
    the data manual and is pretty big, catering to a wide range of devices.
    On a i2c read/write failure the regulator_set_voltage_triplet function
    falls back to set voltage between min and max. The min value from Device
    Tree can be lesser than the optimal value and in that case that can lead
    to a hang or crash. Hence set the u_volt_min dynamically to the optimal
    voltage value.

    Cc: 4.16+ # v4.16+
    Fixes: 9a835fa6e47 ("PM / OPP: Add ti-opp-supply driver")
    Signed-off-by: Keerthy
    Acked-by: Dave Gerlach
    Signed-off-by: Viresh Kumar
    Signed-off-by: Greg Kroah-Hartman

    Keerthy
     

14 Nov, 2018

1 commit

  • commit 2fbb8670b4ff4454f1c0de510f788d737edc4b90 upstream.

    The OPP table was freed, but not the individual OPPs which is done from
    _dev_pm_opp_remove_table(). Fix it by calling _dev_pm_opp_remove_table()
    as well.

    Cc: 4.18 # v4.18
    Fixes: 3ba98324e81a ("PM / OPP: Get performance state using genpd helper")
    Tested-by: Niklas Cassel
    Signed-off-by: Viresh Kumar
    Signed-off-by: Greg Kroah-Hartman

    Viresh Kumar
     

19 Jun, 2018

1 commit

  • This commit fixes a rare but possible case when the clk rate is updated
    without update of the regulator voltage.

    At boot up, CPUfreq checks if the system is running at the right freq. This
    is a sanity check in case a bootloader set clk rate that is outside of freq
    table present with cpufreq core. In such cases system can be unstable so
    better to change it to a freq that is preset in freq-table.

    The CPUfreq takes next freq that is >= policy->cur and this is our
    target_freq that needs to be set now.

    dev_pm_opp_set_rate(dev, target_freq) checks the target_freq and the
    old_freq (a current rate). If these are equal it returns early. If not,
    it searches for OPP (old_opp) that fits best to old_freq (not listed in
    the table) and updates old_freq (!).

    Here, we can end up with old_freq = old_opp.rate = target_freq, which
    is not handled in _generic_set_opp_regulator(). It's supposed to update
    voltage only when freq > old_freq || freq > old_freq.

    if (freq > old_freq) {
    ret = _set_opp_voltage(dev, reg, new_supply);
    [...]
    if (freq < old_freq) {
    ret = _set_opp_voltage(dev, reg, new_supply);
    if (ret)

    It results in, no voltage update while clk rate is updated.

    Example:
    freq-table = {
    1000MHz 1.15V
    666MHZ 1.10V
    333MHz 1.05V
    }
    boot-up-freq = 800MHz # not listed in freq-table
    freq = target_freq = 1GHz
    old_freq = 800Mhz
    old_opp = _find_freq_ceil(opp_table, &old_freq); #(old_freq is modified!)
    old_freq = 1GHz

    Fixes: 6a0712f6f199 ("PM / OPP: Add dev_pm_opp_set_rate()")
    Cc: 4.6+ # v4.6+
    Signed-off-by: Waldemar Rymarkiewicz
    Signed-off-by: Viresh Kumar

    Waldemar Rymarkiewicz
     

13 Jun, 2018

1 commit

  • The kzalloc() function has a 2-factor argument form, kcalloc(). This
    patch replaces cases of:

    kzalloc(a * b, gfp)

    with:
    kcalloc(a * b, gfp)

    as well as handling cases of:

    kzalloc(a * b * c, gfp)

    with:

    kzalloc(array3_size(a, b, c), gfp)

    as it's slightly less ugly than:

    kzalloc_array(array_size(a, b), c, gfp)

    This does, however, attempt to ignore constant size factors like:

    kzalloc(4 * 1024, gfp)

    though any constants defined via macros get caught up in the conversion.

    Any factors with a sizeof() of "unsigned char", "char", and "u8" were
    dropped, since they're redundant.

    The Coccinelle script used for this was:

    // Fix redundant parens around sizeof().
    @@
    type TYPE;
    expression THING, E;
    @@

    (
    kzalloc(
    - (sizeof(TYPE)) * E
    + sizeof(TYPE) * E
    , ...)
    |
    kzalloc(
    - (sizeof(THING)) * E
    + sizeof(THING) * E
    , ...)
    )

    // Drop single-byte sizes and redundant parens.
    @@
    expression COUNT;
    typedef u8;
    typedef __u8;
    @@

    (
    kzalloc(
    - sizeof(u8) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(__u8) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(char) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(unsigned char) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(u8) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(__u8) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(char) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(unsigned char) * COUNT
    + COUNT
    , ...)
    )

    // 2-factor product with sizeof(type/expression) and identifier or constant.
    @@
    type TYPE;
    expression THING;
    identifier COUNT_ID;
    constant COUNT_CONST;
    @@

    (
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (COUNT_ID)
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * COUNT_ID
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (COUNT_CONST)
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * COUNT_CONST
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (COUNT_ID)
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * COUNT_ID
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (COUNT_CONST)
    + COUNT_CONST, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * COUNT_CONST
    + COUNT_CONST, sizeof(THING)
    , ...)
    )

    // 2-factor product, only identifiers.
    @@
    identifier SIZE, COUNT;
    @@

    - kzalloc
    + kcalloc
    (
    - SIZE * COUNT
    + COUNT, SIZE
    , ...)

    // 3-factor product with 1 sizeof(type) or sizeof(expression), with
    // redundant parens removed.
    @@
    expression THING;
    identifier STRIDE, COUNT;
    type TYPE;
    @@

    (
    kzalloc(
    - sizeof(TYPE) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    )

    // 3-factor product with 2 sizeof(variable), with redundant parens removed.
    @@
    expression THING1, THING2;
    identifier COUNT;
    type TYPE1, TYPE2;
    @@

    (
    kzalloc(
    - sizeof(TYPE1) * sizeof(TYPE2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kzalloc(
    - sizeof(THING1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(THING1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    )

    // 3-factor product, only identifiers, with redundant parens removed.
    @@
    identifier STRIDE, SIZE, COUNT;
    @@

    (
    kzalloc(
    - (COUNT) * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    )

    // Any remaining multi-factor products, first at least 3-factor products,
    // when they're not all constants...
    @@
    expression E1, E2, E3;
    constant C1, C2, C3;
    @@

    (
    kzalloc(C1 * C2 * C3, ...)
    |
    kzalloc(
    - (E1) * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - (E1) * (E2) * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - (E1) * (E2) * (E3)
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - E1 * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    )

    // And then all remaining 2 factors products when they're not all constants,
    // keeping sizeof() as the second factor argument.
    @@
    expression THING, E1, E2;
    type TYPE;
    constant C1, C2, C3;
    @@

    (
    kzalloc(sizeof(THING) * C2, ...)
    |
    kzalloc(sizeof(TYPE) * C2, ...)
    |
    kzalloc(C1 * C2 * C3, ...)
    |
    kzalloc(C1 * C2, ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (E2)
    + E2, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * E2
    + E2, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (E2)
    + E2, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * E2
    + E2, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - (E1) * E2
    + E1, E2
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - (E1) * (E2)
    + E1, E2
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - E1 * E2
    + E1, E2
    , ...)
    )

    Signed-off-by: Kees Cook

    Kees Cook
     

30 May, 2018

1 commit

  • The OPP binding says:

    Property: operating-points-v2

    ...

    This can contain more than one phandle for power domain
    providers that provide multiple power domains. That is, one
    phandle for each power domain. If only one phandle is available,
    then the same OPP table will be used for all power domains
    provided by the power domain provider.

    But the OPP core isn't allowing the same OPP table to be used for
    multiple domains. Update dev_pm_opp_of_add_table_indexed() to allow
    that.

    Signed-off-by: Viresh Kumar
    Tested-by: Rajendra Nayak

    Viresh Kumar
     

22 May, 2018

4 commits

  • It should be fine to call dev_pm_opp_register_set_opp_helper() for all
    possible CPUs, even if some of them share the OPP table as the caller
    may not be aware of sharing policy.

    Lets increment the reference count of the OPP table and return its
    pointer. The caller need to call dev_pm_opp_register_put_opp_helper()
    the same number of times later on to drop all the references.

    To avoid adding another counter to count how many times
    dev_pm_opp_register_set_opp_helper() is called for the same OPP table,
    dev_pm_opp_register_put_opp_helper() frees the resources on the very
    first call made to it, assuming that the caller would be calling it
    sequentially for all the CPUs. We can revisit that if that assumption is
    broken in the future.

    Signed-off-by: Viresh Kumar

    Viresh Kumar
     
  • It should be fine to call dev_pm_opp_set_regulators() for all possible
    CPUs, even if some of them share the OPP table as the caller may not be
    aware of sharing policy.

    Lets increment the reference count of the OPP table and return its
    pointer. The caller need to call dev_pm_opp_put_regulators() the same
    number of times later on to drop all the references.

    To avoid adding another counter to count how many times
    dev_pm_opp_set_regulators() is called for the same OPP table,
    dev_pm_opp_put_regulators() frees the resources on the very first call
    made to it, assuming that the caller would be calling it sequentially
    for all the CPUs. We can revisit that if that assumption is broken in
    the future.

    Signed-off-by: Viresh Kumar

    Viresh Kumar
     
  • It should be fine to call dev_pm_opp_set_prop_name() for all possible
    CPUs, even if some of them share the OPP table as the caller may not be
    aware of sharing policy.

    Lets increment the reference count of the OPP table and return its
    pointer. The caller need to call dev_pm_opp_put_prop_name() the same
    number of times later on to drop all the references.

    To avoid adding another counter to count how many times
    dev_pm_opp_set_prop_name() is called for the same OPP table,
    dev_pm_opp_put_prop_name() frees the resources on the very first call
    made to it, assuming that the caller would be calling it sequentially
    for all the CPUs. We can revisit that if that assumption is broken in
    the future.

    Signed-off-by: Viresh Kumar

    Viresh Kumar
     
  • It should be fine to call dev_pm_opp_set_supported_hw() for all possible
    CPUs, even if some of them share the OPP table as the caller may not be
    aware of sharing policy.

    Lets increment the reference count of the OPP table and return its
    pointer. The caller need to call dev_pm_opp_put_supported_hw() the same
    number of times later on to drop all the references.

    To avoid adding another counter to count how many times
    dev_pm_opp_set_supported_hw() is called for the same OPP table,
    dev_pm_opp_put_supported_hw() frees the resources on the very first call
    made to it, assuming that the caller would be calling it sequentially
    for all the CPUs. We can revisit that if that assumption is broken in
    the future.

    Signed-off-by: Viresh Kumar

    Viresh Kumar
     

16 May, 2018

1 commit

  • Smatch complains that it's possible we print "rate" in the debug output
    when it hasn't been initialized. It should be zero on that path.

    Fixes: a1e8c13600bf ("PM / OPP: "opp-hz" is optional for power domains")
    [ Viresh: Added the Fixes tag ]
    Signed-off-by: Dan Carpenter
    Signed-off-by: Viresh Kumar

    Dan Carpenter
     

09 May, 2018

6 commits


12 Feb, 2018

1 commit

  • After checking all possible call chains to
    dev_pm_opp_init_cpufreq_table() here,
    my tool finds that this function is never called in atomic context,
    namely never in an interrupt handler or holding a spinlock.
    And dev_pm_opp_init_cpufreq_table() calls dev_pm_opp_get_opp_count(),
    which calls mutex_lock that can sleep.
    It indicates that atmtcp_v_send() can call functions which may sleep.
    Thus GFP_ATOMIC is not necessary, and it can be replaced with GFP_KERNEL.

    This is found by a static analysis tool named DCNS written by myself.

    Signed-off-by: Jia-Ju Bai
    Signed-off-by: Viresh Kumar

    Jia-Ju Bai
     

28 Dec, 2017

1 commit


18 Dec, 2017

1 commit

  • Introduce a ti-opp-supply driver that will use new multiple regulator
    support that is part of the OPP core This is needed on TI platforms like
    DRA7/AM57 in order to control both CPU regulator and Adaptive Body Bias
    (ABB) regulator. These regulators must be scaled in sequence during an
    OPP transition depending on whether or not the frequency is being scaled
    up or down.

    This driver also implements AVS Class0 for these parts by looking up the
    required values from registers in the SoC and programming adjusted
    optimal voltage values for each OPP.

    Signed-off-by: Dave Gerlach
    Acked-by: Viresh Kumar
    Signed-off-by: Rafael J. Wysocki

    Dave Gerlach
     

14 Oct, 2017

3 commits

  • This adds the dev_pm_opp_{un}register_get_pstate_helper() helper
    routines which will be used to set the get_pstate() callback for a
    device. This callback will be later called internally by the OPP core to
    get performance state corresponding to an OPP.

    This is required temporarily until the time we have proper DT bindings
    to include the performance state information.

    Signed-off-by: Viresh Kumar
    Signed-off-by: Rafael J. Wysocki

    Viresh Kumar
     
  • The genpd framework now provides an API to request device's power
    domain to update its performance state. Use that interface from the
    OPP core for devices whose power domains support performance states.

    Note that this commit doesn't add any mechanism by which performance
    states are made available to the OPP core. That would be done by a
    later commit.

    Note that the current implementation is restricted to the case where
    the device doesn't have separate regulators for itself. We shouldn't
    over engineer the code before we have real use case for them. We can
    always come back and add more code to support such cases later on.

    Tested-by: Rajendra Nayak
    Signed-off-by: Viresh Kumar
    Signed-off-by: Rafael J. Wysocki

    Viresh Kumar
     
  • Commit 762792913f8c (PM / OPP: Fix get sharing CPUs when hotplug
    is used) moved away from using cpu_dev->of_node because of some
    limitations.

    However, commit 7467c9d95989 (of: return of_get_cpu_node from
    of_cpu_device_node_get if CPUs are not registered) added support to
    fall back to of_get_cpu_node() if called if CPUs are not registered
    yet.

    Add the missing of_node_put() for the CPU device nodes. Also go back
    to using of_cpu_device_node_get() in dev_pm_opp_of_get_sharing_cpus()
    to avoid scanning the device tree again.

    Acked-by: Viresh Kumar
    Fixes: 762792913f8c (PM / OPP: Fix get sharing CPUs when hotplug is used)
    Signed-off-by: Sudeep Holla
    Reviewed-by: Stephen Boyd
    Signed-off-by: Rafael J. Wysocki

    Sudeep Holla
     

11 Oct, 2017

4 commits

  • The routine is named incorrectly since the first attempt as there is
    nothing like a put_opp() helper. We wanted to unregister the set_opp()
    helper here and so it should rather be named as
    dev_pm_opp_unregister_set_opp_helper().

    Signed-off-by: Viresh Kumar
    Reviewed-by: Stephen Boyd
    Signed-off-by: Rafael J. Wysocki

    Viresh Kumar
     
  • The for_each_available_child_of_node() loop in _of_add_opp_table_v2()
    doesn't drop the reference to "np" on errors. Fix that.

    Fixes: 274659029c9d (PM / OPP: Add support to parse "operating-points-v2" bindings)
    Cc: 4.3+ # 4.3+
    Signed-off-by: Tobias Jordan
    [ VK: Improved commit log. ]
    Signed-off-by: Viresh Kumar
    Reviewed-by: Stephen Boyd
    Signed-off-by: Rafael J. Wysocki

    Tobias Jordan
     
  • On some i.MX6 platforms which do not have speed grading
    check, opp table will not be created in platform code,
    so cpufreq driver prints the following error message:

    cpu cpu0: dev_pm_opp_get_opp_count: OPP table not found (-19)

    However, this is not really an error in this case because the
    imx6q-cpufreq driver first calls dev_pm_opp_get_opp_count()
    and if it fails, it means that platform code does not provide
    OPP and then dev_pm_opp_of_add_table() will be called.

    In order to avoid such confusing error message, move it to
    debug level.

    It is up to the caller of dev_pm_opp_get_opp_count() to check its
    return value and decide if it will print an error or not.

    Signed-off-by: Fabio Estevam
    Signed-off-by: Rafael J. Wysocki

    Fabio Estevam
     
  • Use snprintf() to avoid unnecessary initializations, avoid calling
    kfree().

    Signed-off-by: Arvind Yadav
    Acked-by: Viresh Kumar
    Reviewed-by: Stephen Boyd
    Signed-off-by: Rafael J. Wysocki

    Arvind Yadav
     

03 Oct, 2017

1 commit

  • The drivers/base/power/ directory is special and contains code related
    to power management core like system suspend/resume, hibernation, etc.
    It was fine to keep the OPP code inside it when we had just one file for
    it, but it is growing now and already has a directory for itself.

    Lets move it directly under drivers/ directory, just like cpufreq and
    cpuidle.

    Signed-off-by: Viresh Kumar
    Acked-by: Stephen Boyd
    Signed-off-by: Rafael J. Wysocki

    Viresh Kumar