linux/drivers/base
Stephan Gerhold dd461cd918 opp: Allow dev_pm_opp_get_opp_table() to return -EPROBE_DEFER
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-25 11:08:54 +05:30
..
firmware_loader firmware_loader: EFI firmware loader must handle pre-allocated buffer 2020-07-25 12:06:33 +02:00
power opp: Allow dev_pm_opp_get_opp_table() to return -EPROBE_DEFER 2020-08-25 11:08:54 +05:30
regmap regmap: Fixes for v5.8 2020-07-17 09:58:18 -07:00
test drivers: base: default KUNIT_* fragments to KUNIT_ALL_TESTS 2020-06-01 14:24:25 -06:00
arch_topology.c arch_topology, sched/core: Cleanup thermal pressure definition 2020-07-22 10:22:05 +02:00
attribute_container.c scsi: drivers: base: Support atomic version of attribute_container_device_trigger 2020-01-15 22:55:36 -05:00
base.h driver core: add deferring probe reason to devices_deferred property 2020-07-30 09:03:43 +02:00
bus.c device.h: move 'struct bus' stuff out to device/bus.h 2019-12-16 10:11:12 +01:00
cacheinfo.c Driver Core and debugfs changes for 5.3-rc1 2019-07-12 12:24:03 -07:00
class.c device.h: move 'struct class' stuff out to device/class.h 2019-12-16 10:11:14 +01:00
component.c component: Silence bind error on -EPROBE_DEFER 2020-04-28 17:54:15 +02:00
container.c
core.c Devicetree updates for v5.9: 2020-08-05 13:02:45 -07:00
cpu.c x86/speculation: Add Special Register Buffer Data Sampling (SRBDS) mitigation 2020-04-20 12:19:22 +02:00
dd.c driver core: add deferring probe reason to devices_deferred property 2020-07-30 09:03:43 +02:00
devcon.c Merge generic_lookup_helpers into usb-next 2019-09-03 17:11:07 +02:00
devcoredump.c devcoredump: fix typo in comment 2019-08-15 17:38:11 +02:00
devres.c devres: handle zero size in devm_kmalloc() 2020-07-02 14:36:02 +02:00
devtmpfs.c init: add an init_chroot helper 2020-07-31 08:17:52 +02:00
driver.c drivers: base: Convert to printk alias functions 2020-07-10 14:16:44 +02:00
firmware.c
hypervisor.c
init.c base: fix order of OF initialization 2018-07-07 17:54:29 +02:00
isa.c
Kconfig drivers: base: default KUNIT_* fragments to KUNIT_ALL_TESTS 2020-06-01 14:24:25 -06:00
Makefile drivers: base: Introducing software nodes to the firmware node framework 2018-11-26 18:19:11 +01:00
map.c
memory.c drivers/base/memory: rename base_memory_block_id to memory_block_id 2020-07-10 14:38:44 +02:00
module.c
node.c mm: memcontrol: account kernel stack per node 2020-08-07 11:33:25 -07:00
pinctrl.c
platform-msi.c platform-msi: Fix typos in comment 2020-05-18 10:28:30 +01:00
platform.c driver core: platform: expose numa_node to users in sysfs 2020-07-10 14:14:37 +02:00
property.c device property: Avoid NULL pointer dereference in device_get_next_child_node() 2020-07-23 17:04:28 +02:00
soc.c driver/base/soc: Use kobj_to_dev() API 2020-04-28 21:05:42 +02:00
swnode.c software node: Use software_node_unregister() when unregistering group of nodes 2020-07-10 14:35:37 +02:00
syscore.c treewide: Switch printk users from %pf and %pF to %ps and %pS, respectively 2019-04-09 14:19:06 +02:00
topology.c topology: mark a function as __init to save some memory 2020-07-10 14:35:37 +02:00
transport_class.c scsi: drivers: base: Propagate errors through the transport component 2020-01-15 22:55:37 -05:00