1. 05 11月, 2018 4 次提交
  2. 04 10月, 2018 3 次提交
    • D
      PM / OPP: _of_add_opp_table_v2(): increment count only if OPP is added · deac8703
      Dave Gerlach 提交于
      Currently the _of_add_opp_table_v2 call loops through the OPP nodes in
      the operating-points-v2 table in the device tree and calls
      _opp_add_static_v2 for each to add them to the table. It counts each
      iteration through this loop as an added OPP, however there are cases
      where _opp_add_static_v2() returns 0 but no new OPP is added to the
      list.
      
      This can happen while adding duplicate OPP or if the OPP isn't supported
      by hardware.
      
      Because of this the count variable will contain the number of OPP nodes
      in the table in device tree but not necessarily the ones that are
      actually added.
      
      As this count value is what is checked to determine if there are any
      valid OPPs, if a platform has an operating-points-v2 table with all OPP
      nodes containing opp-supported-hw values that are not currently
      supported, then _of_add_opp_table_v2 will fail to abort as it should due
      to an empty table.
      
      Additionally, since commit 3ba98324 ("PM / OPP: Get
      performance state using genpd helper"), the same count variable is
      compared against the number of OPPs containing performance states and
      requires that either all or none have pstates set, however in the case
      of any opp table that has any entries that do not get added by
      _opp_add_static_v2 due to incompatible opp-supported-hw fields, these
      numbers will not match and _of_add_opp_table_v2 will incorrectly fail.
      
      We need to clearly identify all the three cases (success, failure,
      unsupported/duplicate OPPs) and then increment count only on success
      case. Change return type of _opp_add_static_v2() to return the pointer
      to the newly added OPP instead of an integer. This routine now returns a
      valid pointer if the OPP is really added, NULL for unsupported or
      duplicate OPPs, and error value cased as a pointer on errors.
      
      Ideally the fixes tag in this commit should point back to the commit
      that introduced OPP v2 initially, as that's where we started incorrectly
      accounting for duplicate OPPs:
      
      commit 27465902 ("PM / OPP: Add support to parse "operating-points-v2" bindings")
      
      But it wasn't a real problem until recently as the count was only used
      to check if any OPPs are added or not. And so this commit points to a
      rather recent commit where we added more code that depends on the value
      of "count".
      
      Fixes: 3ba98324 ("PM / OPP: Get performance state using genpd helper")
      Reported-by: NDave Gerlach <d-gerlach@ti.com>
      Reported-by: NNiklas Cassel <niklas.cassel@linaro.org>
      Tested-by: NNiklas Cassel <niklas.cassel@linaro.org>
      Signed-off-by: NDave Gerlach <d-gerlach@ti.com>
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      deac8703
    • V
      OPP: Return error on error from dev_pm_opp_get_opp_count() · 09f662f9
      Viresh Kumar 提交于
      Return error number instead of 0 on failures.
      
      Fixes: a1e8c136 ("PM / OPP: "opp-hz" is optional for power domains")
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      09f662f9
    • V
      OPP: Improve error handling in dev_pm_opp_of_cpumask_add_table() · 50b6b87c
      Viresh Kumar 提交于
      The error handling wasn't appropriate in
      dev_pm_opp_of_cpumask_add_table(). For example it returns 0 on success
      and also for the case where cpumask is empty or cpu_device wasn't found
      for any of the CPUs.
      
      It should really return error on such cases, so that the callers can be
      aware of the outcome.
      
      Fix it.
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      50b6b87c
  3. 01 10月, 2018 2 次提交
    • V
      OPP: Pass OPP table to _of_add_opp_table_v{1|2}() · 5ed4cecd
      Viresh Kumar 提交于
      Both _of_add_opp_table_v1() and _of_add_opp_table_v2() contain similar
      code to get the OPP table and their parent routine also parses the DT to
      find the OPP table's node pointer. This can be simplified by getting the
      OPP table in advance and then passing it as argument to these routines.
      Tested-by: NNiklas Cassel <niklas.cassel@linaro.org>
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      5ed4cecd
    • V
      OPP: Prevent creating multiple OPP tables for devices sharing OPP nodes · 283d55e6
      Viresh Kumar 提交于
      When two or more devices are sharing their clock and voltage rails, they
      share the same OPP table. But there are some corner cases where the OPP
      core incorrectly creates separate OPP tables for them.
      
      For example, CPU 0 and 1 share clock/voltage rails. The platform
      specific code calls dev_pm_opp_set_regulators() for CPU0 and the OPP
      core creates an OPP table for it (the individual OPPs aren't initialized
      as of now). The same is repeated for CPU1 then. Because
      _opp_get_opp_table() doesn't compare DT node pointers currently, it
      fails to find the link between CPU0 and CPU1 and so creates a new OPP
      table.
      
      Fix this by calling _managed_opp() from _opp_get_opp_table().
      _managed_opp() gain an additional argument (index) to get the right node
      pointer. This resulted in simplifying code in _of_add_opp_table_v2() as
      well.
      Tested-by: NNiklas Cassel <niklas.cassel@linaro.org>
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      283d55e6
  4. 20 9月, 2018 9 次提交
  5. 19 6月, 2018 1 次提交
    • W
      PM / OPP: Update voltage in case freq == old_freq · c5c2a97b
      Waldemar Rymarkiewicz 提交于
      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: 6a0712f6 ("PM / OPP: Add dev_pm_opp_set_rate()")
      Cc: 4.6+ <stable@vger.kernel.org> # v4.6+
      Signed-off-by: NWaldemar Rymarkiewicz <waldemar.rymarkiewicz@gmail.com>
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      c5c2a97b
  6. 13 6月, 2018 1 次提交
    • K
      treewide: kzalloc() -> kcalloc() · 6396bb22
      Kees Cook 提交于
      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: NKees Cook <keescook@chromium.org>
      6396bb22
  7. 30 5月, 2018 1 次提交
    • V
      OPP: Allow same OPP table to be used for multiple genpd · 8a352fd8
      Viresh Kumar 提交于
      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: NViresh Kumar <viresh.kumar@linaro.org>
      Tested-by: NRajendra Nayak <rnayak@codeaurora.org>
      8a352fd8
  8. 22 5月, 2018 4 次提交
    • V
      PM / OPP: Fix shared OPP table support in dev_pm_opp_register_set_opp_helper() · 5019acc6
      Viresh Kumar 提交于
      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: NViresh Kumar <viresh.kumar@linaro.org>
      5019acc6
    • V
      PM / OPP: Fix shared OPP table support in dev_pm_opp_set_regulators() · 779b783c
      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: NViresh Kumar <viresh.kumar@linaro.org>
      779b783c
    • V
      PM / OPP: Fix shared OPP table support in dev_pm_opp_set_prop_name() · 878ec1a9
      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: NViresh Kumar <viresh.kumar@linaro.org>
      878ec1a9
    • V
      PM / OPP: Fix shared OPP table support in dev_pm_opp_set_supported_hw() · 25419de1
      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: NViresh Kumar <viresh.kumar@linaro.org>
      25419de1
  9. 16 5月, 2018 1 次提交
  10. 09 5月, 2018 6 次提交
  11. 12 2月, 2018 1 次提交
  12. 28 12月, 2017 1 次提交
  13. 18 12月, 2017 1 次提交
    • D
      PM / OPP: Add ti-opp-supply driver · 9a835fa6
      Dave Gerlach 提交于
      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: NDave Gerlach <d-gerlach@ti.com>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      9a835fa6
  14. 14 10月, 2017 3 次提交
  15. 11 10月, 2017 2 次提交