X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Ftimer%2Ftimer-uclass.c;h=97a4c7485189bbb5877681268f70ea8b6cadadcb;hb=edf0acb3b462732cc236f2a8d00abb82abebf38d;hp=382c0f2bd15dbb961a764a2be2c4f50256973ff8;hpb=d5c6144fe326e255e42ec273fc5d88f45cd61548;p=oweals%2Fu-boot.git diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c index 382c0f2bd1..97a4c74851 100644 --- a/drivers/timer/timer-uclass.c +++ b/drivers/timer/timer-uclass.c @@ -1,13 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2015 Thomas Chou - * - * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include +#include +#include #include #include @@ -41,10 +42,27 @@ unsigned long notrace timer_get_rate(struct udevice *dev) static int timer_pre_probe(struct udevice *dev) { +#if !CONFIG_IS_ENABLED(OF_PLATDATA) struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct clk timer_clk; + int err; + ulong ret; - uc_priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev->of_offset, - "clock-frequency", 0); + /* It is possible that a timer device has a null ofnode */ + if (!dev_of_valid(dev)) + return 0; + + err = clk_get_by_index(dev, 0, &timer_clk); + if (!err) { + ret = clk_get_rate(&timer_clk); + if (IS_ERR_VALUE(ret)) + return ret; + uc_priv->clock_rate = ret; + } else { + uc_priv->clock_rate = + dev_read_u32_default(dev, "clock-frequency", 0); + } +#endif return 0; } @@ -70,36 +88,43 @@ u64 timer_conv_64(u32 count) int notrace dm_timer_init(void) { - const void *blob = gd->fdt_blob; struct udevice *dev = NULL; - int node; + __maybe_unused ofnode node; int ret; if (gd->timer) return 0; + /* + * Directly access gd->dm_root to suppress error messages, if the + * virtual root driver does not yet exist. + */ + if (gd->dm_root == NULL) + return -EAGAIN; + +#if !CONFIG_IS_ENABLED(OF_PLATDATA) /* Check for a chosen timer to be used for tick */ - node = fdtdec_get_chosen_node(blob, "tick-timer"); - if (node < 0) { - /* No chosen timer, trying first available timer */ - ret = uclass_first_device(UCLASS_TIMER, &dev); + node = ofnode_get_chosen_node("tick-timer"); + + if (ofnode_valid(node) && + uclass_get_device_by_ofnode(UCLASS_TIMER, node, &dev)) { + /* + * If the timer is not marked to be bound before + * relocation, bind it anyway. + */ + if (!lists_bind_fdt(dm_root(), node, &dev, false)) { + ret = device_probe(dev); + if (ret) + return ret; + } + } +#endif + + if (!dev) { + /* Fall back to the first available timer */ + ret = uclass_first_device_err(UCLASS_TIMER, &dev); if (ret) return ret; - if (!dev) - return -ENODEV; - } else { - if (uclass_get_device_by_of_offset(UCLASS_TIMER, node, &dev)) { - /* - * If the timer is not marked to be bound before - * relocation, bind it anyway. - */ - if (node > 0 && - !lists_bind_fdt(gd->dm_root, blob, node, &dev)) { - ret = device_probe(dev); - if (ret) - return ret; - } - } } if (dev) {