summaryrefslogtreecommitdiff
path: root/drivers/opp/core.c
AgeCommit message (Collapse)Author
2020-12-28opp: Call the missing clk_put() on errorViresh Kumar
Fix the clock reference counting by calling the missing clk_put() in the error path. Cc: v5.10 <stable@vger.kernel.org> # v5.10 Fixes: dd461cd9183f ("opp: Allow dev_pm_opp_get_opp_table() to return -EPROBE_DEFER") Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-12-28opp: fix memory leak in _allocate_opp_tableQuanyang Wang
In function _allocate_opp_table, opp_dev is allocated and referenced by opp_table via _add_opp_dev. But in the case that the subsequent calls return -EPROBE_DEFER, it will jump to err label and opp_table will be freed. Then opp_dev becomes an unreferenced object to cause memory leak. So let's call _remove_opp_dev to do the cleanup. This fixes the following kmemleak report: unreferenced object 0xffff000801524a00 (size 128): comm "swapper/0", pid 1, jiffies 4294892465 (age 84.616s) hex dump (first 32 bytes): 40 00 56 01 08 00 ff ff 40 00 56 01 08 00 ff ff @.V.....@.V..... b8 52 77 7f 08 00 ff ff 00 3c 4c 00 08 00 ff ff .Rw......<L..... backtrace: [<00000000b1289fb1>] kmemleak_alloc+0x30/0x40 [<0000000056da48f0>] kmem_cache_alloc+0x3d4/0x588 [<00000000a84b3b0e>] _add_opp_dev+0x2c/0x88 [<0000000062a380cd>] _add_opp_table_indexed+0x124/0x268 [<000000008b4c8f1f>] dev_pm_opp_of_add_table+0x20/0x1d8 [<00000000e5316798>] dev_pm_opp_of_cpumask_add_table+0x48/0xf0 [<00000000db0a8ec2>] dt_cpufreq_probe+0x20c/0x448 [<0000000030a3a26c>] platform_probe+0x68/0xd8 [<00000000c618e78d>] really_probe+0xd0/0x3a0 [<00000000642e856f>] driver_probe_device+0x58/0xb8 [<00000000f10f5307>] device_driver_attach+0x74/0x80 [<0000000004f254b8>] __driver_attach+0x58/0xe0 [<0000000009d5d19e>] bus_for_each_dev+0x70/0xc8 [<0000000000d22e1c>] driver_attach+0x24/0x30 [<0000000001d4e952>] bus_add_driver+0x14c/0x1f0 [<0000000089928aaa>] driver_register+0x64/0x120 Cc: v5.10 <stable@vger.kernel.org> # v5.10 Fixes: dd461cd9183f ("opp: Allow dev_pm_opp_get_opp_table() to return -EPROBE_DEFER") Signed-off-by: Quanyang Wang <quanyang.wang@windriver.com> [ Viresh: Added the stable tag ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-12-09opp: Allow dev_pm_opp_put_*() APIs to accept NULL opp_tableViresh Kumar
This allows the callers to drop the unnecessary checks. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-12-09opp: Don't create an OPP table from dev_pm_opp_get_opp_table()Viresh Kumar
It has been found that some users (like cpufreq-dt and others on LKML) have abused the helper dev_pm_opp_get_opp_table() to create the OPP table instead of just finding it, which is the wrong thing to do. This routine was meant for OPP core's internal working and exposed the whole functionality by mistake. Change the scope of dev_pm_opp_get_opp_table() to only finding the table. The internal helpers _opp_get_opp_table*() are thus renamed to _add_opp_table*(), dev_pm_opp_get_opp_table_indexed() is removed (as we don't need the index field for finding the OPP table) and so the only user, genpd, is updated. Note that the prototype of _add_opp_table() was already left in opp.h by mistake when it was removed earlier and so we weren't required to add it now. Acked-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-12-09opp: Reduce the size of critical section in _opp_kref_release()Viresh Kumar
There is a lot of stuff here which can be done outside of the opp_table->lock, do that. This helps avoiding a circular dependency lockdeps around debugfs. Reported-by: Rob Clark <robdclark@gmail.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-11-06opp: Don't return opp_dev from _find_opp_dev()Viresh Kumar
The caller of _find_opp_dev() only needs to know if the opp_dev is there in the list or not. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-11-06opp: Allocate the OPP table outside of opp_table_lockViresh Kumar
There is no critical section which needs protection with locks while allocating an OPP table, except while adding it to the opp_tables list. And taking the opp_table_lock for the entire duration causes circular dependency issues like the one mentioned below. This patch takes another approach to reduce the size of the critical section to avoid such issues, the details of that are present within the patch. ====================================================== WARNING: possible circular locking dependency detected 5.4.72 #14 Not tainted ------------------------------------------------------ chrome/1865 is trying to acquire lock: ffffffdd34921750 (opp_table_lock){+.+.}, at: _find_opp_table+0x34/0x74 but task is already holding lock: ffffff81f0fc71a8 (reservation_ww_class_mutex){+.+.}, at: submit_lock_objects+0x70/0x1ec fscrypt: AES-256-CTS-CBC using implementation "cts-cbc-aes-ce" which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #4 (reservation_ww_class_mutex){+.+.}: __mutex_lock_common+0xec/0xc0c ww_mutex_lock_interruptible+0x5c/0xc4 msm_gem_fault+0x2c/0x124 __do_fault+0x40/0x16c handle_mm_fault+0x7cc/0xd98 do_page_fault+0x230/0x3b4 do_translation_fault+0x5c/0x78 do_mem_abort+0x4c/0xb4 el0_da+0x1c/0x20 -> #3 (&mm->mmap_sem){++++}: __might_fault+0x70/0x98 compat_filldir+0xf8/0x48c dcache_readdir+0x70/0x1dc iterate_dir+0xd4/0x180 __arm64_compat_sys_getdents+0xa0/0x19c el0_svc_common+0xa8/0x178 el0_svc_compat_handler+0x2c/0x40 el0_svc_compat+0x8/0x10 -> #2 (&sb->s_type->i_mutex_key#3){++++}: down_write+0x54/0x16c start_creating+0x68/0x128 debugfs_create_dir+0x28/0x114 opp_debug_register+0x8c/0xc0 _add_opp_dev_unlocked+0x5c/0x70 _add_opp_dev+0x38/0x58 _opp_get_opp_table+0xdc/0x1ac dev_pm_opp_get_opp_table_indexed+0x24/0x30 dev_pm_opp_of_add_table_indexed+0x48/0x84 of_genpd_add_provider_onecell+0xc0/0x1b8 rpmhpd_probe+0x240/0x268 platform_drv_probe+0x90/0xb0 really_probe+0x134/0x2ec driver_probe_device+0x64/0xfc __device_attach_driver+0x8c/0xa4 bus_for_each_drv+0x90/0xd8 __device_attach+0xc0/0x148 device_initial_probe+0x20/0x2c bus_probe_device+0x34/0x94 device_add+0x1fc/0x3b0 of_device_add+0x3c/0x4c of_platform_device_create_pdata+0xb8/0xfc of_platform_bus_create+0x1e4/0x368 of_platform_populate+0x70/0xbc devm_of_platform_populate+0x58/0xa0 rpmh_rsc_probe+0x36c/0x3cc platform_drv_probe+0x90/0xb0 really_probe+0x134/0x2ec driver_probe_device+0x64/0xfc __device_attach_driver+0x8c/0xa4 bus_for_each_drv+0x90/0xd8 __device_attach+0xc0/0x148 device_initial_probe+0x20/0x2c bus_probe_device+0x34/0x94 device_add+0x1fc/0x3b0 of_device_add+0x3c/0x4c of_platform_device_create_pdata+0xb8/0xfc of_platform_bus_create+0x1e4/0x368 of_platform_bus_create+0x230/0x368 of_platform_populate+0x70/0xbc of_platform_default_populate_init+0xa8/0xc0 do_one_initcall+0x1c8/0x3fc do_initcall_level+0xb4/0x10c do_basic_setup+0x30/0x48 kernel_init_freeable+0x124/0x1a4 kernel_init+0x14/0x104 ret_from_fork+0x10/0x18 -> #1 (&opp_table->lock){+.+.}: __mutex_lock_common+0xec/0xc0c mutex_lock_nested+0x40/0x50 _add_opp_dev+0x2c/0x58 _opp_get_opp_table+0xdc/0x1ac dev_pm_opp_get_opp_table_indexed+0x24/0x30 dev_pm_opp_of_add_table_indexed+0x48/0x84 of_genpd_add_provider_onecell+0xc0/0x1b8 rpmhpd_probe+0x240/0x268 platform_drv_probe+0x90/0xb0 really_probe+0x134/0x2ec driver_probe_device+0x64/0xfc __device_attach_driver+0x8c/0xa4 bus_for_each_drv+0x90/0xd8 __device_attach+0xc0/0x148 device_initial_probe+0x20/0x2c bus_probe_device+0x34/0x94 device_add+0x1fc/0x3b0 of_device_add+0x3c/0x4c of_platform_device_create_pdata+0xb8/0xfc of_platform_bus_create+0x1e4/0x368 of_platform_populate+0x70/0xbc devm_of_platform_populate+0x58/0xa0 rpmh_rsc_probe+0x36c/0x3cc platform_drv_probe+0x90/0xb0 really_probe+0x134/0x2ec driver_probe_device+0x64/0xfc __device_attach_driver+0x8c/0xa4 bus_for_each_drv+0x90/0xd8 __device_attach+0xc0/0x148 device_initial_probe+0x20/0x2c bus_probe_device+0x34/0x94 device_add+0x1fc/0x3b0 of_device_add+0x3c/0x4c of_platform_device_create_pdata+0xb8/0xfc of_platform_bus_create+0x1e4/0x368 of_platform_populate+0x70/0xbc devm_of_platform_populate+0x58/0xa0 rpmh_rsc_probe+0x36c/0x3cc platform_drv_probe+0x90/0xb0 really_probe+0x134/0x2ec driver_probe_device+0x64/0xfc __device_attach_driver+0x8c/0xa4 bus_for_each_drv+0x90/0xd8 __device_attach+0xc0/0x148 device_initial_probe+0x20/0x2c bus_probe_device+0x34/0x94 device_add+0x1fc/0x3b0 of_device_add+0x3c/0x4c of_platform_device_create_pdata+0xb8/0xfc of_platform_bus_create+0x1e4/0x368 of_platform_bus_create+0x230/0x368 of_platform_populate+0x70/0xbc of_platform_default_populate_init+0xa8/0xc0 do_one_initcall+0x1c8/0x3fc do_initcall_level+0xb4/0x10c do_basic_setup+0x30/0x48 kernel_init_freeable+0x124/0x1a4 kernel_init+0x14/0x104 ret_from_fork+0x10/0x18 -> #0 (opp_table_lock){+.+.}: __lock_acquire+0xee4/0x2450 lock_acquire+0x1cc/0x210 __mutex_lock_common+0xec/0xc0c mutex_lock_nested+0x40/0x50 _find_opp_table+0x34/0x74 dev_pm_opp_find_freq_exact+0x2c/0xdc a6xx_gmu_resume+0xc8/0xecc a6xx_pm_resume+0x148/0x200 adreno_resume+0x28/0x34 pm_generic_runtime_resume+0x34/0x48 __rpm_callback+0x70/0x10c rpm_callback+0x34/0x8c rpm_resume+0x414/0x550 __pm_runtime_resume+0x7c/0xa0 msm_gpu_submit+0x60/0x1c0 msm_ioctl_gem_submit+0xadc/0xb60 drm_ioctl_kernel+0x9c/0x118 drm_ioctl+0x27c/0x408 drm_compat_ioctl+0xcc/0xdc __se_compat_sys_ioctl+0x100/0x206c __arm64_compat_sys_ioctl+0x20/0x2c el0_svc_common+0xa8/0x178 el0_svc_compat_handler+0x2c/0x40 el0_svc_compat+0x8/0x10 other info that might help us debug this: Chain exists of: opp_table_lock --> &mm->mmap_sem --> reservation_ww_class_mutex Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(reservation_ww_class_mutex); lock(&mm->mmap_sem); lock(reservation_ww_class_mutex); lock(opp_table_lock); *** DEADLOCK *** 3 locks held by chrome/1865: #0: ffffff81edecc0d8 (&dev->struct_mutex){+.+.}, at: msm_ioctl_gem_submit+0x264/0xb60 #1: ffffff81d0000870 (reservation_ww_class_acquire){+.+.}, at: msm_ioctl_gem_submit+0x8e8/0xb60 #2: ffffff81f0fc71a8 (reservation_ww_class_mutex){+.+.}, at: submit_lock_objects+0x70/0x1ec stack backtrace: CPU: 0 PID: 1865 Comm: chrome Not tainted 5.4.72 #14 Hardware name: Google Lazor (rev1+) with LTE (DT) Call trace: dump_backtrace+0x0/0x158 show_stack+0x20/0x2c dump_stack+0xc8/0x160 print_circular_bug+0x2c4/0x2c8 check_noncircular+0x1a8/0x1b0 __lock_acquire+0xee4/0x2450 lock_acquire+0x1cc/0x210 __mutex_lock_common+0xec/0xc0c mutex_lock_nested+0x40/0x50 _find_opp_table+0x34/0x74 dev_pm_opp_find_freq_exact+0x2c/0xdc a6xx_gmu_resume+0xc8/0xecc a6xx_pm_resume+0x148/0x200 adreno_resume+0x28/0x34 pm_generic_runtime_resume+0x34/0x48 __rpm_callback+0x70/0x10c rpm_callback+0x34/0x8c rpm_resume+0x414/0x550 __pm_runtime_resume+0x7c/0xa0 msm_gpu_submit+0x60/0x1c0 msm_ioctl_gem_submit+0xadc/0xb60 drm_ioctl_kernel+0x9c/0x118 drm_ioctl+0x27c/0x408 drm_compat_ioctl+0xcc/0xdc __se_compat_sys_ioctl+0x100/0x206c __arm64_compat_sys_ioctl+0x20/0x2c el0_svc_common+0xa8/0x178 el0_svc_compat_handler+0x2c/0x40 el0_svc_compat+0x8/0x10 Reported-by: Rob Clark <robdclark@gmail.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-11-02opp: Always add entries in dev_list with opp_table->lock heldViresh Kumar
The readers of dev_list expect the updates to it to take place from within the opp_table->lock and this is missing in the case where the dev_list is updated for already managed OPPs. Fix that by calling _add_opp_dev() from there and remove the now unused _add_opp_dev_unlocked() callback. While at it, also reduce the length of the critical section in _add_opp_dev(). Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-10-27opp: Reduce the size of critical section in _opp_table_kref_release()Viresh Kumar
There is a lot of stuff here which can be done outside of the big opp_table_lock, do that. This helps avoiding few circular dependency lockdeps around debugfs and interconnects. Reported-by: Rob Clark <robdclark@gmail.com> Reported-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-10-27opp: Fix early exit from dev_pm_opp_register_set_opp_helper()Viresh Kumar
We returned earlier by mistake even when there were no failures. Fix it. Fixes: dd461cd9183f ("opp: Allow dev_pm_opp_get_opp_table() to return -EPROBE_DEFER") Reported-by: Naresh Kamboju <naresh.kamboju@linaro.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Tested-by: Naresh Kamboju <naresh.kamboju@linaro.com>
2020-10-05Merge branch 'opp/linux-next' of ↵Rafael J. Wysocki
git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm Pull opertaing performance points (OPP) framework fixes for 5.10-rc1 from Viresh Kumar: "- Return -EPROBE_DEFER properly from dev_pm_opp_get_opp_table() (Stephan Gerhold). - Minor cleanups around required-opps (Stephan Gerhold). - Extends opp-supported-hw property to contain multiple versions (Viresh Kumar). - Multiple cleanups around dev_pm_opp_attach_genpd() (Viresh Kumar). - Multiple fixes, cleanups in the OPP core for overall better design (Viresh Kumar)." * 'opp/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: opp: Allow opp-level to be set to 0 opp: Prevent memory leak in dev_pm_opp_attach_genpd() ARM: tegra: Pass multiple versions in opp-supported-hw property opp: Allow opp-supported-hw to contain multiple versions dt-bindings: opp: Allow opp-supported-hw to contain multiple versions opp: Set required OPPs in reverse order when scaling down opp: Reduce code duplication in _set_required_opps() opp: Drop unnecessary check from dev_pm_opp_attach_genpd() opp: Handle multiple calls for same OPP table in _of_add_opp_table_v1() opp: Allow dev_pm_opp_get_opp_table() to return -EPROBE_DEFER opp: Remove _dev_pm_opp_find_and_remove_table() wrapper opp: Split out _opp_set_rate_zero() opp: Reuse the enabled flag in !target_freq path opp: Rename regulator_enabled and use it as status of all resources
2020-09-16opp: Allow opp-level to be set to 0Viresh Kumar
The DT bindings don't put such a constraint, nor should the kernel. It is perfectly fine for opp-level to be set to 0, if we need to put the performance state votes for a domain for a particular OPP. Reported-by: Stephan Gerhold <stephan@gerhold.net> Tested-by: Stephan Gerhold <stephan@gerhold.net> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-09-16opp: Prevent memory leak in dev_pm_opp_attach_genpd()Viresh Kumar
If dev_pm_opp_attach_genpd() is called multiple times (once for each CPU sharing the table), then it would result in unwanted behavior like memory leak, attaching the domain multiple times, etc. Handle that by checking and returning earlier if the domains are already attached. Now that dev_pm_opp_detach_genpd() can get called multiple times as well, we need to protect that too. Note that the virtual device pointers aren't returned in this case, as they may become unavailable to some callers during the middle of the operation. Reported-by: Stephan Gerhold <stephan@gerhold.net> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-09-16opp: Set required OPPs in reverse order when scaling downStephan Gerhold
The OPP core already has well-defined semantics to ensure required OPPs/regulators are set before/after the frequency change, depending on if we scale up or down. Similar requirements might exist for the order of required OPPs when multiple power domains need to be scaled for a frequency change. For example, on Qualcomm platforms using CPR (Core Power Reduction), we need to scale the VDDMX and CPR power domain. When scaling up, MX should be scaled up before CPR. When scaling down, CPR should be scaled down before MX. In general, if there are multiple "required-opps" in the device tree I would expect that the order is either irrelevant, or there is some dependency between the power domains. In that case, the power domains should be scaled down in reverse order. This commit updates _set_required_opps() to set required OPPs in reverse order when scaling down. Signed-off-by: Stephan Gerhold <stephan@gerhold.net> [ Viresh: Fix rebase conflict and minor rearrangement of the code ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-09-16opp: Reduce code duplication in _set_required_opps()Stephan Gerhold
Move call to dev_pm_genpd_set_performance_state() to a separate function so we can avoid duplicating the code for the single and multiple genpd case. Signed-off-by: Stephan Gerhold <stephan@gerhold.net> [ Viresh: Validate virtual device before use ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-09-16opp: Drop unnecessary check from dev_pm_opp_attach_genpd()Viresh Kumar
Since commit c0ab9e0812da ("opp: Allocate genpd_virt_devs from dev_pm_opp_attach_genpd()"), the allocation of the virtual devices is moved to dev_pm_opp_attach_genpd() and this check isn't required anymore as it will always fail. Drop it. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-09-16Merge branch 'opp/defer-probe' into HEADViresh Kumar
2020-09-01Merge branch 'opp/fixes' of ↵Rafael J. Wysocki
git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm Pull operating performance points (OPP) framework fixes for 5.9-rc4 from Viresh Kumar: "This fixes reference counting for OPP tables. Few patches are getting queued (for various subsystems) for 5.10 which depend on this to be fixed first." * 'opp/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: opp: Don't drop reference for an OPP table that was never parsed
2020-08-31opp: Don't drop reference for an OPP table that was never parsedViresh Kumar
dev_pm_opp_remove_table() should drop a reference to the OPP table only if the DT OPP table was parsed earlier with a call to dev_pm_opp_of_add_table() earlier. Else it may end up dropping the reference to the OPP table, which was added as a result of other calls like dev_pm_opp_set_clkname(). And would hence result in undesirable behavior later on when caller would try to free the resource again. Fixes: 03758d60265c ("opp: Replace list_kref with a local counter") Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org> Reported-by: Anders Roxell <anders.roxell@linaro.org> Tested-by: Naresh Kamboju <naresh.kamboju@linaro.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-08-25opp: Allow dev_pm_opp_get_opp_table() to return -EPROBE_DEFERStephan Gerhold
The OPP core manages various resources, e.g. clocks or interconnect paths. These resources are looked up when the OPP table is allocated once dev_pm_opp_get_opp_table() is called the first time (either directly or indirectly through one of the many helper functions). At this point, the resources may not be available yet, i.e. looking them up will result in -EPROBE_DEFER. Unfortunately, dev_pm_opp_get_opp_table() is currently unable to propagate this error code since it only returns the allocated OPP table or NULL. This means that all consumers of the OPP core are required to make sure that all necessary resources are available. Usually this happens by requesting them, checking the result and releasing them immediately after. For example, we have added "dev_pm_opp_of_find_icc_paths(dev, NULL)" to several drivers now just to make sure the interconnect providers are ready before the OPP table is allocated. If this call is missing, the OPP core will only warn about this and then attempt to continue without interconnect. This will eventually fail horribly, e.g.: cpu cpu0: _allocate_opp_table: Error finding interconnect paths: -517 ... later ... of: _read_bw: Mismatch between opp-peak-kBps and paths (1 0) cpu cpu0: _opp_add_static_v2: opp key field not found cpu cpu0: _of_add_opp_table_v2: Failed to add OPP, -22 This example happens when trying to use interconnects for a CPU OPP table together with qcom-cpufreq-nvmem.c. qcom-cpufreq-nvmem calls dev_pm_opp_set_supported_hw(), which ends up allocating the OPP table early. To fix the problem with the current approach we would need to add yet another call to dev_pm_opp_of_find_icc_paths(dev, NULL). But actually qcom-cpufreq-nvmem.c has nothing to do with interconnects... This commit attempts to make this more robust by allowing dev_pm_opp_get_opp_table() to return an error pointer. Fixing all the usages is trivial because the function is usually used indirectly through another helper (e.g. dev_pm_opp_set_supported_hw() above). These other helpers already return an error pointer. The example above then works correctly because set_supported_hw() will return -EPROBE_DEFER, and qcom-cpufreq-nvmem.c already propagates that error. It should also be possible to remove the remaining usages of "dev_pm_opp_of_find_icc_paths(dev, NULL)" from other drivers as well. Note that this commit currently only handles -EPROBE_DEFER for the clock/interconnects within _allocate_opp_table(). Other errors are just ignored as before. Eventually those should be propagated as well. Signed-off-by: Stephan Gerhold <stephan@gerhold.net> Acked-by: Krzysztof Kozlowski <krzk@kernel.org> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> [ Viresh: skip checking return value of dev_pm_opp_get_opp_table() for EPROBE_DEFER in domain.c, fix NULL return value and reorder code a bit in core.c, and update exynos-asv.c ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-08-24opp: Remove _dev_pm_opp_find_and_remove_table() wrapperViresh Kumar
Remove the unnecessary wrapper and merge _dev_pm_opp_find_and_remove_table() with dev_pm_opp_remove_table(). Tested-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-08-24opp: Split out _opp_set_rate_zero()Viresh Kumar
Create separate routine _opp_set_rate_zero() to handle !target_freq case. Tested-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-08-24opp: Reuse the enabled flag in !target_freq pathViresh Kumar
The OPP core needs to track if the resources of devices are enabled/configured or not, as it disables the resources when target_freq is set to 0. Handle that with the new enabled flag and remove otherwise complex conditional statements. Tested-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-08-24opp: Rename regulator_enabled and use it as status of all resourcesViresh Kumar
Expand the scope of the regulator_enabled flag and use it to track status of all the resources. This will be used for other stuff in the next patch. Tested-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-08-20opp: Enable resources again if they were disabled earlierRajendra Nayak
dev_pm_opp_set_rate() can now be called with freq = 0 in order to either drop performance or bandwidth votes or to disable regulators on platforms which support them. In such cases, a subsequent call to dev_pm_opp_set_rate() with the same frequency ends up returning early because 'old_freq == freq' Instead make it fall through and put back the dropped performance and bandwidth votes and/or enable back the regulators. Cc: v5.3+ <stable@vger.kernel.org> # v5.3+ Fixes: cd7ea582866f ("opp: Make dev_pm_opp_set_rate() handle freq = 0 to drop performance votes") Reported-by: Sajida Bhanu <sbhanu@codeaurora.org> Reviewed-by: Sibi Sankar <sibis@codeaurora.org> Reported-by: Matthias Kaehlcke <mka@chromium.org> Tested-by: Matthias Kaehlcke <mka@chromium.org> Reviewed-by: Stephen Boyd <sboyd@kernel.org> Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org> [ Viresh: Don't skip clk_set_rate() and massaged changelog ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-08-17opp: Put opp table in dev_pm_opp_set_rate() if _set_opp_bw() failsStephen Boyd
We get the opp_table pointer at the top of the function and so we should put the pointer at the end of the function like all other exit paths from this function do. Cc: v5.8+ <stable@vger.kernel.org> # v5.8+ Fixes: b00e667a6d8b ("opp: Remove bandwidth votes when target_freq is zero") Reviewed-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Stephen Boyd <swboyd@chromium.org> [ Viresh: Split the patch into two ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-08-17opp: Put opp table in dev_pm_opp_set_rate() for empty tablesStephen Boyd
We get the opp_table pointer at the top of the function and so we should put the pointer at the end of the function like all other exit paths from this function do. Cc: v5.7+ <stable@vger.kernel.org> # v5.7+ Fixes: aca48b61f963 ("opp: Manage empty OPP tables with clk handle") Reviewed-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Stephen Boyd <swboyd@chromium.org> [ Viresh: Split the patch into two ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-08-04Merge branch 'cpufreq/arm/linux-next' of ↵Rafael J. Wysocki
git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm Pull ARM cpufreq driver changes for v5.9-rc1 from Viresh Kumar: "Here are the details: - Adaptive voltage scaling (AVS) support and minor cleanups for brcmstb driver (Florian Fainelli and Markus Mayer). - A new tegra driver and cleanup for the existing one (Sumit Gupta and Jon Hunter). - Bandwidth level support for Qcom driver along with OPP changes (Sibi Sankar). - Cleanups to sti, cpufreq-dt, ap806, CPPC drivers (Viresh Kumar, Lee Jones, Ivan Kokshaysky, Sven Auhagen, and Xin Hao). - Make schedutil default governor for ARM (Valentin Schneider). - Fix dependency issues for imx (Walter Lozano). - Cleanup around cached_resolved_idx in cpufreq core (Viresh Kumar)." * 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: cpufreq: make schedutil the default for arm and arm64 cpufreq: cached_resolved_idx can not be negative cpufreq: Add Tegra194 cpufreq driver dt-bindings: arm: Add NVIDIA Tegra194 CPU Complex binding cpufreq: imx: Select NVMEM_IMX_OCOTP cpufreq: sti-cpufreq: Fix some formatting and misspelling issues cpufreq: tegra186: Simplify probe return path cpufreq: CPPC: Reuse caps variable in few routines cpufreq: ap806: fix cpufreq driver needs ap cpu clk cpufreq: cppc: Reorder code and remove apply_hisi_workaround variable cpufreq: dt: fix oops on armada37xx cpufreq: brcmstb-avs-cpufreq: send S2_ENTER / S2_EXIT commands to AVS cpufreq: brcmstb-avs-cpufreq: Support polling AVS firmware cpufreq: brcmstb-avs-cpufreq: more flexible interface for __issue_avs_command() cpufreq: qcom: Disable fast switch when scaling DDR/L3 cpufreq: qcom: Update the bandwidth levels on frequency change OPP: Add and export helper to set bandwidth cpufreq: blacklist SC7180 in cpufreq-dt-platdev cpufreq: blacklist SDM845 in cpufreq-dt-platdev
2020-07-30OPP: Add and export helper to set bandwidthSibi Sankar
Add and export 'dev_pm_opp_set_bw' to set the bandwidth levels associated with an OPP. Signed-off-by: Sibi Sankar <sibis@codeaurora.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-07-24opp: Allow disabled OPPs in dev_pm_opp_get_freq()Andrew-sh.Cheng
Allow dev_pm_opp_get_freq() to work for disabled OPPs. Signed-off-by: Andrew-sh.Cheng <andrew-sh.cheng@mediatek.com> [ Viresh: Massaged commit log ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-07-24opp: core: Add missing export for dev_pm_opp_adjust_voltageValdis Klētnieks
Export dev_pm_opp_adjust_voltage() as it may be used by modules later on. Signed-off-by: Valdis Kletnieks <valdis.kletnieks@vt.edu> [ Viresh: Rewrote commit log ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-05-29opp: Remove bandwidth votes when target_freq is zeroViresh Kumar
We already drop several votes when target_freq is set to zero, drop bandwidth votes as well. Reported-by: Sibi Sankar <sibis@codeaurora.org> Reviewed-by: Georgi Djakov <georgi.djakov@linaro.org> Tested-by: Georgi Djakov <georgi.djakov@linaro.org> Reviewed-by: Sibi Sankar <sibis@codeaurora.org> Tested-by: Sibi Sankar <sibis@codeaurora.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-05-29opp: core: add regulators enable and disableKamil Konieczny
Add enable regulators to dev_pm_opp_set_regulators() and disable regulators to dev_pm_opp_put_regulators(). Even if bootloader leaves regulators enabled, they should be enabled in kernel in order to increase the reference count. Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Acked-by: Clément Péron <peron.clem@gmail.com> Tested-by: Clément Péron <peron.clem@gmail.com> Signed-off-by: Kamil Konieczny <k.konieczny@samsung.com> [ Viresh: Enable the regulator only after it is programmed and add a flag to track its status. ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-05-29opp: Reorder the code for !target_freq caseViresh Kumar
Reorder the code a bit to make it more readable. Add additional comment as well. Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Acked-by: Clément Péron <peron.clem@gmail.com> Tested-by: Clément Péron <peron.clem@gmail.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-05-29opp: Update the bandwidth on OPP frequency changesGeorgi Djakov
If the OPP bandwidth values are populated, we want to switch also the interconnect bandwidth in addition to frequency and voltage. Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org> Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Reviewed-by: Sibi Sankar <sibis@codeaurora.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-05-29opp: Add support for parsing interconnect bandwidthGeorgi Djakov
The OPP bindings now support bandwidth values, so add support to parse it from device tree and store it into the new dev_pm_opp_icc_bw struct, which is part of the dev_pm_opp. Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org> Reviewed-by: Matthias Kaehlcke <mka@chromium.org> [ Viresh: Create _read_bw() and use it, renamed _of_find_icc_paths() to dev_pm_opp_of_find_icc_paths(), exported it and made opp_table argument optional. Also drop the depends on from Kconfig. ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-05-13OPP: Add helpers for reading the binding propertiesSaravana Kannan
The opp-hz DT property is not mandatory and we may use another property as a key in the OPP table. Add helper functions to simplify the reading and comparing the keys. Signed-off-by: Saravana Kannan <saravanak@google.com> Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org> Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Reviewed-by: Sibi Sankar <sibis@codeaurora.org> [ Viresh: Removed an unnecessary comment ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2020-04-13opp: Manage empty OPP tables with clk handleRajendra Nayak
With OPP core now supporting DVFS for IO devices, we have instances of IO devices (same IP block) which require an OPP on some platforms/SoCs while just needing to scale the clock on some others. In order to avoid conditional code in every driver which supports such devices (to check for availability of OPPs and then deciding to do either dev_pm_opp_set_rate() or clk_set_rate()) add support to manage empty OPP tables with a clk handle. This makes dev_pm_opp_set_rate() equivalent of a clk_set_rate() for devices with just a clk and no OPPs specified, and makes dev_pm_opp_set_rate(0) bail out without throwing an error. Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2019-12-10opp: Replace list_kref with a local counterViresh Kumar
A kref or refcount isn't the right tool to be used here for counting number of devices that are sharing the static OPPs created for the OPP table. For example, we are reinitializing the kref again, after it reaches a value of 0 and frees the resources, if the static OPPs get added for the same OPP table structure (as the OPP table structure was never freed). That is messy and very unclear. This patch makes parsed_static_opps an unsigned integer and uses it to count the number of users of the static OPPs. The increment and decrement to parsed_static_opps is done under opp_table->lock now to make sure no races are possible if the OPP table is getting added and removed in parallel (which doesn't happen in practice, but can in theory). Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2019-11-11PM / OPP: Support adjusting OPP voltages at runtimeStephen Boyd
On some SoCs the Adaptive Voltage Scaling (AVS) technique is employed to optimize the operating voltage of a device. At a given frequency, the hardware monitors dynamic factors and either makes a suggestion for how much to adjust a voltage for the current frequency, or it automatically adjusts the voltage without software intervention. Add an API to the OPP library for the former case, so that AVS type devices can update the voltages for an OPP when the hardware determines the voltage should change. The assumption is that drivers like CPUfreq or devfreq will register for the OPP notifiers and adjust the voltage according to suggestions that AVS makes. This patch is derived from [1] submitted by Stephen. [1] https://lore.kernel.org/patchwork/patch/599279/ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> [Roger Lu: Changed to rcu less implementation] Signed-off-by: Roger Lu <roger.lu@mediatek.com> [s.nawrocki@samsung.com: added handling of OPP min/max voltage] Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2019-10-21opp: core: Revert "add regulators enable and disable"Marek Szyprowski
All the drivers, which use the OPP framework control regulators, which are already enabled. Typically those regulators are also system critical, due to providing power to CPU core or system buses. It turned out that there are cases, where calling regulator_enable() on such boot-enabled regulator has side-effects and might change its initial voltage due to performing initial voltage balancing without all restrictions from the consumers. Until this issue becomes finally solved in regulator core, avoid calling regulator_enable()/disable() from the OPP framework. This reverts commit 7f93ff73f7c8c8bfa6be33bcc16470b0b44682aa. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Mark Brown <broonie@kernel.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2019-07-26opp: core: add regulators enable and disablek.konieczny@partner.samsung.com
Add enable regulators to dev_pm_opp_set_regulators() and disable regulators to dev_pm_opp_put_regulators(). Even if bootloader leaves regulators enabled, they should be enabled in kernel in order to increase the reference count. Signed-off-by: Kamil Konieczny <k.konieczny@partner.samsung.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2019-07-26opp: Don't decrement uninitialized list_krefViresh Kumar
The list_kref was added for static OPPs and to track their users. The kref is initialized while the static OPPs are added, but removed unconditionally even if the static OPPs were never added. This causes refcount mismatch warnings currently. Fix that by always initializing the kref when the OPP table is first initialized. The refcount is later incremented only for the second user onwards. Fixes: d0e8ae6c26da ("OPP: Create separate kref for static OPPs list") Reported-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2019-07-26opp: Add dev_pm_opp_find_level_exact()Niklas Cassel
Since the performance states in the OPP table are unique, implement a dev_pm_opp_find_level_exact() in order to be able to fetch a specific OPP. Signed-off-by: Niklas Cassel <niklas.cassel@linaro.org> [ Viresh: Updated commit log ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2019-07-26opp: Return genpd virtual devices from dev_pm_opp_attach_genpd()Viresh Kumar
The cpufreq drivers don't need to do runtime PM operations on the virtual devices returned by dev_pm_domain_attach_by_name() and so the virtual devices weren't shared with the callers of dev_pm_opp_attach_genpd() earlier. But the IO device drivers would want to do that. This patch updates the prototype of dev_pm_opp_attach_genpd() to accept another argument to return the pointer to the array of genpd virtual devices. Reported-by: Rajendra Nayak <rnayak@codeaurora.org> Tested-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2019-07-26opp: Not all power-domains are scalableViresh Kumar
A device may have multiple power-domains and not all of them may be scalable (i.e. support performance states). But dev_pm_opp_attach_genpd() doesn't take that into account currently. Fix that by not verifying the names argument with "power-domain-names" DT property and finding the index into the required-opps array. The names argument will anyway get verified later on when we call dev_pm_domain_attach_by_name(). Fixes: 6319aee10e53 ("opp: Attach genpds to devices from within OPP core") Reported-by: Rajendra Nayak <rnayak@codeaurora.org> Tested-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2019-06-26Merge branch 'opp/linux-next' of ↵Rafael J. Wysocki
git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm Pull operating performance points (OPP) framework changes for v5.3 from Viresh Kumar: "This pull request contains: - OPP core changes to support a wider range of devices, like IO devices (Rajendra Nayak and Stehpen Boyd). - Fixes around genpd_virt_devs (Viresh Kumar). - Fix for platform with set_opp() callback (Dmitry Osipenko)." * 'opp/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: opp: Don't use IS_ERR on invalid supplies opp: Make dev_pm_opp_set_rate() handle freq = 0 to drop performance votes opp: Don't overwrite rounded clk rate opp: Allocate genpd_virt_devs from dev_pm_opp_attach_genpd() opp: Attach genpds to devices from within OPP core
2019-06-24opp: Don't use IS_ERR on invalid suppliesDmitry Osipenko
_set_opp_custom() receives a set of OPP supplies as its arguments and the caller of it passes NULL when the supplies are not valid. But _set_opp_custom(), by mistake, checks for error by performing IS_ERR(old_supply) on it which will always evaluate to false. The problem was spotted during of testing of upcoming update for the NVIDIA Tegra CPUFreq driver. Cc: stable <stable@vger.kernel.org> Fixes: 7e535993fa4f ("OPP: Separate out custom OPP handler specific code") Reported-by: Marc Dietrich <marvin24@gmx.de> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> [ Viresh: Massaged changelog ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2019-06-19treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500Thomas Gleixner
Based on 2 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms of the gnu general public license version 2 as published by the free software foundation this program is free software you can redistribute it and or modify it under the terms of the gnu general public license version 2 as published by the free software foundation # extracted by the scancode license scanner the SPDX license identifier GPL-2.0-only has been chosen to replace the boilerplate/reference in 4122 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Enrico Weigelt <info@metux.net> Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org> Reviewed-by: Allison Randal <allison@lohutok.net> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190604081206.933168790@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-17opp: Make dev_pm_opp_set_rate() handle freq = 0 to drop performance votesRajendra Nayak
For devices with performance state, we use dev_pm_opp_set_rate() to set the appropriate clk rate and the performance state. We do need a way to remove the performance state vote when we idle the device and turn the clocks off. Use dev_pm_opp_set_rate() with freq = 0 to achieve this. Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Stephen Boyd <swboyd@chromium.org> [ Viresh: Updated _set_required_opps() to handle the !opp case ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>