
Relocate cpu_ops pointers when CONFIG_NEEDS_MANUAL_RELOC is enabled.
The (gd->flags & GD_FLG_RELOC) check was added to make sure the reloc_done logic works for drivers that use DM_FLAG_PRE_RELOC.
Signed-off-by: Ovidiu Panait ovpanait@gmail.com ---
Changes in v2: - New patch.
drivers/cpu/cpu-uclass.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c index a5cda6a62c..71e5900d70 100644 --- a/drivers/cpu/cpu-uclass.c +++ b/drivers/cpu/cpu-uclass.c @@ -14,6 +14,9 @@ #include <dm/lists.h> #include <dm/root.h> #include <linux/err.h> +#include <relocate.h> + +DECLARE_GLOBAL_DATA_PTR;
int cpu_probe_all(void) { @@ -136,9 +139,36 @@ static int uclass_cpu_init(struct uclass *uc) return ret; }
+static int uclass_cpu_post_bind(struct udevice *dev) +{ + if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC) && + (gd->flags & GD_FLG_RELOC)) { + struct cpu_ops *ops = cpu_get_ops(dev); + static int reloc_done; + + if (!reloc_done) { + if (ops->get_desc) + MANUAL_RELOC(ops->get_desc); + if (ops->get_info) + MANUAL_RELOC(ops->get_info); + if (ops->get_count) + MANUAL_RELOC(ops->get_count); + if (ops->get_vendor) + MANUAL_RELOC(ops->get_vendor); + if (ops->is_current) + MANUAL_RELOC(ops->is_current); + + reloc_done++; + } + } + + return 0; +} + UCLASS_DRIVER(cpu) = { .id = UCLASS_CPU, .name = "cpu", .flags = DM_UC_FLAG_SEQ_ALIAS, .init = uclass_cpu_init, + .post_bind = uclass_cpu_post_bind, };