1. 10 5月, 2019 1 次提交
    • V
      cpufreq: Call transition notifier only once for each policy · df24014a
      Viresh Kumar 提交于
      Currently, the notifiers are called once for each CPU of the policy->cpus
      cpumask. It would be more optimal if the notifier can be called only
      once and all the relevant information be provided to it. Out of the 23
      drivers that register for the transition notifiers today, only 4 of them
      do per-cpu updates and the callback for the rest can be called only once
      for the policy without any impact.
      
      This would also avoid multiple function calls to the notifier callbacks
      and reduce multiple iterations of notifier core's code (which does
      locking as well).
      
      This patch adds pointer to the cpufreq policy to the struct
      cpufreq_freqs, so the notifier callback has all the information
      available to it with a single call. The five drivers which perform
      per-cpu updates are updated to use the cpufreq policy. The freqs->cpu
      field is redundant now and is removed.
      
      Acked-by: David S. Miller <davem@davemloft.net> (sparc)
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      df24014a
  2. 08 4月, 2019 1 次提交
  3. 02 4月, 2019 1 次提交
  4. 13 2月, 2019 1 次提交
    • V
      cpufreq: Allow light-weight tear down and bring up of CPUs · 91a12e91
      Viresh Kumar 提交于
      The cpufreq core doesn't remove the cpufreq policy anymore on CPU
      offline operation, rather that happens when the CPU device gets
      unregistered from the kernel. This allows faster recovery when the CPU
      comes back online. This is also very useful during system wide
      suspend/resume where we offline all non-boot CPUs during suspend and
      then bring them back on resume.
      
      This commit takes the same idea a step ahead to allow drivers to do
      light weight tear-down and bring-up during CPU offline and online
      operations.
      
      A new set of callbacks is introduced, online/offline(). online() gets
      called when the first CPU of an inactive policy is brought up and
      offline() gets called when all the CPUs of a policy are offlined.
      
      The existing init/exit() callback get called on policy
      creation/destruction. They also get called instead of online/offline()
      callbacks if the online/offline() callbacks aren't provided.
      
      This also moves around some code to get executed only for the new-policy
      case going forward.
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      91a12e91
  5. 31 1月, 2019 1 次提交
  6. 29 1月, 2019 1 次提交
    • V
      cpufreq: Use struct kobj_attribute instead of struct global_attr · 625c85a6
      Viresh Kumar 提交于
      The cpufreq_global_kobject is created using kobject_create_and_add()
      helper, which assigns the kobj_type as dynamic_kobj_ktype and show/store
      routines are set to kobj_attr_show() and kobj_attr_store().
      
      These routines pass struct kobj_attribute as an argument to the
      show/store callbacks. But all the cpufreq files created using the
      cpufreq_global_kobject expect the argument to be of type struct
      attribute. Things work fine currently as no one accesses the "attr"
      argument. We may not see issues even if the argument is used, as struct
      kobj_attribute has struct attribute as its first element and so they
      will both get same address.
      
      But this is logically incorrect and we should rather use struct
      kobj_attribute instead of struct global_attr in the cpufreq core and
      drivers and the show/store callbacks should take struct kobj_attribute
      as argument instead.
      
      This bug is caught using CFI CLANG builds in android kernel which
      catches mismatch in function prototypes for such callbacks.
      Reported-by: NDonghee Han <dh.han@samsung.com>
      Reported-by: NSangkyu Kim <skwith.kim@samsung.com>
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      625c85a6
  7. 21 1月, 2019 1 次提交
  8. 11 12月, 2018 1 次提交
    • Q
      sched/topology: Make Energy Aware Scheduling depend on schedutil · 531b5c9f
      Quentin Perret 提交于
      Energy Aware Scheduling (EAS) is designed with the assumption that
      frequencies of CPUs follow their utilization value. When using a CPUFreq
      governor other than schedutil, the chances of this assumption being true
      are small, if any. When schedutil is being used, EAS' predictions are at
      least consistent with the frequency requests. Although those requests
      have no guarantees to be honored by the hardware, they should at least
      guide DVFS in the right direction and provide some hope in regards to the
      EAS model being accurate.
      
      To make sure EAS is only used in a sane configuration, create a strong
      dependency on schedutil being used. Since having sugov compiled-in does
      not provide that guarantee, make CPUFreq call a scheduler function on
      governor changes hence letting it rebuild the scheduling domains, check
      the governors of the online CPUs, and enable/disable EAS accordingly.
      Signed-off-by: NQuentin Perret <quentin.perret@arm.com>
      Signed-off-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Mike Galbraith <efault@gmx.de>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: adharmap@codeaurora.org
      Cc: chris.redpath@arm.com
      Cc: currojerez@riseup.net
      Cc: dietmar.eggemann@arm.com
      Cc: edubezval@gmail.com
      Cc: gregkh@linuxfoundation.org
      Cc: javi.merino@kernel.org
      Cc: joel@joelfernandes.org
      Cc: juri.lelli@redhat.com
      Cc: morten.rasmussen@arm.com
      Cc: patrick.bellasi@arm.com
      Cc: pkondeti@codeaurora.org
      Cc: skannan@codeaurora.org
      Cc: smuckle@google.com
      Cc: srinivas.pandruvada@linux.intel.com
      Cc: thara.gopinath@linaro.org
      Cc: tkjos@google.com
      Cc: valentin.schneider@arm.com
      Cc: vincent.guittot@linaro.org
      Cc: viresh.kumar@linaro.org
      Link: https://lkml.kernel.org/r/20181203095628.11858-9-quentin.perret@arm.comSigned-off-by: NIngo Molnar <mingo@kernel.org>
      531b5c9f
  9. 23 5月, 2018 1 次提交
  10. 10 4月, 2018 1 次提交
  11. 28 2月, 2018 1 次提交
    • V
      cpufreq: Validate frequency table in the core · d417e069
      Viresh Kumar 提交于
      By design, cpufreq drivers are responsible for calling
      cpufreq_frequency_table_cpuinfo() from their ->init()
      callbacks to validate the frequency table.
      
      However, if a cpufreq driver is buggy and fails to do so properly, it
      lead to unexpected behavior of the driver or the cpufreq core at a
      later point in time.  It would be better if the core could
      validate the frequency table during driver initialization.
      
      To that end, introduce cpufreq_table_validate_and_sort() and make
      the cpufreq core call it right after invoking the ->init() callback
      of the driver and destroy the cpufreq policy if the table is invalid.
      
      For the time being the validation of the table happens twice, once
      from the driver and then from the core.  The individual drivers will
      be updated separately to drop table validation if they don't need it
      for other reasons.
      
      The frequency table is marked "sorted" or "unsorted" by the new helper
      now instead of in cpufreq_table_validate_and_show(), as it should only
      be done after validating the table (which the drivers won't do going
      forward).
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      [ rjw: Subject/changelog ]
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      d417e069
  12. 08 2月, 2018 1 次提交
  13. 16 11月, 2017 1 次提交
    • R
      x86 / CPU: Always show current CPU frequency in /proc/cpuinfo · 7d5905dc
      Rafael J. Wysocki 提交于
      After commit 890da9cf (Revert "x86: do not use cpufreq_quick_get()
      for /proc/cpuinfo "cpu MHz"") the "cpu MHz" number in /proc/cpuinfo
      on x86 can be either the nominal CPU frequency (which is constant)
      or the frequency most recently requested by a scaling governor in
      cpufreq, depending on the cpufreq configuration.  That is somewhat
      inconsistent and is different from what it was before 4.13, so in
      order to restore the previous behavior, make it report the current
      CPU frequency like the scaling_cur_freq sysfs file in cpufreq.
      
      To that end, modify the /proc/cpuinfo implementation on x86 to use
      aperfmperf_snapshot_khz() to snapshot the APERF and MPERF feedback
      registers, if available, and use their values to compute the CPU
      frequency to be reported as "cpu MHz".
      
      However, do that carefully enough to avoid accumulating delays that
      lead to unacceptable access times for /proc/cpuinfo on systems with
      many CPUs.  Run aperfmperf_snapshot_khz() once on all CPUs
      asynchronously at the /proc/cpuinfo open time, add a single delay
      upfront (if necessary) at that point and simply compute the current
      frequency while running show_cpuinfo() for each individual CPU.
      
      Also, to avoid slowing down /proc/cpuinfo accesses too much, reduce
      the default delay between consecutive APERF and MPERF reads to 10 ms,
      which should be sufficient to get large enough numbers for the
      frequency computation in all cases.
      
      Fixes: 890da9cf (Revert "x86: do not use cpufreq_quick_get() for /proc/cpuinfo "cpu MHz"")
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NThomas Gleixner <tglx@linutronix.de>
      Tested-by: NThomas Gleixner <tglx@linutronix.de>
      Acked-by: NIngo Molnar <mingo@kernel.org>
      7d5905dc
  14. 03 10月, 2017 1 次提交
  15. 08 8月, 2017 1 次提交
  16. 01 8月, 2017 2 次提交
    • V
      cpufreq: Process remote callbacks from any CPU if the platform permits · 99d14d0e
      Viresh Kumar 提交于
      On many platforms, CPUs can do DVFS across cpufreq policies. i.e CPU
      from policy-A can change frequency of CPUs belonging to policy-B.
      
      This is quite common in case of ARM platforms where we don't
      configure any per-cpu register.
      
      Add a flag to identify such platforms and update
      cpufreq_can_do_remote_dvfs() to allow remote callbacks if this flag is
      set.
      
      Also enable the flag for cpufreq-dt driver which is used only on ARM
      platforms currently.
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      Acked-by: NSaravana Kannan <skannan@codeaurora.org>
      Acked-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      99d14d0e
    • V
      sched: cpufreq: Allow remote cpufreq callbacks · 674e7541
      Viresh Kumar 提交于
      With Android UI and benchmarks the latency of cpufreq response to
      certain scheduling events can become very critical. Currently, callbacks
      into cpufreq governors are only made from the scheduler if the target
      CPU of the event is the same as the current CPU. This means there are
      certain situations where a target CPU may not run the cpufreq governor
      for some time.
      
      One testcase to show this behavior is where a task starts running on
      CPU0, then a new task is also spawned on CPU0 by a task on CPU1. If the
      system is configured such that the new tasks should receive maximum
      demand initially, this should result in CPU0 increasing frequency
      immediately. But because of the above mentioned limitation though, this
      does not occur.
      
      This patch updates the scheduler core to call the cpufreq callbacks for
      remote CPUs as well.
      
      The schedutil, ondemand and conservative governors are updated to
      process cpufreq utilization update hooks called for remote CPUs where
      the remote CPU is managed by the cpufreq policy of the local CPU.
      
      The intel_pstate driver is updated to always reject remote callbacks.
      
      This is tested with couple of usecases (Android: hackbench, recentfling,
      galleryfling, vellamo, Ubuntu: hackbench) on ARM hikey board (64 bit
      octa-core, single policy). Only galleryfling showed minor improvements,
      while others didn't had much deviation.
      
      The reason being that this patch only targets a corner case, where
      following are required to be true to improve performance and that
      doesn't happen too often with these tests:
      
      - Task is migrated to another CPU.
      - The task has high demand, and should take the target CPU to higher
        OPPs.
      - And the target CPU doesn't call into the cpufreq governor until the
        next tick.
      
      Based on initial work from Steve Muckle.
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      Acked-by: NSaravana Kannan <skannan@codeaurora.org>
      Acked-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      674e7541
  17. 26 7月, 2017 2 次提交
  18. 22 7月, 2017 2 次提交
  19. 27 6月, 2017 1 次提交
    • L
      x86: use common aperfmperf_khz_on_cpu() to calculate KHz using APERF/MPERF · f8475cef
      Len Brown 提交于
      The goal of this change is to give users a uniform and meaningful
      result when they read /sys/...cpufreq/scaling_cur_freq
      on modern x86 hardware, as compared to what they get today.
      
      Modern x86 processors include the hardware needed
      to accurately calculate frequency over an interval --
      APERF, MPERF, and the TSC.
      
      Here we provide an x86 routine to make this calculation
      on supported hardware, and use it in preference to any
      driver driver-specific cpufreq_driver.get() routine.
      
      MHz is computed like so:
      
      MHz = base_MHz * delta_APERF / delta_MPERF
      
      MHz is the average frequency of the busy processor
      over a measurement interval.  The interval is
      defined to be the time between successive invocations
      of aperfmperf_khz_on_cpu(), which are expected to to
      happen on-demand when users read sysfs attribute
      cpufreq/scaling_cur_freq.
      
      As with previous methods of calculating MHz,
      idle time is excluded.
      
      base_MHz above is from TSC calibration global "cpu_khz".
      
      This x86 native method to calculate MHz returns a meaningful result
      no matter if P-states are controlled by hardware or firmware
      and/or if the Linux cpufreq sub-system is or is-not installed.
      
      When this routine is invoked more frequently, the measurement
      interval becomes shorter.  However, the code limits re-computation
      to 10ms intervals so that average frequency remains meaningful.
      
      Discerning users are encouraged to take advantage of
      the turbostat(8) utility, which can gracefully handle
      concurrent measurement intervals of arbitrary length.
      Signed-off-by: NLen Brown <len.brown@intel.com>
      Reviewed-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      f8475cef
  20. 28 5月, 2017 1 次提交
  21. 18 4月, 2017 1 次提交
  22. 04 2月, 2017 3 次提交
  23. 21 11月, 2016 1 次提交
  24. 11 11月, 2016 1 次提交
  25. 20 10月, 2016 1 次提交
    • S
      cpufreq: fix overflow in cpufreq_table_find_index_dl() · c6fe46a7
      Sergey Senozhatsky 提交于
      'best' is always less or equals to 'pos', so `best - pos' returns
      a negative value which is then getting casted to `unsigned int'
      and passed to __cpufreq_driver_target()->acpi_cpufreq_target()
      for policy->freq_table selection. This results in
      
       BUG: unable to handle kernel paging request at ffff881019b469f8
       IP: [<ffffffffa00356c1>] acpi_cpufreq_target+0x4f/0x190 [acpi_cpufreq]
       PGD 267f067
       PUD 0
      
       Oops: 0000 [#1] PREEMPT SMP
       CPU: 6 PID: 70 Comm: kworker/6:1 Not tainted 4.9.0-rc1-next-20161017-dbg-dirty
       Workqueue: events dbs_work_handler
       task: ffff88041b808000 task.stack: ffff88041b810000
       RIP: 0010:[<ffffffffa00356c1>]  [<ffffffffa00356c1>] acpi_cpufreq_target+0x4f/0x190 [acpi_cpufreq]
       RSP: 0018:ffff88041b813c60  EFLAGS: 00010282
       RAX: ffff880419b46a00 RBX: ffff88041b848400 RCX: ffff880419b20f80
       RDX: 00000000001dff38 RSI: 00000000ffffffff RDI: ffff88041b848400
       RBP: ffff88041b813cb0 R08: 0000000000000006 R09: 0000000000000040
       R10: ffffffff8207f9e0 R11: ffffffff8173595b R12: 0000000000000000
       R13: ffff88041f1dff38 R14: 0000000000262900 R15: 0000000bfffffff4
       FS:  0000000000000000(0000) GS:ffff88041f000000(0000) knlGS:0000000000000000
       CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
       CR2: ffff881019b469f8 CR3: 000000041a2d3000 CR4: 00000000001406e0
       Stack:
        ffff88041b813cb0 ffffffff813347f9 ffff88041b813ca0 ffffffff81334663
        ffff88041f1d4bc0 ffff88041b848400 0000000000000000 0000000000000000
        0000000000262900 0000000000000000 ffff88041b813d00 ffffffff813355dc
       Call Trace:
        [<ffffffff813347f9>] ? cpufreq_freq_transition_begin+0xf1/0xfc
        [<ffffffff81334663>] ? get_cpu_idle_time+0x97/0xa6
        [<ffffffff813355dc>] __cpufreq_driver_target+0x3b6/0x44e
        [<ffffffff81336ca3>] cs_dbs_timer+0x11a/0x135
        [<ffffffff81336fda>] dbs_work_handler+0x39/0x62
        [<ffffffff81057823>] process_one_work+0x280/0x4a5
        [<ffffffff81058719>] worker_thread+0x24f/0x397
        [<ffffffff810584ca>] ? rescuer_thread+0x30b/0x30b
        [<ffffffff81418380>] ? nl80211_get_key+0x29/0x36a
        [<ffffffff8105d2b7>] kthread+0xfc/0x104
        [<ffffffff8107ceea>] ? put_lock_stats.isra.9+0xe/0x20
        [<ffffffff8105d1bb>] ? kthread_create_on_node+0x3f/0x3f
        [<ffffffff814b2092>] ret_from_fork+0x22/0x30
       Code: 56 4d 6b ff 0c 41 55 41 54 53 48 83 ec 28 48 8b 15 ad 1e 00 00 44 8b 41
       08 48 8b 87 c8 00 00 00 49 89 d5 4e 03 2c c5 80 b2 78 81 <46> 8b 74 38 04 45
       3b 75 00 75 11 31 c0 83 39 00 0f 84 1c 01 00
       RIP  [<ffffffffa00356c1>] acpi_cpufreq_target+0x4f/0x190 [acpi_cpufreq]
        RSP <ffff88041b813c60>
       CR2: ffff881019b469f8
       ---[ end trace 16d9fc7a17897d37 ]---
      
      [ rjw: In some cases this bug may also cause incorrect frequencies to
        be selected by cpufreq governors. ]
      
      Fixes: 899bb664 (cpufreq: skip invalid entries when searching the frequency)
      Link: http://marc.info/?l=linux-kernel&m=147672030714331&w=2Reported-and-tested-by: NSedat Dilek <sedat.dilek@gmail.com>
      Reported-and-tested-by: NJörg Otte <jrg.otte@gmail.com>
      Signed-off-by: NSergey Senozhatsky <sergey.senozhatsky@gmail.com>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      Cc: 4.8+ <stable@vger.kernel.org> # 4.8+
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      c6fe46a7
  26. 13 10月, 2016 1 次提交
  27. 21 7月, 2016 1 次提交
    • S
      cpufreq: add cpufreq_driver_resolve_freq() · e3c06236
      Steve Muckle 提交于
      Cpufreq governors may need to know what a particular target frequency
      maps to in the driver without necessarily wanting to set the frequency.
      Support this operation via a new cpufreq API,
      cpufreq_driver_resolve_freq(). This API returns the lowest driver
      frequency equal or greater than the target frequency
      (CPUFREQ_RELATION_L), subject to any policy (min/max) or driver
      limitations. The mapping is also cached in the policy so that a
      subsequent fast_switch operation can avoid repeating the same lookup.
      
      The API will call a new cpufreq driver callback, resolve_freq(), if it
      has been registered by the driver. Otherwise the frequency is resolved
      via cpufreq_frequency_table_target(). Rather than require ->target()
      style drivers to provide a resolve_freq() callback it is left to the
      caller to ensure that the driver implements this callback if necessary
      to use cpufreq_driver_resolve_freq().
      Suggested-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Signed-off-by: NSteve Muckle <smuckle@linaro.org>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      e3c06236
  28. 07 7月, 2016 1 次提交
  29. 09 6月, 2016 3 次提交
  30. 03 6月, 2016 4 次提交
    • R
      cpufreq: stats: Make the stats code non-modular · 1aefc75b
      Rafael J. Wysocki 提交于
      The modularity of cpufreq_stats is quite problematic.
      
      First off, the usage of policy notifiers for the initialization
      and cleanup in the cpufreq_stats module is inherently racy with
      respect to CPU offline/online and the initialization and cleanup
      of the cpufreq driver.
      
      Second, fast frequency switching (used by the schedutil governor)
      cannot be enabled if any transition notifiers are registered, so
      if the cpufreq_stats module (that registers a transition notifier
      for updating transition statistics) is loaded, the schedutil governor
      cannot use fast frequency switching.
      
      On the other hand, allowing cpufreq_stats to be built as a module
      doesn't really add much value.  Arguably, there's not much reason
      for that code to be modular at all.
      
      For the above reasons, make the cpufreq stats code non-modular,
      modify the core to invoke functions provided by that code directly
      and drop the notifiers from it.
      
      Make the stats sysfs attributes appear empty if fast frequency
      switching is enabled as the statistics will not be updated in that
      case anyway (and returning -EBUSY from those attributes breaks
      powertop).
      
      While at it, clean up Kconfig help for the CPU_FREQ_STAT and
      CPU_FREQ_STAT_DETAILS options.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      1aefc75b
    • R
      cpufreq: Drop the 'initialized' field from struct cpufreq_governor · 9a15fb2c
      Rafael J. Wysocki 提交于
      The 'initialized' field in struct cpufreq_governor is only used by
      the conservative governor (as a usage counter) and the way that
      happens is far from straightforward and arguably incorrect.
      
      Namely, the value of 'initialized' is checked by
      cpufreq_dbs_governor_init() and cpufreq_dbs_governor_exit() and
      the results of those checks are passed (as the second argument) to
      the ->init() and ->exit() callbacks in struct dbs_governor.  Those
      callbacks are only implemented by the ondemand and conservative
      governors and ondemand doesn't use their second argument at all.
      In turn, the conservative governor uses it to decide whether or not
      to either register or unregister a transition notifier.
      
      That whole mechanism is not only unnecessarily convoluted, but also
      racy, because the 'initialized' field of struct cpufreq_governor is
      updated in cpufreq_init_governor() and cpufreq_exit_governor() under
      policy->rwsem which doesn't help if one of these functions is run
      twice in parallel for different policies (which isn't impossible in
      principle), for example.
      
      Instead of it, add a proper usage counter to the conservative
      governor and update it from cs_init() and cs_exit() which is
      guaranteed to be non-racy, as those functions are only called
      under gov_dbs_data_mutex which is global.
      
      With that in place, drop the 'initialized' field from struct
      cpufreq_governor as it is not used any more.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      9a15fb2c
    • V
      cpufreq: governor: Create cpufreq_policy_apply_limits() · bf2be2de
      Viresh Kumar 提交于
      Create a new helper to avoid code duplication across governors.
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      bf2be2de
    • R
      cpufreq: governor: Get rid of governor events · e788892b
      Rafael J. Wysocki 提交于
      The design of the cpufreq governor API is not very straightforward,
      as struct cpufreq_governor provides only one callback to be invoked
      from different code paths for different purposes.  The purpose it is
      invoked for is determined by its second "event" argument, causing it
      to act as a "callback multiplexer" of sorts.
      
      Unfortunately, that leads to extra complexity in governors, some of
      which implement the ->governor() callback as a switch statement
      that simply checks the event argument and invokes a separate function
      to handle that specific event.
      
      That extra complexity can be eliminated by replacing the all-purpose
      ->governor() callback with a family of callbacks to carry out specific
      governor operations: initialization and exit, start and stop and policy
      limits updates.  That also turns out to reduce the code size too, so
      do it.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      e788892b